From a189e32948ac20b2a93098757cb377ccf668e757 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Wed, 4 Feb 2015 16:17:53 -0800 Subject: [PATCH] Refactored sending of HipChat room messages. --- server/commons/Handler.coffee | 5 ++- server/hipchat.coffee | 56 ++++++++++++------------ server/patches/patch_handler.coffee | 2 +- server/payments/payment_handler.coffee | 28 ++++++------ server/purchases/purchase_handler.coffee | 14 +++--- server/routes/db.coffee | 2 +- server/users/user_handler.coffee | 5 +-- server_config.coffee | 7 ++- 8 files changed, 61 insertions(+), 58 deletions(-) diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index ecb6ba893..e2f11b792 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -461,8 +461,9 @@ module.exports = class Handler sendwithus.api.send context, (err, result) -> sendChangedHipChatMessage: (options) -> - message = "#{options.creator.get('name')} saved a change to #{options.target.get('name')}: #{options.target.get('commitMessage')}" - hipchat.sendHipChatMessage message + message = "#{options.creator.get('name')} saved a change to #{options.target.get('name')}: #{options.target.get('commitMessage') or '(no commit message)'}" + rooms = if /Diplomat submission/.test(message) then ['main'] else ['main', 'artisans'] + hipchat.sendHipChatMessage message, rooms makeNewInstance: (req) -> model = new @modelClass({}) diff --git a/server/hipchat.coffee b/server/hipchat.coffee index e8b72fca2..0d872c2d3 100644 --- a/server/hipchat.coffee +++ b/server/hipchat.coffee @@ -2,32 +2,34 @@ config = require '../server_config' request = require 'request' log = require 'winston' -module.exports.sendHipChatMessage = sendHipChatMessage = (message) -> - return unless key = config.hipchatAPIKey - return unless config.isProduction - roomID = 254598 - form = - color: 'yellow' - notify: false - message: message - messageFormat: 'html' - url = "https://api.hipchat.com/v2/room/#{roomID}/notification?auth_token=#{key}" - request.post {uri: url, json: form}, (err, res, body) -> - return log.error 'Error sending HipChat patch request:', err or body if err or /error/i.test body - #log.info "Got HipChat patch response:", body +roomIDMap = + main: 254598 + artisans: 1146994 + tower: 318356 -module.exports.sendTowerHipChatMessage = sendTowerHipChatMessage = (message) -> - secondsFromEpoch = Math.floor(new Date().getTime() / 1000) - link = "PaperTrail" - message = "#{message} #{link}" - return unless key = config.hipchatTowerAPIKey +module.exports.sendHipChatMessage = sendHipChatMessage = (message, rooms, options) -> return unless config.isProduction - roomID = 318356 - form = - color: 'red' - notify: true - message: message - messageFormat: 'html' - url = "https://api.hipchat.com/v2/room/#{roomID}/notification?auth_token=#{key}" - request.post {uri: url, json: form}, (err, res, body) -> - return log.error 'Error sending HipChat Tower message:', err or body if err or /error/i.test body + rooms ?= ['main'] + options ?= {} + for room in rooms + unless roomID = roomIDMap[room] + log.error "Unknown HipChat room #{room}." + continue + unless key = config.hipchat[room] + log.info "No HipChat API key for room #{room}." + continue + form = + color: options.color or 'yellow' + notify: false + message: message + messageFormat: 'html' + if options.papertrail + secondsFromEpoch = Math.floor(new Date().getTime() / 1000) + link = "PaperTrail" + form.message = "#{message} #{link}" + form.color = options.color or 'red' + form.notify = true + url = "https://api.hipchat.com/v2/room/#{roomID}/notification?auth_token=#{key}" + request.post {uri: url, json: form}, (err, res, body) -> + return log.error 'Error sending HipChat message:', err or body if err or /error/i.test body + #log.info "Got HipChat message response:", body diff --git a/server/patches/patch_handler.coffee b/server/patches/patch_handler.coffee index 3a6cd4ff7..9593d8c83 100644 --- a/server/patches/patch_handler.coffee +++ b/server/patches/patch_handler.coffee @@ -101,6 +101,6 @@ PatchHandler = class PatchHandler extends Handler sendPatchCreatedHipChatMessage: (options) -> message = "#{options.creator.get('name')} submitted a patch to #{options.target.get('name')}: #{options.patch.get('commitMessage')}" - hipchat.sendHipChatMessage message + hipchat.sendHipChatMessage message, ['main'] module.exports = new PatchHandler() diff --git a/server/payments/payment_handler.coffee b/server/payments/payment_handler.coffee index fbd47af15..9e24be60e 100644 --- a/server/payments/payment_handler.coffee +++ b/server/payments/payment_handler.coffee @@ -35,7 +35,7 @@ PaymentHandler = class PaymentHandler extends Handler editableProperties: [] postEditableProperties: ['purchased'] jsonSchema: require '../../app/schemas/models/payment.schema' - + get: (req, res) -> return res.send([]) unless req.user q = Payment.find({recipient:req.user._id}) @@ -43,7 +43,7 @@ PaymentHandler = class PaymentHandler extends Handler return @sendDatabaseError(res, err) if err res.send(payments) ) - + logPaymentError: (req, msg) -> console.warn "Payment Error: #{req.user.get('slug')} (#{req.user._id}): '#{msg}'" @@ -57,10 +57,10 @@ PaymentHandler = class PaymentHandler extends Handler post: (req, res, pathName) -> if pathName is 'check-stripe-charges' return @checkStripeCharges(req, res) - + if (not req.user) or req.user.isAnonymous() return @sendForbiddenError(res) - + appleReceipt = req.body.apple?.rawReceipt appleTransactionID = req.body.apple?.transactionID appleLocalPrice = req.body.apple?.localPrice @@ -146,7 +146,7 @@ PaymentHandler = class PaymentHandler extends Handler if validation.valid is false @logPaymentError(req, 'Invalid apple payment object.') return @sendBadInputError(res, validation.errors) - + payment.save((err) => if err @logPaymentError(req, 'Apple payment save error.'+err) @@ -170,24 +170,24 @@ PaymentHandler = class PaymentHandler extends Handler # First, make sure we save the payment info as a Customer object, if we haven't already. if token customerID = req.user.get('stripe')?.customerID - + if customerID # old customer, new token. Save it. stripe.customers.update customerID, { card: token }, (err, customer) => @beginStripePayment(req, res, timestamp, productID) - + else newCustomer = { card: token email: req.user.get('email') metadata: { id: req.user._id + '', slug: req.user.get('slug') } } - + stripe.customers.create newCustomer, (err, customer) => if err @logPaymentError(req, 'Stripe customer creation error. '+err) return @sendDatabaseError(res, err) - + stripeInfo = _.cloneDeep(req.user.get('stripe') ? {}) stripeInfo.customerID = customer.id req.user.set('stripe', stripeInfo) @@ -223,7 +223,7 @@ PaymentHandler = class PaymentHandler extends Handler ((err, results) => if err @logPaymentError(req, 'Stripe async load db error. '+err) - return @sendDatabaseError(res, err) + return @sendDatabaseError(res, err) [payment, charge] = results if not (payment or charge) @@ -285,7 +285,7 @@ PaymentHandler = class PaymentHandler extends Handler timestamp: parseInt(charge.metadata.timestamp) chargeID: charge.id } - + validation = @validateDocumentInput(payment.toObject()) if validation.valid is false @logPaymentError(req, 'Invalid stripe payment object.') @@ -302,9 +302,9 @@ PaymentHandler = class PaymentHandler extends Handler ) ) - + #- Confirm all Stripe charges are recorded on our server - + checkStripeCharges: (req, res) -> return @sendSuccess(res) unless customerID = req.user.get('stripe')?.customerID async.parallel([ @@ -366,7 +366,7 @@ PaymentHandler = class PaymentHandler extends Handler sendPaymentHipChatMessage: (options) -> try message = "#{options.user?.get('name')} bought #{options.payment?.get('amount')} via #{options.payment?.get('service')}." - hipchat.sendHipChatMessage message + hipchat.sendHipChatMessage message, ['tower'] catch e log.error "Couldn't send HipChat message on payment because of error: #{e}" diff --git a/server/purchases/purchase_handler.coffee b/server/purchases/purchase_handler.coffee index cb00a4a67..dbcd5408c 100644 --- a/server/purchases/purchase_handler.coffee +++ b/server/purchases/purchase_handler.coffee @@ -4,8 +4,6 @@ Handler = require '../commons/Handler' {handlers} = require '../commons/mapping' mongoose = require 'mongoose' log = require 'winston' -sendwithus = require '../sendwithus' -hipchat = require '../hipchat' PurchaseHandler = class PurchaseHandler extends Handler modelClass: Purchase @@ -19,22 +17,22 @@ PurchaseHandler = class PurchaseHandler extends Handler purchase.set 'recipient', req.user._id purchase.set 'created', new Date().toISOString() purchase - + post: (req, res) -> purchased = req.body.purchased purchaser = req.user._id purchasedOriginal = purchased?.original - + Handler = require '../commons/Handler' return @sendBadInputError(res) if not Handler.isID(purchasedOriginal) - + collection = purchased?.collection return @sendBadInputError(res) if not collection in @jsonSchema.properties.purchased.properties.collection.enum - + handler = require('../' + handlers[collection]) criteria = { 'original': purchasedOriginal } sort = { 'version.major': -1, 'version.minor': -1 } - + handler.modelClass.findOne(criteria).sort(sort).exec (err, purchasedItem) => gemsOwned = req.user.get('earned')?.gems or 0 return @sendDatabaseError(res, err) if err @@ -51,7 +49,7 @@ PurchaseHandler = class PurchaseHandler extends Handler if purchase @addPurchaseToUser(req, res) return @sendSuccess(res, @formatEntity(req, purchase)) - + else super(req, res) diff --git a/server/routes/db.coffee b/server/routes/db.coffee index 232705e17..8bcc8e231 100644 --- a/server/routes/db.coffee +++ b/server/routes/db.coffee @@ -48,7 +48,7 @@ module.exports.setup = (app) -> log.error(error.stack) # TODO: Generally ignore this error: error: Error trying db method get route analytics.log.event from undefined: Error: Cannot find module '../undefined' unless "#{parts}" in ['analytics.users.active'] - hipchat.sendTowerHipChatMessage errorMessage + hipchat.sendHipChatMessage errorMessage, ['tower'], papertrail: true errors.notFound(res, "Route #{req?.path} not found.") getSchema = (req, res, moduleName) -> diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index 2e22a00cb..f48b97eda 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -249,7 +249,6 @@ UserHandler = class UserHandler extends Handler sendOneTimeEmail: (req, res) -> # TODO: should this API be somewhere else? - # TODO: hipchat tower success message shows up as a misleading PaperTrail error message return @sendForbiddenError(res) unless req.user email = req.query.email or req.body.email type = req.query.type or req.body.type @@ -276,7 +275,7 @@ UserHandler = class UserHandler extends Handler req.user.save (err) => return @sendDatabaseError(res, err) if err @sendSuccess(res, {result: 'success'}) - hipchat.sendTowerHipChatMessage "#{req.user.get('name') or req.user.get('email')} just submitted subscribe modal parent email #{email}." + hipchat.sendHipChatMessage "#{req.user.get('name') or req.user.get('email')} just submitted subscribe modal parent email #{email}.", ['tower'] AnalyticsLogEvent.logEvent req.user, 'Sent one time email', email: email, type: type agreeToCLA: (req, res) -> @@ -295,7 +294,7 @@ UserHandler = class UserHandler extends Handler req.user.save (err) => return @sendDatabaseError(res, err) if err @sendSuccess(res, {result: 'success'}) - hipchat.sendHipChatMessage "#{req.body.githubUsername or req.user.get('name')} just signed the CLA." + hipchat.sendHipChatMessage "#{req.body.githubUsername or req.user.get('name')} just signed the CLA.", ['main'] avatar: (req, res, id) -> @modelClass.findById(id).exec (err, document) => diff --git a/server_config.coffee b/server_config.coffee index 4b426be48..3d9fd2e43 100644 --- a/server_config.coffee +++ b/server_config.coffee @@ -48,8 +48,11 @@ config.mail = cronHandlerPublicIP: process.env.COCO_CRON_PUBLIC_IP or '' cronHandlerPrivateIP: process.env.COCO_CRON_PRIVATE_IP or '' -config.hipchatAPIKey = process.env.COCO_HIPCHAT_API_KEY or '' -config.hipchatTowerAPIKey = process.env.COCO_HIPCHAT_TOWER_API_KEY or '' +config.hipchat = + main: process.env.COCO_HIPCHAT_API_KEY or '' + tower: process.env.COCO_HIPCHAT_TOWER_API_KEY or '' + artisans: process.env.COCO_HIPCHAT_ARTISANS_API_KEY or '' + config.queue = accessKeyId: process.env.COCO_AWS_ACCESS_KEY_ID or '' secretAccessKey: process.env.COCO_AWS_SECRET_ACCESS_KEY or ''