Hi,
I have an ASP.NET Web Forms site, where staff members can view all the details of a customer including phone number, and I want those staff members to be able to make RingOut calls to customers by clicking a button next to their phone number.
Can anybody help me out on the process of how this would work? There are plenty of non-real-life demos of the technical side, and I can reproduce all the steps of getting authenticated and making the call, I am just struggling to see how the process would work in real life?
From a customer details page, when the staff member clicked the button, the first thing Id have to do is get the auth URL, right? But that then sends an auth code back to a different page the callback page. So now Ive lost the details about who Im trying to call? Am I supposed to use the state parameter to remember those details or something? (I presume not from the description of it). Or add the number Im trying to call as a parameter on the end of the callback page?
How often am I supposed to have to get the auth URL and code just once and then store it in a database? Or I store the URL in a database and get the code each time I need to make a call? Or get both each time I need to place a call?
It may be a blind spot on my part but I just cannot see at all how to map the technical examples available to a real life example. It's not at all clear which bits are one off actions and which need to be repeated for each RingOut call.
I appreciate JavaScript may be a better option for me but my JS isnt too strong and I cant get the example (https://ringcentral.github.io/cti-demo) working for me. Nothing happens when I click Link Account.
Would appreciate any help from anyone who has done this stuff.
Thanks in advance.
Okay so the process is:
User clicks button to make call.
If no token in database newer than 7 days, get authorization URL and show it in a pop up for user to log in. With returned token call rc.Authorize and store token in database. (In order to store the token against a particular username I will pass username as the state parameter, because the callback URL is an external (public) site that wont be able to reference the users username otherwise. Is that usual/acceptable use of the state parameter?)
If token present in database between 1 hour and 7 days old, call rc.Refresh and store returned token in database.
If token present less than 1 hour old, use that.
Does that sound about right?
Are you able to advise on maximum field sizes for the token properties for database storage please?
Side note is there a reason most of the code here is commented out? https://github.com/ringcentral/ringcentral-csharp-client/blob/master/RingCentral/TokenInfo.csAs long as you have a token, you don't have to do authorization. Because authorization is just to retrieve a token:
var token = <read token from DB or somewhere else>
rc.token = token
rc.<make an API call>
https://github.com/ringcentral/ringcentral-csharp-client/blob/master/RingCentral/RestClient.cs#L82
The token object contains access_token and refresh_token properties, the former expires in an hour, the latter expires in 7 days. If the former expires, you refresh the token. If the latter expired, you need to authorization again.
There is also auto token refresh. You can disable it if you save the token and mange it yourself: https://github.com/ringcentral/ringcentral-csharp-client#auto-refresh
Also am I right to assume that after a call to rc.Authorize I should store the cookie for 7 days? The expires_in value no longer seems to be returned - any reason why? If this changes in future how will I know?
Finally, this is pretty difficult to test with only one test account number, because I am now authorised for the next 7 days - is there any way to replicate what would happen if I wasn't authorised?
However the problem with that picture is that as far as I can see the token is never actually used to make the phone calls - see my MakeCallAsync method. It seems to me as though the important bit is not actually the token value itself, but the call to rc.Authorize - is that correct? Once that is called, I can make and cancel calls.
So really the correct logic is, if rc.Authorize hasn't been called, call it. If it has already been called, don't.
The token is just a way of recording whether or not it's happened, and when it happened. When the token is 7 days old, I know I have to call rc.Authorize again.
Is that a correct interpretation?
Also, does rc.Authorize handle whether or not to use the refresh token or get a new token the long way? Is that something I don't need to worry about?
Thanks, Brandon. I appreciate your reply. My staff will have physical phones so the setup is like yours, except Im Web Forms.
So Ive created this class, give or take a bit of error handling:
public static class RingCentralCall
{
private static RestClient rc = new RestClient("ClientId", "ClientSecret", false);
public static async Task<TokenInfo> GetTokenAsync(string authCode, string redirectUrl)
{
TokenInfo token = await rc.Authorize(authCode, redirectUrl);
return token;
}
public static async Task<string> MakeCallAsync(string from, string to)
{
var extension = rc.Restapi().Account().Extension();
var requestBody = new
{
from = new { phoneNumber = from },
to = new { phoneNumber = to },
playPrompt = true
};
var response = await extension.RingOut().Post(requestBody);
string CallId = response.id;
return CallId;
}
public static async Task CancelCallAsync(string callId)
{
var extension = rc.Restapi().Account().Extension().RingOut(callId);
var Url = extension.Url();
var response = await extension.Delete();
}
public static async Task<string> GetAuthorizeUri()
{
var authorizeUri = rc.AuthorizeUri("https://mycompany/Callback.aspx";);
return authorizeUri;
}
}
Then I have a page lets call it CustomerDetail.aspx that I can use to get to the Authorization URL:
protected void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(() => GoToAuthorizeUri()));
}
private async Task GoToAuthorizeUri()
{
var AuthorizeUri = await RingCentralCall.GetAuthorizeUri();
Response.Redirect(AuthorizeUri);
}
That returns an Authorise Uri and redirects me there to the page that says Click Authorise to allow this app and RingCentral to use your information etc. On clicking Authorise Im then redirected to my callback page Callback.aspx. But now Ive lost the details of who I was trying to call.
On Callback.aspx I get the token, and then I can make or cancel a call to a hardcoded number thats all working successfully.
protected async void Page_Load(object sender, EventArgs e)
{
var authCode = Request.QueryString["code"].ToString();
var state = Request.QueryString["state"].ToString();
TokenInfo token = await RingCentralCall.GetTokenAsync(authCode, " https://mycompany/Callback.aspx";);
}
protected void btnCall_Click(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(() => PlaceCall(from: txtFrom.Text, to: txtTo.Text)));
}
protected void btnCancel_Click(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(() => CancelCall()));
}
private async Task PlaceCall(string from, string to)
{
lblCallId.Text = await RingCentralCall.MakeCallAsync(from, to);
}
private async Task CancelCall()
{
await RingCentralCall.CancelCallAsync(lblCallId.Text);
}
But again, the issue is that I knew the customers phone number at CustomerDetail.aspx, but Ive lost it by Callback.aspx. How can I retain it through that process?
Is there anything obvious Im doing badly or inefficiently?
Do I need to do all these things each time? Or is the Authorise URL always the same, per organisation? So once I get it once I can just store it and re-use it? Or is it per user? Or does it expire?
Also should I be getting a new token like this each time I make a call? Or is that bad practice? Should I store it if so how? I see theres a refresh token option what are the pros/cons of using this? Seems like just as much work as getting a fresh token, if not more?
I would really appreciate any guidance in the areas of best practice and best user experience, as well as the practical problem of retaining the destination phone number after being redirected to the Authorization URI.
A new Community is coming to RingCentral!
Posts are currently read-only as we transition into our new platform.We thank you for your patience
during this downtime.
Try Workflow Builder
Did you know you can easily automate tasks like responding to SMS, team messages, and more? Plus it's included with RingCentral Video and RingEX plans!Try RingCentral Workflow Builder