UNPKG

3.94 kBJavaScriptView Raw
1const oauth2Client = require('./auth')
2const google = require('googleapis')
3const gmail = google.gmail({ version: 'v1' })
4const btoa = require('btoa')
5const chalk = require('chalk')
6const db = require('./db')
7const base64url = require('base64-url')
8const createFetch = require('./create-fetch')
9
10async function getMessagesList ({
11 filter,
12 next,
13 accessToken
14}) {
15 const params = {
16 maxResults: 10
17 }
18 if (filter) {
19 params.q = filter
20 }
21 if (next) {
22 params.pageToken = next
23 }
24 const { messages, nextPageToken } = await createFetch({
25 accessToken,
26 endpoint: '/gmail/v1/users/me/messages',
27 base: 'https://www.googleapis.com',
28 params
29 })
30 return { messages, nextPageToken }
31}
32
33async function getEmail (params) {
34 const { accessToken, id, format = 'metadata' } = params
35 const endpoint = `/gmail/v1/users/me/messages/${id}`
36 return createFetch({ accessToken, endpoint, params: { format } })
37}
38
39async function getEmails ({ accessToken, messages, format }) {
40 if (!format) format = 'metadata'
41
42 return Promise.all(messages.map((message) => {
43 const endpoint = `/gmail/v1/users/me/messages/${message.id}`
44 return createFetch({ accessToken, endpoint, params: { format } })
45 }))
46}
47
48class Client {
49 constructor (oauth2Client, account) {
50 oauth2Client.setCredentials(account.tokens)
51 this.oauth2Client = oauth2Client
52 this.accessToken = account.tokens.access_token
53 this.account = account
54 }
55
56 static async create (account) {
57 let auth = await oauth2Client()
58 return new Client(auth, account)
59 }
60
61 send ({ text, sender, recipient, subject }) {
62 const base64Encoded = btoa([
63 'Content-Type: text/plain; charset=\"UTF-8\"',
64 'MIME-Version: 1.0',
65 `Subject: ${subject}`,
66 `From: ${sender}`,
67 `To: ${recipient}\n`,
68 `${text}`
69 ].join('\n')).replace(/\+/g, '-').replace(/\//g, '_')
70 gmail.users.messages.send({
71 auth: this.oauth2Client,
72 userId: 'me',
73 resource: { raw: base64Encoded }
74 })
75 }
76
77 reply ({
78 text,
79 sender,
80 recipient,
81 subject,
82 threadId
83 }) {
84 const arr = [
85 'Content-Type: text/plain; charset=\"UTF-8\"',
86 'MIME-Version: 1.0',
87 `Subject: ${subject}`,
88 `From: ${sender}`,
89 `To: ${recipient}\n`,
90 `${text}`
91 ]
92 console.log(chalk.cyan(arr.join('\n')))
93 const base64EncodedEmail = btoa(arr.join('\n'))
94 .replace(/\+/g, '-')
95 .replace(/\//g, '_')
96
97 gmail.users.messages.send({
98 auth: this.oauth2Client,
99 userId: 'me',
100 resource: {
101 raw: base64EncodedEmail,
102 threadId
103 }
104 })
105 }
106
107 async fetchMessages (page, filter) {
108 const store = db.get('messages')
109 const next = db.get(`pages.${page}`, undefined).value()
110 const resp = await getMessagesList({
111 accessToken: this.accessToken,
112 next,
113 filter
114 })
115 db.set(`pages.${page + 1}`, resp.nextPageToken).write()
116
117 let _messages = resp.messages.filter(message =>
118 !store.find({id: message.id}).value()
119 )
120
121 if (_messages && _messages.length) {
122 const messages = await getEmails({
123 accessToken: this.accessToken,
124 messages: _messages,
125 format: 'full'
126 })
127 db.set(
128 'messages',
129 messages.concat(store.value()).sort((a, b) =>
130 parseInt(b.internalDate) - parseInt(a.internalDate)
131 )
132 ).write()
133 }
134 }
135
136 async getMessage (id) {
137 let message = db.get('messages').find(message => message.id === id)
138 let accessToken = this.account.tokens.access_token
139 let raw = await getEmail({ accessToken, id, format: 'raw' })
140 let source = base64url.decode(raw.raw)
141 return {
142 source,
143 message,
144 raw
145 }
146 }
147
148 deleteMessage (messageId) {
149 gmail.users.messages.trash({
150 auth: this.oauth2Client,
151 userId: 'me',
152 id: messageId
153 })
154 db.get('messages').remove({id: messageId}).write()
155 }
156}
157
158module.exports = Client