Forward Call In Twilio - function

I am facing an Issue I want to forward call to an agent if not answered then transfer call to next agent but the issue is I don't have first agent number. I have to make call on Ivr and send keys to connect with agent it is working fine. But Issue is if agent not answered call after 4 rings call to another agent .
Call is not timeout because that is seem to be answered by IVR and when hang-up status is completed
Is there a way to do call forwarding in that way.
Here is the code
const twiml = new Twilio.twiml.VoiceResponse();
const functionPath = '';
if (event.reason === "dialStatus") {
console.log(event.DialCallStatus);
if (event.DialCallStatus === "no-answer" || event.DialCallStatus === "busy" || (event.DialCallStatus === "completed")) {
console.log('Duration'+event.DialCallDuration);
return callback(null, twiml);
} else {
console.log(event.DialCallDuration);
return callback(null, twiml);
}
}
var phonenumber=ph.split('-');
const dialedPartyNumber =ph;
var digit='www3'
console.log(dialedPartyNumber);
console.log(digit);
const dial = twiml.dial({timeout:`5`, action: `${functionPath}?reason=dialStatus`,hangupOnStar:true });
dial.number({ sendDigits: digit }, dialedPartyNumber);
callback(null, twiml);

How I've done this before is to put the original call in a conference room. Then call the first agent and ask them to press X to join the conference. If they do not, then go to the second agent and repeat.
david

The problem you are describing isn't really an issue on Twilio, it's actually a question of state management. From your description, it sounds like you are trying to implement an "inbound queue" solution - where multiple agents are "logged-in" to a queue and will receive calls accordingly.
If what I described is what you are trying to achieve, then a I would recommend trying something like the below:
A call comes into your system and queries a remote script for the first agent.
The remote script returns a Twiml to route to the relevant agent, with a dial timeout of 8 seconds.
The remote script will re-invoked, in case where the call was not answered. When invoked, your server should know that the new invocation is from an existing session - which will respond back with a new agent.
Upon answering the call, the answering agent marks the call is answered - making sure step one doesn't return that agent while they are on the phone.
Remember, Twilio (and other CPaaS platforms as well) are asynchronous, which means that you will need to manage your call-routing and call-control states yourself.

Related

My messages are delivered out of flow sequence order and how do I compensate?

I wish to use Twilio in the context of an adventure game. As the gamer (Geocacher) progresses on an actual treasure (cache) hunt, clues are given by text when certain code words or numbers are entered as part of the thread. I am very comfortable creating the flow in Studio and have a working flow that is debugged and ready to go.
Not so fast, grasshopper! Strange things started to happen when beta testing the flow. Basically texts that show as being sent arrive to the user out of sequence in the thread. The SM logs show everything is working correctly (message sent) but, what I call Zombie messages arrive to the user after a previous message has arrived. The Zombies are legitimate messages from the Flow but out of the correct sequence and that makes the thread unusable for my purposes.
I learned too late in my "programming" that Twilio states, "If you send multiple SMS messages to the same user in a short time, Twilio cannot guarantee that those messages will arrive in the order that you sent them." Ugh!
So , I started with the Help Techs at Twillio and one solution is to create a subflow that basically is inserted after a Send Message Widget. This sub flow basically Fetches the message via the SMS SID to check for SMS status. If status is "delivered", we can safely say the message has been received by the recipient and then permit the next message in the flow.
That sound great but I am not a programmer and will never be able to integrate the suggested code much less debug it when things don't work. There might be many other approaches that you guys can suggest. The task is 1.) Send a message, 2.) Run a subflow that checks for message delivery, 3.) send the next message in the sequence.
I need to move on to implementation and this type of sub flow is out of my wheelhouse. I am willing to pay for programming help.
I can post the JSON code that was created as a straw man but have no idea how to use it and if it is the optimum solution if that is of help. It would seem that a lot of folks experience this issue and would like a solution. A nice tight JSON subflow with directions on how to insert would seem to be a necessary part of the Widget toolkit provided by Twillio in Studio.
Please Help Me! =)
As you stated, the delivery of the message cannot be guaranteed. Checking the status of the sent message is the most reliable, using a subflow, a Twilio Function, or a combination. Just keep in mind that Twilio Functions have a 10s execution time limit. I don't expect delivering the SMS will take longer than 10s is most cases. If you're worried about edge cases, you'd have to loop the check for the status multiple times. I'll share a proof of concept later for this.
An easier way, but it still doesn't guarantee delivery order, would be to add some delay between each message. There's no built-in delay widget, but here's code on how to create a Twilio Function to add delays, up to 10s.
A more hacky way to implement delays without having to use this Twilio Function, is to use the Send & Wait For Reply Widget and configure the "Stop Gathering After" property to the amount of delay you'd like to add. If the user responds, connect to the next widget, if they don't also connect to the widget.
As mentioned earlier, here's th Subflow + Function proof of concept I hacked together:
First, create a Twilio Functions Service, in the service create two functions:
/delay:
// Helper function for quickly adding await-able "pauses" to JavaScript
const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
exports.handler = async (context, event, callback) => {
// A custom delay value could be passed to the Function, either via
// request parameters or by the Run Function Widget
// Default to a 5 second delay
const delay = event.delay || 5000;
// Pause Function for the specified number of ms
await sleep(delay);
// Once the delay has passed, return a success message, TwiML, or
// any other content to whatever invoked this Function.
return callback(null, `Timer up: ${delay}ms`);
};
/get-message:
exports.handler = function(context, event, callback) {
const messageSid = event.message_sid,
client = context.getTwilioClient();
if(!event.message_sid) throw "message_sid parameter is required.";
client.messages(messageSid)
.fetch()
.then(message => callback(null, message))
.catch((error) => {
console.error(error);
return callback(error);
});
};
Then, create a Studio Flow named something like "Send and Wait until Delivered".
In this flow, you send the message, grabbing the message body passed in from the parent flow, {{trigger.parent.parameters.message_body}}.
Then, you run the /get-message Function, and check the message status.
If delivered, set status variable to delivered. This variable will be passed back to the parent flow. If any of these accepted,queued,sending,sent, then the message is still in route, so wait a second using the /delay function, then loop back to the /get-message function.
If any other status, it is assumed there's something wrong and status is set to error.
Now you can create your parent flow where you call the subflow, specifying the message_body parameter. Then you can check the status variable for the subflow, whether it is 'delivered' or 'error'.
You can find the export for the subflow and the parent flow in this GitHub Gist. You can import it and it could be useful as a reference.
Personally, I'd add the /delay function, and use that after every message, adding a couple of seconds delay. I'd personally assume the delay adds enough buffer for no zombie messages to appear.
Note: The code, proof of concept, and advice is offered as is without liability to me or Twilio. It is not tested against a production workload, so make sure you test this thoroughly for your use case!

Google Apps Script: I want to display Script Property in the client-side code, but its value is undefined [duplicate]

I am trying to write a Google Apps script which has a client and server side component. The client side component displays a progress bar. The client calls server side functions (which are called asynchronously), whose progress has to be shown in the client side progress-bar. Now, what I want is to be able to update the client side progress bar based on feedback from the server side functions. Is this possible?
The complexity is created due the the fact that JS makes the server-side calls asynchronously and hence I cannot really have a loop on the client side calling the functions and updating the progress bar.
I could of course split up the execution of the server side function in multiple steps, call one by one from the client side, each time updating the status bar. But I'm wondering if there's a better solution. Is there a way to call a client side function from the server side, and have that update the progress bar based on the argument passed? Or is there a way to access the client side progress-bar object from server side and modify it?
The way I've handled this is to have a middleman (giving a shout out now to Romain Vialard for the idea) handle the progress: Firebase
The HTML/client side can connect to your Firebase account (they're free!) and "watch" for changes.
The client side code can update the database as it progresses through the code - those changes are immediately fed back to the HTML page via Firebase. With that, you can update a progress bar.
Romain has a small example/description here
The code I use:
//Connect to firebase
var fb = new Firebase("https://YOUR_DATABASE.firebaseio.com/");
//Grab the 'child' holding the progress info
var ref = fb.child('Progress');
//When the value changes
ref.on("value", function(data) {
if (data.val()) {
var perc = data.val() * 100;
document.getElementById("load").innerHTML = "<div class='determinate' style='width:" + perc + "%\'></div>";
}
});
On the client side, I use the Firebase library to update the progress:
var fb = FirebaseApp.getDatabaseByUrl("https://YOUR_DATABASE..firebaseio.com/");
var data = { "Progress": .25};
fb.updateData("/",data);
Rather than tying the work requests and progress updating together, I recommend you separate those two concerns.
On the server side, functions that are performing work at the request of the client should update a status store; this could be a ScriptProperty, for example. The work functions don't need to respond to the client until they have completed their work. The server should also have a function that can be called by the client to simply report the current progress.
When the client first calls the server to request work, it should also call the progress reporter. (Presumably, the first call will get a result of 0%.) The onSuccess handler for the status call can update whatever visual you're using to express progress, then call the server's progress reporter again, with itself as the success handler. This should be done with a delay, of course.
When progress reaches 100%, or the work is completed, the client's progress checker can be shut down.
Building on Jens' approach, you can use the CacheService as your data proxy, instead of an external service. The way that I've approached this is to have my "server" application generate an interim cache key which it returns to the "client" application's success callback. The client application then polls this cache key at an interval to see if a result has been returned into the cache by the server application.
The server application returns an interim cache key and contains some helper functions to simplify checking this on the client-side:
function someAsynchronousOperation() {
var interimCacheKey = createInterimCacheKey();
doSomethingComplicated(function(result) {
setCacheKey(interimCacheKey, result);
});
return interimCacheKey;
}
function createInterimCacheKey() {
return Utilities.getUuid();
}
function getCacheKey(cacheKey, returnEmpty) {
var cache = CacheService.getUserCache();
var result = cache.get(cacheKey);
if(result !== null || returnEmpty) {
return result;
}
}
function setCacheKey(cacheKey, value) {
var cache = CacheService.getUserCache();
return cache.put(cacheKey, value);
}
Note that by default getCacheKey doesn't return. This is so that google.script.run's successHandler doesn't get invoked until the cache entry returns non-null.
In the client application (in which I'm using Angular), you call off to the asynchronous operation in the server, and wait for its result:
google.script.run.withSuccessHandler(function(interimCacheKey) {
var interimCacheCheck = $interval(function() {
google.script.run.withSuccessHandler(function(result) {
$interval.cancel(interimCacheCheck);
handleSomeAsynchronousOperation(result);
}).getCacheKey(interimCacheKey, false);
}, 1000, 600); // Check result once per second for 10 minutes
}).someAsynchronousOperation();
Using this approach you could also report progress, and only cancel your check after the progress reaches 100%. You'd want to eliminate the interval expiry in that case.

Any workaround for Chrome M40 redirect bug for service workers?

We have images that redirect from our media server to a CDN that I'm trying to exclude from my service worker logic to work around the bug in Chrome 40. In Canary the same worker is able to work just fine. I thought there was an event.default() to fall back to the standard behavior but I don't see that in Chrome's implementation, and reading the spec it seems like the current recommendation is to just use fetch(event.request).
So the problem I have is do I have to wait until 99% of all of our users move to Chrome 41+ in order to use service workers in this scenario, or is there some sort of way I can opt out for certain requests?
The core of my logic is below:
worker.addEventListener('install', function(event){
event.waitUntil(getDefaultCache().then(function(cache){
return cache.addAll(precacheUrls);
}));
});
worker.addEventListener('fetch', function(event){
event.respondWith(getDefaultCache().then(function(cache){
return cache.match(event.request).then(function(response){
if (!response){
return fetch(event.request.clone()).then(function(response){
if (cacheablePatterns.some(function(pattern){
return pattern.test(event.request.url);
})) {
cache.put(event.request, response.clone());
}
return response;
});
}
return response;
});
}));
});
Once you're inside a event.respondWith() you do need to issue a response or you'll incur a Network Error. You're correct that event.default() isn't currently implemented.
A general solution is to not enter the event.respondWith() if you can determine synchronously that you don't want to handle the event. A basic example is something like:
function fetchHandler(event) {
if (event.request.url.indexOf('abc') >= 0) {
event.respondWith(abcResponseLogic);
} else if (event.request.url.indexOf('def') >= 0) {
event.respondWith(defResponseLogic);
}
}
self.addEventListener('fetch', fetchHandler);
If event.respondWith() isn't called, then this fetch handler is a no-op, and any additional registered fetch handlers get a shot at the request. Multiple fetch handlers are called in the order in which they're added via addEventListener, one at a time, until the first one calls event.respondWith().
If no fetch handlers call event.respondWith(), then the user agent makes the request exactly as it normally would if there were no service worker involvement.
The one tricky thing to take into account is that the determination as to whether to call event.respondWith() needs to be done synchronously inside each fetch handler. Anything that relies on asynchronous promise resolution can't be used to determine whether or not to call event.respondWith(). If you attempt to do something asynchronous and then call event.respondWith(), you'll end up with a race condition, and likely will see errors in the service worker console about how you can't respond to an event that was already handled.

Long polling using node.js to get database updates

I'm fairly new to Node JS,As I switched from java server pages to node mainly to implement server push technology.
I want to implement a simple application, Which will push the data to users if any new record insertion in Mysql database taken place.
And take database name as wst and table name is registered_people,Table consists of one column named users.
Know if any record is inserted into table it should notify that a new user is added to current users.
How can I achieve that.
Thanks for any help.
This is what libraries like socket.io were designed for. It makes server push operations trivial.
As far as how to actually trigger the server push, that can be more complicated based on how you're getting the data into the database. If all the data into and out of the mysql database goes through the same node application, it's fairly straightforward. Just raise an event when there is an insert into the table, and have your socket.io (or other push code) listen for those events. Then every time a user it added, the message gets sent.
If the database is updated from multiple applications things get a bit more tricky. You can poll the database for updates to the user table, and then fetch the latest users when it changes. You could do something like the following:
setInterval(function() {
getUserCount(function(userCount) {
if(userCount > originalUserCount) {
// We have new users!
// Get the latest user and send it to the connected browsers.
}
});
}, 1000);
This isn't very efficient, but doing a SELECT COUNT(id) FROM Users; shouldn't add much overhead to your database. A cleaner solution would be to use some sort of messaging queue. If you have multiple systems interacting on a single database, a messaging system can ensure that you give all of those systems a chance to subscribe to things that are happening in other parts of the system. In this case you can have your node app subscribe to new user messages in the system and send them to the browsers.
http://socket.io/ is what you are looking for.
As shown in he documentation, its very simple to listen on server using socket.io
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
And connect to it using,
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
You could achieve push by broadcasting the update to all connected clients using io.sockets.emit(object); whenever your database state is changed.
Its also possible to restrict the message to a specific set of clients by using rooms

How should I perform an asynchronous action within an accessor?

I have a simple accessor in my class:
public function get loggedIn():Boolean
{
var loggedIn:Boolean = somePrivateMethodToCheckStatus();
return loggedIn;
}
The API I'm now working with checks login status in an asynchronous fashion:
API_Class.addEventListener(API_Class.LOGIN_STATUS,onStatusCheck);
API_Class.checkLoginStatus();
function onStatusCheck(evt:API_Event):void
{
//evt.loggedIn == true or false
}
Is there a way I can perform this asynchronous request without exiting my accessor?
Simple answer: No, there is not. You will have to set up login verification in an asynchronous fashion.
I am a bit curious: Why is there a need to repeatedly poll the login status remotely? If your user logged in from within the Flash application, the status should be known. Same goes for logging out. If login and logout is handled from outside the Flash app, why not implement a notification mechanism (via JavaScript or socket connection)?
Also, if not being logged in prevents users from performing actions on the server, you could check for authorization on the server, whenever remote calls are made, and return an error if the session has expired. This would still be more efficient than repeatedly polling status info.
Not really, no. Flash runs in a single thread, and every function has to finish before events etc will be called.
One (sort of) solution would be to return three values; "yes", "no" and "pending". If it's pending the loggedIn()-method would start a check, and the client of that method should check again in a little while.
Another way would be to have the loggedIn-method send the answer to a callback instead. Eg "getLoggedInStatus(callback:Function)"
You may be interested in http://www.as3commons.org/as3-commons-eventbus/index.html
It is a handy lib that focuses on asynchronous jobs.