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) } }