88 lines
2.8 KiB
CoffeeScript
88 lines
2.8 KiB
CoffeeScript
_ = require('lodash')
|
|
request = require("request")
|
|
url = require('url')
|
|
EventEmitter = require('events').EventEmitter
|
|
|
|
config = require("./config")
|
|
Logger = require("./logger")
|
|
Utils = require("./utils")
|
|
|
|
# Use to perform a callback. Will try several times until the callback is
|
|
# properly emitted and stop when successful (or after a given number of tries).
|
|
# Used to emit a single callback. Destroy it and create a new class for a new callback.
|
|
# Emits "success" on success, "failure" on error and "stopped" when gave up trying
|
|
# to perform the callback.
|
|
module.exports = class CallbackEmitter extends EventEmitter
|
|
|
|
constructor: (@callbackURL, @message) ->
|
|
@nextInterval = 0
|
|
@timestap = 0
|
|
|
|
start: ->
|
|
@timestamp = new Date().getTime()
|
|
@nextInterval = 0
|
|
@_scheduleNext 0
|
|
|
|
_scheduleNext: (timeout) ->
|
|
setTimeout( =>
|
|
@_emitMessage (error, result) =>
|
|
if not error? and result
|
|
@emit "success"
|
|
else
|
|
@emit "failure", error
|
|
|
|
# get the next interval we have to wait and schedule a new try
|
|
interval = config.hooks.retryIntervals[@nextInterval]
|
|
if interval?
|
|
Logger.warn "xx> Trying the callback again in #{interval/1000.0} secs"
|
|
@nextInterval++
|
|
@_scheduleNext(interval)
|
|
|
|
# no intervals anymore, time to give up
|
|
else
|
|
@nextInterval = 0
|
|
@emit "stopped"
|
|
|
|
, timeout)
|
|
|
|
_emitMessage: (callback) ->
|
|
# data to be sent
|
|
# note: keep keys in alphabetical order
|
|
data =
|
|
event: JSON.stringify(@message)
|
|
timestamp: @timestamp
|
|
|
|
# calculate the checksum
|
|
checksum = Utils.checksum("#{@callbackURL}#{JSON.stringify(data)}#{config.bbb.sharedSecret}")
|
|
|
|
# get the final callback URL, including the checksum
|
|
urlObj = url.parse(@callbackURL, true)
|
|
callbackURL = @callbackURL
|
|
callbackURL += if _.isEmpty(urlObj.search) then "?" else "&"
|
|
callbackURL += "checksum=#{checksum}"
|
|
|
|
requestOptions =
|
|
followRedirect: true
|
|
maxRedirects: 10
|
|
uri: callbackURL
|
|
method: "POST"
|
|
form: data
|
|
|
|
request requestOptions, (error, response, body) ->
|
|
if error? or not (response?.statusCode >= 200 and response?.statusCode < 300)
|
|
Logger.warn "xx> Error in the callback call to: [#{requestOptions.uri}] for #{simplifiedEvent(data.event)}"
|
|
Logger.warn "xx> Error:", error
|
|
Logger.warn "xx> Status:", response?.statusCode
|
|
callback error, false
|
|
else
|
|
Logger.info "==> Successful callback call to: [#{requestOptions.uri}] for #{simplifiedEvent(data.event)}"
|
|
callback null, true
|
|
|
|
# A simple string that identifies the event
|
|
simplifiedEvent = (event) ->
|
|
try
|
|
eventJs = JSON.parse(event)
|
|
"event: { name: #{eventJs.envelope?.name}, timestamp: #{eventJs.envelope?.timestamp} }"
|
|
catch e
|
|
"event: #{event}"
|