auto deployment und tests
This commit is contained in:
@@ -126,6 +126,52 @@ func (cl *Client) FetchUnread() ([]Message, error) {
|
||||
return parseMessages(msgs), nil
|
||||
}
|
||||
|
||||
// FetchUnreadSeqNums holt ungelesene Emails und gibt zusätzlich die Sequenznummern zurück.
|
||||
// Selektiert den Ordner im Lese-Schreib-Modus (für nachfolgendes Verschieben).
|
||||
func (cl *Client) FetchUnreadSeqNums() ([]Message, []uint32, error) {
|
||||
folder := config.Cfg.Email.Folder
|
||||
if folder == "" {
|
||||
folder = "INBOX"
|
||||
}
|
||||
|
||||
if _, err := cl.c.Select(folder, nil).Wait(); err != nil {
|
||||
return nil, nil, fmt.Errorf("IMAP select: %w", err)
|
||||
}
|
||||
|
||||
searchData, err := cl.c.Search(&imap.SearchCriteria{
|
||||
NotFlag: []imap.Flag{imap.FlagSeen},
|
||||
}, nil).Wait()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("IMAP search: %w", err)
|
||||
}
|
||||
|
||||
seqNums := searchData.AllSeqNums()
|
||||
if len(seqNums) == 0 {
|
||||
return nil, nil, nil
|
||||
}
|
||||
|
||||
var seqSet imap.SeqSet
|
||||
seqSet.AddNum(seqNums...)
|
||||
|
||||
msgs, err := cl.c.Fetch(seqSet, &imap.FetchOptions{Envelope: true}).Collect()
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("IMAP fetch: %w", err)
|
||||
}
|
||||
|
||||
return parseMessages(msgs), seqNums, nil
|
||||
}
|
||||
|
||||
// MoveMessages verschiebt Nachrichten in einen anderen IMAP-Ordner.
|
||||
// Der Ordner muss im Lese-Schreib-Modus selektiert sein (via FetchUnreadSeqNums).
|
||||
func (cl *Client) MoveMessages(seqNums []uint32, destFolder string) error {
|
||||
var seqSet imap.SeqSet
|
||||
seqSet.AddNum(seqNums...)
|
||||
if _, err := cl.c.Move(seqSet, destFolder).Wait(); err != nil {
|
||||
return fmt.Errorf("IMAP move: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseMessages(msgs []*imapclient.FetchMessageBuffer) []Message {
|
||||
result := make([]Message, 0, len(msgs))
|
||||
for _, msg := range msgs {
|
||||
|
||||
@@ -19,6 +19,7 @@ func Summarize() (string, error) {
|
||||
}
|
||||
|
||||
// SummarizeUnread fasst ungelesene Emails zusammen.
|
||||
// Wenn email.processed_folder konfiguriert ist, werden die Emails danach dorthin verschoben.
|
||||
func SummarizeUnread() (string, error) {
|
||||
cl, err := Connect()
|
||||
if err != nil {
|
||||
@@ -26,7 +27,16 @@ func SummarizeUnread() (string, error) {
|
||||
}
|
||||
defer cl.Close()
|
||||
|
||||
msgs, err := cl.FetchUnread()
|
||||
processedFolder := config.Cfg.Email.ProcessedFolder
|
||||
|
||||
var msgs []Message
|
||||
var seqNums []uint32
|
||||
|
||||
if processedFolder != "" {
|
||||
msgs, seqNums, err = cl.FetchUnreadSeqNums()
|
||||
} else {
|
||||
msgs, err = cl.FetchUnread()
|
||||
}
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("Emails abrufen: %w", err)
|
||||
}
|
||||
@@ -35,7 +45,21 @@ func SummarizeUnread() (string, error) {
|
||||
}
|
||||
|
||||
slog.Info("Email-Zusammenfassung gestartet", "anzahl", len(msgs), "typ", "unread")
|
||||
return summarizeWithLLM(msgs, "Fasse diese ungelesenen Emails zusammen. Hebe wichtige, dringende oder actionable Emails hervor.")
|
||||
result, err := summarizeWithLLM(msgs, "Fasse diese ungelesenen Emails zusammen. Hebe wichtige, dringende oder actionable Emails hervor.")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Nach dem Zusammenfassen: Emails in Processed-Ordner verschieben
|
||||
if processedFolder != "" && len(seqNums) > 0 {
|
||||
if moveErr := cl.MoveMessages(seqNums, processedFolder); moveErr != nil {
|
||||
slog.Warn("Emails konnten nicht verschoben werden", "fehler", moveErr, "ordner", processedFolder)
|
||||
} else {
|
||||
slog.Info("Emails verschoben", "anzahl", len(seqNums), "ordner", processedFolder)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// ExtractReminders sucht in den letzten Emails nach Terminen/Deadlines.
|
||||
|
||||
Reference in New Issue
Block a user