diff --git a/labs/bbb-callback/app.coffee b/labs/bbb-callback/app.coffee deleted file mode 100644 index 1b374fea4691e36f0acd55baefcb26edb9676621..0000000000000000000000000000000000000000 --- a/labs/bbb-callback/app.coffee +++ /dev/null @@ -1,50 +0,0 @@ -request = require("request") -redis = require("redis") - -# Class that defines the application. -module.exports = class Application - - constructor: -> - @subscriber = redis.createClient() - @client = redis.createClient() - - start: -> - @_subscribe() - - _subscribe: -> - - @subscriber.on "psubscribe", (channel, count) -> - console.log "subscribed to " + channel - - @subscriber.on "pmessage", (pattern, channel, message) => - console.log "got message [", channel, "]", message - - try - properties = JSON.parse(message) - catch e - properties = null - # TODO: handle the error properly - console.log e - - if properties? - @client.lrange "meeting:" + properties.meetingID + ":subscriptions", 0, -1, (error, reply) => - reply.forEach (sid, index) => - console.log "subscriber id = " + sid - @client.hgetall "meeting:" + properties.meetingID + ":subscription:" + sid, (err, rep) -> - if rep.active is "true" - properties.meetingID = rep.externalMeetingID - post_options = - uri: rep.callbackURL - method: "POST" - json: properties - - request post_options, (error, response, body) -> - if not error and response.statusCode is 200 - console.log "Error calling url: [" + post_options.uri + "]" - console.log "Error: [" + JSON.stringify(error) + "]" - console.log "Response: [" + JSON.stringify(response) + "]" - else - console.log "Passed calling url: [" + post_options.uri + "]" - console.log "Response: [" + JSON.stringify(response) + "]" - - @subscriber.psubscribe "bigbluebutton:*" diff --git a/labs/bbb-callback/app.js b/labs/bbb-callback/app.js index dd1971995389ad1ae3efac8db5354ed77cfec0e3..e21c144726a3ec97f2bec194128054190ea7c030 100755 --- a/labs/bbb-callback/app.js +++ b/labs/bbb-callback/app.js @@ -2,6 +2,6 @@ require("coffee-script/register"); -Application = require('./app.coffee'); +Application = require('./application.coffee'); application = new Application(); application.start(); diff --git a/labs/bbb-callback/application.coffee b/labs/bbb-callback/application.coffee new file mode 100644 index 0000000000000000000000000000000000000000..59cd8293555f3159203c6039645d54c78fc71027 --- /dev/null +++ b/labs/bbb-callback/application.coffee @@ -0,0 +1,43 @@ +request = require("request") +redis = require("redis") + +Callbacks = require("./callbacks") + +# Class that defines the application. +module.exports = class Application + + constructor: -> + @subscriber = redis.createClient() + @callbacks = new Callbacks() + + start: -> + @_subscribe() + + _subscribe: -> + + @subscriber.on "psubscribe", (channel, count) -> + console.log "Application: subscribed to " + channel + + @subscriber.on "pmessage", (pattern, channel, message) => + console.log "---------------------------------------------------------" + console.log "Application: got message [", channel, "]", message + try + message = JSON.parse(message) + + # TODO: filter the messages we want to process + @_processMessage(message) if message? + + catch e + # TODO: handle the error properly + console.log e + + @subscriber.psubscribe "bigbluebutton:*" + + _processMessage: (message) -> + @callbacks.getCallbackUrls (error, callbackUrls) => + console.log "Application: got callback urls:", callbackUrls + callbackUrls.forEach (callbackUrl) -> + if callbackUrl.isActive() + # TODO: the external meeting ID is not on redis yet + # message.meetingID = rep.externalMeetingID + callbackUrl.enqueue(message) diff --git a/labs/bbb-callback/callback_url.coffee b/labs/bbb-callback/callback_url.coffee new file mode 100644 index 0000000000000000000000000000000000000000..378c34d3055f5d823dd1f2409c9a8b461ae78053 --- /dev/null +++ b/labs/bbb-callback/callback_url.coffee @@ -0,0 +1,32 @@ +request = require("request") + +# The representation of a callback URL and its properties, taken from redis. +module.exports = class CallbackURL + + # constructor: -> + + mapFromRedis: (redisData) -> + @url = redisData?.callbackURL + @externalMeetingID = redisData?.externalMeetingID + @active = redisData?.active + + isActive: -> + @active + + # TODO: use a queue and enqueue the message instead of sending it + # use another class to manage the queue and make the callback calls + enqueue: (message) -> + console.log "CallbackURL: enqueueing message", message + requestOptions = + uri: @url + method: "POST" + json: message + + request requestOptions, (error, response, body) -> + if not error and response.statusCode is 200 + console.log "Error calling url: [" + requestOptions.uri + "]" + console.log "Error: [" + JSON.stringify(error) + "]" + console.log "Response: [" + JSON.stringify(response) + "]" + else + console.log "Passed calling url: [" + requestOptions.uri + "]" + console.log "Response: [" + JSON.stringify(response) + "]" diff --git a/labs/bbb-callback/callbacks.coffee b/labs/bbb-callback/callbacks.coffee new file mode 100644 index 0000000000000000000000000000000000000000..fab3df003c4a4d1d00b9dee3c786979ba60f1c86 --- /dev/null +++ b/labs/bbb-callback/callbacks.coffee @@ -0,0 +1,72 @@ +_ = require("lodash") +async = require("async") +redis = require("redis") + +CallbackURL = require("./callback_url") + +# Helper class to fetch the list of callbacks from redis. +module.exports = class Callbacks + + constructor: -> + @subscriber = redis.createClient() + @client = redis.createClient() + @meetings = [] + @_subscribe() + + getCallbackUrls: (callback) -> + tasks = [] + @meetings.forEach (meetingId) => + console.log "Callbacks: checking callbacks for the meeting", meetingId + tasks.push (done) => + + @client.lrange "meeting:#{meetingId}:subscriptions", 0, -1, (error, subscriptions) => + # TODO: treat error + @_getCallbackUrlsForSubscriptions meetingId, subscriptions, done + + async.series tasks, (errors, result) -> + result = _.flatten result + console.log "Callbacks#getCallbackUrls: returning", result + callback?(errors, result) + + _getCallbackUrlsForSubscriptions: (meetingId, subscriptions, callback) -> + tasks = [] + subscriptions.forEach (sid, index) => + + tasks.push (done) => + @client.hgetall "meeting:#{meetingId}:subscription:#{sid}", (error, redisData) -> + # TODO: treat error + console.log "Callbacks: creating callbackUrl for", redisData + cb = new CallbackURL() + cb.mapFromRedis redisData + done null, cb + + async.series tasks, (errors, result) -> + console.log "Callbacks#_getCallbackUrlsForSubscriptions: returning", result + callback?(errors, result) + + + # TODO: for now we have to check for all meetings created and store their internal + # meeting ID so we can read from redis the callbacks registered for these meetings + _subscribe: -> + @subscriber.on "subscribe", (channel, count) -> + console.log "Callbacks: subscribed to " + channel + @subscriber.on "message", (channel, message) => + console.log "Callbacks: got message [", channel, "]", message + try + message = JSON.parse(message) + + if message.header?.name is "meeting_created_message" + @_addMeeting(message.payload?.meeting_id) + + # TODO: remove meetings from the list + + catch e + # TODO: handle the error properly + console.log e + + @subscriber.subscribe "bigbluebutton:from-bbb-apps:meeting" + + _addMeeting: (meetingId) -> + unless _.contains(@meetings, meetingId) + console.log "Callbacks: adding meeting to the list", meetingId + @meetings.push meetingId diff --git a/labs/bbb-callback/package.json b/labs/bbb-callback/package.json index e3b2ea47878edfff417c7b148ae59386ff415263..2077aa1052d20be3533fdfae936f6112fc99c928 100755 --- a/labs/bbb-callback/package.json +++ b/labs/bbb-callback/package.json @@ -10,7 +10,9 @@ "dependencies" : { "redis": "0.12.1", "request": "2.47.0", - "coffee-script": "1.8.0" + "coffee-script": "1.8.0", + "lodash": "2.4.1", + "async": "0.9.0" }, "engines": { "node": "0.10.26"