Twilio Taskrouter: How to prevent last worker in queue from being reassigned rejected task?

删除回忆录丶 提交于 2020-01-06 08:42:08

问题


I'm using NodeJS to manage a Twilio Taskrouter workflow. My goal is to have a task assigned to an Idle worker in the main queue identified with queueSid, unless one of the following is true:

  1. No workers in the queue are set to Idle

  2. Reservations for the task have already been rejected by every worker in the queue

In these cases, the task should fall through to the next queue identified with automaticQueueSid. Here is how I construct the JSON for the workflow (it includes a filter such that an inbound call from an agent should not generate an outbound call to that same agent):

configurationJSON(){
    var config={
        "task_routing":{
            "filters":[
                {

                    "filter_friendly_name":"don't call self",
                    "expression":"1==1",
                    "targets":[
                        {
                            "queue":queueSid,
                            "expression":"(task.caller!=worker.contact_uri) and (worker.sid NOT IN task.rejectedWorkers)",
                            "skip_if": "workers.available == 0"
                        },
                        {
                            "queue":automaticQueueSid
                        }
                    ]

                }
            ],
            "default_filter":{
                "queue":queueSid
            }
        }
    }
    return config;
}

This results in no reservation being created after the task reaches the queue. My event logger shows that the following events have occurred:

workflow.target-matched
workflow.entered
task.created 

That's as far as it gets and just hangs there. When I replace the line

"expression":"(task.caller!=worker.contact_uri) and (worker.sid NOT IN task.rejectedWorkers)"

with

"expression":"(task.caller!=worker.contact_uri)

Then the reservation is correctly created for the next available worker, or sent to automaticQueueSid if no workers are available when the call comes in, so I guess the skip_if is working correctly. So maybe there is something wrong with how I wrote the target expression?

I tried working around this by setting a worker to unavailable once they reject a reservation, as follows:

clientWorkspace
.workers(parameters.workerSid)
.reservations(parameters.reservationSid)
.update({
    reservationStatus:'rejected'
})
.then(reservation=>{
//this function sets the worker's Activity to Offline
    var updateResult=worker.updateWorkerFromSid(parameters.workerSid,process.env.TWILIO_OFFLINE_SID);
})
.catch(err=>console.log("/agent_rejects: error rejecting reservation: "+err));

But what seems to be happening is that as soon as the reservation is rejected, before worker.updateWorkerFromSid() is called, Taskrouter has already generated a new reservation and assigned it to that same worker, and my Activity update fails with the following error:

Error: Worker [workerSid] cannot have its activity updated while it has 1 pending reservations.

Eventually, it seems that the worker is naturally set to Offline and the task does time out and get moved into the next queue, as shown by the following events/descriptions:

worker.activity.update
Worker [friendly name] updated to Offline Activity
reservation.timeout
Reservation [sid] timed out
task-queue.moved
Task [sid] moved out of TaskQueue [friendly name]
task-queue.timeout
Task [sid] timed out of TaskQueue [friendly name]

After this point the task is moved into the next queue automaticQueueSid to be handled by available workers registered with that queue. I'm not sure why a timeout is being used, as I haven't included one in my workflow configuration.

I'm stumped--how can I get the task to successfully move to the next queue upon the last worker's reservation rejection?

UPDATE: although @philnash's answer helped me correctly handle the worker.sid NOT IN task.rejectedWorkers issue, I ultimately ended up implementing this feature using the RejectPendingReservations parameter when updating the worker's availability.


回答1:


Twilio developer evangelist here.

rejectedWorkers is not an attribute that is automatically handled by TaskRouter. You reference this answer by my colleague Megan in which she says:

For example, you could update TaskAttributes to have a rejected worker SID list, and then in the workflow say that worker.sid NOT IN task.rejectedWorkerSids.

So, in order to filter by a rejectedWorkers attribute you need to maintain one yourself, by updating the task before you reject the reservation.

Let me know if that helps at all.



来源:https://stackoverflow.com/questions/55381603/twilio-taskrouter-how-to-prevent-last-worker-in-queue-from-being-reassigned-rej

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!