Twilio incoming call to client browser not working - browser

I can't get a browser to accept and answer an incoming call using Twilio JavaScript API.
Every time I call my Twilio number the call just hangs up and I don't see anything happen in my browser.
According to my JS I should get an alert popup when the call is connected/answered.
I've setup my Request URL correctly in my Twilio account and I've even checked the Twilio Debugger and don't see any error messages.
See code below for what I'm using in my browser app that should answer the incoming call.
FYI, I'm using PHP library to generate the Twilio Token. And I've double checked my Twilio API credentials - they're all correct (I've removed them in my code post below).
FYI2, I get the JS alert that the Twilio Device setup is ready.
FY3, I know the voice request URL is setup in Twilio correctly because if I change that code to Say Hello it says hello and then hangs up when I call my Twilio number.
<?php
###############
# Define Vars #
###############
include 'Services/Twilio/Capability.php';
$accountSid = 'A_xxxxxxxxxxxxxxxxxxx';
$authToken = 'f_xxxxxxxxxxxxxxxxxxx';
$appSid = 'AP_xxxxxxxxxxxxxxxxxxx';
$clientName = 'jack';
####################
# Get Twilio Token #
####################
$capability = new Services_Twilio_Capability($accountSid, $authToken);
$capability->allowClientOutgoing($appSid);
$capability->allowClientIncoming($clientName);
$token = $capability->generateToken();
?>
<!DOCTYPE html>
<html>
<head>
<title>Twilio Incoming Call Test</title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="//static.twilio.com/libs/twiliojs/1.1/twilio.min.js"></script>
<script>
Twilio.Device.setup('<?=$token?>');
Twilio.Device.ready(function(device) {
alert('ready!');
});
Twilio.Device.incoming(function(conn) {
conn.accept(incomingCall(data));
});
function incomingCall(data)
{
alert("Incomging Call:\n"+data);
}
Twilio.Device.error(function(conn) {
alert("Error:\n"+data);
});
</script>
</head>
<body>
<h1>Twilio Incoming Call Test</h1>
</body>
</html>
Here is my Voice Request URL code:
<?php
header('Content-type: text/xml');
echo '<?xml version="1.0" encoding="UTF-8"?>';
?>
<Response>
<Dial>
<Client>jack</Client>
</Dial>
</Response>

I figured out what the issue was. Pretty simple. The account sid and auth token where set to my sandbox/test credentials and when I changed this to live credentials it worked. Problem solved!

Related

How do I get a Electron app object through HTML (script tag)?

So I have here this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Oh no!</title>
</head>
<body>
<label>Oh dear. A serious error occurred and the app needs to restart. Press the button below to restart.</label>
<br>
<button onclick="restart()">Restart</button>
<script>
const { app } = require("electron")
function restart() {
app.relaunch()
app.exit()
}
</script>
</body>
</html>
And now, when the app receives an unhandled error this will show... but when the user clicks the button, the app doesn't restart so how would I make the app restart?
You can't get the app object without using preload.js and neither is directly getting the app object safe. There is a method to do the above using preload.js and ipcRenderer which are pure Electon APIs
In electron (even in web development), there is server-side code and browser-side code. The code written in between the script tags in your snippet is server side code which will fail to execute in browser side.
Server-side code in your case is in NodeJS Backend and browser-side code is the one which is the HTML Page and its own javascript.
So to close the window (which only NodeJS can do, i.e., the backend) you need to use Electron's ipcRenderer which helps string based communication between the browser-side javascript and the server-side javascript.
While creating a browser window in electron using new BrowserWindow(options) where options is an object. Define the object as:
options = {
webPreferences: {
preload: preload.js, //You need to create a file named preload.js (or any name) in your code
nodeIntegration: true,
contextIsolation: false,
}
}
Now in a new file called preload.js:
window.ipcRenderer = require('electron').ipcRenderer;
In your snippet you added const { app } ... which should be done this way to inject the javascript using a preload property in the object.
Now in the main app.js file (whatever you named maybe index.js) where you created the browser window:
const ipc = require('electron').ipcMain; //Add to your pre-existing code
ipc.on("close-app", (event, message) => { //"close-app" can be anything but, you need to use the same key in the send message side (later in this answer)
browserWindow.close(); //If you named the browserwindow as browserWindow
});
Now in your HTML (i.e., send message side)
...
<script>
window.ipcRenderer("close-app", ""); //Second parameter is used if you want to send some extra message. The extra message can be viewed in the server side from the message parameter in the app.js code (just above this paragraph)
</script>
This is a bit difficult if you are doing it for the first time.
I've added more articles which will help you clear your confusions:
Highlight about server-side and browser-side code
Relation with socket.io communication in NodeJS

How does one make Oauth2.0 work with a nologin msgraph (Sharepoint) client?

Here are the program imports.
import com.google.gson.Gson;
import com.microsoft.graph.auth.confidentialClient.ClientCredentialProvider;
import com.microsoft.graph.auth.enums.NationalCloud;
import com.microsoft.graph.httpcore.HttpClients;
import okhttp3.*;
The program invokes the ClientCredentialProvider constructor to create an authProvider.
ClientCredentialProvider authProvider = new ClientCredentialProvider(...);
The program creates a client to send a post request to the server to get an access token.
OkHttpClient client = HttpClients.createDefault( authProvider );
A subroutine uses the access token in a get request in an effort to obtain a site ID.
request = new Request.Builder()
.url(target)
.header("Authorization",
"Bearer " + tokenResponse.get_access_token())
.get()
.build();
Here is the code that transmits the get request.
response = client.newCall( request ).execute();
Here is the result that comes back from the server.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Bad Request</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Bad Request - Invalid Header</h2>
<hr><p>HTTP Error 400. The request has an invalid header name.</p>
</BODY></HTML>
When I manually send the get request from Postman or Charles, it works fine.
When I look at the outgoing request just before it is sent, I find that the okhttp3 code has tacked on a few more headers including a second Authorization header that uses a slightly different token.
How should the program configure okhttp3 classes to stop this interception and rewriting of the header section of the outgoing request?

How do you use an Oauth callback between React and Express?

I'm trying to integrate MailChimp's API into my React App which will allow users to authorize their MailChimp accounts for use in my app. I haven't found a tutorial on it, so I'm following this tutorial which uses only express: https://www.codementor.io/mattgoldspink/integrate-mailchimp-with-nodejs-app-du10854xp
I've gone through Mailchimp to set up my app/my client secret/client id, etc:
Redirect URI
```http://127.0.0.1:3001/mailchimp/auth/callback````
I kept the same express code as the tutorial, except I put my client secret in a .env file:
server.js
const querystring = require('querystring');
const mailchimpClientId = `${process.env.MC_CLIENT}`
app.get('/mailchimp/auth/authorize', function (req, res) {
res.redirect('https://login.mailchimp.com/oauth2/authorize?' +
querystring.stringify({
'response_type': 'code',
'client_id': mailchimpClientId,
'redirect_uri': 'http://127.0.0.1:3000/mailchimp/auth/callback'
}));
});
However, in the tutorial, the callback function is in an HTML file written like this:
<!doctype html>
<html>
<head>
<title>Integrate MailChimp</title>
</head>
<body>
<a class="btn btn-primary" href="/mailchimp/auth/authorize">Connect with MailChimp</a>
</body>
</html>
I've added this (using JSX syntax):
MailChimp.jsx
class MailChimp extends Component {
render() {
return (
<div>
<h1>MailChimp Auth</h1>
<a href={'http://127.0.0.1:3000/mailchimp/auth/authorize'}>Mailchimp</a>
</div >
)
}
}
export default withRouter(MailChimp);
On clicking that link inside my React App's route localhost:3001/mailchimp, I'm sent to mailchimp where I sucessfully login with my account (not the one requesting permission) and I am returned to the react app.
However, I'm getting the following error:
GET /mailchimp/auth/callback 404 2.818 ms - 162
Failed to load resource: the server responded with a status of 404 (Not Found)
I've scoured the web trying to find a working example of using React & Express for MailChimp Oauth for app authorization but I haven't found one. My question is, did I set something up wrong in the redirect, or is there a better recommendation for handling this request in React?
The 404 error is saying that you don't have a route that maps to /mailchimp/auth/callback. Looks like from your code you haven't written that.
Unless you haven't provided the code for it, you need the route handler mentioned with the code in the tutorial:
app.get('/mailchimp/auth/callback', function(req, res) {
request.post('https://login.mailchimp.com/oauth2/token')
.send(querystring.stringify({
...
}

CORB blocking JSONP GET Request

Attempting to tap http://www.anagramica.com/api to determine all words that can be made from an inputted word. As expected cross-origin policy does not allow using a normal GET request to receive the JSON data. On the anagramica homepage, JSONP is mentioned. I attempted implementing this below.
<!DOCTYPE html>
<html>
<head>
<script src="jquery-3.3.1.min.js"></script>
<title>word play</title>
</head>
<body>
<h1>Speak A Word</h1>
<script>
document.body.onclick = function() {
$.getJSON("http://www.anagramica.com/all/dog?callback=?",function(json){
console.log(json);
});
}
</script>
</body>
</html>
This resulted in the following error.
"Cross-Origin Read Blocking (CORB) blocked cross-origin response http://www.anagramica.com/all/dog?callback=jQuery33106950206857384036_1542003732614&_=1542003732615 with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details."
Relevant posts here: Loading cross-domain endpoint with jQuery AJAX
Make cross-domain ajax JSONP request with jQuery
Wondering why JSONP is not working in this case?

How Do I Broadcast Json To Users via Node JS server?

Goal: After user saves data to my mysql DB, a JSON teaser of the newly saved content is broadcasted to all users.
What are some quick and dirty solutions to achieve this? I am working with php/mysql. Got a taste of Socket.io, and a node.js server listening on the side....
Any good links would be greatly appreciated.
Background--------
After many years of working with php, I have decided to jump onto the NodeJS Bandwagon- and have no clue to do anything other than the vanilla "Hello World".... This is my starting point. Thanks again!!
If you would like to broadcast to all users including yourself, then you should use:
io.sockets.emit('global', {data: 'this will be received by everyone'});
If you would like to broadcast to all users without yourself being notified, then you should use:
socket.broadcast.emit('Hello everyone!');
Hope this helps!
Can you define what you mean by "broadcast" in this context?
Do you want to display an alert on a web page?
If so, do you wish to alert only those users who are currently viewing pages on your site or those who come to your site during a period of time? If the later, do you care if the alert appears to a single user more than once?
Socket.IO is one way to transmit/receive messages to/from a remote browser, but without a client-side handler that has some way of displaying your message to the user, it's kind of moot.
I've found now.js to be a far better abstraction of browser<-->server communications as shown in this possible solution that will display an alert on pages currently viewed by your users:
Step 1: Install now.js (remove the -g if you don't want now installed globally):
npm install -g now
Step 2: Create a HTTP server and cause it to listen on a port 80
var PORT=80,
http=require('http'),
nowjs=require('now'),
app=http.createServer(requestHandler).listen(PORT), // create your server
everyone=nowjs.initialize(app); // initialize now on your listening server
function alertUsers(msg){ // sends msg to showAlert() callback on clients
everyone.now.showAlert(msg);
}
function requestHandler(req,res) {
...
...
/*
* Ok, something has happened you want to inform your currently
* connected users of...
*
* if the thing can happen as a result of a request, do it here
*/
var msg="Whoohoo! Something's happened!";
alertUsers(msg);
...
...
}
// or if it happens somewhere else, just call alertUsers() there.
Step 3: And then in the browser-side HTML:
<html>
<head>
<style type="text/css">
.alert { background-color:red; color:white; font:24pt bold sans-serif; }
.hidden { display:hidden; visibility:none; }
</style>
</head>
<body>
<div id="alert" class="alert hidden">
<div class="main-content">
<!-- main page content -->
</div>
<script type="text/javascript" src="...load jQuery here..."></script>
<script src="/nowjs/now.js"></script> <!-- *SEE NOTE BELOW -->
<script type="text/javascript>
$(document).ready(function(){
// after the document has finished loading
now.showAlert=function(msg){ // define your callback function
$('#alert').removeClass('hidden').text(msg);
};
});
</script>
</body>
</html>
* Note that the <script src="/nowjs/now.js"></script> request is magic in that the referenced file doesn't really exist server-side at that location. By running nowjs.initialize() on your http server instance, you're setting things up so that nowjs will intercept the request for /nowjs/now.js and serve it back to the client without invoking your requestHandler().
Also, this solution does not display your alert to anyone who connects after the alert is sent from the server. If you want to do that, you'll need to do something different.

Resources