- Notifications
You must be signed in to change notification settings - Fork107
Vonage REST API client for Ruby. API support for SMS, Voice, Text-to-Speech, Numbers, Verify (2FA) and more.
License
Vonage/vonage-ruby-sdk
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
This is the Ruby Server SDK for Vonage APIs. To use it you'llneed a Vonage account. Sign upfor free at vonage.com.
Vonage Ruby supports MRI/CRuby (2.5 or newer), JRuby (9.2.x), and Truffleruby.
To install the Ruby Server SDK using Rubygems:
gem install vonageAlternatively you can clone the repository:
git clone git@github.com:Vonage/vonage-ruby-sdk.gitBegin by requiring the Vonage library:
require'vonage'
Then construct a client object with your key and secret:
client=Vonage::Client.new(api_key:'YOUR-API-KEY',api_secret:'YOUR-API-SECRET')
You can now use the client object to call Vonage APIs. For example, to send an SMS:
client.sms.send(from:'Ruby',to:'447700900000',text:'Hello world')
For production you can specify theVONAGE_API_KEY andVONAGE_API_SECRETenvironment variables instead of specifying the key and secret explicitly,keeping your credentials out of source control.
For APIs which use a JWT for authentication you'll need to passapplication_id andprivate_key arguments to theClient constructor as well as or instead ofapi_key andapi_secret. SeeJWT Authentication.
It is also possible to over-ride the default hosts atClient instantiation. SeeOverriding the default hosts.
To call newer endpoints that support JWT authentication such as the Voice API and Messages API you'llalso need to specify theapplication_id andprivate_key options. For example:
client=Vonage::Client.new(application_id:application_id,private_key:private_key)
Both arguments should have string values corresponding to theid andprivate_keyvalues returned in a"create an application"response. These credentials can be stored in a datastore, in environment variables,on disk outside of source control, or in some kind of key management infrastructure.
By default the library generates a short lived JWT per request. To generate a long livedJWT for multiple requests or to specify JWT claims directly useVonage::JWT.generate andthe token option. For example:
claims={application_id:application_id,private_key:'path/to/private.key',nbf:1483315200,ttl:800}token=Vonage::JWT.generate(claims)client=Vonage::Client.new(token:token)
Documentation for the Vonage Ruby JWT generator gem can be found at:https://www.rubydoc.info/gems/vonage-jwt
The documentation outlines all the possible parameters you can use to customize and build a token with.
Use the logger option to specify a logger. For example:
require'logger'logger=Logger.new(STDOUT)client=Vonage::Client.new(logger:logger)
By default the library sets the logger toRails.logger if it is defined.
To disable logging set the logger tonil.
Where exceptions result from an error response from the Vonage API (HTTP responses that aren't ion the range2xx or3xx), theNet::HTTPResponse object will be available as a property of theException object via ahttp_response getter method (where there is noNet::HTTPResponse object associated with the exception, the value ofhttp_response will benil).
You can rescue the the exception to access thehttp_response, as well as use other getters provided for specific parts of the response. For example:
beginverification_request=client.verify2.start_verification(brand:'Acme',workflow:[{channel:'sms',to:'44700000000'}])rescueVonage::APIError=>erroriferror.http_responseerror.http_response# => #<Net::HTTPUnauthorized 401 Unauthorized readbody=true>error.http_response_code# => "401"error.http_response_headers# => {"date"=>["Sun, 24 Sep 2023 11:08:47 GMT"], ...rest of headers}error.http_response_body# => {"title"=>"Unauthorized", ...rest of body}endend
For certain legacy API products, such as theSMS API,Verify v1 API andNumber Insight v1 API, a200 response is received even in situations where there is an API-related error. For exceptions raised in these situation, rather than aNet::HTTPResponse object, aVonage::Response object will be made available as a property of the exception via aresponse getter method. The properties on this object will depend on the response data provided by the API endpoint. For example:
beginsms=client.sms.send(from:'Vonage',to:'44700000000',text:'Hello World!')rescueVonage::Error=>erroriferror.is_a?Vonage::ServiceErrorerror.response# => #<Vonage::Response:0x0000555b2e49d4f8>error.response.messages.first.status# => "4"error.response.messages.first.error_text# => "Bad Credentials"error.response.http_response# => #<Net::HTTPOK 200 OK readbody=true>endend
To override the default hosts that the SDK uses for HTTP requests, you need tospecify theapi_host,rest_host or both in the client configuration. For example:
client=Vonage::Client.new(api_host:'api-sg-1.nexmo.com',rest_host:'rest-sg-1.nexmo.com')
By default the hosts are set toapi.nexmo.com andrest.nexmo.com, respectively.
It is possible to set configuration options on the HTTP client. This can be don in a couple of ways.
Using an
:httpkey duringVonage::Clientinstantiation, for example:client=Vonage::Client.new(api_key:'YOUR-API-KEY',api_secret:'YOUR-API-SECRET',http:{max_retries:1})
By using the
http=setter on theVonage::Configobject, for example:client=Vonage::Client.new(api_key:'YOUR-API-KEY',api_secret:'YOUR-API-SECRET')client.config.http={max_retries:1}
The Vonage Ruby SDK uses theNet::HTTP::Persistent library as an HTTP client. For available configuration options seethe documentation for that library.
Certain Vonage APIs provide signedwebhooks as a means of verifying the origin of the webhooks. The exact signing mechanism varies depending on the API.
TheSMS API signs the webhook request using a hash digest. This is assigned to asig parameter in the request body.
You can verify the webhook request using theVonage::SMS#verify_webhook_sig method. As well as therequest params from the received webhook, the method also needs access to the signature secret associated with the Vonage account (available from theVonage Dashboard), and the signature method used for signing (e.g.sha512), again this is based on thes setting in the Dashboard.
There are a few different ways of providing these values to the method:
- Pass all values to the method invocation.
client=Vonage::Client.newclient.sms.verify_webhook_sig(webhook_params:params,signature_secret:'secret',signature_method:'sha512')# => returns true if the signature is valid, false otherwise
- Set
signature_secretandsignature_methodatClientinstantiation.
client=Vonage::Client.new(signature_secret:'secret',signature_method:'sha512')client.sms.verify_webhook_sig(webhook_params:params)# => returns true if the signature is valid, false otherwise
- Set
signature_secretandsignature_methodon theConfigobject.
client=Vonage::Client.newclient.config.signature_secret='secret'client.config.signature_method='sha512'client.sms.verify_webhook_sig(webhook_params:params)# => returns true if the signature is valid, false otherwise
- Set
signature_secretandsignature_methodas environment variables namedVONAGE_SIGNATURE_SECRETandVONAGE_SIGNATURE_METHOD
client=Vonage::Client.newclient.sms.verify_webhook_sig(webhook_params:params)# => returns true if the signature is valid, false otherwise
Note: Webhook signing for the SMS API is not switched on by default. You'll need to contactsupport@vonage.com to enable message signing on your account.
TheVoice API andMessages API both include anAuthorization header in their webhook requests. The value of this header includes a JSON Web Token (JWT) signed using the Signature Secret associated with your Vonage account.
TheVonage::Voice andVonage::Messaging classes both define averify_webhook_token method which can be used to verify the JWT received in the webhookAuthorization header.
To verify the JWT, you'll first need to extract it from theAuthorization header. The header value will look something like the following:
"Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1OTUyN"# remainder of token omitted for brevity
Note: we are only interested in the token itself, which comesafter the wordBearer and the space.
Once you have extrated the token, you can pass it to theverify_webhook_token method in order to verify it.
The method also needs access to the the method also needs access to the signature secret associated with the Vonage account (available from theVonage Dashboard). There are a few different ways of providing this value to the method:
- Pass all values to the method invocation.
client=Vonage::Client.newclient.voice.verify_webhook_token(token:extracted_token,signature_secret:'secret')# => returns true if the token is valid, false otherwise
- Set
signature_secretatClientinstantiation.
client=Vonage::Client.new(signature_secret:'secret')client.voice.verify_webhook_token(token:extracted_token)# => returns true if the token is valid, false otherwise
- Set
signature_secreton theConfigobject.
client=Vonage::Client.newclient.config.signature_secret='secret'client.config.signature_method='sha512'client.voice.verify_webhook_token(token:extracted_token)# => returns true if the token is valid, false otherwise
- Set
signature_secretas an environment variable namedVONAGE_SIGNATURE_SECRET
client=Vonage::Client.newclient.voice.verify_webhook_token(token:extracted_token)# => returns true if the token is valid, false otherwise
Vonage APIs paginate list requests. This means that if a collection is requested that is larger than the API default, the API will return the first page of items in the collection. The Ruby SDK provides anauto_advance parameter that will traverse through the pages and return all the results in one response object.
Theauto_advance parameter is set to a default oftrue for the following APIs:
To modify theauto_advance behavior you can specify it in your method:
client.applications.list(auto_advance:false)
TheVonage Messages API allows you to send messages over a number of different channels, and various message types within each channel. See the Vonage Developer Documentation for acomplete API reference listing all the channel and message type combinations.
The Ruby SDK implements aMessaging object which can be accessed via amessaging method on theClient object. TheMessaging object has asend method which lets you send any message type via any channel.
response=client.messaging.send(# message data)
There are a number of ways in which you can pass the necessary message data to the method.
Using Keyword Arguments
You can pass the message properties and their values as keyword arguments to the method. For example:
response=client.messaging.send(to:'447700900000',from:'447700900001',channel:'sms',message_type:'text',text:'Hello world!')
Spread a Hash
For more complex message structures, you can define the message as a Hash literal and then spread that Hash as keyword arguments by passing it to thesend method using the double-splat opertator (**). For example:
message={to:'447700900000',from:'447700900001',channel:'mms',message_type:'image',image:{url:'https://example.com/image.jpg',caption:'This is an image'}}response=client.messaging.send(**message)
Using a Combination of Keyword Arguments and Spread
You can use a combination of the above two approaches. This might be useful in situations where you want to iteratively send the same message to multiple recipients, for example:
message={from:'447700900000',channel:'sms',message_type:'text',text:'Hello world!'}['447700900001','447700900002','447700900003'].eachdo |to_number|client.messaging.send(to:to_number, **message)end
Using Channel Convenience Methods
The Ruby SDK provides convenience methods for each channel which return a Hash object which you can then pass to thesend method in the same way that you would with a Hash literal. As well as a simpler interface, the convenience methods also provide some basic validation.
Other than SMS (which has only one type --text), these methods require a:type argument, which defines themessage_type of the message within that channel. They also require a:message argument, which defvines the message itself; this is a String in the case oftext messages, and a Hash containing the appopriate properties for other message types (e.g.image). You can also optionally pass anopts arguments, the value of which should be a Hash which defines any other property that you want to include in the message.
# Using the SMS method like this:message=client.messaging.sms(to:"447700900000",from:"447700900001",message:"Hello world!")# is the equivalent of using a Hash literal like this:message={channel:"sms",to:"447700900000",from:"447700900001",message_type:"text",text:"Hello world!"}
Once the message Hash is created, you can then pass it into thesend method using the double-splat opertator (**).
response=client.messaging.send(**message)
A few additional examples of using these convenience methods are shown below:
# creating an RCS Text messagemessage=client.messaging.rcs(to:"447700900000",from:"RCS-Agent",type:'text',message:'Hello world!')# creating a WhatsApp Text messagemessage=client.messaging.whatsapp(to:"447700900000",from:"447700900001",type:'text',message:'Hello world!')# creating a WhatsApp Image messagemessage=client.messaging.whatsapp(to:"447700900000",from:"447700900001",type:'image',message:{url:'https://example.com/image.jpg'})# creating an MMS audio message with optional propertiesmessage=client.messaging.mms(to:"447700900000",from:"447700900001",type:'audio',message:{url:'https://example.com/audio.mp3'},opts:{client_ref:"abc123"})
You can choose to omit theto and/orfrom arguments from the convenience method calls and instead pass them in as keyword arguments during thesend method invocation.
message=client.messaging.sms(from:"447700900001",message:"Hello world!")['447700900001','447700900002','447700900003'].eachdo |to_number|client.messaging.send(to:to_number, **message)end
The Messages API lets you define one or more failover messages which will be sent if the initial message is rejected. In the Ruby SDK, this feature is implemented by passing afailover keyword argument during the invocation of thesend method. The value of this argument must be an Array containing one or more Hash objects representing the failover message(s). For example:
# Sending an RCS message with failover to SMSrcs_message=messaging.rcs(to:'447900000000',from:'RCS-Agent',type:'text',message:'This is an RCS message. If you see this, RCS is working!')sms_message=messaging.sms(to:'447900000000',from:'Vonage',message:'This is a failover SMS message in case RCS fails.')response=messaging.send(**rcs_message,failover:[sms_message])
TheVonage Verify API v2 allows you to manage 2FA verification workflows over a number of different channels such as SMS, WhatsApp, WhatsApp Interactive, Voice, Email, and Silent Authentication, either individually or in combination with each other. See the Vonage Developer Documentation for acomplete API reference listing all the channels, verification options, and callback types.
The Ruby SDK provides two methods for interacting with the Verify v2 API:
Verify2#start_verification: starts a new verification request. Here you can specify options for the request and the workflow to be used.Verify2#check_code: for channels where the end-user is sent a one-time code, this method is used to verify the code against therequest_idof the verification request created by thestart_verificationmethod.
verify=client.verify2
For simple requests, you may prefer to manually set the value forworkflow (an array of one or more hashes containing the settings for a particular channel) and any optional params.
Example with the required:brand and:workflow arguments:
verification_request=verify.start_verification(brand:'Acme',workflow:[{channel:'sms',to:'447000000000'}])
Example with the required:brand and:workflow arguments, and an optionalcode_length:
verification_request=verify.start_verification(brand:'Acme',workflow:[{channel:'sms',to:'447000000000'}],code_length:6)
For more complex requests (e.g. with mutliple workflow channels or addtional options), or to take advantage of built-in input validation, you can use theStartVerificationOptions object and theWorkflow and various channel objects or theWorkflowBuilder:
opts=verify.start_verification_options(locale:'fr-fr',code_length:6,client_ref:'abc-123').to_hverification_request=verify.start_verification(brand:'Acme',workflow:[{channel:'email',to:'alice.example.com'}], **opts)
# Instantiate a Workflow objectworkflow=verify.workflow# Add channels to the workflowworkflow <<workflow.sms(to:'447000000000')workflow <<workflow.email(to:'alice.example.com')# Channel data is encpsulated in channel objects stored in the Workflow list arrayworkflow.list# => [ #<Vonage::Verify2::Channels::SMS:0x0000561474a74778 @channel="sms", @to="447000000000">,#<Vonage::Verify2::Channels::Email:0x0000561474c51a28 @channel="email", @to="alice.example.com">]# To use the list as the value for `:workflow` in a `start_verification` request call,# the objects must be hashifiedworkflow_list=workflow.hashified_list# => [{:channel=>"sms", :to=>"447000000000"}, {:channel=>"email", :to=>"alice.example.com"}]verification_request=verify.start_verification(brand:'Acme',workflow:workflow_list)
workflow=verify.workflow_builder.builddo |builder|builder.add_voice(to:'447000000001')builder.add_whatsapp(to:'447000000000')endworkflow_list=workflow.hashified_list# => [{:channel=>"voice", :to=>"447000000001"}, {:channel=>"whatsapp", :to=>"447000000000"}]verification_request=verify.start_verification(brand:'Acme',workflow:workflow_list)
You can cancel in in-progress verification request
# Get the `request_id` from the Vonage#Response object returned by the `start_verification` method callrequest_id=verification_request.request_idverify.cancel_verification_request(request_id:request_id)
# Get the `request_id` from the Vonage#Response object returned by the `start_verification` method callrequest_id=verification_request.request_id# Get the one-time code via user input# e.g. from params in a route handler or controller action for a form inputcode=params[:code]begincode_check=verify.check_code(request_id:request_id,code:code)rescue=>error# an invalid code will raise an exception of type Vonage::ClientErrorendifcode_check.http_response.code =='200'# code is validend
Verify custom templates allow you to customize the message sent to deliver an OTP to your users, rather than using the default Vonage templates. See theTemplate Management Guide document for more information.
# Get a list of all templatestemplate_list=verify.templates.list# Get details of a specific templatetemplate=verify.templates.info(template_id:'8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9')# Create a new templateverify.templates.create(name:'my-template')# Update an existing templateverify.templates.update(template_id:'8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9',name:'my-updated-template')# Delete a templateverify.templates.delete(template_id:'8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9')
# Get a list of template fragments for a specific templatetemplate_fragment_list=verify.template_fragments.list(template_id:'8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9')# Get details of a specific template fragmenttemplate_fragment=verify.template_fragments.info(template_id:'8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9',template_fragment_id:'c70f446e-997a-4313-a081-60a02a31dc19')# Create a new template fragementverify.template_fragments.create(template_id:'8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9',channel:'sms',locale:'en-gb',text:'Your code is: ${code}')# Update an existing template fragmentverify.template_fragments.update(template_id:'8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9',template_fragment_id:'c70f446e-997a-4313-a081-60a02a31dc1',text:'Your one-time code is: ${code}')# Delete a template fragmentverify.template_fragments.delete(template_id:'8f35a1a7-eb2f-4552-8fdf-fffdaee41bc9',template_fragment_id:'c70f446e-997a-4313-a081-60a02a31dc19')
The [Vonage Voice API](TheVonage Verify API v2 allows you to automate voice interactions by creating calls, streaming audio, playing text to speech, playing DTMF tones, and other actions. See the Vonage Developer Documentation for acomplete API reference listing all the Voice API capabilities.
The Ruby SDK provides numerous methods for interacting with the Voice v2 API. Here's an example of using thecreate method to make an outbound text-to-speech call:
response=client.voice.create(to:[{type:'phone',number:'447700900000'}],from:{type:'phone',number:'447700900001'},answer_url:['https://raw.githubusercontent.com/nexmo-community/ncco-examples/gh-pages/text-to-speech.json'])
The Vonage Voice API accepts instructions via JSON objects called NCCOs. Each NCCO can be made up multiple actions that are executed in the order they are written. The Vonage API Developer Portal contains anNCCO Reference with instructions and information on all the parameters possible.
The SDK includes an NCCO builder that you can use to build NCCOs for your Voice API methods.
For example, to buildtalk andinput NCCO actions and then combine them into a single NCCO you would do the following:
talk=Vonage::Voice::Ncco.talk(text:'Hello World!')input=Vonage::Voice::Ncco.input(type:['dtmf'],dtmf:{bargeIn:true})ncco=Vonage::Voice::Ncco.build(talk,input)# => [{:action=>"talk", :text=>"Hello World!"}, {:action=>"input", :type=>["dtmf"], :dtmf=>{:bargeIn=>true}}]
Once you have the constructed NCCO you can then use it in a Voice API request:
response=client.voice.create({to:[{type:'phone',number:'14843331234'}],from:{type:'phone',number:'14843335555'},ncco:ncco})
Vonage Ruby SDK documentation:https://www.rubydoc.info/gems/vonage
Vonage Ruby SDK code examples:https://github.com/Vonage/vonage-ruby-code-snippets
Vonage APIs API reference:https://developer.vonage.com/api
The following is a list of Vonage APIs for which the Ruby SDK currently provides support:
- Account API
- Application API
- Conversation API
- Meetings API
- Messages API
- Network Number Verification API
- Network SIM Swap API
- Number Insight API
- Numbers API
- Proactive Connect API *
- Redact API
- SMS API
- Subaccounts API
- Verify API
- Voice API
* The Proactive Connect API is partially supported in the SDK. Specifically, the Events, Items, and Lists endpoints are supported.
You can find information about other Vonage SDKs and Tooling on ourDeveloper Portal.
This library is released under theApache 2.0 License
We ❤️ contributions to this library!
It is a good idea totalk to usfirst if you plan to add any new functionality.Otherwise,bug reports,bug fixes and feedback on thelibrary are always appreciated.
About
Vonage REST API client for Ruby. API support for SMS, Voice, Text-to-Speech, Numbers, Verify (2FA) and more.
Topics
Resources
License
Code of conduct
Contributing
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.