89 lines
3.4 KiB
CoffeeScript
89 lines
3.4 KiB
CoffeeScript
_ = require("lodash")
|
|
async = require("async")
|
|
redis = require("redis")
|
|
request = require("request")
|
|
|
|
config = require("./config")
|
|
Hook = require("./hook")
|
|
IDMapping = require("./id_mapping")
|
|
Logger = require("./logger")
|
|
|
|
# Web hooks will listen for events on redis coming from BigBlueButton and
|
|
# perform HTTP calls with them to all registered hooks.
|
|
module.exports = class WebHooks
|
|
|
|
constructor: ->
|
|
@subscriberEvents = redis.createClient()
|
|
|
|
start: ->
|
|
@_subscribeToEvents()
|
|
|
|
# Subscribe to the events on pubsub that might need to be sent in callback calls.
|
|
_subscribeToEvents: ->
|
|
@subscriberEvents.on "psubscribe", (channel, count) ->
|
|
Logger.info "WebHooks: subscribed to " + channel
|
|
|
|
@subscriberEvents.on "pmessage", (pattern, channel, message) =>
|
|
|
|
processMessage = =>
|
|
if @_filterMessage(channel, message)
|
|
Logger.info "WebHooks: processing message on [#{channel}]:", JSON.stringify(message)
|
|
@_processEvent(message)
|
|
|
|
try
|
|
message = JSON.parse(message)
|
|
if message?
|
|
id = message.payload?.meeting_id
|
|
IDMapping.reportActivity(id)
|
|
|
|
# First treat meeting events to add/remove ID mappings
|
|
if message.header?.name is "meeting_created_message"
|
|
Logger.info "WebHooks: got create message on meetings channel [#{channel}]", message
|
|
IDMapping.addOrUpdateMapping message.payload?.meeting_id, message.payload?.external_meeting_id, (error, result) ->
|
|
# has to be here, after the meeting was created, otherwise create calls won't generate
|
|
# callback calls for meeting hooks
|
|
processMessage()
|
|
|
|
# TODO: Temporarily commented because we still need the mapping for recording events,
|
|
# after the meeting ended.
|
|
# else if message.header?.name is "meeting_destroyed_event"
|
|
# Logger.info "WebHooks: got destroy message on meetings channel [#{channel}]", message
|
|
# IDMapping.removeMapping message.payload?.meeting_id, (error, result) ->
|
|
# processMessage()
|
|
|
|
else
|
|
processMessage()
|
|
|
|
catch e
|
|
Logger.error "WebHooks: error processing the message", message, ":", e
|
|
|
|
@subscriberEvents.psubscribe config.hooks.pchannel
|
|
|
|
# Returns whether the message read from redis should generate a callback
|
|
# call or not.
|
|
_filterMessage: (channel, message) ->
|
|
for event in config.hooks.events
|
|
if channel? and message.header?.name? and
|
|
event.channel.match(channel) and event.name.match(message.header?.name)
|
|
return true
|
|
false
|
|
|
|
# Processes an event received from redis. Will get all hook URLs that
|
|
# should receive this event and start the process to perform the callback.
|
|
_processEvent: (message) ->
|
|
hooks = Hook.allGlobalSync()
|
|
|
|
# TODO: events that happen after the meeting ended will never trigger the hooks
|
|
# below, since the mapping is removed when the meeting ends
|
|
|
|
# filter the hooks that need to receive this event
|
|
# only global hooks or hooks for this specific meeting
|
|
idFromMessage = message.payload?.meeting_id
|
|
if idFromMessage?
|
|
eMeetingID = IDMapping.getExternalMeetingID(idFromMessage)
|
|
hooks = hooks.concat(Hook.findByExternalMeetingIDSync(eMeetingID))
|
|
|
|
hooks.forEach (hook) ->
|
|
Logger.info "WebHooks: enqueueing a message in the hook:", hook.callbackURL
|
|
hook.enqueue message
|