mirror of
https://github.com/lone-cloud/prism
synced 2026-06-03 08:43:10 -07:00
112 lines
2.3 KiB
Go
112 lines
2.3 KiB
Go
package proton
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"prism/service/notification"
|
|
|
|
"github.com/emersion/go-imap"
|
|
)
|
|
|
|
func (m *Monitor) handleNewMessages() error {
|
|
criteria := imap.NewSearchCriteria()
|
|
criteria.WithoutFlags = []string{m.cfg.IMAPSeenFlag}
|
|
|
|
uids, err := m.client.UidSearch(criteria)
|
|
if err != nil {
|
|
return fmt.Errorf("search failed: %w", err)
|
|
}
|
|
|
|
if len(uids) == 0 {
|
|
return nil
|
|
}
|
|
|
|
seqSet := new(imap.SeqSet)
|
|
seqSet.AddNum(uids...)
|
|
|
|
messages := make(chan *imap.Message, 10)
|
|
done := make(chan error, 1)
|
|
|
|
go func() {
|
|
done <- m.client.UidFetch(seqSet, []imap.FetchItem{imap.FetchEnvelope, imap.FetchUid}, messages)
|
|
}()
|
|
|
|
for msg := range messages {
|
|
if err := m.processMessage(msg); err != nil {
|
|
m.logger.Error("Failed to process message", "error", err)
|
|
}
|
|
}
|
|
|
|
if err := <-done; err != nil {
|
|
return fmt.Errorf("fetch failed: %w", err)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (m *Monitor) processMessage(msg *imap.Message) error {
|
|
if msg.Envelope == nil {
|
|
return nil
|
|
}
|
|
|
|
if msg.Envelope.Date.Before(m.monitorStartTime) {
|
|
m.logger.Debug("Skipping old email", "date", msg.Envelope.Date, "subject", msg.Envelope.Subject)
|
|
return nil
|
|
}
|
|
|
|
var from string
|
|
if len(msg.Envelope.From) > 0 {
|
|
addr := msg.Envelope.From[0]
|
|
if addr.PersonalName != "" {
|
|
from = addr.PersonalName
|
|
} else {
|
|
from = addr.Address()
|
|
}
|
|
} else {
|
|
from = "Unknown sender"
|
|
}
|
|
|
|
subject := msg.Envelope.Subject
|
|
if subject == "" {
|
|
subject = "No subject"
|
|
}
|
|
|
|
endpoint := m.cfg.EndpointPrefixProton + m.cfg.ProtonPrismTopic
|
|
|
|
notif := notification.Notification{
|
|
Title: from,
|
|
Message: subject,
|
|
Actions: []notification.Action{
|
|
{
|
|
ID: "mark-read",
|
|
Endpoint: "/api/proton-mail/mark-read",
|
|
Method: "POST",
|
|
Data: map[string]interface{}{
|
|
"uid": msg.Uid,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
if err := m.dispatcher.Send(endpoint, notif); err != nil {
|
|
m.logger.Error("Failed to send notification", "endpoint", endpoint, "error", err)
|
|
return err
|
|
}
|
|
|
|
m.logger.Info("Processed Proton Mail notification", "from", from, "subject", subject)
|
|
return nil
|
|
}
|
|
|
|
func (m *Monitor) MarkAsRead(uid uint32) error {
|
|
if m.client == nil {
|
|
return fmt.Errorf("not connected")
|
|
}
|
|
|
|
seqSet := new(imap.SeqSet)
|
|
seqSet.AddNum(uid)
|
|
|
|
item := imap.FormatFlagsOp(imap.AddFlags, true)
|
|
flags := []interface{}{m.cfg.IMAPSeenFlag}
|
|
|
|
return m.client.UidStore(seqSet, item, flags, nil)
|
|
}
|