Class: BigBlueButton::BigBlueButtonApi

Inherits:
Object
  • Object
show all
Defined in:
lib/bigbluebutton_api.rb

Overview

This class provides access to the BigBlueButton API. For more details see README.rdoc.

Sample usage of the API is as follows:

  1. Create a meeting with create_meeting;

  2. Redirect a user to the URL returned by join_meeting_url;

  3. Get information about the meetings with get_meetings and get_meeting_info;

  4. To force meeting to end, call end_meeting .

Important info about the data returned by the methods:

  • The XML returned by BBB is converted to a Hash. See individual method’s documentation for examples.

  • Three values will always exist in the hash:

    • :returncode (boolean)

    • :messageKey (string)

    • :message (string)

  • Some of the values returned by BBB are converted to better represent the data. Some of these are listed bellow. They will always have the type informed:

    • :meetingID (string)

    • :attendeePW (string)

    • :moderatorPW (string)

    • :running (boolean)

    • :hasBeenForciblyEnded (boolean)

    • :endTime and :startTime (DateTime or nil)

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, salt, version = '0.7', debug = false) ⇒ BigBlueButtonApi

Initializes an instance

url

URL to a BigBlueButton server (e.g. demo.bigbluebutton.org/bigbluebutton/api)

salt

Secret salt for this server

version

API version: 0.7 (valid for 0.7, 0.71 and 0.71a)



44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/bigbluebutton_api.rb', line 44

def initialize(url, salt, version='0.7', debug=false)
  @supported_versions = ['0.7', '0.8']
  @url = url
  @salt = salt
  @debug = debug
  @timeout = 10 # default timeout for api requests

  @version = version || get_api_version
  unless @supported_versions.include?(@version)
    raise BigBlueButtonException.new("BigBlueButton error: Invalid API version #{version}. Supported versions: #{@supported_versions.join(', ')}")
  end

  puts "BigBlueButtonAPI: Using version #{@version}" if @debug
end

Instance Attribute Details

#debugObject

Returns the value of attribute debug.



38
39
40
# File 'lib/bigbluebutton_api.rb', line 38

def debug
  @debug
end

#saltObject

Returns the value of attribute salt.



38
39
40
# File 'lib/bigbluebutton_api.rb', line 38

def salt
  @salt
end

#supported_versionsObject

Returns the value of attribute supported_versions.



38
39
40
# File 'lib/bigbluebutton_api.rb', line 38

def supported_versions
  @supported_versions
end

#timeoutObject

Returns the value of attribute timeout.



38
39
40
# File 'lib/bigbluebutton_api.rb', line 38

def timeout
  @timeout
end

#urlObject

Returns the value of attribute url.



38
39
40
# File 'lib/bigbluebutton_api.rb', line 38

def url
  @url
end

#versionObject

Returns the value of attribute version.



38
39
40
# File 'lib/bigbluebutton_api.rb', line 38

def version
  @version
end

Instance Method Details

#==(other) ⇒ Object

API’s are equal if all the following attributes are equal.



440
441
442
443
444
445
446
# File 'lib/bigbluebutton_api.rb', line 440

def ==(other)
  r = true
  [:url, :supported_versions, :salt, :version, :debug].each do |param|
    r = r && self.send(param) == other.send(param)
  end
  r
end

#create_meeting(meeting_name, meeting_id, options = {}, modules = nil) ⇒ Object

Creates a new meeting. Returns the hash with the response or throws BigBlueButtonException on failure.

meeting_name (string)

Name for the meeting

meeting_id (string, integer)

Unique identifier for the meeting

options (Hash)

Hash with optional parameters. The accepted parameters are: moderatorPW (string, int), attendeePW (string, int), welcome (string), dialNumber (int), logoutURL (string), maxParticipants (int), voiceBridge (int), record (boolean), duration (int) and “meta” parameters (usually strings). If a parameter passed in the hash is not supported it will simply be discarded. For details about each see BBB API docs.

modules (BigBlueButtonModules)

Configuration for the modules. The modules are sent as an xml and the request will use an HTTP POST instead of GET. Currently only the “presentation” module is available. Only used for version > 0.8. See usage examples below.

Example

options = { :moderatorPW => "123", :attendeePW => "321", :welcome => "Welcome here!",
            :dialNumber => 5190909090, :logoutURL => "http://mconf.org", :maxParticipants => 25,
            :voiceBridge => 76543, :record => "true", :duration => 0, :meta_category => "Remote Class" }
create_meeting("My Meeting", "my-meeting", options)

Example with modules (see BigBlueButtonModules docs for more)

modules = BigBlueButton::BigBlueButtonModules.new
modules.add_presentation(:url, "http://www.samplepdf.com/sample.pdf")
modules.add_presentation(:url, "http://www.samplepdf.com/sample2.pdf")
modules.add_presentation(:file, "presentations/class01.ppt")
modules.add_presentation(:base64, "JVBERi0xLjQKJ....[clipped here]....0CiUlRU9GCg==", "first-class.pdf")
create_meeting("My Meeting", "my-meeting", nil, modules)

Example response for 0.7

On successful creation:

{
 :returncode => true, :meetingID => "test",
 :attendeePW => "1234", :moderatorPW => "4321", :hasBeenForciblyEnded => false,
 :messageKey => "", :message => ""
}

Meeting that was forcibly ended:

{
 :returncode => true, :meetingID => "test",
 :attendeePW => "1234", :moderatorPW => "4321", :hasBeenForciblyEnded => true,
 :messageKey => "duplicateWarning",
 :message => "This conference was already in existence and may currently be in progress."
}

Example response for 0.8

{
 :returncode => true, :meetingID => "Test", :createTime => 1308591802,
 :attendeePW => "1234", :moderatorPW => "4321", :hasBeenForciblyEnded => false,
 :messageKey => "", :message => ""
}


123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/bigbluebutton_api.rb', line 123

def create_meeting(meeting_name, meeting_id, options={}, modules=nil)
  valid_options = [:moderatorPW, :attendeePW, :welcome, :maxParticipants,
                   :dialNumber, :voiceBridge, :webVoice, :logoutURL]

  selected_opt = options.clone
  if @version >= "0.8"
    # v0.8 added "record", "duration" and "meta_" parameters
    valid_options += [:record, :duration]
    selected_opt.reject!{ |k,v| !valid_options.include?(k) and !(k.to_s =~ /^meta_.*$/) }
    selected_opt[:record] = selected_opt[:record].to_s if selected_opt.has_key?(:record)
  else
    selected_opt.reject!{ |k,v| !valid_options.include?(k) }
  end
  params = { :name => meeting_name, :meetingID => meeting_id }.merge(selected_opt)

  # with modules we send a post request (only for >= 0.8)
  if modules and @version >= "0.8"
    response = send_api_request(:create, params, modules.to_xml)
  else
    response = send_api_request(:create, params)
  end

  formatter = BigBlueButtonFormatter.new(response)
  formatter.to_string(:meetingID)
  formatter.to_string(:moderatorPW)
  formatter.to_string(:attendeePW)
  formatter.to_boolean(:hasBeenForciblyEnded)
  if @version >= "0.8"
    formatter.to_int(:createTime)
  end

  response
end

#delete_recordings(recordIDs) ⇒ Object

Delete one or more recordings for a given recordID (or set of record IDs).

recordIDs (string, Array)

ID or IDs of the target recordings. Any of the following values are accepted:

"id1"
"id1,id2,id3"
["id1"]
["id1", "id2", "id3"]

Example responses

{ :returncode => true, :deleted => true }


421
422
423
424
425
426
# File 'lib/bigbluebutton_api.rb', line 421

def delete_recordings(recordIDs)
  raise BigBlueButtonException.new("Method only supported for versions >= 0.8") if @version < "0.8"

  recordIDs = recordIDs.join(",") if recordIDs.instance_of?(Array) # ["id1", "id2"] becomes "id1,id2"
  response = send_api_request(:deleteRecordings, { :recordID => recordIDs })
end

#end_meeting(meeting_id, moderator_password) ⇒ Object

Ends an existing meeting. Throws BigBlueButtonException on failure.

meeting_id (string, int)

Unique identifier for the meeting

moderator_password (string, int)

Moderator password

Return examples (for 0.7)

On success:

{
 :returncode=>true, :messageKey=>"sentEndMeetingRequest",
 :message=>"A request to end the meeting was sent.  Please wait a few seconds, and then use the getMeetingInfo
            or isMeetingRunning API calls to verify that it was ended."
}


171
172
173
# File 'lib/bigbluebutton_api.rb', line 171

def end_meeting(meeting_id, moderator_password)
  send_api_request(:end, { :meetingID => meeting_id, :password => moderator_password } )
end

#get_api_versionObject

Returns the API version (as string) of the associated server. This actually returns the version returned by the BBB server, and not the version set by the user in the initialization of this object.



322
323
324
325
# File 'lib/bigbluebutton_api.rb', line 322

def get_api_version
  response = send_api_request(:index)
  response[:returncode] ? response[:version].to_s : ""
end

#get_meeting_info(meeting_id, password) ⇒ Object

Returns a hash object containing the meeting information. See the API documentation for details on the return XML (code.google.com/p/bigbluebutton/wiki/API).

meeting_id (string, int)

Unique identifier for the meeting

password (string, int)

Moderator password for this meeting

Example responses for 0.7

With attendees:

{
 :returncode=>true, :meetingID=>"bigbluebutton-api-ruby-test", :attendeePW=>"1234", :moderatorPW=>"4321", :running=>true,
 :hasBeenForciblyEnded=>false, :startTime=>DateTime("Wed Apr 06 17:09:57 UTC 2011"), :endTime=>nil, :participantCount=>4, :moderatorCount=>2,
 :attendees => [
   {:userID=>"ndw1fnaev0rj", :fullName=>"House M.D.", :role=>:moderator},
   {:userID=>"gn9e22b7ynna", :fullName=>"Dexter Morgan", :role=>:moderator},
   {:userID=>"llzihbndryc3", :fullName=>"Cameron Palmer", :role=>:viewer},
   {:userID=>"rbepbovolsxt", :fullName=>"Trinity", :role=>:viewer}
 ], :messageKey=>"", :message=>""
}

Without attendees (not started):

{
 :returncode=>true, :meetingID=>"bigbluebutton-api-ruby-test", :attendeePW=>"1234", :moderatorPW=>"4321", :running=>false,
 :hasBeenForciblyEnded=>false, :startTime=>nil, :endTime=>nil, :participantCount=>0, :moderatorCount=>0,
 :attendees=>[], :messageKey=>"", :message=>""
}

Example responses for 0.8

{
  :returncode => true, :meetingName => "test", :meetingID => "test", :createTime => 1321906390524,
  :voiceBridge => 72194, :attendeePW => "1234", :moderatorPW => "4321", :running => false, :recording => false,
  :hasBeenForciblyEnded => false, :startTime => nil, :endTime => nil, :participantCount => 0, :maxUsers => 9,
  :moderatorCount => 0, :attendees => [],
  :metadata => { :two => "TWO", :one => "one" },
  :messageKey => "", :message => ""
}


264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/bigbluebutton_api.rb', line 264

def get_meeting_info(meeting_id, password)
  response = send_api_request(:getMeetingInfo, { :meetingID => meeting_id, :password => password } )

  formatter = BigBlueButtonFormatter.new(response)
  formatter.flatten_objects(:attendees, :attendee)
  response[:attendees].each { |a| BigBlueButtonFormatter.format_attendee(a) }

  formatter.to_string(:meetingID)
  formatter.to_string(:moderatorPW)
  formatter.to_string(:attendeePW)
  formatter.to_boolean(:hasBeenForciblyEnded)
  formatter.to_boolean(:running)
  formatter.to_datetime(:startTime)
  formatter.to_datetime(:endTime)
  formatter.to_int(:participantCount)
  formatter.to_int(:moderatorCount)
  if @version >= "0.8"
    formatter.to_string(:meetingName)
    formatter.to_int(:maxUsers)
    formatter.to_int(:voiceBridge)
    formatter.to_int(:createTime)
    formatter.to_boolean(:recording)
  end

  response
end

#get_meetingsObject

Returns a hash object containing information about the meetings currently existent in the BBB server, either they are running or not.

Example responses for 0.7

Server with one or more meetings:

{ :returncode => true,
  :meetings => [
    {:meetingID=>"Demo Meeting", :attendeePW=>"ap", :moderatorPW=>"mp", :hasBeenForciblyEnded=>false, :running=>true},
    {:meetingID=>"I was ended Meeting", :attendeePW=>"pass", :moderatorPW=>"pass", :hasBeenForciblyEnded=>true, :running=>false}
  ],
 :messageKey=>"", :message=>""
}

Server with no meetings:

{:returncode=>true, :meetings=>[], :messageKey=>"noMeetings", :message=>"no meetings were found on this server"}


310
311
312
313
314
315
316
317
# File 'lib/bigbluebutton_api.rb', line 310

def get_meetings
  response = send_api_request(:getMeetings, { :random => rand(9999999999) } )

  formatter = BigBlueButtonFormatter.new(response)
  formatter.flatten_objects(:meetings, :meeting)
  response[:meetings].each { |m| BigBlueButtonFormatter.format_meeting(m) }
  response
end

#get_recordings(options = {}) ⇒ Object

Retrieves the recordings that are available for playback for a given meetingID (or set of meeting IDs).

options (Hash)

Hash with optional parameters. The accepted parameters are: :meetingID (string, Array). For details about each see BBB API docs. Any of the following values are accepted for :meetingID :

:meetingID => "id1"
:meetingID => "id1,id2,id3"
:meetingID => ["id1"]
:meetingID => ["id1", "id2", "id3"]

Example responses

TODO: this example is not accurate yet

{ :returncode => true,
  :recordings => [
    {
      :recordID => "7f5745a08b24fa27551e7a065849dda3ce65dd32-1321618219268", :meetingID=>"bd1811beecd20f24314819a52ec202bf446ab94b",
      :name => "Evening Class1", :published => true,
      :startTime => #<DateTime: 2011-11-18T12:10:23+00:00 (212188378223/86400,0/1,2299161)>,
      :endTime => #<DateTime: 2011-11-18T12:12:25+00:00 (42437675669/17280,0/1,2299161)>,
      :metadata => { :course => "Fundamentals Of JAVA",
                     :description => "List of recordings",
                     :activity => "Evening Class1" },
      :playback => {
        :format => {
          :type => "slides",
          :url => "http://test-install.blindsidenetworks.com/playback/slides/playback.html?meetingId=7f5745a08b24fa27551e7a065849dda3ce65dd32-1321618219268",
          :length=>3
        }
      }
    },
    { :recordID => "183f0bf3a0982a127bdb8161-13085974450", :meetingID => "CS102",
      ...
      ...
    }
  ]
}


370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
# File 'lib/bigbluebutton_api.rb', line 370

def get_recordings(options={})
  raise BigBlueButtonException.new("Method only supported for versions >= 0.8") if @version < "0.8"

  valid_options = [:meetingID]
  options.reject!{ |k,v| !valid_options.include?(k) }

  # ["id1", "id2", "id3"] becomes "id1,id2,id3"
  if options.has_key?(:meetingID)
    options[:meetingID] = options[:meetingID].join(",") if options[:meetingID].instance_of?(Array)
  end

  response = send_api_request(:getRecordings, options)

  formatter = BigBlueButtonFormatter.new(response)
  formatter.flatten_objects(:recordings, :recording)
  response[:recordings].each { |r| BigBlueButtonFormatter.format_recording(r) }
  response
end

#get_url(method, params = {}) ⇒ Object

Formats an API call URL for the method ‘method’ using the parameters in ‘params’.

method (symbol)

The API method to be called (:create, :index, :join, and others)

params (Hash)

The parameters to be passed in the URL



461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
# File 'lib/bigbluebutton_api.rb', line 461

def get_url(method, params={})
  if method == :index
    return @url
  end

  url = "#{@url}/#{method}?"

  # stringify and escape all params
  params.delete_if { |k, v| v.nil? } unless params.nil?
  params_string = ""
  params_string = params.map{ |k,v| "#{k}=" + CGI::escape(v.to_s) unless k.nil? || v.nil? }.join("&")

  # checksum calc
  checksum_param = params_string + @salt
  checksum_param = method.to_s + checksum_param
  checksum = Digest::SHA1.hexdigest(checksum_param)

  # final url
  url += "#{params_string}&" unless params_string.empty?
  url += "checksum=#{checksum}"
end

#is_meeting_running?(meeting_id) ⇒ Boolean

Returns true or false as to whether meeting is open. A meeting is only open after at least one participant has joined.

meeting_id (string, int)

Unique identifier for the meeting

Returns:

  • (Boolean)


178
179
180
181
# File 'lib/bigbluebutton_api.rb', line 178

def is_meeting_running?(meeting_id)
  hash = send_api_request(:isMeetingRunning, { :meetingID => meeting_id } )
  BigBlueButtonFormatter.new(hash).to_boolean(:running)
end

#join_meeting(meeting_id, user_name, password, options = {}) ⇒ Object

Warning: As of this version of the gem, this call does not work (instead of returning XML response, it should join the meeting).

Joins a user into the meeting using an API call, instead of directing the user’s browser to moderator_url or attendee_url (note: this will still be required however to actually use bbb). Returns the URL a user can use to enter this meeting.

meeting_id (string, int)

Unique identifier for the meeting

user_name (string)

Name of the user

password (string, int)

Moderator or attendee password for this meeting

options (Hash)

Hash with optional parameters. The accepted parameters are: userID (string, int), webVoiceConf (string, int) and createTime (int). For details about each see BBB API docs.



213
214
215
216
217
218
219
220
221
# File 'lib/bigbluebutton_api.rb', line 213

def join_meeting(meeting_id, user_name, password, options={})
  valid_options = [:userID, :webVoiceConf]
  valid_options += [:createTime] if @version >= "0.8"
  options.reject!{ |k,v| !valid_options.include?(k) }

  params = { :meetingID => meeting_id, :password => password, :fullName => user_name }.merge(options)

  send_api_request(:join, params)
end

#join_meeting_url(meeting_id, user_name, password, options = {}) ⇒ Object

Returns the url used to join the meeting

meeting_id (string, int)

Unique identifier for the meeting

user_name (string)

Name of the user

password (string)

Password for this meeting - used to set the user as moderator or attendee

options (Hash)

Hash with optional parameters. The accepted parameters are: userID (string, int), webVoiceConf (string, int) and createTime (int). For details about each see BBB API docs.



190
191
192
193
194
195
196
197
198
# File 'lib/bigbluebutton_api.rb', line 190

def join_meeting_url(meeting_id, user_name, password, options={})
  valid_options = [:userID, :webVoiceConf]
  valid_options += [:createTime] if @version >= "0.8"
  options.reject!{ |k,v| !valid_options.include?(k) }

  params = { :meetingID => meeting_id, :password => password, :fullName => user_name }.merge(options)

  get_url(:join, params)
end

#last_http_responseObject

Returns the HTTP response object returned in the last API call.



449
450
451
# File 'lib/bigbluebutton_api.rb', line 449

def last_http_response
  @http_response
end

#last_xml_responseObject

Returns the XML returned in the last API call.



454
455
456
# File 'lib/bigbluebutton_api.rb', line 454

def last_xml_response
  @xml_response
end

#publish_recordings(recordIDs, publish) ⇒ Object

Publish and unpublish recordings for a given recordID (or set of record IDs).

recordIDs (string, Array)

ID or IDs of the target recordings. Any of the following values are accepted:

"id1"
"id1,id2,id3"
["id1"]
["id1", "id2", "id3"]
publish (boolean)

Publish or unpublish the recordings?

Example responses

{ :returncode => true, :published => true }


402
403
404
405
406
407
# File 'lib/bigbluebutton_api.rb', line 402

def publish_recordings(recordIDs, publish)
  raise BigBlueButtonException.new("Method only supported for versions >= 0.8") if @version < "0.8"

  recordIDs = recordIDs.join(",") if recordIDs.instance_of?(Array) # ["id1", "id2"] becomes "id1,id2"
  response = send_api_request(:publishRecordings, { :recordID => recordIDs, :publish => publish.to_s })
end

#send_api_request(method, params = {}, data = nil) ⇒ Object

Performs an API call.

Throws a BigBlueButtonException if something goes wrong (e.g. server offline). Also throws an exception of the request was not successful (i.e. returncode == FAILED).

Only formats the standard values in the response (the ones that exist in all responses).

method (symbol)

The API method to be called (:create, :index, :join, and others)

params (Hash)

The parameters to be passed in the URL

data (string)

Data to be sent with the request. If set, the request will use an HTTP POST instead of a GET and the data will be sent in the request body.



494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
# File 'lib/bigbluebutton_api.rb', line 494

def send_api_request(method, params={}, data=nil)
  url = get_url(method, params)

  @http_response = send_request(url, data)
  return { } if @http_response.body.empty?

  # 'Hashify' the XML
  @xml_response = @http_response.body
  hash = Hash.from_xml(@xml_response)

  # simple validation of the xml body
  unless hash.has_key?(:returncode)
    raise BigBlueButtonException.new("Invalid response body. Is the API URL correct? \"#{@url}\", version #{@version}")
  end

  # default cleanup in the response
  hash = BigBlueButtonFormatter.new(hash).default_formatting

  # if the return code is an error generates an exception
  unless hash[:returncode]
    exception = BigBlueButtonException.new(hash[:message])
    exception.key = hash.has_key?(:messageKey) ? hash[:messageKey] : ""
    raise exception
  end

  hash
end

#test_connectionObject

Make a simple request to the server to test the connection.



434
435
436
437
# File 'lib/bigbluebutton_api.rb', line 434

def test_connection
  response = send_api_request(:index)
  response[:returncode]
end