-
Notifications
You must be signed in to change notification settings - Fork 0
/
gmail.go
146 lines (113 loc) · 3.58 KB
/
gmail.go
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package gmail
import (
"context"
"crypto/rand"
"encoding/base64"
"io/ioutil"
"log"
"net/http"
"github.com/pkg/errors"
"google.golang.org/api/gmail/v1"
"google.golang.org/api/option"
)
type Service struct {
service *gmail.Service
}
// NewService returns new service instance
func NewService(client *http.Client) (*Service, error) {
srv, err := gmail.NewService(context.Background(), option.WithHTTPClient(client))
if err != nil {
return &Service{}, errors.Wrap(err, "unable to retrieve Drive client")
}
return &Service{
service: srv,
}, nil
}
func (s *Service) SendMessage(userID string, message gmail.Message) error {
_, err := s.service.Users.Messages.Send(userID, &message).Do()
return err
}
func CreateMessage(from string, to string, subject string, content string) gmail.Message {
var message gmail.Message
messageBody := []byte("From: " + from + "\r\n" +
"To: " + to + "\r\n" +
"Subject: " + subject + "\r\n\r\n" +
content)
message.Raw = base64.StdEncoding.EncodeToString(messageBody)
return message
}
func ChunkSplit(body string, limit int, end string) string {
var charSlice []rune
// push characters to slice
for _, char := range body {
charSlice = append(charSlice, char)
}
var result string = ""
for len(charSlice) >= 1 {
// convert slice/array back to string
// but insert end at specified limit
result = result + string(charSlice[:limit]) + end
// discard the elements that were copied over to result
charSlice = charSlice[limit:]
// change the limit
// to cater for the last few words in
//
if len(charSlice) < limit {
limit = len(charSlice)
}
}
return result
}
func randStr(strSize int, randType string) string {
var dictionary string
if randType == "alphanum" {
dictionary = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
}
if randType == "alpha" {
dictionary = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
}
if randType == "number" {
dictionary = "0123456789"
}
var bytes = make([]byte, strSize)
_, err := rand.Read(bytes)
if err != nil {
return ""
}
for k, v := range bytes {
bytes[k] = dictionary[v%byte(len(dictionary))]
}
return string(bytes)
}
func CreateMessageWithAttachment(from string, to string, subject string, content string, fileDir string, fileName string) gmail.Message {
var message gmail.Message
// read file for attachment purpose
fileBytes, err := ioutil.ReadFile(fileDir + fileName)
if err != nil {
log.Fatalf("Unable to read file for attachment: %v", err)
}
fileMIMEType := http.DetectContentType(fileBytes)
fileData := base64.StdEncoding.EncodeToString(fileBytes)
boundary := randStr(32, "alphanum")
messageBody := []byte("Content-Type: multipart/mixed; boundary=" + boundary + " \n" +
"MIME-Version: 1.0\n" +
"to: " + to + "\n" +
"from: " + from + "\n" +
"subject: " + subject + "\n\n" +
"--" + boundary + "\n" +
"Content-Type: text/plain; charset=" + string('"') + "UTF-8" + string('"') + "\n" +
"MIME-Version: 1.0\n" +
"Content-Transfer-Encoding: 7bit\n\n" +
content + "\n\n" +
"--" + boundary + "\n" +
"Content-Type: " + fileMIMEType + "; name=" + string('"') + fileName + string('"') + " \n" +
"MIME-Version: 1.0\n" +
"Content-Transfer-Encoding: base64\n" +
"Content-Disposition: attachment; filename=" + string('"') + fileName + string('"') + " \n\n" +
ChunkSplit(fileData, 76, "\n") +
"--" + boundary + "--")
// see https://godoc.org/google.golang.org/api/gmail/v1#Message on .Raw
// use URLEncoding here !! StdEncoding will be rejected by Google API
message.Raw = base64.URLEncoding.EncodeToString(messageBody)
return message
}