Webhooks: store meeting ID mappings in a global model
This commit is contained in:
parent
fd90a46563
commit
bfdae8f204
@ -42,7 +42,7 @@ module.exports = class CallbackEmitter extends EventEmitter
|
|||||||
|
|
||||||
request requestOptions, (error, response, body) ->
|
request requestOptions, (error, response, body) ->
|
||||||
if error?
|
if error?
|
||||||
console.log "Error calling url:",requestOptions.uri
|
console.log "X=> Error in the callback call to: [#{requestOptions.uri}] for #{simplifiedEvent(data.event)}"
|
||||||
console.log "Error:", error
|
console.log "Error:", error
|
||||||
console.log "Response:", response
|
console.log "Response:", response
|
||||||
callback error, false
|
callback error, false
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
_ = require("lodash")
|
_ = require("lodash")
|
||||||
|
|
||||||
CallbackEmitter = require("./callback_emitter")
|
CallbackEmitter = require("./callback_emitter")
|
||||||
|
MeetingIDMap = require("./meeting_id_map")
|
||||||
|
|
||||||
# The database of hooks.
|
# The database of hooks.
|
||||||
db = {}
|
db = {}
|
||||||
@ -76,7 +77,7 @@ module.exports = class Hook
|
|||||||
if hook?
|
if hook?
|
||||||
callback?(new Error("There is already a subscription for this callback URL"), hook)
|
callback?(new Error("There is already a subscription for this callback URL"), hook)
|
||||||
else
|
else
|
||||||
msg = "Hook: adding a subscription with callback URL [#{callbackURL}]"
|
msg = "Hook: adding a hook with callback URL [#{callbackURL}]"
|
||||||
msg += " for the meeting [#{meetingID}]" if meetingID?
|
msg += " for the meeting [#{meetingID}]" if meetingID?
|
||||||
console.log msg
|
console.log msg
|
||||||
|
|
||||||
@ -85,6 +86,7 @@ module.exports = class Hook
|
|||||||
hook.callbackURL = callbackURL
|
hook.callbackURL = callbackURL
|
||||||
hook.externalMeetingID = meetingID
|
hook.externalMeetingID = meetingID
|
||||||
hook.saveSync()
|
hook.saveSync()
|
||||||
|
|
||||||
callback?(null, hook)
|
callback?(null, hook)
|
||||||
|
|
||||||
@removeSubscription = (hookID, callback) ->
|
@removeSubscription = (hookID, callback) ->
|
||||||
@ -112,11 +114,10 @@ module.exports = class Hook
|
|||||||
else
|
else
|
||||||
null
|
null
|
||||||
|
|
||||||
@allForMeetingSync = (externalMeetingID) ->
|
@findByExternalMeetingIDSync = (externalMeetingID) ->
|
||||||
hooks = Hook.allSync()
|
hooks = Hook.allSync()
|
||||||
_.filter(hooks, (hook) ->
|
_.filter(hooks, (hook) ->
|
||||||
hook.isGlobal() or
|
(externalMeetingID? and externalMeetingID is hook.externalMeetingID)
|
||||||
(externalMeetingID? and externalMeetingID is hook.targetMeetingID())
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@allGlobalSync = ->
|
@allGlobalSync = ->
|
||||||
|
28
labs/bbb-callback/meeting_id_map.coffee
Normal file
28
labs/bbb-callback/meeting_id_map.coffee
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
_ = require("lodash")
|
||||||
|
|
||||||
|
# The database of mappings. Format:
|
||||||
|
# { internalMeetingID: externalMeetingID }
|
||||||
|
db = {}
|
||||||
|
|
||||||
|
# A simple model to store mappings for meeting IDs.
|
||||||
|
module.exports = class MeetingIDMap
|
||||||
|
|
||||||
|
@addMapping = (internalMeetingID, externalMeetingID) ->
|
||||||
|
unless internalMeetingID in _.keys(db)
|
||||||
|
db[internalMeetingID] = externalMeetingID
|
||||||
|
console.log "MeetingIDMap: added meeting mapping to the list { #{internalMeetingID}: #{db[internalMeetingID]} }"
|
||||||
|
|
||||||
|
@removeMapping = (internalMeetingID) ->
|
||||||
|
if internalMeetingID in _.keys(db)
|
||||||
|
console.log "MeetingIDMap: removing meeting mapping from the list { #{internalMeetingID}: #{db[internalMeetingID]} }"
|
||||||
|
delete db[internalMeetingID]
|
||||||
|
db[internalMeetingID] = null
|
||||||
|
|
||||||
|
@getInternalMeetingID = (externalMeetingID) ->
|
||||||
|
for internal, external of db
|
||||||
|
if external is externalMeetingID
|
||||||
|
return internal
|
||||||
|
null
|
||||||
|
|
||||||
|
@getExternalMeetingID = (internalMeetingID) ->
|
||||||
|
db[internalMeetingID]
|
@ -5,6 +5,7 @@ request = require("request")
|
|||||||
|
|
||||||
config = require("./config")
|
config = require("./config")
|
||||||
Hook = require("./hook")
|
Hook = require("./hook")
|
||||||
|
MeetingIDMap = require("./meeting_id_map")
|
||||||
|
|
||||||
# Web hooks will listen for events on redis coming from BigBlueButton and
|
# Web hooks will listen for events on redis coming from BigBlueButton and
|
||||||
# perform HTTP calls with them to all registered hooks.
|
# perform HTTP calls with them to all registered hooks.
|
||||||
@ -15,7 +16,6 @@ module.exports = class WebHooks
|
|||||||
@client = redis.createClient()
|
@client = redis.createClient()
|
||||||
|
|
||||||
# To map internal and external meeting IDs
|
# To map internal and external meeting IDs
|
||||||
@meetingMappings = {}
|
|
||||||
@subscriberMeetings = redis.createClient()
|
@subscriberMeetings = redis.createClient()
|
||||||
|
|
||||||
start: ->
|
start: ->
|
||||||
@ -51,16 +51,14 @@ module.exports = class WebHooks
|
|||||||
# Processes an event received from redis. Will get all hook URLs that
|
# Processes an event received from redis. Will get all hook URLs that
|
||||||
# should receive this event and start the process to perform the callback.
|
# should receive this event and start the process to perform the callback.
|
||||||
_processEvent: (message) ->
|
_processEvent: (message) ->
|
||||||
hooks = Hook.allSync(message)
|
hooks = Hook.allGlobalSync()
|
||||||
|
|
||||||
# filter the hooks that need to receive this event
|
# filter the hooks that need to receive this event
|
||||||
# only global hooks or hooks for this specific meeting
|
# only global hooks or hooks for this specific meeting
|
||||||
idFromMessage = message.payload?.meeting_id # always the internal meetingID
|
idFromMessage = message.payload?.meeting_id
|
||||||
if idFromMessage?
|
if idFromMessage?
|
||||||
externalMeetingID = @meetingMappings[idFromMessage]
|
eMeetingID = MeetingIDMap.getExternalMeetingID(idFromMessage)
|
||||||
hooks = Hook.allForMeetingSync(externalMeetingID)
|
hooks = hooks.concat(Hook.findByExternalMeetingIDSync(eMeetingID))
|
||||||
else
|
|
||||||
hooks = Hook.allGlobalSync(externalMeetingID)
|
|
||||||
|
|
||||||
hooks.forEach (hook) ->
|
hooks.forEach (hook) ->
|
||||||
console.log "WebHooks: enqueueing a message in the hook:", hook.callbackURL
|
console.log "WebHooks: enqueueing a message in the hook:", hook.callbackURL
|
||||||
@ -77,26 +75,15 @@ module.exports = class WebHooks
|
|||||||
try
|
try
|
||||||
message = JSON.parse(message)
|
message = JSON.parse(message)
|
||||||
if message.header?.name is "meeting_created_message"
|
if message.header?.name is "meeting_created_message"
|
||||||
@_addMeetingMapping(message.payload?.meeting_id, message.payload?.external_meeting_id)
|
MeetingIDMap.addMapping(message.payload?.meeting_id, message.payload?.external_meeting_id)
|
||||||
else if message.header?.name is "meeting_destroyed_event"
|
else if message.header?.name is "meeting_destroyed_event"
|
||||||
@_removeMeetingMapping(message.payload?.meeting_id)
|
MeetingIDMap.removeMapping(message.payload?.meeting_id)
|
||||||
|
|
||||||
catch e
|
catch e
|
||||||
console.log "WebHooks: error processing the message", JSON.stringify(message), ":", e
|
console.log "WebHooks: error processing the message", JSON.stringify(message), ":", e
|
||||||
|
|
||||||
@subscriberMeetings.subscribe config.hooks.meetingsChannel
|
@subscriberMeetings.subscribe config.hooks.meetingsChannel
|
||||||
|
|
||||||
_addMeetingMapping: (meetingID, externalMeetingID) ->
|
|
||||||
unless meetingID in _.keys(@meetingMappings)
|
|
||||||
@meetingMappings[meetingID] = externalMeetingID
|
|
||||||
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]} }"
|
|
||||||
delete @meetingMappings[meetingID]
|
|
||||||
@meetingMappings[meetingID] = null
|
|
||||||
|
|
||||||
# TODO: enable the methods below again when we persist hooks to redis again
|
# TODO: enable the methods below again when we persist hooks to redis again
|
||||||
# # Gets all hooks from redis.
|
# # Gets all hooks from redis.
|
||||||
# # Calls `callback(errors, result)` when done. `result` is an array of `Hook` objects.
|
# # Calls `callback(errors, result)` when done. `result` is an array of `Hook` objects.
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
_ = require("lodash")
|
||||||
express = require("express")
|
express = require("express")
|
||||||
url = require("url")
|
url = require("url")
|
||||||
|
|
||||||
@ -71,9 +72,13 @@ module.exports = class WebServer
|
|||||||
meetingID = urlObj.query["meetingID"]
|
meetingID = urlObj.query["meetingID"]
|
||||||
|
|
||||||
if meetingID?
|
if meetingID?
|
||||||
hooks = Hook.allForMeetingSync(meetingID)
|
# all the hooks that receive events from this meeting
|
||||||
else
|
|
||||||
hooks = Hook.allGlobalSync()
|
hooks = Hook.allGlobalSync()
|
||||||
|
hooks = hooks.concat(Hook.findByExternalMeetingIDSync(meetingID))
|
||||||
|
hooks = _.sortBy(hooks, (hook) -> hook.id)
|
||||||
|
else
|
||||||
|
# no meetingID, return all hooks
|
||||||
|
hooks = Hook.allSync()
|
||||||
|
|
||||||
msg = "<response><returncode>SUCCESS</returncode><hooks>"
|
msg = "<response><returncode>SUCCESS</returncode><hooks>"
|
||||||
hooks.forEach (hook) ->
|
hooks.forEach (hook) ->
|
||||||
|
Loading…
Reference in New Issue
Block a user