Twilio Client Making a Call status - node.js

I am writing a node.js application to make a call or send sms to users.
However, after making a call or sending SMS, I wish to know its status.
client.makeCall({
to:'+358xxxxxxxxx',
from: '+15005550006',
url: "https://demo.twilio.com/welcome/voice/",
}, function(err, responseData) {
}
I know on responseData, but its status indicates 'Queued'
I wish to know the real call status after the actual call takes place.
Is there anyway to do so?

I haven't used twilio node.js client, but here's some that might help you -
You are not getting the call status because the voice call or SMS wont complete immediately when the API call is returned. You need to make subsequent requests again until the status is complete (polling) or configure twilio/pass parameters so that twilio will notify you when the call is actually complete (push).
To let twilio push the status to your server, pass application_sid or status_callback field while making the call request as explained in the API doc http://www.twilio.com/docs/api/rest/making-calls.
To manually request the call status, do the get request from the client after few seconds (or whatever time you think call takes to complete) perhaps using a timer until you get the status you want. http://www.twilio.com/docs/api/rest/call
Something like below: (Note: I have not tested or verified this)
client.calls(<sid>).get(function(err, call) {
console.log(call.status);
});

Related

Fetch event never gets triggered in Chrome extension service worker. Is this expected?

What I want to do
I'm trying to intercept a third party website's fetch events and modify its request body in a Chrome extension. Modifying the request body is not allowed by the chrome.webRequest.onBeforeRequest event handler. But it looks like regular service workers do have the ability to listen for and modify fetch events and manually respond to the request using my own response, which means I should be able to intercept the request, modify the body, send the modified request to the API, and then respond to the original request with my modified request's response.
The problem
It looks like neither of these event handlers ever get triggered, despite plenty of fetch events being triggered by the website, as I can see in the Network panel.
// background.js
self.onfetch = (event) => console.log(event.request); // never shows
// or
self.addEventListener("fetch", (event) => {
console.log(event.request); // never shows
});
I can verify that the service worker is running by seeing other console.logs appearing in the service worker console, both top-level logs as well as logs triggered by the "install" event
// background.js
console.log(self); // works
self.addEventListener("install", (event) => {
console.log(event); // works
});
Hypothesis
Do the fetch event handlers not get triggered because extension service workers are not allowed access to these for security reasons? That would make sense, I just haven't seen this documented anywhere explicitly so it would be good to know if this is indeed a platform limitation or if I'm doing something wrong.
Alternate solutions?
If this is indeed a limitation of the extensions platform, is there any way other way I can use a Chrome extension to modify request bodies on a third party website?

How to programmatically manipulate voice in real time while dialing using Twilio?

I have a small Twilio app that calls a real phone number (e.g. +3333333) whenever my Twilio number (e.g. +22222222) is called using my personal number (e.g. +1111111). I implement this using the following Twilio function:
exports.handler = (context, event, callback) => {
const twiml = new Twilio.twiml.VoiceResponse();
twiml.dial("+3333333");
return callback(null, twiml);
};
Now when the owner of +3333333 picks up his phone, a call connection is established between the caller (+1111111) and the target (+3333333).
How can I intercept speeches in this call, in real-time, by running a function whenever either the caller (+1111111) or the target (+3333333) speaks, to do things such as changing voice, filtering profanity, etc?
I have tried using <Gather> and <Say> TwiML verbs in my Twilio function but these will only get triggered after the call has ended or hung up.
You can actually achieve this with Twilio now. You can receive and send audio streams using the <Connect><Stream> TwiML. <Stream> allows you to receive and send audio to the call over a websocket connection in real time.
To change the audio in between, you would want to connect the callers just to the <Stream>, not to each other, and relay the audio from one call, through the websocket and whatever processing you want to do to it, and then out through the websocket connected to the other call (and vice versa).
I don't have more information on how to do that, as I've not seen it done. But it's possible in theory.

Dialogflow fulfillment with Please wait functionality

I am working on custom event integration which will call one by one three event as I am using third party API which is taking more then 11 sec, I need a functionality where user will receive message from first intent saying "Please wait", meanwhile our 2nd and 3rd intent will wait for the API response, as soon as we get the response from our API we will return it to Dialogflow Agent.
In the below code I want to send message(Please wait) from the Demo intent then the other two custom event will call intent(followOne, followUpTwo) this intent will be process for specific time, after that it will send one more message with actual API response.
async function Demo(agent){
// here we call our API and wait to get an response and will set that response in Redis server
await customsleep(1500);
agent.add('Please wait');
agent.setFollowupEvent('followUpOne');
}
async function followOne(agent){
await customsleep(4500);
agent.setFollowupEvent('followUpTwo');
}
async function followUpTwo(agent){
// in this intnet will get response from Redis server which we stored from intnet Demo, This response will return to the user
await customsleep(4700);
agent.add('here we go');
}
Is there anyway to implement this kind of functionality where we can send message(Please wait). Once we get the response from API we can return it to the Dialogflow Agent.
To my knowledge you can't send any message while following up an event. (it will be ignore)
If you want to provide a message you should :
Step 1 :
- call the third party api
- send a message with a quick reply : "Please Wait" + qr: "Click here to display the answer"
Step 2 :
- check if the third party api has answered
- yes : return the answer
- no : follow up a waiting event

Twilio client js status busy/cancelled no fired

I'm using the Twilio client js in my browser in order to make calls.
In the server I build the Twiml:
const dial = twiml.dial({
/*action: `http://270311bb.ngrok.io/twilio/callend`,*/
callerId: availableNum.phoneNumber || availableNumbers[0].phoneNumber
}, (n) => {
n.number(request.body.number, {
statusCallback: `http://270311bb.ngrok.io/twilio/${request.body.agentId}/status`
});
});
I also tried with the 'action' parameter.
In my status/callend route I get the callstatus only as completed or no-answer, even if the called number is busy, or not connected.
Twilio developer evangelist here.
The StatusCallbackEvent's that you can receive from a call are only initiated, ringing, answered, or completed. Busy or not connected calls are also completed calls. Can you try querying the call from the API when you receive the completed event and see what status the actual call in.

node.js wait for response

I have a very limited knowledge about node and nob-blocking IO so forgive me if my question is too naive.
In order to return needed information in response body, I need to
Make a call to 3rd party API
Wait for response
Add some modifications and return JSON response with the information I got from API.
My question is.. how can I wait for response? Or is it possible to send the information to the client only when I received response from API (as far as I know, connection should be bidirectional in this case which means I won't be able to do so using HTTP).
And yet another question. If one request waits for response from API, does this mean than other users will be forced to wait too (since node is single-threaded) until I increase numbers of threads/processes from 1 to N?
You pass a callback to the function which calls the service. If the service is a database, for example:
db.connect(host, callback);
And somewhere else in the code:
var callback = function(err, dbObject) {
// The connection was made, it's safe to handle the code here
console.log(dbObject.status);
res.json(jsonObject, 200)
};
Or you can use anonymous functions, so:
db.connect(host, function(err, dbObject) {
// The connection was made, it's safe to handle the code here
console.log(dbObject.status);
res.json(jsonObject, 200)
});
Between the call and the callback, node handles other clients / connections freely, "non-blocking".
This type of situation is exactly what node was designed to solve. Once you receive the request from your client, you can make a http request, which should take a callback parameter. This will call your callback function when the request is done, but node can do other work (including serving other clients) while you are waiting for the response. Once the request is done, you can have your code return the response to the client that is still waiting.
The amount of memory and CPU used by the node process will increase as additional clients connect to it, but only one process is needed to handle many simultaneous clients.
Node focuses on doing slow I/O asynchronously, so that the application code can start a task, and then have code start executing again after the I/O has completed.
An typical example might make it clear. We make a call to the FB API. When we get a response, we modify it and then send JSON to the user.
var express = require('express');
var fb = require('facebook-js');
app.get('/user', function(req, res){
fb.apiCall('GET', '/me/', {access_token: access_token}, function(error, response, body){ // access FB API
// when FB responds this part of the code will execute
if (error){
throw new Error('Error getting user information');
}
body.platform = 'Facebook' // modify the Facebook response, available as JSON in body
res.json(body); // send the response to client
});
});

Resources