imap-json-fetcher/main.go

109 lines
2.5 KiB
Go

package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"time"
"github.com/emersion/go-imap"
"github.com/emersion/go-imap/client"
"github.com/emersion/go-message/mail"
)
func main() {
host := os.Getenv("IMAP_HOST")
username := os.Getenv("IMAP_USERNAME")
password := os.Getenv("IMAP_PASSWORD")
if host == "" || username == "" || password == "" {
log.Fatal("Environment variables IMAP_HOST, IMAP_USERNAME, and IMAP_PASSWORD must be set")
}
log.Println("Connecting to server...")
// Connect to the IMAP server
c, err := client.DialTLS(host, nil)
if err != nil {
log.Fatalf("Failed to connect to IMAP server: %v", err)
}
log.Println("Connected")
defer c.Logout()
// Login
if err := c.Login(username, password); err != nil {
log.Fatalf("Failed to log in: %v", err)
}
log.Println("Logged in")
// Select INBOX
_, err = c.Select("INBOX", false)
if err != nil {
log.Fatalf("Failed to select INBOX: %v", err)
}
// Set up criteria to search for new unseen emails
criteria := imap.NewSearchCriteria()
criteria.WithoutFlags = []string{imap.SeenFlag}
ids, err := c.Search(criteria)
if err != nil {
log.Fatalf("Failed to search emails: %v", err)
}
if len(ids) == 0 {
log.Println("No new emails")
return
}
seqset := new(imap.SeqSet)
seqset.AddNum(ids...)
section := &imap.BodySectionName{}
items := []imap.FetchItem{section.FetchItem(), imap.FetchEnvelope}
messages := make(chan *imap.Message)
go func() {
if err := c.Fetch(seqset, items, messages); err != nil {
log.Fatalf("Failed to fetch emails: %v", err)
}
}()
for msg := range messages {
if msg == nil {
continue
}
r := mail.NewReader(msg.GetBody(section))
email, err := r.NextPart()
if err != nil {
log.Fatalf("Failed to read message body: %v", err)
}
body, err := ioutil.ReadAll(email)
if err != nil {
log.Fatalf("Failed to read body content: %v", err)
}
emailData := map[string]interface{}{
"subject": msg.Envelope.Subject,
"from": msg.Envelope.From,
"to": msg.Envelope.To,
"date": msg.Envelope.Date,
"body": string(body),
}
emailJSON, err := json.MarshalIndent(emailData, "", " ")
if err != nil {
log.Fatalf("Failed to marshal JSON: %v", err)
}
timestamp := time.Now().Format("20060102-150405")
fileName := fmt.Sprintf("email-%s.json", timestamp)
err = os.WriteFile(fileName, emailJSON, 0644)
if err != nil {
log.Fatalf("Failed to write file %s: %v", fileName, err)
}
log.Printf("Saved %s", fileName)
}
}