From 9d19d9c4e8548596d367f23ca34a750b68065521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C4=B1dvan=20Akca?= Date: Tue, 23 Apr 2024 11:54:56 +0200 Subject: [PATCH] feat(gmail): add send email action --- .../backend/src/apps/gmail/actions/index.js | 3 + .../apps/gmail/actions/send-email/index.js | 234 ++++++++++++++++++ .../src/apps/gmail/dynamic-data/index.js | 4 +- .../gmail/dynamic-data/list-emails/index.js | 23 ++ .../dynamic-data/list-signatures/index.js | 24 ++ packages/backend/src/apps/gmail/index.js | 2 + packages/docs/pages/.vitepress/config.js | 6 +- packages/docs/pages/apps/gmail/actions.md | 12 + 8 files changed, 306 insertions(+), 2 deletions(-) create mode 100644 packages/backend/src/apps/gmail/actions/index.js create mode 100644 packages/backend/src/apps/gmail/actions/send-email/index.js create mode 100644 packages/backend/src/apps/gmail/dynamic-data/list-emails/index.js create mode 100644 packages/backend/src/apps/gmail/dynamic-data/list-signatures/index.js create mode 100644 packages/docs/pages/apps/gmail/actions.md diff --git a/packages/backend/src/apps/gmail/actions/index.js b/packages/backend/src/apps/gmail/actions/index.js new file mode 100644 index 00000000..e1d8a996 --- /dev/null +++ b/packages/backend/src/apps/gmail/actions/index.js @@ -0,0 +1,3 @@ +import sendEmail from './send-email/index.js'; + +export default [sendEmail]; diff --git a/packages/backend/src/apps/gmail/actions/send-email/index.js b/packages/backend/src/apps/gmail/actions/send-email/index.js new file mode 100644 index 00000000..e8101324 --- /dev/null +++ b/packages/backend/src/apps/gmail/actions/send-email/index.js @@ -0,0 +1,234 @@ +import defineAction from '../../../../helpers/define-action.js'; + +export default defineAction({ + name: 'Send email', + key: 'sendEmail', + description: 'Send a new email message.', + arguments: [ + { + label: 'TOs', + key: 'tos', + type: 'dynamic', + required: false, + description: '', + fields: [ + { + label: 'To', + key: 'to', + type: 'string', + required: false, + variables: true, + }, + ], + }, + { + label: 'CCs', + key: 'ccs', + type: 'dynamic', + required: false, + description: '', + fields: [ + { + label: 'CC', + key: 'cc', + type: 'string', + required: false, + variables: true, + }, + ], + }, + { + label: 'BCCs', + key: 'bccs', + type: 'dynamic', + required: false, + description: '', + fields: [ + { + label: 'BCC', + key: 'bcc', + type: 'string', + required: false, + variables: true, + }, + ], + }, + { + label: 'From', + key: 'from', + type: 'dropdown', + required: false, + description: + 'Select an email address or alias from your Gmail Account. Defaults to the primary email address.', + variables: true, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listEmails', + }, + ], + }, + }, + { + label: 'From Name', + key: 'fromName', + type: 'string', + required: false, + description: '', + variables: true, + }, + { + label: 'Reply To', + key: 'replyTo', + type: 'string', + required: false, + description: 'Specify a single reply address other than your own.', + variables: true, + }, + { + label: 'Subject', + key: 'subject', + type: 'string', + required: true, + description: '', + variables: true, + }, + { + label: 'Body Type', + key: 'bodyType', + type: 'dropdown', + required: false, + description: '', + variables: true, + options: [ + { + label: 'plain', + value: 'plain', + }, + { + label: 'html', + value: 'html', + }, + ], + }, + { + label: 'Body', + key: 'emailBody', + type: 'string', + required: true, + description: '', + variables: true, + }, + { + label: 'Signature', + key: 'signature', + type: 'dropdown', + required: false, + description: '', + variables: true, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listSignatures', + }, + ], + }, + }, + { + label: 'Label', + key: 'labelId', + type: 'dropdown', + required: false, + description: '', + variables: true, + source: { + type: 'query', + name: 'getDynamicData', + arguments: [ + { + name: 'key', + value: 'listLabels', + }, + ], + }, + }, + ], + + async run($) { + const { + tos, + ccs, + bccs, + from, + fromName, + replyTo, + subject, + bodyType, + emailBody, + signature, + labelId, + } = $.step.parameters; + const userId = $.auth.data.userId; + + const allTos = tos?.map((entry) => entry.to); + const allCcs = ccs?.map((entry) => entry.cc); + const allBccs = bccs?.map((entry) => entry.bcc); + const contentType = + bodyType === 'html' + ? 'text/html; charset="UTF-8"' + : 'text/plain; charset="UTF-8"'; + + const email = + 'From: ' + + fromName + + ' <' + + from + + '>' + + '\r\n' + + 'Reply-To: ' + + replyTo + + '\r\n' + + 'To: ' + + allTos.join(',') + + '\r\n' + + 'Cc: ' + + allCcs.join(',') + + '\r\n' + + 'Bcc: ' + + allBccs.join(',') + + '\r\n' + + 'Subject: ' + + subject + + '\r\n' + + 'Content-Type: ' + + contentType + + '\r\n' + + '\r\n' + + emailBody + + '\r\n' + + '\r\n' + + signature; + + const base64EncodedEmailBody = Buffer.from(email).toString('base64'); + + const body = { + labelIds: [labelId], + raw: base64EncodedEmailBody, + }; + + const { data } = await $.http.post( + `/gmail/v1/users/${userId}/messages/send`, + body + ); + + $.setActionItem({ + raw: data, + }); + }, +}); diff --git a/packages/backend/src/apps/gmail/dynamic-data/index.js b/packages/backend/src/apps/gmail/dynamic-data/index.js index a7a52e3a..46af300e 100644 --- a/packages/backend/src/apps/gmail/dynamic-data/index.js +++ b/packages/backend/src/apps/gmail/dynamic-data/index.js @@ -1,3 +1,5 @@ +import listEmails from './list-emails/index.js'; import listLabels from './list-labels/index.js'; +import listSignatures from './list-signatures/index.js'; -export default [listLabels]; +export default [listEmails, listLabels, listSignatures]; diff --git a/packages/backend/src/apps/gmail/dynamic-data/list-emails/index.js b/packages/backend/src/apps/gmail/dynamic-data/list-emails/index.js new file mode 100644 index 00000000..1820a1a1 --- /dev/null +++ b/packages/backend/src/apps/gmail/dynamic-data/list-emails/index.js @@ -0,0 +1,23 @@ +import getCurrentUser from '../../common/get-current-user.js'; + +export default { + name: 'List emails', + key: 'listEmails', + + async run($) { + const emails = { + data: [], + }; + + const currentUser = await getCurrentUser($); + + for (const emailAddress of currentUser.emailAddresses) { + emails.data.push({ + value: emailAddress.value, + name: emailAddress.value, + }); + } + + return emails; + }, +}; diff --git a/packages/backend/src/apps/gmail/dynamic-data/list-signatures/index.js b/packages/backend/src/apps/gmail/dynamic-data/list-signatures/index.js new file mode 100644 index 00000000..dab0b38a --- /dev/null +++ b/packages/backend/src/apps/gmail/dynamic-data/list-signatures/index.js @@ -0,0 +1,24 @@ +export default { + name: 'List signatures', + key: 'listSignatures', + + async run($) { + const signatures = { + data: [], + }; + const userId = $.auth.data.userId; + + const { data } = await $.http.get( + `/gmail/v1/users/${userId}/settings/sendAs` + ); + + for (const sendAs of data.sendAs) { + signatures.data.push({ + value: sendAs.signature, + name: sendAs.sendAsEmail, + }); + } + + return signatures; + }, +}; diff --git a/packages/backend/src/apps/gmail/index.js b/packages/backend/src/apps/gmail/index.js index a201ec19..ca20b94b 100644 --- a/packages/backend/src/apps/gmail/index.js +++ b/packages/backend/src/apps/gmail/index.js @@ -3,6 +3,7 @@ import addAuthHeader from './common/add-auth-header.js'; import auth from './auth/index.js'; import triggers from './triggers/index.js'; import dynamicData from './dynamic-data/index.js'; +import actions from './actions/index.js'; export default defineApp({ name: 'Gmail', @@ -17,4 +18,5 @@ export default defineApp({ auth, triggers, dynamicData, + actions, }); diff --git a/packages/docs/pages/.vitepress/config.js b/packages/docs/pages/.vitepress/config.js index a4ba2ef8..62b13e44 100644 --- a/packages/docs/pages/.vitepress/config.js +++ b/packages/docs/pages/.vitepress/config.js @@ -218,7 +218,11 @@ export default defineConfig({ text: 'Gmail', collapsible: true, collapsed: true, - items: [{ text: 'Connection', link: '/apps/gmail/connection' }], + items: [ + { text: 'Triggers', link: '/apps/gmail/triggers' }, + { text: 'Connection', link: '/apps/gmail/connection' }, + { text: 'Actions', link: '/apps/gmail/actions' }, + ], }, { text: 'Google Calendar', diff --git a/packages/docs/pages/apps/gmail/actions.md b/packages/docs/pages/apps/gmail/actions.md new file mode 100644 index 00000000..2f12fe51 --- /dev/null +++ b/packages/docs/pages/apps/gmail/actions.md @@ -0,0 +1,12 @@ +--- +favicon: /favicons/gmail.svg +items: + - name: Send email + desc: Send a new email message. +--- + + + +