I have been programming in PowerShell for years, but I am pretty new at dealing with APIs. I have written code to deal with Meraki, where authentication just uses an API key. For RingCentral, I am a bit lost on making this work with OAUTH.
The program I am writing needs to be in PowerShell so I can integrate with AD and Exchange.
I have functioning code that I wrote to get data from RingCentral, but that only works if I first go to https://developers.ringcentral.com/api-reference and authorize my Sandbox or Production environment. I currently have a Bearer value hard-coded for now while I test, but will get it out of the code later.
It seems I may be stuck with username/password -type authentication and not something more-preferred that does not require me to have credentials stored somewhere.
In PowerShell, some basic code to get data looks like this:
#IDs, secrets, etc. are fake values below but look similar.
$ProductionClientID = "Q9GTXil5ZwqJhgzS7pBb5X"
$ProductionClientSecret = "IpUdDFj6KVFM7cYSJPXO4cK1i7eWdwvSQGYYofWLl5Oc"
$api = @{"endpoint" = 'https://platform.ringcentral.com/restapi/v1.0'}
$header = @{"accept" = 'application/json'
"authorization" = "Bearer 2piE4Dxnz3fGH2T1GBSE2m2D8ewFXOyxOYBN3K3ygsyr4OQ6vVnrnDGZxNOwxCZm7sIiuQipTds6NYm2kIp6cvjJIgNuYcM09NXil3nxKVOZMbJmHbH98EWkdFHNrq0R0oarLoK4OomxFeJdVgPgE5SxwzdDVQmSGgHyq0d66pMSfJ8nPLDkjumFrfxDLIfr3lpCf4ffrT5AV9JetoWCiZG2qvU35x4VsX66aitP8knPLe9aXuGlcXnEX5fLuUl9FOA9NCofZHKBKy3YKJ6EOrVXW8JITPbNml5zLJIHMsY2yvEWnfqyyU513FNcvXQh66P52AY7sNjMZfIiT58Ni7iw7qvlMzlLlHdNlqFeH1boZF"}
#This is just a sample Bearer value - not the actual one that I have hard-coded
Function Get-RingCentralAccount {
$api.url = "/account/~"
$uri = $api.endpoint + $api.url
$request = Invoke-RestMethod -Method GET -Uri $uri -Headers $header
return $request
}
Function Get-RingCentralCompanyPhoneNumbers {
$api.url = "/account/~/phone-number?page=1&perPage=1000"
$uri = $api.endpoint + $api.url
$request = Invoke-RestMethod -Method GET -Uri $uri -Headers $header
return $request
}
The problem I have is that there is cURL example to go by to figure out how the heck I am going to write this in PowerShell.
I am also not entirely sure if I am going to ultimately end up with the same type of header for when I run my functions. Maybe there is no Bearer value and instead there is something else I'll end up using because of the type of authentication I will have to use.
For those who have developed their app using Password Flow, can you provide examples and explain how your application keeps "logged in" to continue to interact with RingCentral while it is in use?
https://developers.ringcentral.com/guide/authentication/password-flow
This is my attempted function for authenticating, but I get errors:
Function Get-RingCentralAuthenticate {
$AuthHeader = @{"Content-Type" = 'application/x-www-form-urlencoded'
"Authorization" = 'Basic IpUdDFj6KVFM7cYSJPXO4cK1i7eWdwvSQGYYofWLl5Oc' }
$AuthAPI = @{"endpoint" = 'https://platform.ringcentral.com/restapi'
"url" = '/oauth/authorize'}
$AuthBody = @{"grant_type" = 'password'
"username" = '17175551212'
"password" = 'SuperSecretPassword'
#"audience" = 'The name of my API'
#"scope" = 'read:sample'
"response_type" = 'code'
"client_id" = 'Q9GTXil5ZwqJhgzS7pBb5X'
"client_secret" = 'IpUdDFj6KVFM7cYSJPXO4cK1i7eWdwvSQGYYofWLl5Oc'}
$uri = $AuthAPI.endpoint + $AuthAPI.url
$request = Invoke-RestMethod -Method POST -Uri $uri -Headers $AuthHeader -Body $AuthBody
return $request
}
For the function, Get-RingCentralAuthenticate, originally I did not have the "Authorization" line in the header, or audience, scope, response_type, client_id, or client_secret in the body, and I get this error, which to me indicates I am missing the response type.
Invoke-RestMethod: {
"error" : "unsupported_response_type",
"errors" : [ {
"errorCode" : "OAU-152",
"message" : "Unsupported response type: ",
"parameters" : [ {
"parameterName" : "response_type",
"parameterValue" : ""
} ]
} ],
"error_description" : "Unsupported response type: "
}
To resolve the above error, I tried adding the response_type, trying "code" and "token" - not sure if there are other possible values. I get this error:
Invoke-RestMethod: {
"error" : "invalid_request",
"errors" : [ {
"errorCode" : "OAU-155",
"message" : "Client id is undefined"
} ],
"error_description" : "Client id is undefined"
}
So, now I need a client ID it seems.
At this point I don't know if I am going in a wrong direction - I am now pretty much stabbing in the dark until I hit something.
If I use the client_id value, I am now told I don't have a redirect uri, so now I am stuck until I either figure that out, or find a different rabbit hole. Redirect uri I thought was not part of Password Flow.
Invoke-RestMethod: {
"error" : "invalid_client",
"errors" : [ {
"errorCode" : "OAU-113",
"message" : "No redirect uri is registered for the client"
} ],
"error_description" : "No redirect uri is registered for the client"
}
------------------------------------------------------
After more monkeying around...
In the app settings (in the RingCentral app website), I created a fake oauth redirect uri: myapp://redirect
No idea if that is the right thing to do or if it can work. I found this on some site that tries to explain oauth and how it is used. It did get rid of my redirect errors.
I think I need to be using /oauth/token based on what I have seen by example on several non-RingCentral sites.
So, currently I am running my code like this. Note that I currently have client_id and client_secret commented out. In my current state, I get the same authentication error whether those are commented or not. I think I may just have a bad password value, and I have no idea how to look it up - I thought I used the same password I use when I log into RingCentral with my normal admin account, and since I don't have an extension 101 in RingCentral, I have no way to reset its password. I did try my normal extension instead of 101 - no help. If I omit username or password, it does tell me that I need those specified.
- #IDs, secrets, etc. are fake values below but look similar to actual values.
- Â
- Function Get-RingCentralAuthenticate {
- $AuthHeader = @{"Content-Type" = 'application/x-www-form-urlencoded' }
- $AuthAPI = @{"endpoint" = 'https://platform.ringcentral.com/restapi'
- "url" = '/oauth/token'}
- $AuthBody = @{"grant_type" = 'password'
- "username" = '17175551212'
- "extension" = '101'
- "password" = 'My admin login password'
- #"client_id" = 'Q9GTXil5ZwqJhgzS7pBb5X'
- #"client_secret" = 'IpUdDFj6KVFM7cYSJPXO4cK1i7eWdwvSQGYYofWLl5Oc'}
- $uri = $AuthAPI.endpoint + $AuthAPI.url
- $request = Invoke-RestMethod -Method POST -Uri $uri -Headers $AuthHeader -Body $AuthBody
- return $request
- }
Error:
- Invoke-RestMethod:
- "error" : "invalid_client",
- "errors" : {
- "errorCode" : "OAU-123",
- "message" : "Client authentication is required"
- } ],
- "error_description" : "Client authentication is required"
I really think I just have bad credentials here, but invalid_client is a pretty crappy response if that is the actual problem. I tried bad credentials, too, with the same results.