question

todd125 avatar image
todd125 asked todd125 answered

Anyone have any C# sample code to authenicate to the API and make some requests?

Not sure how to do Oauth2 authentication to a web API in C#. If anyone has done so already, could please share some sample code, so I don't have to re-invent the wheel.

getting started
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

benjamin-dean avatar image
benjamin-dean answered John Wang Deactivated commented
Hey Todd,

There is an unofficial C# SDK available here which might be of help:  https://github.com/grokify/ringcentral-sdk-csharp-simple

There are examples for just obtaining the RingCentral SDK Client, and a simple example for sending an SMS message once you've authenticated.
10 comments
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

firstlab-admin2126 avatar image firstlab-admin2126 commented ·
All we want to do is download incoming faxes. Can we use the SDK to accomplish this, or do we need to use a regular HttpWebRequest?

Thank you for you help!


0 Likes 0 ·
benjamin-dean avatar image benjamin-dean commented ·
You can use either the SDK, or a standard REST API request directly.
0 Likes 0 ·
firstlab-admin2126 avatar image firstlab-admin2126 commented ·
So, I was thinking we could use the standard REST API request directly. Which is why I asked if anyone has any sample code to authenticate. Sending and receiving JSON is pretty simple. They only tricky part is authenticating.

Do you have any code sample for how to do the authentication? Or do you suggest I just try to use the SDK?
0 Likes 0 ·
benjamin-dean avatar image benjamin-dean commented ·
Have you tried ripping the authentication code out of the community C# SDK?
0 Likes 0 ·
firstlab-admin2126 avatar image firstlab-admin2126 commented ·
No, I looked for the authentication code but could not find it.  It was calling the SDK. I found this but it was calling the SKD.

public Client(string appKey, string appSecret, string serverUrl) { Sdk = new RingCentral.SDK.SDK(appKey, appSecret, serverUrl); }

So where is the code in the SDK that does the authentication? That's all I need.


0 Likes 0 ·
firstlab-admin2126 avatar image firstlab-admin2126 commented ·
I went to here https://github.com/ringcentral/ringcentral-csharp and there is nothing. Just a readme.

0 Likes 0 ·
vyshakhbabji avatar image vyshakhbabji ♦♦ commented ·
Could you have a look at this? https://github.com/grokify/ringcentral-sdk-csharp-simple

Its a unofficial SDK implementation inC# . You could use this as a reference or could start your own implementation keeping this as a base SDK.


Let us know if you need help.  
0 Likes 0 ·
firstlab-admin2126 avatar image firstlab-admin2126 commented ·
I looked at it. It didn't help. You said I could use the REST API. Can you give me an example of some code to do the authentication rather than asking me to look at https://github.com/grokify/ringcentral-sdk-csharp-simple? Why can't you provide a sample for me? I know you can do it, but the source code is is not on GIT. Why is it hidden?
0 Likes 0 ·
vyshakhbabji avatar image vyshakhbabji ♦♦ commented ·
C# SDK is still under prealpha stage and not ready to be made public. If you just want to see how it can be implemented in C# - you could even use my Java SDK as a reference :   https://github.com/vyshakhbabji/ringcentral-java

I could provide you some code snippets for C# Authentication. Please find it below: 

https://github.com/vyshakhbabji/ringcentral-csharp/blob/develop/RingCentral/platform/Platform.cs
public Response Authorize(string userName, string extension, string password, bool isRemember) { var body = new Dictionary < string,
string > {
{
"username", userName
}, {
"password", Uri.EscapeUriString(password)
}, {
"extension", extension
}, {
"grant_type", "password"
}, {
"access_token_ttl", AccessTokenTtl
}, {
"refresh_token_ttl", isRemember ? RefreshTokenTtlRemember : RefreshTokenTtl
}
};
var request = new Request(TokenEndpoint, body);
var result = AuthCall(request);
Auth.SetRemember(isRemember);
Auth.SetData(result.GetJson());
_client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", Auth.GetAccessToken());
return result;
}
0 Likes 0 ·
John Wang avatar image John Wang ♦♦ commented ·
The source code for the C# SDK is in the 'develop' branch of the GitHub repository available here:  https://github.com/ringcentral/ringcentral-csharp/tree/develop

We are finalizing this SDK and will migrate the code in the develop branch to the master branch shortly.
0 Likes 0 ·
todd125 avatar image
todd125 answered
I downloaded the sample project from the link you provided me and when I run the code it says "Access Expired". Please advise. Thank you for all your help.
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

vyshakhbabji avatar image
vyshakhbabji Deactivated answered benjamin-dean commented
Can you share the Response Message ? And what is the HTTP status code? 
9 comments
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

todd125 avatar image todd125 commented ·
I tried following the tutorial first. https://developer.ringcentral.com/library/tutorials/get-started.html  Cause if I can make it work in the browser I should be able to replicate that in code.

The post is to https://platform.devtest.ringcentral.com/restapi/oauth/token

The response is.

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><errorEntity><error>invalid_grant</error><error_description>Invalid resource owner credentials.</error_description></errorEntity>

I was using 12154223514 as the username. I don't want to put the password here, but it is the same user name and password I use to log in to developer.ringcentral.com.

Should I be using a different username and password? We aren't going to have a user, it will just be running from our server.

Thanks for your help.









0 Likes 0 ·
todd125 avatar image todd125 commented ·
Here are the headers...


Host: platform.devtest.ringcentral.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:43.0) Gecko/20100101 Firefox/43.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Authorization: Basic WnZYMG94YVlRbW1JcWVVd3FYWWZBZzo2MVhNblh3N1JaR3ItbXRzZjZLMDh3b2VNbWJ4V25TZ21UZjlCcl9aVWZvZw==
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Content-Length: 60
Cookie: _ga=GA1.2.1582640206.1445977993; RCRoutingInfo=B:JjvG963zMhLp2i9ovcWFNByPb5vRnRQA539tb0pH+XWHl8qMEhGXRFDcYy5wxzWX
Connection: keep-alive
Proxy-Authorization: Negotiate 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

0 Likes 0 ·
benjamin-dean avatar image benjamin-dean commented ·
Did you follow the documentation for obtaining the access token?

I think you're receiving the "Invalid Grant" and "Invalid Resource Owner Credentials" because you might not be using the proper values or URI in your POST request for the access token.

  1. To use the RingCentral API, an access and refresh token are needed. The simplest way to get an access token needed for production resources is to complete Two-legged Authorization Flow (OAuth 2.0). The required fields are below:

    • ApplicationKey  granted after successful application/developer registration. Required.

    • ApplicationSecret  granted after successful application/developer registration. Required.

    • UserName  main company number of a RingCentral account or direct extension phone number (unformatted, sequence of digits starting with country code). Required.

    • Extension  extension number to log into for the RingCentral account. Required if main company number is provided as a UserName.

    • Password  for the RingCentral account. Required.


  2. Once you have the ApplicationKey and ApplicationSecret for your app (You obtain these raw values from your application definition page available by selecting your application from the list of your defined apps here: https://developers.ringcentral.com/my-account.html#/applications ), you must Base64 encode them to be used in the request for an access/refresh token. A free tool is available at http://www.base64encode.org.

    In C# you can also create a method to encode base64 values:

     public static string Base64Encode(string plainText) {   var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);   return System.Convert.ToBase64String(plainTextBytes); }

  3. Once you have the payload data to obtain an access token, you'll want to create an HTTP POST request to: https://platform.devtest.ringcentral.com/restapi/oauth/token (notice this URI is for your Sandbox environment, for a production environment just remove "devtest." from the URI).

     //Be sure to run "Install-Package Newtonsoft.Json -Version 7.0.1" from your nuget command line. //Be sure to run "Install-Package System.Net.Http -Version 4.0.0" from your nuget command line.  HttpClient client = new HttpClient();  client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", "BASE64 ENCODED APPKEY:APPSECRET");<br> FormUrlEncodedContent form = new FormUrlEncodedContent(new Dictionary { { "username", "username" }, { "password", "password" }, { "grant_type": "password" }, { "extension": "extension" } } );  Task message = client.PostAsync( "https://platform.devtest.ringcentral.com/restapi/oauth/token", form ); String result = message.Result.Content.ReadAsStringAsync().Result;  JObject RCAuth = JObject.Parse( result ); string token = ( string )RCAuth["access_token"] string refreshToken = ( string )RCAuth["refresh_token"]; string tokenExpires = ( string )RCAuth["access_token_expires_in"]; string refreshTokenExpires = ( string )RCAuth["refresh_token_expires_in"]; 

  4. That should get you to the point you're able to begin making calls. You will want to use this token until around 80% of the expiration time, then you'll want to use the refresh token to request a new access and refresh token.
Let me know if this doesn't work for you, or if you hit snags.
0 Likes 0 ·
todd125 avatar image todd125 commented ·
Awesome! Thanks! I am working on other stuff, but I'll get to this sometime soon. I'll probably try it out from home first to rule out any corporate firewall issues. I'll let you know how it goes.
0 Likes 0 ·
todd125 avatar image todd125 commented ·
What should I be using for extension?
0 Likes 0 ·
Show more comments
todd125 avatar image
todd125 answered
Today I finally got the answer my original question. The code snippet below.


    public class Worker
    {
        private static string Base64Encode(string plainText)
        {
            var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
            return System.Convert.ToBase64String(plainTextBytes);
        }

        private string _accessToken;
       
       public async void WaitForAuthToken()
        {
            using (var client = new HttpClient())
            {
                var request = new HttpRequestMessage()
                {
                    RequestUri = new System.Uri($"{Settings.ServerUrl}restapi/oauth/token"),
                    Method = HttpMethod.Post,
                };
                 request.Headers.TryAddWithoutValidation("Content-Type", @"application/x-www-form-urlencoded;charset=UTF-8");
                request.Headers.Add("Authorization", $"Basic {Base64Encode($"{Settings.AppKey}:{Settings.AppSecret}")}"); 
                request.Content = new FormUrlEncodedContent(new[] {
                new KeyValuePair<string, string>("grant_type", "password"),
                new KeyValuePair<string, string>("username", Settings.PhoneNumber),
                new KeyValuePair<string, string>("password", Settings.Password),
                new KeyValuePair<string, string>("extension", Settings.Extension)
            });

                var response = await client.SendAsync(request);
                var responseContent = await response.Content.ReadAsStringAsync();
                var d = (dynamic) Newtonsoft.Json.JsonConvert.DeserializeObject(responseContent);
                _accessToken = d.access_token;
            }
        }
    }




Simple really.
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

benjamin-dean avatar image
benjamin-dean answered
Thanks for sharing this Todd...great help.

Love seeing the use of async in there that makes a ton of sense in addition to setting this up as a worker.
1 |3000

Up to 8 attachments (including images) can be used with a maximum of 1.0 MiB each and 10.0 MiB total.

Developer sandbox tools

Using the RingCentral Phone for Desktop, you can dial or receive test calls, send and receive test SMS or Fax messages in your sandbox environment.

Download RingCentral Phone for Desktop:

Tip: switch to the "sandbox mode" before logging in the app:

  • On MacOS: press "fn + command + f2" keys
  • On Windows: press "Ctrl + F2" keys