diff --git a/app/assets/images/pages/community/logo_slack.png b/app/assets/images/pages/community/logo_slack.png
new file mode 100644
index 000000000..ef3b21178
Binary files /dev/null and b/app/assets/images/pages/community/logo_slack.png differ
diff --git a/app/locale/en.coffee b/app/locale/en.coffee
index 6f12fe859..276f2b07e 100644
--- a/app/locale/en.coffee
+++ b/app/locale/en.coffee
@@ -868,7 +868,7 @@
social_facebook: "Like CodeCombat on Facebook"
social_twitter: "Follow CodeCombat on Twitter"
social_gplus: "Join CodeCombat on Google+"
- social_hipchat: "Chat with us in the public CodeCombat Slack channel"
+ social_slack: "Chat with us in the public CodeCombat Slack channel"
contribute_to_the_project: "Contribute to the project"
clans:
@@ -1294,7 +1294,7 @@
join_desc_3: ", or find us in our "
join_desc_4: "and we'll go from there!"
join_url_email: "Email us"
- join_url_hipchat: "public Slack channel"
+ join_url_slack: "public Slack channel"
archmage_subscribe_desc: "Get emails on new coding opportunities and announcements."
artisan_introduction_pref: "We must construct additional levels! People be clamoring for more content, and we can only build so many ourselves. Right now your workstation is level one; our level editor is barely usable even by its creators, so be wary. If you have visions of campaigns spanning for-loops to"
artisan_introduction_suf: ", then this class might be for you."
diff --git a/app/templates/community-view.jade b/app/templates/community-view.jade
index 0ca72419f..bb2b7e1d6 100644
--- a/app/templates/community-view.jade
+++ b/app/templates/community-view.jade
@@ -66,7 +66,7 @@ block content
img(src="/images/pages/community/logo_g+.png", data-i18n="[data-content]community.social_gplus" data-content="Join CodeCombat on Google+")
a(href="https://coco-slack-invite.herokuapp.com/")
- img(src="/images/pages/community/logo_hipchat.png", data-i18n="[data-content]community.social_hipchat" data-content="Chat with us in the public CodeCombat Slack channel")
+ img(src="/images/pages/community/logo_slack.png", data-i18n="[data-content]community.social_slack" data-content="Chat with us in the public CodeCombat Slack channel")
.half-width
diff --git a/app/templates/contribute/archmage.jade b/app/templates/contribute/archmage.jade
index bbbcaf80c..687665ae5 100644
--- a/app/templates/contribute/archmage.jade
+++ b/app/templates/contribute/archmage.jade
@@ -51,7 +51,7 @@ block content
| Email us
span(data-i18n="contribute.join_desc_3")
| , or find us in our
- a(href="https://coco-slack-invite.herokuapp.com/", data-i18n="contribute.join_url_hipchat") public Slack channel
+ a(href="https://coco-slack-invite.herokuapp.com/", data-i18n="contribute.join_url_slack") public Slack channel
span
span(data-i18n="contribute.join_desc_4")
| and we'll go from there!
diff --git a/multicore.coffee b/multicore.coffee
index de179e25e..eac603287 100644
--- a/multicore.coffee
+++ b/multicore.coffee
@@ -76,10 +76,10 @@ if cluster.isMaster
message = "Worker #{worker.id} died! #{deaths[Math.floor Math.random() * deaths.length]}"
console.log message
try
- hipchat = require './server/hipchat'
- hipchat.sendHipChatMessage(message, ['tower'], {papertrail: true})
+ slack = require './server/slack'
+ slack.sendSlackMessage(message, ['tower'], {papertrail: true})
catch error
- console.log "Couldn't send HipChat message on server death:", error
+ console.log "Couldn't send Slack message on server death:", error
cluster.fork()
else
require('coffee-script')
diff --git a/server/campaigns/campaign_handler.coffee b/server/campaigns/campaign_handler.coffee
index 45870a594..b5a330556 100644
--- a/server/campaigns/campaign_handler.coffee
+++ b/server/campaigns/campaign_handler.coffee
@@ -126,7 +126,7 @@ CampaignHandler = class CampaignHandler extends Handler
onPutSuccess: (req, doc) ->
docLink = "http://codecombat.com#{req.headers['x-current-path']}"
- @sendChangedHipChatMessage creator: req.user, target: doc, docLink: docLink
+ @sendChangedSlackMessage creator: req.user, target: doc, docLink: docLink
getNamesByIDs: (req, res) -> @getNamesByOriginals req, res, true
diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee
index ea830e064..aba77bd5d 100644
--- a/server/commons/Handler.coffee
+++ b/server/commons/Handler.coffee
@@ -6,7 +6,7 @@ log = require 'winston'
Patch = require '../patches/Patch'
User = require '../users/User'
sendwithus = require '../sendwithus'
-hipchat = require '../hipchat'
+slack = require '../slack'
deltasLib = require '../../app/core/deltas'
PROJECT = {original: 1, name: 1, version: 1, description: 1, slug: 1, kind: 1, created: 1, permissions: 1}
@@ -457,7 +457,7 @@ module.exports = class Handler
notifyWatchersOfChange: (editor, changedDocument, editPath) ->
docLink = "http://codecombat.com#{editPath}"
- @sendChangedHipChatMessage creator: editor, target: changedDocument, docLink: docLink
+ @sendChangedSlackMessage creator: editor, target: changedDocument, docLink: docLink
watchers = changedDocument.get('watchers') or []
# Don't send these emails to the person who submitted the patch, or to Nick, George, or Scott.
watchers = (w for w in watchers when not w.equals(editor.get('_id')) and not (w + '' in ['512ef4805a67a8c507000001', '5162fab9c92b4c751e000274', '51538fdb812dd9af02000001']))
@@ -479,10 +479,10 @@ module.exports = class Handler
commit_message: changedDocument.get('commitMessage')
sendwithus.api.send context, (err, result) ->
- sendChangedHipChatMessage: (options) ->
+ sendChangedSlackMessage: (options) ->
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
+ slack.sendSlackMessage message, rooms
makeNewInstance: (req) ->
model = new @modelClass({})
diff --git a/server/middleware/versions.coffee b/server/middleware/versions.coffee
index 18da20f66..c1eb916bc 100644
--- a/server/middleware/versions.coffee
+++ b/server/middleware/versions.coffee
@@ -2,7 +2,7 @@ utils = require '../lib/utils'
errors = require '../commons/errors'
User = require '../users/User'
sendwithus = require '../sendwithus'
-hipchat = require '../hipchat'
+slack = require '../slack'
_ = require 'lodash'
wrap = require 'co-express'
mongoose = require 'mongoose'
@@ -94,10 +94,10 @@ module.exports =
editPath = req.headers['x-current-path']
docLink = "http://codecombat.com#{editPath}"
- # Post a message on HipChat
+ # Post a message on Slack
message = "#{req.user.get('name')} saved a change to #{doc.get('name')}: #{doc.get('commitMessage') or '(no commit message)'}"
rooms = if /Diplomat submission/.test(message) then ['main'] else ['main', 'artisans']
- hipchat.sendHipChatMessage message, rooms
+ slack.sendSlackMessage message, rooms
# Send emails to watchers
watchers = doc.get('watchers') or []
diff --git a/server/models/TrialRequest.coffee b/server/models/TrialRequest.coffee
index 1a525fa67..c1e3e5012 100644
--- a/server/models/TrialRequest.coffee
+++ b/server/models/TrialRequest.coffee
@@ -2,7 +2,6 @@ closeIO = require '../lib/closeIO'
log = require 'winston'
mongoose = require 'mongoose'
config = require '../../server_config'
-hipchat = require '../hipchat'
sendwithus = require '../sendwithus'
Prepaid = require '../prepaids/Prepaid'
jsonSchema = require '../../app/schemas/models/trial_request.schema'
diff --git a/server/patches/patch_handler.coffee b/server/patches/patch_handler.coffee
index 63debc894..93654e972 100644
--- a/server/patches/patch_handler.coffee
+++ b/server/patches/patch_handler.coffee
@@ -6,7 +6,7 @@ schema = require '../../app/schemas/models/patch'
mongoose = require 'mongoose'
log = require 'winston'
sendwithus = require '../sendwithus'
-hipchat = require '../hipchat'
+slack = require '../slack'
PatchHandler = class PatchHandler extends Handler
modelClass: Patch
@@ -88,7 +88,7 @@ PatchHandler = class PatchHandler extends Handler
log.error 'Error sending patch created: could not find the loaded target on the patch object.' unless doc.targetLoaded
return unless doc.targetLoaded
docLink = "http://codecombat.com#{req.headers['x-current-path']}"
- @sendPatchCreatedHipChatMessage creator: req.user, patch: doc, target: doc.targetLoaded, docLink: docLink
+ @sendPatchCreatedSlackMessage creator: req.user, patch: doc, target: doc.targetLoaded, docLink: docLink
watchers = doc.targetLoaded.get('watchers') or []
# Don't send these emails to the person who submitted the patch, or to Nick, George, or Scott.
watchers = (w for w in watchers when not w.equals(req.user.get('_id')) and not (w + '' in ['512ef4805a67a8c507000001', '5162fab9c92b4c751e000274', '51538fdb812dd9af02000001']))
@@ -111,8 +111,8 @@ PatchHandler = class PatchHandler extends Handler
commit_message: patch.get('commitMessage')
sendwithus.api.send context, (err, result) ->
- sendPatchCreatedHipChatMessage: (options) ->
+ sendPatchCreatedSlackMessage: (options) ->
message = "#{options.creator.get('name')} submitted a patch to #{options.target.get('name')}: #{options.patch.get('commitMessage')}"
- hipchat.sendHipChatMessage message, ['main']
+ slack.sendSlackMessage message, ['main']
module.exports = new PatchHandler()
diff --git a/server/payments/payment_handler.coffee b/server/payments/payment_handler.coffee
index a8b729a28..b5e5837fe 100644
--- a/server/payments/payment_handler.coffee
+++ b/server/payments/payment_handler.coffee
@@ -7,7 +7,7 @@ Handler = require '../commons/Handler'
mongoose = require 'mongoose'
log = require 'winston'
sendwithus = require '../sendwithus'
-hipchat = require '../hipchat'
+slack = require '../slack'
config = require '../../server_config'
request = require 'request'
async = require 'async'
@@ -178,7 +178,7 @@ PaymentHandler = class PaymentHandler extends Handler
if err
@logPaymentError(req, 'Apple incr db error.'+err)
return @sendDatabaseError(res, err)
- @sendPaymentHipChatMessage user: req.user, payment: payment
+ @sendPaymentSlackMessage user: req.user, payment: payment
@sendCreated(res, @formatEntity(req, payment))
)
)
@@ -270,7 +270,7 @@ PaymentHandler = class PaymentHandler extends Handler
if err
@logPaymentError(req, 'Stripe recalc db error. '+err)
return @sendDatabaseError(res, err)
- @sendPaymentHipChatMessage user: req.user, payment: payment
+ @sendPaymentSlackMessage user: req.user, payment: payment
@sendSuccess(res, @formatEntity(req, payment))
)
)
@@ -333,7 +333,7 @@ PaymentHandler = class PaymentHandler extends Handler
if err
@logPaymentError(req, 'Stripe incr db error. '+err)
return @sendDatabaseError(res, err)
- @sendPaymentHipChatMessage user: req.user, payment: payment
+ @sendPaymentSlackMessage user: req.user, payment: payment
@sendCreated(res, @formatEntity(req, payment))
)
)
@@ -403,12 +403,12 @@ PaymentHandler = class PaymentHandler extends Handler
user.save((err) -> done(err))
)
- sendPaymentHipChatMessage: (options) ->
+ sendPaymentSlackMessage: (options) ->
try
message = "#{options.user?.get('name')} bought #{options.payment?.get('amount')} via #{options.payment?.get('service')}"
message += " for #{options.payment.get('description')}" if options.payment?.get('description')
- hipchat.sendHipChatMessage message, ['tower']
+ slack.sendSlackMessage message, ['tower']
catch e
- log.error "Couldn't send HipChat message on payment because of error: #{e}"
+ log.error "Couldn't send Slack message on payment because of error: #{e}"
module.exports = new PaymentHandler()
diff --git a/server/payments/subscription_handler.coffee b/server/payments/subscription_handler.coffee
index bfd957faa..4643d8a14 100644
--- a/server/payments/subscription_handler.coffee
+++ b/server/payments/subscription_handler.coffee
@@ -7,7 +7,7 @@ mongoose = require 'mongoose'
async = require 'async'
config = require '../../server_config'
Handler = require '../commons/Handler'
-hipchat = require '../hipchat'
+slack = require '../slack'
discountHandler = require './discount_handler'
Prepaid = require '../prepaids/Prepaid'
User = require '../users/User'
@@ -185,9 +185,9 @@ class SubscriptionHandler extends Handler
return @sendDatabaseError(res, err)
try
msg = "Year subscription purchased by #{req.user.get('email')} #{req.user.id}"
- hipchat.sendHipChatMessage msg, ['tower']
+ slack.sendSlackMessage msg, ['tower']
catch error
- @logSubscriptionError(req.user, "Year sub sale HipChat tower msg error: #{JSON.stringify(error)}")
+ @logSubscriptionError(req.user, "Year sub sale Slack tower msg error: #{JSON.stringify(error)}")
@sendSuccess(res, user)
subscribeWithPrepaidCode: (req, res) ->
diff --git a/server/prepaids/prepaid_handler.coffee b/server/prepaids/prepaid_handler.coffee
index b92af6a72..4bee237df 100644
--- a/server/prepaids/prepaid_handler.coffee
+++ b/server/prepaids/prepaid_handler.coffee
@@ -1,6 +1,6 @@
Course = require '../courses/Course'
Handler = require '../commons/Handler'
-hipchat = require '../hipchat'
+slack = require '../slack'
Prepaid = require './Prepaid'
User = require '../users/User'
StripeUtils = require '../lib/stripe_utils'
@@ -212,7 +212,7 @@ PrepaidHandler = class PrepaidHandler extends Handler
@logError(user, "createPayment error: #{JSON.stringify(err)}")
return done(err)
msg = "Prepaid code purchased: #{type} seats=#{maxRedeemers} #{user.get('email')}"
- hipchat.sendHipChatMessage msg, ['tower']
+ slack.sendSlackMessage msg, ['tower']
done(null, prepaid)
purchasePrepaidTerminalSubscription: (user, description, maxRedeemers, months, timestamp, token, product, done) ->
@@ -249,7 +249,7 @@ PrepaidHandler = class PrepaidHandler extends Handler
@logError(user, "createPayment error: #{JSON.stringify(err)}")
return done(err)
msg = "Prepaid code purchased: #{type} users=#{maxRedeemers} months=#{months} #{user.get('email')}"
- hipchat.sendHipChatMessage msg, ['tower']
+ slack.sendSlackMessage msg, ['tower']
done(null, prepaid)
get: (req, res) ->
diff --git a/server/routes/contact.coffee b/server/routes/contact.coffee
index 7518d5115..2056af9ef 100644
--- a/server/routes/contact.coffee
+++ b/server/routes/contact.coffee
@@ -5,7 +5,6 @@ sendwithus = require '../sendwithus'
async = require 'async'
LevelSession = require '../levels/sessions/LevelSession'
moment = require 'moment'
-hipchat = require '../hipchat'
module.exports.setup = (app) ->
app.post '/contact', (req, res) ->
diff --git a/server/routes/db.coffee b/server/routes/db.coffee
index 728677b98..f3bad3596 100644
--- a/server/routes/db.coffee
+++ b/server/routes/db.coffee
@@ -3,7 +3,7 @@ errors = require '../commons/errors'
handlers = require('../commons/mapping').handlers
handlerUrlOverrides = require('../commons/mapping').handlerUrlOverrides
mongoose = require 'mongoose'
-hipchat = require '../hipchat'
+slack = require '../slack'
module.exports.setup = (app) ->
# This is hacky and should probably get moved somewhere else, I dunno
@@ -50,7 +50,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.sendHipChatMessage errorMessage, ['tower'], papertrail: true
+ slack.sendSlackMessage errorMessage, ['tower'], papertrail: true
errors.notFound(res, "Route #{req?.path} not found.")
app.all '/db/' + moduleName + '/*', routeHandler
diff --git a/server/slack.coffee b/server/slack.coffee
new file mode 100644
index 000000000..bcbec8d74
--- /dev/null
+++ b/server/slack.coffee
@@ -0,0 +1,31 @@
+config = require '../server_config'
+request = require 'request'
+log = require 'winston'
+
+roomChannelMap =
+ main: '#general'
+ artisans: '#artisan'
+
+module.exports.sendSlackMessage = sendSlackMessage = (message, rooms=['tower'], options={}) ->
+ return unless config.isProduction
+ unless token = config.slackToken
+ log.info "No Slack token."
+ return
+ for room in rooms
+ channel = roomChannelMap[room] ? room
+ form =
+ channel: channel
+ token: token
+ text: message
+ if options.papertrail
+ secondsFromEpoch = Math.floor(new Date().getTime() / 1000)
+ link = "https://papertrailapp.com/groups/488214/events?time=#{secondsFromEpoch}"
+ form.text += " #{link}"
+ # https://api.slack.com/docs/formatting
+ form.text = form.text.replace('&', '&').replace('<', '<').replace('>', '>')
+ url = "https://slack.com/api/chat.postMessage"
+ request.post {uri: url, form: form}, (err, res, body) ->
+ return log.errr('Error sending Slack message:', err) if err
+ return log.error("Slack returned error: #{body.error}") unless body.ok
+ log.warn("Slack returned warning: #{body.warning}") if body.warning
+ # log.info "Got Slack message response:", body
diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee
index a3dd83e09..26224dbcb 100644
--- a/server/users/user_handler.coffee
+++ b/server/users/user_handler.coffee
@@ -21,7 +21,7 @@ EarnedAchievement = require '../achievements/EarnedAchievement'
UserRemark = require './remarks/UserRemark'
{findStripeSubscription} = require '../lib/utils'
{isID} = require '../lib/utils'
-hipchat = require '../hipchat'
+slack = require '../slack'
sendwithus = require '../sendwithus'
Prepaid = require '../prepaids/Prepaid'
UserPollsRecord = require '../polls/UserPollsRecord'
@@ -503,7 +503,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.", ['main']
+ slack.sendSlackMessage "#{req.body.githubUsername or req.user.get('name')} just signed the CLA.", ['main']
avatar: (req, res, id) ->
if not isID(id)
diff --git a/server_config.coffee b/server_config.coffee
index 394024920..0d936c74e 100644
--- a/server_config.coffee
+++ b/server_config.coffee
@@ -69,6 +69,8 @@ config.hipchat =
tower: process.env.COCO_HIPCHAT_TOWER_API_KEY or ''
artisans: process.env.COCO_HIPCHAT_ARTISANS_API_KEY or ''
+config.slackToken = process.env.COCO_SLACK_TOKEN or ''
+
config.queue =
accessKeyId: process.env.COCO_AWS_ACCESS_KEY_ID or ''
secretAccessKey: process.env.COCO_AWS_SECRET_ACCESS_KEY or ''
diff --git a/server_setup.coffee b/server_setup.coffee
index 0c676664b..75a9ba6c5 100644
--- a/server_setup.coffee
+++ b/server_setup.coffee
@@ -16,7 +16,7 @@ config = require './server_config'
auth = require './server/routes/auth'
routes = require './server/routes'
UserHandler = require './server/users/user_handler'
-hipchat = require './server/hipchat'
+slack = require './server/slack'
Mandate = require './server/models/Mandate'
global.tv4 = require 'tv4' # required for TreemaUtils to work
global.jsondiffpatch = require 'jsondiffpatch'
@@ -71,7 +71,7 @@ setupErrorMiddleware = (app) ->
res.status(err.status ? 500).send(error: "Something went wrong!")
message = "Express error: #{req.method} #{req.path}: #{err.message}"
log.error "#{message}, stack: #{err.stack}"
- hipchat.sendHipChatMessage(message, ['tower'], {papertrail: true})
+ slack.sendSlackMessage(message, ['tower'], {papertrail: true})
else
next(err)
diff --git a/spec/server/functional/article.spec.coffee b/spec/server/functional/article.spec.coffee
index f450ffa37..fed443726 100644
--- a/spec/server/functional/article.spec.coffee
+++ b/spec/server/functional/article.spec.coffee
@@ -468,11 +468,11 @@ describe 'POST /db/article/:handle/new-version', ->
yield postNewVersion({ name: 'Article name', body: 'New body', commitMessage: 'Commit message' })
- it 'sends a notification to artisan and main HipChat channels', utils.wrap (done) ->
- hipchat = require '../../../server/hipchat'
- spyOn(hipchat, 'sendHipChatMessage')
+ it 'sends a notification to artisan and main Slack channels', utils.wrap (done) ->
+ slack = require '../../../server/slack'
+ spyOn(slack, 'sendSlackMessage')
yield postNewVersion({ name: 'Article name', body: 'New body' })
- expect(hipchat.sendHipChatMessage).toHaveBeenCalled()
+ expect(slack.sendSlackMessage).toHaveBeenCalled()
done()
describe 'version fetching endpoints', ->