Skip to content

Commit

Permalink
Add Video API (#297)
Browse files Browse the repository at this point in the history
* Implementing Video API functionality
  • Loading branch information
superchilled authored Dec 11, 2023
1 parent d4d2317 commit 0d458ab
Show file tree
Hide file tree
Showing 24 changed files with 1,303 additions and 5 deletions.
1 change: 1 addition & 0 deletions lib/vonage.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ module Vonage
'http' => 'HTTP',
'json' => 'JSON',
'jwt' => 'JWT',
'sip' => 'SIP',
'sms' => 'SMS',
'mms' => 'MMS',
'tfa' => 'TFA',
Expand Down
7 changes: 7 additions & 0 deletions lib/vonage/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@ def verify2
@verify2 ||= T.let(Verify2.new(config), T.nilable(Vonage::Verify2))
end

# @return [Video]
#
sig { returns(T.nilable(Vonage::Video)) }
def video
@video ||= T.let(Video.new(config), T.nilable(Vonage::Video))
end

# @return [Voice]
#
sig { returns(T.nilable(Vonage::Voice)) }
Expand Down
4 changes: 4 additions & 0 deletions lib/vonage/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ def initialize
self.signature_secret = ENV['VONAGE_SIGNATURE_SECRET']
self.signature_method = ENV['VONAGE_SIGNATURE_METHOD'] || 'md5hash'
self.token = T.let(nil, T.nilable(String))
self.video_host = 'video.api.vonage.com'
self.vonage_host = 'api-eu.vonage.com'
end

Expand Down Expand Up @@ -203,6 +204,9 @@ def token
sig { params(token: T.nilable(String)).returns(T.nilable(String)) }
attr_writer :token

sig { returns(String) }
attr_accessor :video_host

sig { returns(String) }
attr_accessor :vonage_host

Expand Down
10 changes: 9 additions & 1 deletion lib/vonage/keys.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@ def camelcase(hash)
'voice_callback_value',
'voice_status_callback',
'messages_callback_value',
'messages_callback_type'
'messages_callback_type',
'add_stream',
'has_audio',
'has_video',
'remove_stream',
'screenshare_type',
'session_id',
'stream_mode',
'archive_mode'
]
hash.transform_keys do |k|
if exceptions.include?(k.to_s)
Expand Down
7 changes: 4 additions & 3 deletions lib/vonage/namespace.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ def self.host
end

def self.host=(host)
raise ArgumentError unless %i[rest_host vonage_host].include?(host)

raise ArgumentError unless %i[rest_host video_host vonage_host].include?(host)
@host = host
end

Expand Down Expand Up @@ -273,7 +272,7 @@ def parse(response, response_class)
when Net::HTTPNoContent
response_class.new(nil, response)
when Net::HTTPSuccess
if response['Content-Type'] && response['Content-Type'].split(';').first == 'application/json'
if response['Content-Type'] && response['Content-Type'].split(';').first == 'application/json' && !response.body.empty?
entity = ::JSON.parse(response.body, object_class: Vonage::Entity)

response_class.new(entity, response)
Expand All @@ -295,6 +294,8 @@ def set_host
case self.class.host
when :rest_host
@config.rest_host
when :video_host
@config.video_host
when :vonage_host
@config.vonage_host
else
Expand Down
2 changes: 1 addition & 1 deletion lib/vonage/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# typed: strong

module Vonage
VERSION = "7.18.0"
VERSION = '7.19.0'
end
109 changes: 109 additions & 0 deletions lib/vonage/video.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
# typed: true
# frozen_string_literal: true

module Vonage
class Video < Namespace
include Keys

self.authentication = BearerToken

self.host = :video_host

# Generate a new session.
#
# @example
# session = client.video.create_session({
# archive_mode: 'always',
# location: '10.1.200.30',
# media_mode: 'routed'
# })
#
# @params [optional, String] :archive_mode (either 'always' or 'manual')
#
# @param [optional, String] :location
#
# @params [optional, String] :media_mode (either 'routed' or 'relayed')
#
# @return [Response]
#
# @see TODO: Add document link here
#
def create_session(**params)
request_params = params.clone
request_params[:archive_mode] ||= 'manual'
media_mode = request_params.delete(:media_mode) || 'routed'

if media_mode == 'relayed' && request_params[:archive_mode] == 'manual'
request_params['p2p.preference'] = 'enabled'
else
request_params['p2p.preference'] = 'disabled'
end

response = request('/session/create', params: camelcase(request_params), type: Post)

public_response_data = {
session_id: response.entity.first.session_id,
archive_mode: request_params[:archive_mode],
media_mode: media_mode,
location: request_params[:location]
}

entity = Entity.new(public_response_data)

response.class.new(entity, response.http_response)
end

def generate_client_token(session_id:, scope: 'session.connect', role: 'publisher', **params)
claims = {
application_id: @config.application_id,
scope: scope,
session_id: session_id,
role: role,
initial_layout_class_list: '',
sub: 'video',
acl: {
paths: {'/session/**' => {}}
}
}


claims[:data] = params[:data] if params[:data]
claims[:initial_layout_class_list] = params[:initial_layout_class_list].join(' ') if params[:initial_layout_class_list]
claims[:exp] = params[:expire_time].to_i if params[:expire_time]

JWT.generate(claims, @config.private_key)
end

# @return [Archives]
#
def archives
@archives ||= Archives.new(@config)
end

# @return [Broadcasts]
#
def broadcasts
@broadcasts ||= Broadcasts.new(@config)
end

# @return [Moderation]
#
def moderation
@moderation ||= Moderation.new(@config)
end

# @return [Signals]
#
def signals
@signals ||= Signals.new(@config)
end

# @return [Streams]
#
def streams
@streams ||= Streams.new(@config)
end


end
end
152 changes: 152 additions & 0 deletions lib/vonage/video/archives.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# typed: true
# frozen_string_literal: true

module Vonage
class Video::Archives < Namespace
include Keys

self.authentication = BearerToken

self.request_body = JSON

self.host = :video_host

# Get a list of archives for a specified Vonage application.
#
# @param [optional, Integer] :offset
#
# @param [optional, Integer] :count
#
# @param [optional, String] :session_id
#
# TODO: add auto_advance option
#
# @return [ListResponse]
#
# @see TODO: add docs link
#
def list(**params)
request('/v2/project/' + @config.application_id + '/archive', params: params, response_class: ListResponse)
end

# Return information for specified archive.
#
# @param [required, String] archive_id
#
# @return [Response]
#
# @see TODO: add docs link
#
def info(archive_id:)
request('/v2/project/' + @config.application_id + '/archive/' + archive_id)
end

# Create a new archive.
#
# @param [required, String] :session_id
#
# @param [optional, String] :hasAudio
#
# @param [optional, String] :hasVideo
#
# @param [optional, String] :name
#
# @param [optional, String] :outputMode
#
# @param [optional, String] :resolution
#
# @param [optional, String] :streamMode
#
# @param [optional, String] :multiArchiveTag
#
# @param [optional, Hash] :layout
#
# @option layout [optional, String] :type
#
# @option layout [optional, String] :stylesheet
#
# @option layout [optional, String] :screenshareType
#
# @return [Response]
#
# @see TODO: add docs link
#
def start(session_id:, **params)
request('/v2/project/' + @config.application_id + '/archive', params: camelcase(params.merge(session_id: session_id)), type: Post)
end

# Stop recording a specified archive.
#
# @param [required, String] archive_id
#
# @return [Response]
#
# @see TODO: add docs link
#
def stop(archive_id:)
request('/v2/project/' + @config.application_id + '/archive/' + archive_id + '/stop', type: Post)
end

# Delete a specified archive.
#
# @param [required, String] archive_id
#
# @return [Response]
#
# @see TODO: add docs link
#
def delete(archive_id:)
request('/v2/project/' + @config.application_id + '/archive/' + archive_id, type: Delete)
end

# Add a stream to a composed archive that was started with the streamMode set to "manual".
#
# @param [required, String] archive_id
#
# @param [required, String] stream_id The ID of the stream to be added
#
# @param [optional, Boolean] has_audio
#
# @param [optional, Boolean] has_video
#
# @return [Response]
#
# @see TODO: add docs link
#
def add_stream(archive_id:, stream_id:, **params)
request('/v2/project/' + @config.application_id + '/archive/' + archive_id + '/streams', params: camelcase(params.merge(addStream: stream_id)), type: Patch)
end

# Remove a stream from a composed archive that was started with the streamMode set to "manual".
#
# @param [required, String] archive_id
#
# @param [required, String] stream_id The ID of the stream to be removed
#
# @return [Response]
#
# @see TODO: add docs link
#
def remove_stream(archive_id:, stream_id:)
request('/v2/project/' + @config.application_id + '/archive/' + archive_id + '/streams', params: {removeStream: stream_id}, type: Patch)
end

# Change the layout of a composed archive while it is being recorded.
#
# @param [required, String] archive_id
#
# @param [optional, String] type
#
# @param [optional, String] stylesheet
#
# @param [optional, String] screenshare_type
#
# @return [Response]
#
# @see TODO: add docs link
#
def change_layout(archive_id:, **params)
request('/v2/project/' + @config.application_id + '/archive/' + archive_id + '/layout', params: camelcase(params), type: Put)
end
end
end
11 changes: 11 additions & 0 deletions lib/vonage/video/archives/list_response.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# typed: true

class Vonage::Video::Archives::ListResponse < Vonage::Response
include Enumerable

def each
return enum_for(:each) unless block_given?

@entity.items.each { |item| yield item }
end
end
Loading

0 comments on commit 0d458ab

Please sign in to comment.