summaryrefslogtreecommitdiff
path: root/jobs/emails.go
blob: f5abda8f0ec58efe6eb6d25fd566193f89f1bf6c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package jobs

import (
	"fmt"
	"lain/database"
	"lain/models"
	"lain/repository"
	"lain/utils/crypto"
	"lain/utils/email"
	"lain/utils/format"
	"lain/utils/storage"
	"strings"
)

func SyncEmails(userEmail string, folderID uint, folderPath string) error {
	var prefs models.Preferences
	if err := database.DB.Where("email = ?", userEmail).First(&prefs).Error; err != nil {
		return err
	}

	password, err := crypto.Decrypt(prefs.Authorization)
	if err != nil {
		return err
	}

	client, err := email.ConnectIMAP(userEmail, password)
	if err != nil {
		return err
	}
	defer email.DisconnectIMAP(client)

	messages, err := email.FetchMessages(client, folderPath, 50)
	if err != nil {
		return fmt.Errorf("failed to fetch messages: %w", err)
	}

	for _, msg := range messages {
		exists, err := repository.EmailExists(userEmail, folderID, msg.UID)
		if err != nil {
			continue
		}
		if exists {
			continue
		}

		snippet := format.GenerateSnippet(msg.BodyText, msg.BodyHTML)

		message := models.Email{
			UserEmail:     userEmail,
			FolderID:      folderID,
			UID:           msg.UID,
			MessageID:     msg.MessageID,
			From:          msg.From,
			FromName:      msg.FromName,
			To:            strings.Join(msg.To, ", "),
			CC:            strings.Join(msg.CC, ", "),
			BCC:           strings.Join(msg.BCC, ", "),
			ReplyTo:       strings.Join(msg.ReplyTo, ", "),
			Subject:       msg.Subject,
			Date:          msg.Date,
			BodyText:      msg.BodyText,
			BodyHTML:      msg.BodyHTML,
			RawHeaders:    msg.RawHeaders,
			Snippet:       snippet,
			Size:          int64(msg.Size),
			InReplyTo:     msg.InReplyTo,
			IsRead:        msg.IsRead,
			IsFlagged:     msg.IsFlagged,
			IsAnswered:    msg.IsAnswered,
			IsDraft:       msg.IsDraft,
			HasAttachment: msg.HasAttachment,
		}

		createdMessage, err := repository.CreateEmail(&message)
		if err != nil {
			continue
		}

		for _, att := range msg.Attachments {
			path, err := storage.UploadAttachment(userEmail, createdMessage.ID, att.Filename, att.Data, att.ContentType)
			if err != nil {
				continue
			}

			attachment := models.Attachment{
				EmailID:     createdMessage.ID,
				Filename:    att.Filename,
				ContentType: att.ContentType,
				Size:        int64(len(att.Data)),
				MinIOPath:   path,
			}

			repository.CreateAttachment(&attachment)
		}
	}

	return nil
}