Wehbooks: hooks can now subscribe to a single meeting

Hooks can be global, to receive events from all meetings, or can receive
events for a single meeting. Depends on whether the meetingID parameter is
informed or not in the hooks/subscribe API call.

Also improved the log messages a bit.
This commit is contained in:
Leonardo Crauss Daronco 2014-11-12 10:53:49 -02:00
parent 31fe86c19d
commit c25082bafa
4 changed files with 48 additions and 9 deletions

View File

@ -47,5 +47,9 @@ module.exports = class CallbackEmitter extends EventEmitter
console.log "Response:", response
callback error, false
else
console.log "Successful callback call to:", requestOptions.uri
console.log "==> Successful callback call to: [#{requestOptions.uri}] for #{simplifiedEvent(data.event)}"
callback null, true
# A simple string that identifies the event
simplifiedEvent = (event) ->
"event: { name: #{event.header?.name}, timestamp: #{event.header?.timestamp} }"

View File

@ -6,6 +6,9 @@ nextId = 1
# The representation of a hook and its properties. Stored in memory and persisted
# to redis.
# Hooks can be global, receiving callback calls for events from all meetings on the
# server, or for a specific meeting. If an `externalMeetingID` is set in the hook,
# it will only receive calls related to this meeting, otherwise it will be global.
# TODO: at some point the queue needs to be cleared, or we need a size limit on it
module.exports = class Hook
@ -26,6 +29,14 @@ module.exports = class Hook
destroySync: ->
Hook.destroySync @id
# Is this a global hook?
isGlobal: ->
not @externalMeetingID?
# The meeting from which this hook should receive events.
targetMeetingID: ->
@externalMeetingID
# mapFromRedis: (redisData) ->
# @callbackURL = redisData?.callbackURL
# @externalMeetingID = redisData?.externalMeetingID
@ -34,7 +45,7 @@ module.exports = class Hook
# Puts a new message in the queue. Will also trigger a processing in the queue so this
# message might be processed instantly.
enqueue: (message) ->
console.log "Hook: enqueueing message", message
console.log "Hook: enqueueing message", JSON.stringify(message)
@queue.push message
@_processQueue()
@ -63,6 +74,10 @@ module.exports = class Hook
if hook?
callback?(new Error("There is already a subscription for this callback URL"), hook)
else
msg = "Hook: adding a subscription with callback URL [#{callbackURL}]"
msg += " for the meeting [#{meetingID}]" if meetingID?
console.log msg
hook = new Hook()
hook.id = nextId++
hook.callbackURL = callbackURL
@ -73,6 +88,10 @@ module.exports = class Hook
@removeSubscription = (subscriptionID, callback) ->
hook = Hook.getSync(subscriptionID)
if hook?
msg = "Hook: removing the hook with callback URL [#{hook.callbackURL}]"
msg += " for the meeting [#{hook.externalMeetingID}]" if hook.externalMeetingID?
console.log msg
hook.destroySync()
callback?(null, true)
else

View File

@ -31,7 +31,7 @@ module.exports = class WebHooks
try
message = JSON.parse message
if message? and @_filterMessage channel, message
console.log "\nWebHooks: processing message [#{channel}]", message
console.log "WebHooks: processing message on [#{channel}]:", JSON.stringify(message)
@_processEvent message
catch e
@ -51,9 +51,25 @@ module.exports = class WebHooks
# 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.allSync()
hooks = Hook.allSync(message)
# get the meeting ID from the message and try to find the external meeting ID
# from our mappings
idFromMessage = message.payload?.meeting_id
if idFromMessage?
extMeetingID = @meetingMappings[idFromMessage]
else
extMeetingID = null
# filter the hooks that need to receive this event
# only global hooks or hooks for this specific meeting
hooks = _.filter(hooks, (hook) ->
hook.isGlobal() or
(extMeetingID? and extMeetingID is hook.targetMeetingID())
)
hooks.forEach (hook) ->
console.log "WebHooks: enqueuing a message in the hook:", hook.callbackURL
console.log "WebHooks: enqueueing a message in the hook:", hook.callbackURL
hook.enqueue message
# Subscribe to the meeting events on pubsub to keep track of the mapping
@ -79,11 +95,11 @@ module.exports = class WebHooks
_addMeetingMapping: (meetingID, externalMeetingID) ->
unless meetingID in _.keys(@meetingMappings)
@meetingMappings[meetingID] = externalMeetingID
console.log "WebHooks: added meeting mapping to the list", meetingID, "=", @meetingMappings[meetingID]
console.log "WebHooks: added meeting mapping to the list { #{meetingID}: #{@meetingMappings[meetingID]} }"
_removeMeetingMapping: (meetingID) ->
if meetingID in _.keys(@meetingMappings)
console.log "WebHooks: removing meeting mapping from the list", meetingID, "=", @meetingMappings[meetingID]
console.log "WebHooks: removing meeting mapping from the list { #{meetingID}: #{@meetingMappings[meetingID]} }"
delete @meetingMappings[meetingID]
@meetingMappings[meetingID] = null

View File

@ -18,12 +18,12 @@ module.exports = class WebServer
console.log "Could not bind to port", port
console.log "Aborting."
process.exit(1)
console.log "*** Server listening on port", port, "in", @app.settings.env.toUpperCase(), "mode"
console.log "== Server listening on port", port, "in", @app.settings.env.toUpperCase(), "mode"
_registerRoutes: ->
# Request logger
@app.all "*", (req, res, next) ->
console.log "*", req.method, "request to", req.url, "from:", clientDataSimple(req)
console.log "<==", req.method, "request to", req.url, "from:", clientDataSimple(req)
next()
@app.get "/bigbluebutton/api/hooks/subscribe", @_validateChecksum, @_subscribe