Permalink
Browse files

feat(mailer): add support for sending SMS messages

#259

r=vbudhram
  • Loading branch information...
1 parent a721920 commit 3bc10275651fb10feb38d7c039a45ccbbcca0085 @philbooth philbooth committed on GitHub Feb 16, 2017
View
@@ -4,6 +4,7 @@
var P = require('bluebird')
var createMailer = require('./mailer')
+var createSms = require('./lib/sms')
module.exports = function (log, config, sender) {
var Mailer = createMailer(log)
@@ -15,7 +16,10 @@ module.exports = function (log, config, sender) {
)
.spread(
function (translator, templates) {
- return new Mailer(translator, templates, config.mail, sender)
+ return {
+ email: new Mailer(translator, templates, config.mail, sender),
+ sms: createSms(log, translator, templates, config.sms)
+ }
}
)
}
View
@@ -0,0 +1,98 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+'use strict'
+
+var Nexmo = require('nexmo')
+var P = require('bluebird')
+
+var TEMPLATE_NAMES = new Map([
+ [ 1, 'installFirefox' ]
+])
+
+module.exports = function (log, translator, templates, smsConfig) {
+ var nexmo = new Nexmo({
+ apiKey: smsConfig.apiKey,
+ apiSecret: smsConfig.apiSecret
+ })
+ var sendSms = P.promisify(nexmo.message.sendSms, { context: nexmo.message })
+
+ return {
+ send: function (phoneNumber, senderId, messageId, acceptLanguage) {
+ log.trace({
+ op: 'sms.send',
+ senderId: senderId,
+ messageId: messageId,
+ acceptLanguage: acceptLanguage
+ })
+
+ return P.resolve()
+ .then(function () {
+ var message = getMessage(messageId, acceptLanguage)
+
+ return sendSms(senderId, phoneNumber, message.trim())
+ })
+ .then(function (result) {
+ var resultCount = result.messages && result.messages.length
+ if (resultCount !== 1) {
+ // I don't expect this condition to be entered, certainly I haven't
+ // seen it in testing. But because I'm making an assumption about
+ // the result format, I want to log an error if my assumption proves
+ // to be wrong in production.
+ log.error({ op: 'sms.send', err: new Error('Unexpected result count'), resultCount: resultCount })
+ }
+
+ result = result.messages[0]
+ var status = result.status
+
+ // https://docs.nexmo.com/messaging/sms-api/api-reference#status-codes
+ if (status === '0') {
+ log.info({
+ op: 'sms.send.success',
+ senderId: senderId,
+ messageId: messageId,
+ acceptLanguage: acceptLanguage
+ })
+ } else {
+ var reason = result['error-text']
+ fail('Message rejected', {
+ status: 500,
+ reason: reason,
+ reasonCode: status
+ })
+ }
+ })
+ }
+ }
+
+ function getMessage (messageId, acceptLanguage) {
+ var templateName = TEMPLATE_NAMES.get(messageId)
+ var template = templates['sms.' + templateName]
+
+ if (! template) {
+ fail('Invalid message id', { status: 400 })
+ }
+
+ return template({
+ link: smsConfig[templateName + 'Link'],
+ translator: translator(acceptLanguage)
+ }).text
+ }
+
+ // If/when fxa-auth-mailer is moved into the auth server repo,
+ // calls to this function can be replaced with the auth server's
+ // AppError methods directly.
+ function fail (message, properties) {
+ log.error({ op: 'sms.send', err: message })
+
+ var error = new Error(message)
+ if (properties) {
+ Object.keys(properties).forEach(function (key) {
+ error[key] = properties[key]
+ })
+ }
+
+ throw error
+ }
+}
Oops, something went wrong.

0 comments on commit 3bc1027

Please sign in to comment.