Vonage Video Transition Guide for Ruby

Transitioning from OpenTok-Ruby-SDK to vonage-ruby-sdk

Introduction

Purpose

The goal of this document is to provide a starting point for transitioning from the OpenTok Ruby Server SDK to the Vonage Ruby Server SDK.

Scope

This document assumes that you are using at least version 4.9.0 or later of the OpenTok Ruby SDK. A initial implementation of the Video API was added to the Ruby Server SDK in version 7.19.0, with additional features implemented in version 7.24.0. However, for your migration we recommend using the current latest version of the Vonage Ruby SDK, which can be found on GitHub or RubyGems.

Assumptions

This guide is intended to be followed by a professional software engineer. At least a basic level of competency with Ruby, common Ruby developer tools, and Git (or other version control system) is assumed. You should be comfortable with reading and writing Ruby code, managing project dependencies, deploying and executing a Ruby project. An introduction to the Ruby language, platform and associated tooling is well beyond the scope of this document.

Resources

The following links are useful for further reading to accompany this document and for reference to anything not covered in this document:

Vonage

TokBox

Planning Your Migration

Before transitioning from OpenTok to Vonage Video, you should consider the scale of the task to set realistic expectations.

Evaluate Impact

In order to evaluate the impact of the migration on your application, there are some questions that you will need to consider.

  1. How much of your application's code depends on the OpenTok SDK? Make a list of all the files in which the SDK is directly used. One way of determining this might be to identify any .rb file which contains a require 'opentok' reference. For example, you can search through the files in your project for the statement require 'opentok' using a code editor, IDE, or command-line tool to identify the files affected.

  2. How many of the OpenTok SDK's features does your application use? For an example an application that is using the SDK solely to create video sessions and generate client tokens will likely be simpler to migrate than one which is also using archive, broadcast, moderation, and other features.

  3. Which of the OpenTok SDK's features does your application use? Some features may require more effort to migrate than others. See the Key Changes and Considerations section for details of changes between the implementation of the two SDKs.

  4. How tightly-coupled is your application code with the OpenTok SDK? In the context of a Ruby on Rails application, for example, are you invoking methods from the SDK directly in your controller actions, or have you abstracted those method calls in some way (e.g. via use of the Gateway Pattern or Adapter Pattern)?

There may also be other considerations for your specific project that aren't listed above.

Timeline

Take into account the time required to complete the transition. This will depend on a number of factors such as your familiarity with the project and the impact of migrating the project (as described above). It is crucial to have a good test suite in place so that you can verify equivalence between the OpenTok and Vonage Video implementations. The time it will take to complete the transition is roughly proportional to the number of places where the OpenTok SDK is used in your code, as well as the variety of features used, but, as mentioned earlier, some API calls will be simpler to replace than others.

Versioning

OpenTok and Vonage Video are two different products. This makes a progressive migration impossible.

You should create a temporary branch on your version control system for the transition, so that you can make changes gradually and frequently without breaking the existing project. You can also use the existing project's tests as an oracle for correctness. Ideally, you should only merge the transition branch into the main branch once you have completed the conversion.

Key Changes and Considerations

The Vonage Video API has feature parity with OpenTok, and the Ruby SDK is actively maintained to be in line with the API specification. There are, however, some differences between the two SDKs that you should be aware of.

New Features and Standards

Package Structure

Both the OpenTok Ruby SDK and the Vonage Ruby SDK follow the approach for structuring a Ruby gems recommended by Bundler, and so at a high level are similar in structure. There are, however, a couple of key differences:

  1. The Vonage Ruby SDK uses the zeitwerk library for code autoloading and so follows zeitwerk's conventions for file and directory structure and naming. If you know how Ruby on Rails applications are structured, then you'll already be familiar with these conventions. If not, then it might be worth spending a few minutes familiarizing yourself with them. Considering this structure in terms of the video API implementation:
  • The primary Video class is defined in this file
  • Any classes namespaced under Video (such as Video::Broadcasts and Video::Archives) are defined under this directory.
  1. The Vonage Ruby SDK implements other Vonage APIs in addition to the Video API. The SDK implements classes that represent each of these API products, and the Client class provides accessors for objects of these classes.

Bearing in mind points 1 and 2 above, starting from the Vonage Client object one or more additional method invocations may be required before you get to method representing the specific video API endpoint that you want to call.

Example 1: Creating a session

Using the OpenTok Ruby SDK might look something like this:

Whereas using the Vonage Ruby SDK might look something like this:

As you would expect with Ruby, you can combine steps 2 and 3 via method chaining:

Example 2: Getting a list of archive recordings

Using the OpenTok Ruby SDK might look something like this:

Whereas using the Vonage Ruby SDK might look something like this:

Again, steps can be combined via method chaining:

A Note on Typing

The Vonage Ruby SDK uses Sorbet for static type checking. To simply the migration from the OpenTok Ruby SDK to the Vonage Ruby SDK, type signatures have not currently been defined for any of the methods in the Video API implementation. Type signatures will be defined for these methods as part of a future release.

A Note on Front-end Changes

The front-end libraries used for your application will be the same as the OpenTok libraries. There is, however, one minor change in terms of their usage.

The interaction between the back-end and front-end will be the same: the SDK will create sessions and also generate tokens for the front-end client libraries to access those sessions. Just as with an OpenTok implementation, the front-end client libraries will expect the back-end server to provide a Session ID and a token. However, with a Vonage implementation the server will also need to provide an Application ID. This Application ID effectively takes the place of the API Key which would be used in an OpenTok implementation, although the front-end client libraries will still label it as an API Key. For more information on Application IDs, see the section on Authentication Changes.

This small change in the interaction between front-end and back-end may require some minor updates to your implementation, for example in your view templates or in the logic that passes data to those view templates.

Package Update

To use the Vonage Ruby SDK you'll need to update your project's dependencies to use the vonage Ruby gem instead of the opentok Ruby gem. You can do this by updating your Gemfile to include the vonage gem:

and then running bundle install.

Authentication Changes

Whereas the opentok gem uses an api_key and api_secret for Authorization, the Video API implementation in the vonage gem uses a JWT. The SDK handles JWT generation in the background for you, but will require an application_id and private_key as credentials in order to generate the token. You can obtain these by setting up a Vonage Application, and generating an application ID and private key for that application. The Vonage Application is also where you can set other settings such as which API products the application is enabled for, callback URLs, storage preferences, etc.

There are a number of ways in which you can create a Vonage Application:

NEVER SHARE OR EXPOSE YOUR PRIVATE KEY!

Should you lose your private key, or should it become compromised in any way, you can generate a new private key by editing the Vonage Application. Updating the Vonage Application with a new key and will automatically invalidate the old key. When editing a Vonage Application via the Dashboard, make sure to click on 'Save' to ensure that the changes take effect.

Your application_id and private_key credentials are then passed in when instantiating a Client object (the example below assumes you have these set as environment variables):

If you have your environment variables named as shown in the above example, you can actually omit the arguments from the new method invocation. The SDK will automatically search the ENV hash for variables of those names and use their values if it finds them. In this case, the following example of instantiating a Vonage::Client object is functionally equivalent to the previous one:

Note that the value for the VONAGE_PRIVATE_KEY can be the path to the location for your private.key file. How you determine the value for this path will depend on how you are deploying your application. If you are deploying your application locally, you can store your private.key file in the root of your project and set the path as private.key. For example, if using dotenv to manage your environment variables, your VONAGE_PRIVATE_KEY definition in your .env file would look like this:

If using the approach described above, make sure you add .env and private.key to your .gitignore file.

If deploying to production using a service such as Render, these types of services usually provide ways of securely storing files such as private keys. The exact method for doing so will depend on the service being used and is beyond the scope of this document.

Method Changes

There are some changes to methods between the OpenTok Ruby SDK and the Video API implementation in the Vonage Ruby SDK.

Method Parameters

Any positional parameters in method signatures have been replaced with keyword parameters in the Vonage SDK.

Method Name Changes

Some methods have been renamed and/or moved, for clarity and/or to better reflect what the method does. These are listed below:

OpenTok Method NameVonage Video Method Name
opentok.generate_tokenvideo.generate_client_token
opentok.archives.allvideo.archives.list
opentok.archives.createvideo.archives.start
opentok.archives.delete_by_idvideo.archives.delete
opentok.archives.findvideo.archives.info
opentok.archives.layoutvideo.archives.change_layout
opentok.archives.stop_by_idvideo.archives.stop
opentok.broadcasts.allvideo.broadcasts.list
opentok.broadcasts.createvideo.broadcasts.start
opentok.broadcasts.delete_by_idvideo.broadcasts.delete
opentok.broadcasts.findvideo.broadcasts.info
opentok.broadcasts.layoutvideo.broadcasts.change_layout
opentok.connections.forceDisconnectvideo.moderation.force_disconnect
opentok.renders.findvideo.renders.info
opentok.signals.sendvideo.signals.send_to_one and video.signals.send_to_all
opentok.streams.allvideo.streams.list
opentok.streams.findvideo.streams.info
opentok.streams.force_mutevideo.moderation.mute_single_stream
opentok.streams.force_mute_allvideo.moderation.mute_multiple_streams
opentok.streams.layoutvideo.streams.change_layout

Response Objects

Unlike the OpenTok Ruby SDK, the Vonage Ruby SDK doesn't use specific object classes when deserializing the JSON payload of an HTTP response, but instead deserializes responses to generic response objects.

Single Resource Response Objects

Responses where the JSON payload represents a single resource are deserialized by the Vonage Ruby SDK to a generic Vonage::Response object.

At a general level you can use this Vonage::Response object in the same way as you would do the OpenTok::Archive, OpenTok::Broadcast, OpenTok::Stream, etc, objects in that you can access properties from the response payload by calling methods on the object with names equivalent to the property name. For example, if you wanted to start a new archive recording and get its ID from the response, the approach to do this would be broadly similar for the two SDKs.

Example: OpenTok Ruby SDK

Example: Vonage Ruby SDK

One key difference in the implementation of the response objects between the two SDKs is in the use of the facade pattern within the OpenTok Ruby SDK's response objects. The OpenTok SDK's response objects are initialized with a reference to the object which invoked the method that created them. That object in turn carries a reference to an OpenTok::Client object. What this means is that you can invoke methods which interact with some of the Video API endpoints directly on those objects. The response objects in the Vonage Ruby SDK do not provide a direct way of calling methods which wrap Video API endpoints, so you will need to use objects representing the specific feature class as the caller of the method.

Say, for example, you want to stop an archive recording that is currently in progress.

Example: OpenTok Ruby SDK

In the OpenTok SDK you could call the stop method directly on the Archive object returned by the Archives#create method invocation.

Example: Vonage Ruby SDK

In the Vonage SDK you would need to call the stop method on a Video::Archives object and pass in the relevant archive_id as an argument.

Multi Resource Response Objects

Responses where the JSON payload represents a collection of one or more resources are deserialized by the Vonage Ruby SDK to a ListResponse object namespaced under product and then the object type that made the request, for example Vonage::Video::Broadcasts::ListResponse.

Essentially they provide the same functionality as the list response object types from the OpenTok Ruby SDK in that they're iterable collections of individual resource objects. The implementation differs slightly between the SDKs but generally this shouldn't impact the way that you can interact with these objects, and is outlined below more for completeness:

  • The ListResponse objects in the Vonage Ruby SDK implement an each method and include Ruby's Enumerable module.
  • The list-type responses in the OpenTok Ruby SDK (e.g. ArchiveList, BroadcastList, etc) sub-class from Ruby's Array class.
Error Response Objects

Both SDKs define a generic error class which subclass from Ruby's StandardError class, with more specific error classes that subclass from that generic class.

The OpenTok Ruby SDK defines an OpenTok::OpenTokError class and then specific error classes by feature type that subclass from OpenTokError, such as OpenTokArchiveError, OpenTokBroadcastError, OpenTokAuthenticationError, etc. None of these error types implement any additional functionality beyond what StandardError provides.

The Vonage Ruby SDK defines a generic Vonage::Error class and also a Vonage::APIError class which subclasses from Vonage::Error. The APIError class represents errors which result from an HTTP request to a Vonage API endpoint. The SDK then defines a number of more specific error classes, according to the nature of the response received, that subclass from APIError. These classes include Vonage::ClientError (for 4xx responses), Vonage::ServerError (for 5xx responses), and Vonage::AuthenticationError (which subclasses from Vonage::ClientError, and is specifically used for 401 responses).

The APIError class implements some additional logic that provides getter methods for the Net:HTTPResponse object, as well as the response code, headers, and body. You can rescue the exception to access these properties.

Example

Migration Strategies

Incremental Migration

We would recommend an incremental migration, moving from one use case to another, committing every time you end up in a " stable" state. Of course, it would require both OpenTok and Vonage Video API to temporarily coexist.

Please note that, during such incremental process, your application as a whole would not be fully functional anymore as OpenTok and Vonage Video API are two fully different systems.

The exact plan for an incremental approach will depend on how many, and which, Video API features you are using and how you have integrated those features into your application. Although it is not possible to provide implementation-specific guidance in this area, in terms of general approach a possible plan is to update your code feature by feature, and within each feature method by method.

A good place to start would be with any code that instantiates an OpenTok::OpenTok object and replace this with code that instantiates a Vonage::Client object, following the comparison between the two demonstrated in the Package Structure section.

The next step could be update any code which deals with creating sessions, generating client tokens, and passing data to the front-end client libraries.

You could then move on to update in turn any code that implements specific features of the Video API. To use Archives as an example:

  • Identify any code where Archives are created or interacted with.
  • Update method invocations so that methods are called on client.video instead of opentok objects.
  • Update any method names that have changed.
  • If a method call passes any arguments, update it to use the correct keyword parameters.
  • Identify any code where a method is called directly on an Archive response object, and amend this as outlined in the Response Objects section.

Repeat this process for each feature and method.

There might be additional steps you need to take, such as updating any code where you rescue specific errors. The above list of steps is not exhaustive, but should hopefully provide a good starting point for defining your migration plan.

Gateway/Adapter Pattern

If you are not already using some sort of gateway or adapter pattern as part of your implementation, this migration would be a good opportunity to do so. This would not only help facilitate the migration, but also mean that in general usage your application code would be less tightly coupled with the SDK code.

There are many different approaches to implementing these patterns depending on how your application is structured and/or the framework you are using. It is beyond the scope of this document to provide any specific guidance in this area.

Testing Recommendations

Thorough testing is essential for a smooth transition, both during and after the migration. This includes not only unit tests but also integration and regression testing. It is also worth manually testing your application flow at least once before and after the migration to ensure that your automated tests do what you think they do, or to pick up on any issues that the tests may not have caught. You may even consider creating equivalence tests. The idea is to create a suite which asserts that both the OpenTok and Vonage Video versions of your application do the same thing. These can then be discarded once your transition is complete and the OpenTok version of your application is removed.

Troubleshooting & Support

Support Channels

For general help and discussion on transitioning to Vonage Video, check out the #video-api channel on our Community Slack, where you can get answers from Vonage staff and fellow users. You can also get in touch with us on X @VonageDev.

The primary contact for any issues with the Video API itself is support@api.vonage.com.

If you find a bug with the SDK, please file an issue, with steps to reproduce, on GitHub.

Additional Resources

Code Samples