Skip to content

Commit

Permalink
add mailgun email provider #18
Browse files Browse the repository at this point in the history
  • Loading branch information
BDav24 committed Sep 14, 2017
1 parent 585ea47 commit 8b0f6a9
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 3 deletions.
17 changes: 17 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,23 @@ new NotifmeSdk({
})
```

</p></details>
<details><summary>Mailgun</summary><p>

```javascript
new NotifmeSdk({
channels: {
email: {
providers: [{
type: 'mailgun',
apiKey: 'xxxxx',
domainName: 'example.com'
}]
}
}
})
```

</p></details>
<details><summary>Sendgrid</summary><p>

Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"scripts": {
"build": "yarn run clean && babel src --out-dir lib && yarn run build-dot-flow",
"build-dot-flow": "grep -rwl './src' -e 'export type' | while read filepath; do cp $filepath `echo $filepath | sed 's/\\/src\\//\\/lib\\//g'`.flow; done",
"clean": "rm -rf lib/",
"clean": "rm -rf lib/ coverage/",
"demo": "notification-catcher & babel-node examples/with-notification-catcher.js && printf '\n>>> Please visit http://localhost:1080 <<<\n\n'",
"dev": "nodemon -e js -r babel-register examples/with-notification-catcher.js",
"lint": "yarn run flow && standard",
Expand Down
2 changes: 1 addition & 1 deletion src/models/notification-request.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export type EmailRequestType = RequestMetadataType & {
text?: string,
html?: string,
attachments?: {
contentType: string,
contentType: string, // text/plain...
filename: string,
content: string | Buffer
// path?: string,
Expand Down
6 changes: 5 additions & 1 deletion src/models/provider-email.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* @flow */
import type {EmailRequestType} from './notification-request'

// TODO?: provider APIs (mailgun, SES, sendinblue, mailjet, mandrill, elasticemail...)
// TODO?: provider APIs (SES, sendinblue, mailjet, mandrill, elasticemail...)
export type EmailProviderType = {
type: 'logger'
} | {
Expand Down Expand Up @@ -68,6 +68,10 @@ export type EmailProviderType = {
rateLimit?: number,
// Proxy options (Doc: https://nodemailer.com/smtp/proxies/)
proxy?: string
} | {
type: 'mailgun',
apiKey: string,
domainName: string
} | {
type: 'sendgrid',
apiKey: string
Expand Down
4 changes: 4 additions & 0 deletions src/providers/email/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* @flow */
import EmailLoggerProvider from '../logger'
import EmailMailgunProvider from './mailgun'
import EmailNotificationCatcherProvider from './notificationCatcher'
import EmailSendGridProvider from './sendgrid'
import EmailSendmailProvider from './sendmail'
Expand Down Expand Up @@ -34,6 +35,9 @@ export default function factory ({type, ...config}: Object): EmailProviderType {
return new EmailSmtpProvider(config)

// Providers
case 'mailgun':
return new EmailMailgunProvider(config)

case 'sendgrid':
return new EmailSendGridProvider(config)

Expand Down
52 changes: 52 additions & 0 deletions src/providers/email/mailgun.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/* @flow */
import fetch from 'node-fetch'
import FormData from 'form-data'
// types
import type {EmailRequestType} from '../../models/notification-request'

export default class EmailMailgunProvider {
id: string = 'email-mailgun-provider'
apiKeyBase64: string
domainName: string

constructor (config: Object) {
this.apiKeyBase64 = Buffer.from(`api:${config.apiKey}`).toString('base64')
this.domainName = config.domainName
}

async send (request: EmailRequestType): Promise<string> {
const {id, userId, from, replyTo, subject, html, text, headers, to, cc, bcc, attachments} = request
const form = new FormData()
form.append('from', from)
form.append('to', to)
form.append('subject', subject)
if (text) form.append('text', text)
if (html) form.append('html', html)
if (replyTo) form.append('h:Reply-To', replyTo)
if (cc && cc.length > 0) cc.forEach((email) => form.append('cc', email))
if (bcc && bcc.length > 0) bcc.forEach((email) => form.append('bcc', email))
if (attachments && attachments.length > 0) {
attachments.forEach(({contentType, filename, content}) => {
form.append('attachment', content, {filename, contentType})
})
}
if (headers) Object.keys(headers).forEach((header) => form.append(`h:${header}`, headers[header]))
if (id) form.append('v:Notification-Id', id)
if (userId) form.append('v:User-Id', userId)

const response = await fetch(`https://api.mailgun.net/v3/${this.domainName}/messages`, {
method: 'POST',
headers: {
Authorization: `Basic ${this.apiKeyBase64}`
},
body: form
})

const responseBody = await response.json()
if (response.ok) {
return responseBody.id
} else {
throw new Error(`${response.status} - ${responseBody.message}`)
}
}
}

0 comments on commit 8b0f6a9

Please sign in to comment.