I am trying to pull some statistics for a TaskQueue using the TaskRouter.js SDK. For this I need to generate a capability router token, which allows access to the TaskQueue. According to the sample at twilio docs, I am supposed to pass null as the channel parameter(look in C# .Net sample), to generate the TaskRouterCapability token. But when I do this, I get an exception (object is null in get_Claims).
Looking at the source code, I should pass in the TaskQueue Sid as the channel id instead of null. When I did this a token was correctly generated.
To start off, am using the basic token generation example code at twilio docs :
class Program {
static void Main(string[] args)
{
// Find your Account Sid and Auth Token at twilio.com/console
const string accountSid = "ACbe0c12d747XXXXXXXXXXXXXXXXXb";
const string authToken = "your_auth_token";
const string workspaceSid = "WSXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
const string taskQueueSid = "WQXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX";
var urls = new PolicyUrlUtils(workspaceSid, taskQueueSid);
var allowFetchSubresources = new Policy($"{urls.TaskQueue}/**",
HttpMethod.Get);
var allowUpdates = new Policy(urls.TaskQueue, HttpMethod.Post);
var policies = new List<Policy>
{
allowFetchSubresources,
allowUpdates
};
// By default, tokens are good for one hour.
// Override this default timeout by specifiying a new value (in seconds).
// For example, to generate a token good for 8 hours:
var capability = new TaskRouterCapability(
accountSid,
authToken,
workspaceSid,
null,
policies: policies,
expiration: DateTime.UtcNow.AddSeconds(28800) // 60 * 60 * 8
);
Console.WriteLine(capability.ToJwt());
} }
class PolicyUrlUtils {
const string taskRouterBaseUrl = "https://taskrouter.twilio.com";
const string taskRouterVersion = "v1";
readonly string _workspaceSid;
readonly string _taskQueueSid;
public PolicyUrlUtils(string workspaceSid, string taskQueueSid)
{
_workspaceSid = workspaceSid;
_taskQueueSid = taskQueueSid;
}
public string TaskQueue => $"{Workspace}/TaskQueue/{_taskQueueSid}";
string Workspace =>
$"{taskRouterBaseUrl}/{taskRouterVersion}/Workspaces/{_workspaceSid}";
}
This gives me an exception on the last line(capability.ToJwt()). Exception is:
System.NullReferenceException occurred
HResult=0x80004003
Message=Object reference not set to an instance of an object.
Source=<Cannot evaluate the exception source>
StackTrace:
at Twilio.Jwt.Taskrouter.TaskRouterCapability.get_Claims()
at Twilio.Jwt.BaseJwt.ToJwt()
at DeleteMe.Program.Main(String[] args) in D:\Projects\DeleteMe\DeleteMe\Program.cs:line 46
Now, I looked at the source code of TaskRouterCapability at twilio-csharp github, and seems to be the queue sid should be passed as the channel parameter. When I do this, the token is created. So I took the token generated here, and put it into this HTML file:
<html>
<head>
<script type="text/javascript" src="https://media.twiliocdn.com/taskrouter/js/v1.11/taskrouter.min.js"></script>
<script type="text/javascript">
var taskQueue = new Twilio.TaskRouter.TaskQueue("token generated by console application");
taskQueue.on("ready", function (taskQueue) {
console.log(taskQueue.sid) // 'WQxxx'
console.log(taskQueue.friendlyName) // 'Simple FIFO Queue'
console.log(taskQueue.targetWorkers) // '1==1'
console.log(taskQueue.maxReservedWorkers) // 20
});
</script>
</head>
<body>
</body>
This then gives me some messages in the console:
taskrouter.min.js:1 Websocket opened: wss://event-bridge.twilio.com/v1/wschannels/ACxxxxxxxxxxxxxx/WQxxxxxxxx?token=eyJh.....&closeExistingSessions=false taskrouter.min.js:1 Received a message of type [connected] taskrouter.min.js:1 POST https://event-bridge.twilio.com/v1/wschannels/ACxxxxxxxxx/WQxxxxxxxxxxx 403 (Policies defined such that we cannot access the given resource)
So the connected event is called, but the ready event never happens.
Turns out there are 2 errors in the sample:
The channel parameter of TaskRouterCapability constructor should be passed the TaskQueue Sid rather than null. A value of null causes an Exception System.NullReferenceException occurred HResult=0x80004003 Message=Object reference not set to an instance of an object. Source= StackTrace: at Twilio.Jwt.Taskrouter.TaskRouterCapability.get_Claims() at Twilio.Jwt.BaseJwt.ToJwt()
There is a typo in the TaskQueue property of PolicyUrlUtils. The URL should have TaskQueues instead of TaskQueue
Have submitted a pull request for the same https://github.com/TwilioDevEd/api-snippets/pull/539
User contributions licensed under CC BY-SA 3.0