Coder Social home page Coder Social logo

ringcentral-ruby's Introduction

RingCentral SDK for Ruby

Ruby Reference Twitter

RingCentral Developers is a cloud communications platform which can be accessed via more than 70 APIs. The platform's main capabilities include technologies that enable: Voice, SMS/MMS, Fax, Glip Team Messaging, Data and Configurations.

Additional resources

  • RingCentral API Reference - an interactive reference for the RingCentral API that allows developers to make API calls with no code.
  • Document - an interactive reference for the SDK code documentation.

Getting help and support

If you are having difficulty using this SDK, or working with the RingCentral API, please visit our developer community forums for help and to get quick answers to your questions. If you wish to contact the RingCentral Developer Support team directly, please submit a help ticket from our developer website.

Installation

gem install ringcentral-sdk

If for some reason eventmachine failed to install, please check this.

Name collision with ringcentral gem

The ringcentral gem is using RingCentral's legacy API which was End-of-Lifed in 2018. Everyone is recommended to move to the REST API.

If you have both the ringcentral and ringcentral-sdk gems installed, you will run into a collision error when attempting to initialize the ringcentral-sdk RingCentral SDK.

The solution is gem uninstall ringcentral

Documentation

https://developer.ringcentral.com/api-docs/latest/index.html

Usage

require 'ringcentral'

rc = RingCentral.new('clientID', 'clientSecret', 'serverURL')
rc.authorize(jwt: 'jwt-token')

# get
r = rc.get('/restapi/v1.0/account/~/extension/~')
expect(r).not_to be_nil
expect('101').to eq(r.body['extensionNumber'])

How to specify query parameters

for get & delete

rc.get('/restapi/v1.0/account/~/extension', { hello: 'world' })

for post, put & patch

rc.post('/restapi/v1.0/account/~/extension/~/sms', payload: body, params: { hello: 'world' })

multi-value query parameter

rc.get('/restapi/v1.0/account/~/extension', { hello: ['world1', 'world2'] })

Above will be translated to /restapi/v1.0/account/~/extension?hello=world1&hello=world2.

Token Refresh

Access token expires. You need to call rc.refresh() before it expires. If you want the SDK to do auto refresh please rc.auto_refresh = true before authorization.

Load pre-existing token

Let's say you already have a token. Then you can load it like this: rc.token = your_token_object. The benefit of loading a preexisting token is you don't need to go through any authorization flow.

If what you have is a JSON string instead of a Ruby object, you need to convert it first: JSON.parse(your_token_string).

If you only have a string for the access token instead of for the whole object, you can set it like this:

rc.token = { access_token: 'the token string' }

Send SMS

r = rc.post('/restapi/v1.0/account/~/extension/~/sms', payload: {
    to: [{phoneNumber: ENV['RINGCENTRAL_RECEIVER']}],
    from: {phoneNumber: ENV['RINGCENTRAL_SENDER']},
    text: 'Hello world'
})

Send fax

rc.post('/restapi/v1.0/account/~/extension/~/fax',
payload: { to: [{ phoneNumber: ENV['RINGCENTRAL_RECEIVER'] }] },
    files: [
        ['spec/test.txt', 'text/plain'],
        ['spec/test.png', 'image/png']
    ]
)

Send MMS

r = rc.post('/restapi/v1.0/account/~/extension/~/sms',
    payload: {
        to: [{ phoneNumber: ENV['RINGCENTRAL_RECEIVER'] }],
        from: { phoneNumber: ENV['RINGCENTRAL_SENDER'] },
        text: 'hello world'
    },
    files: [
        ['spec/test.png', 'image/png']
    ]
)

Subscriptions

WebSocket Subscriptions

events = [
  '/restapi/v1.0/account/~/extension/~/message-store',
]
subscription = WS.new(rc, events, lambda { |message|
  puts message
})
subscription.subscribe()

How to keep a subscription running 24 * 7?

There are two main cases that a subscription will be terminated:

  • Absolute time out. The maximum time for a subscription to run is 24 hours. After that, the websocket connection will be closed by the server.
  • Network issue. It could be your local network issue or the server's network issue. In either case, your websocket connection will be closed

In order to keep a subscription running 24 * 7, you need to re-subscribe when the connection is closed.

subscription.on_ws_closed = lambda { |event|
  # make sure that there is no network issue and re-subscribe
  subscription.subscribe()
}

How to test

bundle install

Rename .env.sample to .env.

Edit .env file to specify credentials.

RINGCENTRAL_RECEIVER is a phone number to receive SMS, Fax..etc.

Run bundle exec rspec

License

MIT

ringcentral-ruby's People

Contributors

byrnereese avatar dakingkong avatar grokify avatar pacovu avatar sushilmallrc avatar tylerlong avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ringcentral-ruby's Issues

Name collision with `ringcentral` gem

Problem

If you have both the ringcentral and ringcentral-sdk gems installed, you will run into a collision error when attempting to initialize the ringcentral-sdk RingCentral SDK:

undefined method `new' for RingCentral:Module (NoMethodError)

This occurs because both gems use the ringcentral namespace, e.g. require 'ringcentral'

Check this by running gem list:

$ gem list | grep -i ringcentral
ringcentral (0.2.0)
ringcentral-sdk (0.8.1, 0.5.0)

Solution

In this case, uninstall the legacy gem and then the new gem will run as expected.

$ gem uninstall ringcentral

Everyone is recommended to move to the REST API and no longer use the legacy API so the legacy API SDK should not be needed.

Lower minimum version for Faraday to increase compatibility

Faraday is required with a minimum version of 0.13

Some other gems (such as oauth) in our projects require the version to be <= 0.10, so we couldn't start working with this gem.

I forked the project and used a requirement of Faraday 0.10 and there don't seem to be any negative consequences.

Query parameter in URL seems to be stripped

The following request gets made without the sessionId query parameter.

res = rc.get  '/restapi/v1.0/account/~/extension/~/call-log?sessionId=174812747016'

This request returns an API response without sessionId parameter as shown in the navigation property. Other properties are omitted below.

{
  "navigation": {
    "firstPage": {
      "uri": "https://platform.ringcentral.com/restapi/v1.0/account/11111111/extension/22222222/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-03-07T21:28:00.000Z&page=1&perPage=100"
    },
    "lastPage": {
      "uri": "https://platform.ringcentral.com/restapi/v1.0/account/11111111/extension/22222222/call-log?view=Simple&showBlocked=true&withRecording=false&dateFrom=2019-03-07T21:28:00.000Z&page=1&perPage=100"
    }
  }
}

Demo causes `uninitialized constant PubNub (NameError)`

The README.md demo uses PubNub however, the PubNub docs indicate Pubnub.new should be used.

PubNub Documentation:

https://www.pubnub.com/docs/ruby/pubnub-ruby-sdk

RingCentral README.md:

def createSubscription(callback)
    events = [
        '/restapi/v1.0/account/~/extension/~/message-store',
    ]
    subscription = PubNub.new(rc, events, lambda { |message|
        callback.call(message)
    })
    subscription.subscribe()
    return subscription
end

createSubscription(lambda { |message|
    puts message
})

Support ATT OfficeAtHand

There's no way to pass in a brandId right now for the oauth client authorize_uri. Would need that to support ATT Office At Hand and other partner brands

Add better error message for incorrect args

I was reading in my app and user credentials via the environment and had an error where nil values were being used for clientId, clientSecret, etc. I received the following error message which is confusing. It would be better to have a more explicit error for missing parameters.

Request:

I'm sending:

rc = RingCentral.new(
  ENV['RINGCENTRAL_CLIENT_ID'],
  ENV['RINGCENTRAL_CLIENT_SECRET'],
  ENV['RINGCENTRAL_SERVER_URL'])

rc.authorize(
  username:  ENV['RINGCENTRAL_USERNAME'],
  extension: ENV['RINGCENTRAL_EXTENSION'],
  password:  ENV['RINGCENTRAL_PASSWORD'])

But because the .env file isn't being read correctly, this gets translated to:

rc = RingCentral.new nil, nil, nil
rc.authorize username:nil, extension:nil, password:nil

Error:

The nil values result in a addr_port error which is hard to understand given the inputs don't specifically include a port.

Traceback (most recent call last):
	18: from get_ringcentral_extension.rb:16:in `<main>'
	17: from /usr/local/rvm/gems/ruby-2.5.0/gems/ringcentral-sdk-0.8.2/lib/ringcentral.rb:62:in `authorize'
	16: from /usr/local/rvm/gems/ruby-2.5.0/gems/ringcentral-sdk-0.8.2/lib/ringcentral.rb:104:in `post'
	15: from /usr/local/rvm/gems/ruby-2.5.0/gems/faraday-0.15.0/lib/faraday/connection.rb:175:in `post'
	14: from /usr/local/rvm/gems/ruby-2.5.0/gems/faraday-0.15.0/lib/faraday/connection.rb:387:in `run_request'
	13: from /usr/local/rvm/gems/ruby-2.5.0/gems/faraday-0.15.0/lib/faraday/rack_builder.rb:143:in `build_response'
	12: from /usr/local/rvm/gems/ruby-2.5.0/gems/faraday-0.15.0/lib/faraday/request/multipart.rb:15:in `call'
	11: from /usr/local/rvm/gems/ruby-2.5.0/gems/faraday-0.15.0/lib/faraday/request/url_encoded.rb:15:in `call'
	10: from /usr/local/rvm/gems/ruby-2.5.0/gems/faraday-0.15.0/lib/faraday/adapter/net_http.rb:33:in `call'
	 9: from /usr/local/rvm/gems/ruby-2.5.0/gems/faraday-0.15.0/lib/faraday/adapter/net_http.rb:87:in `with_net_http_connection'
	 8: from /usr/local/rvm/gems/ruby-2.5.0/gems/faraday-0.15.0/lib/faraday/adapter/net_http.rb:38:in `block in call'
	 7: from /usr/local/rvm/gems/ruby-2.5.0/gems/faraday-0.15.0/lib/faraday/adapter/net_http.rb:82:in `perform_request'
	 6: from /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/net/http.rb:1455:in `request'
	 5: from /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/net/http.rb:910:in `start'
	 4: from /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/net/http.rb:1457:in `block in request'
	 3: from /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/net/http.rb:1464:in `request'
	 2: from /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/net/http.rb:1490:in `transport_request'
	 1: from /usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/net/http.rb:1551:in `begin_transport'
/usr/local/rvm/rubies/ruby-2.5.0/lib/ruby/2.5.0/net/http.rb:1616:in `addr_port': undefined method `include?' for nil:NilClass (NoMethodError)

Gemfile compatibility issues

Recent gem updates fails to resolve dependency issues:

Could not find compatible versions

Because every version of ringcentral-sdk depends on pubnub >= 5.0.0, < 6.A
  and pubnub >= 4.1.5 depends on concurrent-ruby ~> 1.1.5,
  every version of ringcentral-sdk requires concurrent-ruby ~> 1.1.5.

Need a simple and documented way to set auth token

The API Reference supports a "Try it out" feature which allows someone to copy-and-paste a code sample that just works. This system works well for cURL requests because the framework is able to insert the HTTP Bearer token directly into the "code sample." However, we cannot do that with any specific language because there is not a clear/obvious way to initialize the client/SDK with an already-existant token.

Screen Shot 2019-08-26 at 5 51 56 PM

We need a simple and single API call for getting the Bearer token in this SDK. Something to the effect of:

sdk.platform().auth().setData(...)

If a capability like this already exists, then can we add that to the documentation?

Acceptance criteria includes the very subjective criteria of the solution not feeling like a "hack." It should not feel like the developer is going into set the value via a backdoor, but by setting it via a public and sanctioned manner.

Gem dependency conflicts on 0.9.4

ringcentral-sdk (~> 0.9.4) was resolved to 0.9.4, which depends on
  pubnub (>= 4.1.2, ~> 4.1) was resolved to 4.1.2, which depends on
    concurrent-ruby (~> 1.0.5)

ringcentral-sdk (~> 0.9.4) was resolved to 0.9.4, which depends on
  concurrent-ruby (>= 1.1.5, ~> 1.1)

Should probably relax concurrent-ruby version dependency

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.