error in post publish recording ready callback script

113 views
Skip to first unread message

Abdulrahman Aljabri

unread,
Mar 18, 2024, 8:32:07 PM3/18/24
to BigBlueButton-dev
Hi everyone,

Hope you are doing well.

I am facing an issue with post publish recording ready callback script.
I will share some context to be all on same page.

I am using bbb 2.5, after enabling the recording feature. I noticed bbb 2.5 all files are stored as raw. After some research, I found this project bbb-recording-exporter

https://github.com/danielpetri1/bbb-recording-exporter

I used it and it works fine, after that I thought it would be better to upload the recording file to S3 so I updated this file:

/usr/local/bigbluebutton/core/scripts/post_publish/post_publish_recording_ready_callback.rb

to upload the file after being published.

snippet of the script:

#!/usr/bin/ruby
# encoding: UTF-8

#
# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
#
# Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU Lesser General Public License as published by the Free
# Software Foundation; either version 3.0 of the License, or (at your option)
# any later version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
# details.
#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
#

require "optimist"
require 'net/http'
require "jwt"
require "java_properties"
require File.expand_path('../../../lib/recordandplayback', __FILE__)
require "date"
require "aws-sdk-s3"
require "securerandom"
require "streamio-ffmpeg"


logger = Logger.new("/var/log/bigbluebutton/post_publish.log", 'weekly' )
logger.level = Logger::INFO
BigBlueButton.logger = logger

opts = Optimist::options do
opt :meeting_id, "Meeting id to archive", :type => String
opt :format, "Playback format name", :type => String
end
meeting_id = opts[:meeting_id]

bbb_web_properties = "/etc/bigbluebutton/bbb-web.properties"
events_xml = "/var/bigbluebutton/recording/raw/#{meeting_id}/events.xml"

def get_metadata(key, meeting_metadata)
meeting_metadata.key?(key) ? meeting_metadata[key].value : nil
end

def get_callback_url(events_xml)
meeting_metadata = BigBlueButton::Events.get_meeting_metadata(events_xml)

meta_bbb_rec_ready_url = "bbb-recording-ready-url"

callback_url = get_metadata(meta_bbb_rec_ready_url, meeting_metadata)

# For compatibility with some 3rd party implementations, look up for
# bn-recording-ready-url or canvas-recording-ready, when bbb-recording-ready
# is not included.
meta_bn_rec_ready_url = "bn-recording-ready-url"
meta_canvas_rec_ready_url = "canvas-recording-ready-url"

callback_url ||= get_metadata(meta_bn_rec_ready_url, meeting_metadata)
callback_url ||= get_metadata(meta_canvas_rec_ready_url, meeting_metadata)

callback_url
end


def upload_recording_to_object_storage(metadata)
BigBlueButton.logger.info("Uploading recording to object storage")

props = JavaProperties::Properties.new(bbb_web_properties)

endpoint = props[:s3Endpoint]
access_key_id = props[:s3AccessKey]
secret_access_key = props[:s3SecretKey]
bucket_name = props[:s3BucketName]
object_path = props[:s3ObjectPath]
object_name = props[:s3ObjectName]


s3_client = Aws::S3::Client.new(
endpoint: endpoint,
access_key_id: access_key_id,
secret_access_key: secret_access_key,
region: 'us-east-1',
force_path_style: true)


uuid = SecureRandom.uuid
bucket_name = bucket_name
object_path = object_path + '/' + metadata[:recordId] + '/' + object_name
object_key = uuid + '.mp4'
metadata = {
'meetingId' => metadata[:meetingId],
'recordId' => metadata[:recordId],
'title' => metadata[:title],
'duration' => metadata[:duration],
'owner' => metadata[:owner],
'uuid' => uuid,
}

s3_client.put_object(bucket: bucket_name, key: object_key, body: File.open(object_path), metadata: metadata)
BigBlueButton.logger.info("File '#{object_key}' uploaded successfully to bucket '#{bucket_name}'.")

rescue Aws::S3::Errors::ServiceError => e
BigBlueButton.logger.info("Failed to upload recording: #{e}")
end

#
# Main code
#
BigBlueButton.logger.info("Recording Ready Notify for [#{meeting_id}] starts")

begin
BigBlueButton.logger.info("events_xml: #{events_xml}")
callback_url = get_callback_url(events_xml)

unless callback_url.nil?
BigBlueButton.logger.info("Making callback for recording ready notification")
meeting_metadata = BigBlueButton::Events.get_meeting_metadata(events_xml)
BigBlueButton.logger.info("metadate #{meeting_metadata}")

props = JavaProperties::Properties.new(bbb_web_properties)
secret = props[:securitySalt]

external_meeting_id = BigBlueButton::Events.get_external_meeting_id(events_xml)
BigBlueButton.logger.info("external_meeting_id: #{external_meeting_id}")

meeting_title = get_metadata('title',meeting_metadata)
meeting_owner = get_metadata('owner',meeting_metadata)
recording_path = object_path + '/' + meeting_id + '/' + object_name
recording = FFMPEG::Movie.new(recording_path)
meeting_duration = recording.duration
recording_date = Date.today.to_s
bbb_url= get_metadata('bbburl',meeting_metadata)
recording_url = "#{bbb_url}/presentation/#{meeting_id}/meeting.mp4"

payload = { meetingId: external_meeting_id, recordId: meeting_id, title: meeting_title, url: recording_url, date: recording_date, duration: meeting_duration, owner: meeting_owner }
upload_recording_to_object_storage(payload)

BigBlueButton.logger.info("payload: #{payload}")
payload_encoded = JWT.encode(payload, secret)

uri = URI.parse(callback_url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = (uri.scheme == 'https')

BigBlueButton.logger.info("Sending request to #{uri.scheme}://#{uri.host}#{uri.request_uri}")
request = Net::HTTP::Post.new(uri.request_uri)
request.set_form_data(payload)

response = http.request(request)
code = response.code.to_i

if code == 410
BigBlueButton.logger.info("Notified for deleted meeting: #{meeting_id}")
# TODO: should we automatically delete the recording here?
elsif code == 404
BigBlueButton.logger.info("404 error when notifying for recording: #{meeting_id}, ignoring")
elsif code < 200 || code >= 300
BigBlueButton.logger.info("Callback HTTP request failed: #{response.code} #{response.message} (code #{code})")
else
BigBlueButton.logger.info("Recording notifier successful: #{meeting_id} (code #{code})")
end
end

rescue => e
BigBlueButton.logger.info("Rescued")
BigBlueButton.logger.info(e.to_s)
end

BigBlueButton.logger.info("Recording Ready notify ends")

exit 0





However, I faced an issue ruby script did not recognize 'aws-sdk-s3' package

Does anyone know how to fix it ?
I tested the script to check if the package is installed, as a standalone, it works fine.

error:

error.png

Abdulrahman Aljabri

unread,
Mar 19, 2024, 7:09:23 AM3/19/24
to BigBlueButton-dev
update:

I noticed the /usr/local/bigbluebutton/core is a ruby app
this is why I was able to run the script locally but bigbluebutton failed to do so


I added the aws-sdk-s3 to Gemfile

```

# frozen_string_literal: true


# BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
#
# Copyright © 2019 BigBlueButton Inc. and by respective authors (see below).
#
# This program is free software; you can redistribute it and/or modify it under the
# terms of the GNU Lesser General Public License as published by the Free Software
# Foundation; either version 3.0 of the License, or (at your option) any later
# version.
#
# BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

#
# You should have received a copy of the GNU Lesser General Public License along
# with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.

source 'https://rubygems.org'

gem 'absolute_time', '~> 1.0'
gem 'builder', '~> 3.2'
gem 'fastimage', '~> 2.1'
gem 'java_properties'
gem 'journald-logger', '~> 3.0'
gem 'jwt', '~> 2.2'
gem 'locale', '~> 2.1'
gem 'loofah', '~> 2.19.1'
gem 'nokogiri', '~> 1.13.10', '>= 1.13.10'
gem 'open4', '~> 1.3'
gem 'rb-inotify', '~> 0.10'
gem 'redis', '~> 4.1'
gem 'rubyzip', '~> 2.0'
gem 'optimist'
gem 'resque', '~> 2.5', '>= 2.5.0'
gem 'bbbevents', '~> 1.2'
gem 'rake', '>= 12.3', '<14'
gem 'tzinfo', '>= 1.2.10'
gem 'aws-sdk-s3', '>= 1.145.0'

group :test, optional: true do
  gem 'rubocop', '~> 1.31.1'
  gem 'minitest', '~> 5.14.1'
end


```

then I ran bundle install
However, I got this error


You are trying to install in deployment mode after changing
your Gemfile. Run `bundle install` elsewhere and add the
updated Gemfile.lock to version control.

If this is a development machine, remove the /usr/local/bigbluebutton/core/Gemfile freeze
by running `bundle config unset deployment`.

The dependencies in your gemfile changed

You have added to the Gemfile:
* aws-sdk-s3 (>= 1.145.0)



is there a way to add the package deployment mode, not development ?

Abdulrahman Aljabri

unread,
Mar 20, 2024, 1:56:09 AM3/20/24
to BigBlueButton-dev
I solved the issue by first running 'bundle config unset deployment'  to switch to development mode and then running 'bundle install' to install deps after that, I switched to deployment mode by running 'bundle install --deployment'
Now everything works as expected.

sd...@distancelearning.cloud

unread,
Mar 20, 2024, 7:44:15 AM3/20/24
to bigblueb...@googlegroups.com

No need to get this into packaging.

 

 

Just run  >gem install aws-sdk-s3        on the bbb server and the ruby script should run.

 

I’ve done this many times in the past.

 

Regards,

Stephen

 

From: bigblueb...@googlegroups.com <bigblueb...@googlegroups.com> On Behalf Of Abdulrahman Aljabri
Sent: Wednesday, March 20, 2024 1:56 AM
To: BigBlueButton-dev <bigblueb...@googlegroups.com>
Subject: [bigbluebutton-dev] Re: error in post publish recording ready callback script

 

I solved the issue by first running 'bundle config unset deployment'  to switch to development mode and then running 'bundle install' to install deps after that, I switched to deployment mode by running 'bundle install --deployment'
Now everything works as expected.

On Tuesday, March 19, 2024 at 2:09:23PM UTC+3 Abdulrahman Aljabri wrote:

update:

I noticed the /usr/local/bigbluebutton/core is a ruby app
this is why I was able to run the script locally but bigbluebutton failed to do so



--
You received this message because you are subscribed to the Google Groups "BigBlueButton-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to bigbluebutton-...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/bigbluebutton-dev/eba639c5-3251-4677-900b-a4b1097a168dn%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages