Skip to content

Commit 7c9c486

Browse files
authored
fix!: append sent emails to the SENT folder (#496)
1 parent 0ab333a commit 7c9c486

File tree

5 files changed

+103
-52
lines changed

5 files changed

+103
-52
lines changed

backend/imap/imap.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package imap
44

55
import (
66
"context"
7+
"log"
78

89
"github.com/floatpane/matcha/backend"
910
"github.com/floatpane/matcha/config"
@@ -76,14 +77,28 @@ func (p *Provider) MoveEmails(_ context.Context, uids []uint32, srcFolder, dstFo
7677
}
7778

7879
func (p *Provider) SendEmail(_ context.Context, msg *backend.OutgoingEmail) error {
79-
return sender.SendEmail(
80+
rawMsg, err := sender.SendEmail(
8081
p.account, msg.To, msg.Cc, msg.Bcc,
8182
msg.Subject, msg.PlainBody, msg.HTMLBody,
8283
msg.Images, msg.Attachments,
8384
msg.InReplyTo, msg.References,
8485
msg.SignSMIME, msg.EncryptSMIME,
8586
msg.SignPGP, msg.EncryptPGP,
8687
)
88+
if err != nil {
89+
return err
90+
}
91+
92+
// Gmail automatically saves sent messages server-side; skip APPEND to avoid duplicates.
93+
if p.account.ServiceProvider == "gmail" {
94+
return nil
95+
}
96+
97+
if err := fetcher.AppendToSentMailbox(p.account, rawMsg); err != nil {
98+
log.Printf("Failed to append sent message to Sent folder: %v", err)
99+
}
100+
101+
return nil
87102
}
88103

89104
func (p *Provider) FetchFolders(_ context.Context) ([]backend.Folder, error) {

backend/pop3/pop3.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,15 @@ func (p *Provider) MoveEmails(_ context.Context, _ []uint32, _, _ string) error
224224
}
225225

226226
func (p *Provider) SendEmail(_ context.Context, msg *backend.OutgoingEmail) error {
227-
return sender.SendEmail(
227+
_, err := sender.SendEmail(
228228
p.account, msg.To, msg.Cc, msg.Bcc,
229229
msg.Subject, msg.PlainBody, msg.HTMLBody,
230230
msg.Images, msg.Attachments,
231231
msg.InReplyTo, msg.References,
232232
msg.SignSMIME, msg.EncryptSMIME,
233233
msg.SignPGP, msg.EncryptPGP,
234234
)
235+
return err
235236
}
236237

237238
func (p *Provider) FetchFolders(_ context.Context) ([]backend.Folder, error) {

fetcher/fetcher.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,6 +1274,19 @@ func ArchiveSentEmail(account *config.Account, uid uint32) error {
12741274
return ArchiveEmailFromMailbox(account, getSentMailbox(account), uid)
12751275
}
12761276

1277+
// AppendToSentMailbox appends a raw RFC822 message to the Sent mailbox via IMAP APPEND.
1278+
func AppendToSentMailbox(account *config.Account, msg []byte) error {
1279+
c, err := connect(account)
1280+
if err != nil {
1281+
return err
1282+
}
1283+
defer c.Logout()
1284+
1285+
sentMailbox := getSentMailbox(account)
1286+
flags := []string{imap.SeenFlag}
1287+
return c.Append(sentMailbox, flags, time.Now(), bytes.NewReader(msg))
1288+
}
1289+
12771290
// getTrashMailbox returns the trash mailbox name for the account
12781291
func getTrashMailbox(account *config.Account) string {
12791292
switch account.ServiceProvider {

main.go

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2004,11 +2004,19 @@ func sendEmail(account *config.Account, msg tui.SendEmailMsg) tea.Cmd {
20042004
attachments[filename] = fileData
20052005
}
20062006

2007-
err := sender.SendEmail(account, recipients, cc, bcc, msg.Subject, body, string(htmlBody), images, attachments, msg.InReplyTo, msg.References, msg.SignSMIME, msg.EncryptSMIME, msg.SignPGP, false)
2007+
rawMsg, err := sender.SendEmail(account, recipients, cc, bcc, msg.Subject, body, string(htmlBody), images, attachments, msg.InReplyTo, msg.References, msg.SignSMIME, msg.EncryptSMIME, msg.SignPGP, false)
20082008
if err != nil {
20092009
log.Printf("Failed to send email: %v", err)
20102010
return tui.EmailResultMsg{Err: err}
20112011
}
2012+
2013+
// Append to Sent folder via IMAP (Gmail auto-saves, so skip it)
2014+
if account.ServiceProvider != "gmail" {
2015+
if err := fetcher.AppendToSentMailbox(account, rawMsg); err != nil {
2016+
log.Printf("Failed to append sent message to Sent folder: %v", err)
2017+
}
2018+
}
2019+
20122020
return tui.EmailResultMsg{}
20132021
}
20142022
}
@@ -2771,12 +2779,19 @@ func runSendCLI(args []string) {
27712779
ccList := splitEmails(*cc)
27722780
bccList := splitEmails(*bcc)
27732781

2774-
err = sender.SendEmail(account, recipients, ccList, bccList, *subject, emailBody, string(htmlBody), images, attachMap, "", nil, *signSMIME, *encryptSMIME, *signPGP, false)
2775-
if err != nil {
2776-
fmt.Fprintf(os.Stderr, "Error: %v\n", err)
2782+
rawMsg, sendErr := sender.SendEmail(account, recipients, ccList, bccList, *subject, emailBody, string(htmlBody), images, attachMap, "", nil, *signSMIME, *encryptSMIME, *signPGP, false)
2783+
if sendErr != nil {
2784+
fmt.Fprintf(os.Stderr, "Error: %v\n", sendErr)
27772785
os.Exit(1)
27782786
}
27792787

2788+
// Append to Sent folder via IMAP (Gmail auto-saves, so skip it)
2789+
if account.ServiceProvider != "gmail" {
2790+
if err := fetcher.AppendToSentMailbox(account, rawMsg); err != nil {
2791+
log.Printf("Failed to append sent message to Sent folder: %v", err)
2792+
}
2793+
}
2794+
27802795
fmt.Println("Email sent successfully.")
27812796
}
27822797

0 commit comments

Comments
 (0)