It is not immediately obvious how one would go about adding Network Traversal Service if you are using Twilio Video.
The example of using the Network Traversal Service here shows token creation using :
var client = require('twilio')(accountSid, authToken);
client.tokens.create({}, function(err, token) {
process.stdout.write(token.username);
});
However the basic video example here shows a completely different method of token creation using the AccessToken lib.
var token = new AccessToken(
process.env.TWILIO_ACCOUNT_SID,
process.env.TWILIO_API_KEY,
process.env.TWILIO_API_SECRET
);
Twilio developer evangelist here.
The Twilio Video service actually uses the Network Traversal Service under the hood, so you don't need to worry about adding it in yourself. The AccessToken method is the most up to date version of granting access to the client side SDKs, so I would continue to use that.
Let me know if that helps at all.
Related
Ok guys, I've been viewing twilio tutorials for the last couple hours and I seem to just not get it. Can someone give me a basic rundown on how to do the following?
I want to create an app that uses the microphone/speaker of my computer to receive a call.
I have a twilio account with a twilio voice phone # but I just don't seem to get how to connect a JS Device object to a phone #. I think it has something to do with a capability/auth token but can someone give me a step by step on how a phone # can be called and the headset will receive a voice call and begin the conversation. The tutorials show how you can make twilio speak a written statement in twiML but I don't understand how to make it make an actual voice call.
My current guess is that I need to do the following in the browser to accept a call. But I'm not sure what needs to be inside the token.
//I don't know what needs to be in the token in order to connect this
//web page twilio 'Device' to. I use c# but if you have a node.js or php example that would be fine
fetch('https://mybackend/getPhoneToken').then((token) => {
const device = new Device(token);
device.on('incoming', call => {
call.accept();
});
});
Thank you for your help.
This is my first answer, let's see if I can help.
First you have to generate the access token by giving the Voice grant.
Generate access token with your account sid, API key ,API key secret and identity.
access_token = AccessToken(<Account_sid>, <api_key>,<api_secret>, identity=identity)
Note: Identity Should be unique for each user. You can put identity as twiliophonenumber_userid
Grant the Voice incoming Access.
voice_grant = VoiceGrant(outgoing_application_sid=<twiml_sid>,incoming_allow=True)
Add grant to the access_token
access_token.add_grant(voice_grant)
Initialise the Twilio device with this access_token. Then you can make the incoming call to the twilio number and receive the call on browser.
You just need only one Twiml App for all the twilio phone numbes. Create a Twiml App with Request Url and method. (Whenever the js device make/receive calls, then twilio will send a request to this URL to get further instructions)
In the above Request URL function, you have to tell twilio what needs to do with the request. Here is a sample function
function handle_calls():
if outgoing_call:
dial.number(customer_phone_number)
else:
# handle incoming call
dial.client(identity) # This is the same identity which we have given while generating access_token. This will trigger "incoming" event on Js device.
To differentiate between outgoing / incoming calls, you can send extra parameters to twilio while making outgoing calls and handle the request accordingly in the above function (pt. 6). See below sample function.
var params = {"direction":"Outgoing"} # Based on this parameter you can differentiate between outgoing/incoming calls.
device.connect(params)
You can setup status_callback events to better handle the call progress. have a look at this article...https://www.twilio.com/docs/voice/twiml/number#attributes-status-callback-event
Have a look at this article, you can get some more information - https://www.twilio.com/blog/generate-access-token-twilio-chat-video-voice-using-twilio-functions
Problem: I am trying to pair two users together in Twilio's Programmable Video API for iOS on a single call using a server generated Twilio Access Token.
Steps taken:
I have setup the web server that generates tokens successfully on node.js and deployed to Heroku. Each time the connect button is pressed on the client app, the token URL (web server URL) is visited, token is generated and client app uses token to create room.
This creates a problem because each user connecting generates a new token for each time pressing connect - so no two users can ever connect together.
How can I create a token that relies on the room and not the user / a token that is generated each time a room is made, and not each time a user connects?
For additional background, I leveraged the Twilio Quickstart app for Swift iOS and swapped the localhost URL for the my Heroku hosted server. The first code shown is from the server. The second is from the client-side Swift app.
function tokenGenerator(identity, room) {
const token = new AccessToken(
process.env.TWILIO_ACCOUNT_SID,
process.env.TWILIO_API_KEY,
process.env.TWILIO_API_SECRET
);
// Assign identity to the token
token.identity = identity;
// Grant the access token Twilio Video capabilities
const grant = new VideoGrant();
grant.room = room;
token.addGrant(grant);
// Serialize the token to a JWT string
return token.toJwt();
}
do {
accessToken = try TokenUtils.fetchToken(url: tokenUrl)
print(accessToken)
} catch {
let message = "Failed to fetch access token"
logMessage(messageText: message)
return
}
Each grant.room uses a room. The Twilio Programmable Video API default behavior is, if the room is blank, create a randomly generated room id (called sid in the docs). Note that, in my app, even when I specify a room across two different machines, I cannot connect because there are two separate access tokens. When this happens, one user is disconnected and the other connects. What steps can be taken to fix this use case? -- Thank you all
I'm currently using Cloud Firestore as my backend for a mobile app. I've got basic payments working with Stripe with cloud functions programmed with node.js, however, when setting up for Stripe Connect, the process requires a redirect uri (which I input in the settings of my Stripe account).
I have very little experience with redirects and callbacks. What is the address that I can use as a redirect uri? How does this address get established?
It would also be great to hear your thoughts on how I would go about capturing the information from the redirect through a firestore trigger (node.js).
Any help would be much appreciated!
Thank you.
One solution is to use an HTTPS Cloud Function.
As explained in the doc, "after you deploy an HTTPS function, you can invoke it through its own unique URL.". The URL will look like: https://us-central1-.cloudfunctions.net/stripeWebhook and you just have to declare it in your Stripe settings.
In the Cloud Function, you will be able to get the values passed to the body of the HTTP request, as follows:
exports.stripeWebhook = functions.https.onRequest((req, res) => {
const orderId = req.body.data.object.metadata.orderId;
const sourceId = req.body.data.object.id;
const sourceType = req.body.data.object.type;
....
});
and also to write to Firestore, in order to update the record corresponding to the paiement. You may watch the following official video for an example:https://www.youtube.com/watch?v=7IkUgCLr5oA&t=1s&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM&index=3
I want to automatically upload videos to YouTube without user involvement so I've created a service account, jumped through the hoops, all was looking great, then the upload, chunk one, is attempted and my code bombs with this Google_Exception exception:
"Failed to start the resumable upload (HTTP 401: youtube.header, Unauthorized)"
I then dug and found on the YouTube API v3 error information:
https://developers.google.com/youtube/v3/docs/errors
"This error is commonly seen if you try to use the OAuth 2.0 Service Account flow. YouTube does not support Service Accounts, and if you attempt to authenticate using a Service Account, you will get this error."
Is this correct? I cannot use a service account to upload video to YouTube automatically?
(that was a waste of a couple of days hard work!)
Yes, it is correct.
The way forward is to do a manual authorisation and grab the resultant 'refresh token' and then use that for any automated uploads.
Ensure to add the refresh token to the PHP Google_Client object prior to any other action.
I am now automatically uploading to YouTube.
For anyone attempting to do this today, be aware that any uploads will be set as "Private (Locked)" if they are uploaded using the API unless/until the app is submitted for verification and approved.
https://github.com/porjo/youtubeuploader/issues/86
YouTube requires verification of the OAuth App/credentials used for upload, otherwise the video will be locked as Private.
It's possible to get an app approved, but if you're doing a personal project, it's less likely.
More: https://github.com/porjo/youtubeuploader/issues/86
Yes you can use Service Accounts for Youtube. One way is to add the service account to a CMS where the content owner is part of. When you retrieve an access_token for the Service Account, you can work with the content owners videos.
Looks like this, using Javascript and a npm package:
import { google } from 'googleapis';
const youtube = google.youtube('v3');
const fetchYoutubeData = async (keyfile, scopes) => {
const auth = new google.auth.GoogleAuth({
credentials: keyfile,
scopes,
});
const accessToken = await auth.getAccessToken();
const { data } = await youtube.videos.list({
part: ['snippet'],
id: 'YOUR_VIDEO_ID',
access_token: accessToken
});
return data;
}
Note that the keyfile is the JSON you downloaded from Gcloud when creating the service accounts keys. NOT the path pointing to the file! If you want to use path, use this instead:
const auth = new google.auth.GoogleAuth({
keyFile: 'PATH_TO_KEYFILE_IN_FILE_SYSTEM',
scopes: ['READ_STUFF', 'WRITE_STUFF'],
});
Further reading on server-server authentication using Oauth2
I'm using Pusher to add realtime functionality to my app. Is there a way to provide my users with realtime functionality through an API? I'm using private and presence channels, so connections to these need to be authenticated. Has anyone worked with Pusher and provided some sort of API to their users?
I'm doing this using Rails 3.1.
The solution here is to give the users you want to be able to access your data your app_key (not app_secret). They can then connect to Pusher and try to subscribe to your channels. They'll need to use JSONP authentication which makes a call to your server where you can authenticate the request to the private or presence channels.
Pusher.channel_auth_endpoint = 'http://yourserver.com/pusher_jsonp_auth';
Pusher.channel_auth_transport = 'jsonp';
var pusher = new Pusher('YOUR_APP_KEY');
var channel = pusher.subscribe('private-your-channel');
channel.bind('your_event', function(data) {
// do something here with data
});
In your authentication you'll need to check the referrer (domain) to see if you've given them access to your data along with what they are subscribing to.
You could also wrap this JavaScript up in your own library so that a subscription_error (authentication error) disconnects the client from Pusher.
Hope this helps. You can always drop an email to support#pusher.com too.