Using Powershell with the RingCentral API

I had the opportunity to work with the RingCentral API. I ended up with a series of functions that will handle the authorization/token information for you as long as you don’t mind using the Password authorization work flow. [When getting the API key](https://developer.ringcentral.com/library/getting-started.html). Make sure the “Platform Type” is set to Desktop (Mac/Windows/Other).

Code covered in this post can be found on pastebin or on my github
Quick Review of the Process and API:

RingCentral’s API is still pretty new, it looks like it has been around for about a year and half. There are some strict requirements needed before going to their production environment from the sandbox environment:
1) All Permissions requested must be used

2) A total of 20 calls must be made and each permission must be used at least once.

3) Out of all calls made over 48 hours no more than 5% can generate errors (getting throttled, bad calls, etc.)

4) It can take up to 7 days for your app to be approved.

Much of the detection is automatic, but it can take several hours for it to pickup your usage and errors. None of the requirements from the sandbox app to the production app are unreasonable but I found the process a bit clunky. Another interesting quirk is not all permissions for your app can be requested from the portal. You’ll need to contact email support for something like downloading call recordings. The email support is pretty responsive and I was pleased with that. I do wish the sandbox environment came with bogus data already populated. Rather than explore and get ideas what I can do with the API I kept spending time building fake data to resemble the production environment. Not horrible, but something that could be a bit more friendly.

The API documentation lacked any examples for Powershell. Though they didn’t have any examples, the documentation is generalized and written well enough that it wasn’t show stopping to figure out how to get a few examples done.

Before I go into the authorization scripts I want to focus on the global variables and configuration.

To get started:

$api_server_url = "https://platform.devtest.ringcentral.com"
$media_server_url = "https://media.devtest.ringcentral.com:443"
$username = ''
$password = ''
$extension = ''

#Base64 encoded strings as : Appkey:Appsecurity_key use this site: https://www.base64encode.org/ or build your own. it never changes so meh
$app_key = “”

$log_path = “C:\scripts\log\ringcentral.log”

All of the information can be found at https://service.devtest.ringcentral.com and https://developer.ringcentral.com/library/tutorials/get-started.html . The $app_key I didn’t bother to do dynamically since it is set and forget. You can go to most websites and get it encoded.
Make sure your $log_path is pointed to the log file.

You can test if everything is working by running get-authstatus.
If it returns true you’re ready to start running API calls. If you get false check the $log_path file and check your authorization information for typos.

If you want to use the auth functions in your own scripts you only really need a small chunk of code:

if(get-authstatus) {
$auth_token = $auth_obj.authorization
} else {
return $false
}

An example of a function making a call to the RingCentral API:

Function get-calllog() {
if(get-authstatus) {
$auth_token = $auth_obj.authorization
} else {
return $false
}
try {
$call = invoke-restmethod -uri "$api_server_url/restapi/v1.0/account/~/call-log" -Headers @{"Authorization" = "$auth_token"}
} catch {
return $false
}
return $call
}

The code can be found on pastebin or on my github

Besides the global calls the whole thing is 3 functions:

get-authstatus :

function get-authstatus() {

if(($auth_obj.expires_in -gt (get-date)) -and ($auth_obj.isset -eq $true)) {
return $true
} elseif(($auth_obj.expires_in -lt (get-date)) -and ($auth_obj.isset -eq $true) -and ($auth_object.refresh_token_expires_in -gt (get-date)) {

if(auth_refresh) {
echo “Token expired and refreshed successfully” >> $log_path
return $true
} else {
echo “Failed Token refresh” >> $log_path
return $false
}

} else {

if(auth_initiate) {
echo “Initializing Auth token”>> $log_path
return $true
}
}
}

This function checks that the initial authorization has been done, and none of the tokens have expired. If they have expired, it calls the correct function to initialize the authorization or to renew it.

auth_initiate:

function auth_initiate() {

#Authentication post data
$auth_post = @{
grant_type = ‘password’
username = $username
password = $password
extension = $extension
}

$headers = New-Object “System.Collections.Generic.Dictionary[[String],[String]]”
$headers.Add(“Authorization”, “Basic $app_key”)
$headers.Add(“Content-Type”, “application/x-www-form-urlencoded;charset=UTF-8”)

try {
$url = $api_server_url + “/restapi/oauth/token”
$auth_token = invoke-restmethod -Method Post -Uri $url -Body $auth_post -headers $headers -ContentType “application/x-www-form-urlencoded”
$authorization = $auth_token.token_type + ” ” +$auth_token.Access_token
} catch {
echo “Error refresh token: $_” >> $log_path
return $False
}

$Global:auth_obj = [PSCustomObject] @{
Isset = $true
authorization = $authorization
refresh_token = $auth_token.refresh_token
expires_in = (Get-date).Addseconds($auth_token.expires_in)
refresh_token_expires_in = (Get-date).Addseconds($auth_token.refresh_token_expires_in)
scope = $auth_token.scope
owner_id = $auth_token.owner_id
endpoint_id = $auth_token.endpoint_id
}

return $auth_obj
}

The above function creates the initial authorization token, and changes the time the token expires into the local system time. It does the same for the refresh token’s expiration as well. All of that information is populated into the authorization global object.

auth_refresh:

function auth_refresh() {
$refresh_post = @{
grant_type = 'refresh_token'
refresh_token = $auth_token.refresh_token
}

$url = $api_server_url + “/restapi/oauth/token”

$headers = New-Object “System.Collections.Generic.Dictionary[[String],[String]]”
$headers.Add(“Authorization”, “Basic $app_key”)
$headers.Add(“Content-Type”, “application/x-www-form-urlencoded;charset=UTF-8”)

try {
$auth_token = invoke-restmethod -Method Post -Uri $url -Body $refresh_post -headers $headers -ContentType “application/x-www-form-urlencoded”
$authorization = $auth_token.token_type + ” ” +$auth_token.Access_token
} catch {
echo “Error refresh token: $_” >> $log_path
return $false
}

$Global:auth_obj = [PSCustomObject] @{
Isset = $true
authorization = $authorization
refresh_token = $auth_token.refresh_token
expires_in = (Get-date).Addseconds($auth_token.expires_in)
refresh_token_expires_in = (Get-date).Addseconds($auth_token.refresh_token_expires_in)
scope = $auth_token.scope
owner_id = $auth_token.owner_id
endpoint_id = $auth_token.endpoint_id
}

return $auth_obj
}

If the token has expired it uses the refresh token to re-authorize the call.

That is it for today. Thanks for reading.

Sharing is caring!

2 thoughts on “Using Powershell with the RingCentral API

  1. I think I ran into this and it had to do with the wrong “Platform Type” when setting up the API keys. Make sure you are set to Desktop (Mac/Windows/Other) .
    If that doesn’t sort it out let me know. I was looking through and I think I failed to mention that. I’ll update the blog with the information.

Leave your comment

one × 5 =