I am using the sample Video application pulled from GitHub. I am using a node.js server to supply the sample application with the access token. When I use the Twilio Console to generate a video access token and put it in my Node.js server as a literal and return it I am able to run the example application and connect to a room. If I use the sample token generation code in my Node.js server I get 'Invalid Access Token' back in an exception in the onDisconnected method in the Room.Listener.
The following code is what is running in the server to create the access token, I also found a different sample which I tried as well. I have gone back and verified that my data values for the account SID and the API keys are correct. I have a similar method running returning the VoiceGrant access token and that is working, but something about this VideoGrant one is off, I just do not see it.
// ***********************************************************************************
// ***********************************************************************************
// Video Access Token
// ***********************************************************************************
// ***********************************************************************************
var videoCallAccessToken = function(request, response) {
console.log('/twilio/video/accessToken');
var accessToken = makeVideoAccessToken();
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end(accessToken);
console.log(accessToken);
};
app.get('/twilio/video/accessToken', videoCallAccessToken);
var makeVideoAccessToken = function() {
const AccessToken = twilio.AccessToken;
const VideoGrant = AccessToken.VideoGrant;
const grant = new VideoGrant({configurationProfileSid: accountData.videoConfigurationProfileSid});
const accessToken = new AccessToken(accountData.sid, accountData.videoApiSid, accountData.videoApiSecret);
accessToken.identity = 'ABC123';
accessToken.addGrant(grant);
return accessToken.toJwt();
};
FYI...I plan to alter the identity generation, but have not got there yet.
Thanks,
Adding this from my comment as an answer to close this question out, the issue was that the example code was flawed...
Ok, thought I had waited long enough prior to actually sending this, but apparently not. The issue is the example does not work in that the value passed into the VideoGrant constructor needed to have the attribute name quoted, so {configurationProfileSid: accountData.videoConfigurationProfileSid}); needed to be {'configurationProfileSid': accountData.videoConfigurationProfileSid}); Glad I finally found that, wasted a ton of time on it, but at least it is working properly now.
Related
The documentation isn't perfectly clear on this, I am able to hardcode in my token and get it to work as such
const socketToken = 'mytokenrandomlongstringofchars';
//Connect to socket
const streamlabs = io(`https://sockets.streamlabs.com?token=${socketToken}`, {
transports: ['websocket']
});
Then listen in for events as such
streamlabs.on("event", (eventData) => {
if (eventData.for === "streamlabs" && eventData.type == "donation") {
var donobj = eventData.message;
var dononame = donobj[0].from;
var donomessage = donobj[0].message;
document.getElementById("alert-message").innerHTML = dononame;
document.getElementById("alert-user-message").innerHTML = donomessage;
console.log(donobj);
}
});
The API uses oAuth 2 to allow users to connect and this is where I'm stuck and the snippets in the documentation aren't exactly helping, I'm supposed to send the user to an authorization link that looks something like this
streamlabs.com/api/v1.0/authorize?client_id=CLIENT-ID-HERE&redirect_uri=REDIRECT-URI&response_type=code&scope=SOME+SCOPES+HERE
as per this stack overflow answser, then once they accept the authorization they are redirected by to the redirect uri that I specified when registering the app alongside a code, that looks something like this
my.site/callback?code=randomstringofcharacters.
I'm supposed to send a POST request to https://streamlabs.com/api/v1.0/token with that code to get an access token, then use that access token to send a GET request to https://streamlabs.com/api/v1.0/socket/token so that I can finally get the web socket token that I could use to listen for events, where I have no clue where to procede is how to get the code from the redirected URL, if I'm understanding the process correctly then I should be able to manage the other steps, but how to I get the code in the first place?
I don't know if this is what you are asking for, but you can add authorized users on the streamlabs website, under the app settings. Let me know if I need to clarify.
I'm currently using firebase for the backend of a project I'm working on. In this project, the client authenticates using the firebase-twitter sign in method. For the purpose of security, I'm trying to minimise the amount of communication between the client and backend when it comes to auth data. In jest of this, I'm wondering if there is a way to access the auth data i.e. the user's twitter key/secret (as well as things like the user's twitter handle) from the server-side after the user authenticates ? I figured there might be a way as the authentication happens through twitter + firebase, but I'm struggling to find the exact solution I need in the documentation (been stuck on this for a week now) so was hoping someone else already knows if this is possible and how :) cheers
Maybe not the best way, but you can try: on client side use RealTime database and add a new entry every time the user log in. They call this 'realtime triggers'.
You don't mention what front are you using, but on ionic is something like:
firebase.auth().onAuthStateChanged(function(user) {
if (user)
this.db.addLogin(user.uid)
});
On database class function:
addLogin(uid){
let path = "/logins/"
let ref = this.db.list(path)
let body = {uid: uid}
return ref.push(body)
}
On the server side, listen the path using child_added
var ref = db.ref("logins");
ref.on("child_added", function(snapshot, prevChildKey) {
var newPost = snapshot.val();
console.log("Uid: " + newPost.uid);
console.log("Previous Post ID: " + prevChildKey);
});
More information about triggers
I am using xero as my accounting software. I have one requirement that part of my application need to be integrated with xero to perform automation. Using the nodejs sdk seems so easy, but the fact is i cannot connect to xero even using the simplest example. Here is the code:
const xero = require('xero-node');
const config = {
"userAgent": "Firefox",
"consumerKey": "<MY_CONSUMER_KEY>",
"consumerSecret": "<MY_CONSUMER_SECRET>",
"privateKeyPath": "./privatekey.pem"
};
const xeroClient = new xero.PrivateApplication(config);
xeroClient.core.contacts.getContacts()
.then(contacts => {
console.log(contacts);
}).catch(err => {
console.log(err);
});
The code does nothing and prints no error. Anyone ever deal with this problem?
The most likely reason is that your privatekey is invalid. If you put these lines(https://github.com/XeroAPI/xero-node/pull/169/files) into your module then it will check it first.
You could also copy a few of those lines and validate your privateKey.
At the moment the SDK swallows the exception when the key is invalid.
Also, please make sure you are running server side - not browser side.
Solved. I need to add following code:
if (config.privateKeyPath && !config.privateKey)
config.privateKey = fs.readFileSync(config.privateKeyPath);
I want to create a google docs sheet within my alexa skill, that is written in Node.js. I have the enabled the google API, I set the required scope in amazon dev portal, I actually can log into the google account (so the first few lines of the posted code seem to work), and I do not get any error messages. But the sheet is never created.
Now the main question would be whether anyone can see the problem in my code.
But I would also have an additional question I would be very interested in: since I use account linking, I can not try that code in the Alexa test simulator, but have to upload it to Alexa before running it, where I can not get any debug messages. How does one best debug in that way?
if (this.event!== undefined)
{
if (this.event.session.user.accessToken === undefined)
{
this.emit(':tellWithLinkAccountCard','to start using this skill, please use the companion app to authenticate on Google');
return;
}
}
else
{
this.emit(':tellWithLinkAccountCard','to start using this skill, please use the companion app to authenticate on Google');
return;
}
var oauth2Client = new google.auth.OAuth2('***.apps.googleusercontent.com', '***', '***');
oauth2Client.setCredentials({
access_token: this.event.session.user.accessToken,
refresh_token: this.event.session.user.refreshToken
});
var services = google.sheets('v4');
services.spreadsheets.create({
resource : {properties:{title:"MySheet"}},
auth : oauth2Client
}, function(err,response) {
if( err ) {
console.log('Error : unable to create file, ' + err);
return;
} else {
console.dir(response);
}
});
Edit: I tried just the lower part manually, and could create a spreadsheet. So the problem seems indeed to be retrieving the access token with "this.event.session.user.accessToken" .
I find it is much easier to debug issues like this using unit tests. This allows rerunning code locally. I use NPM and Mocha and it makes it easier to debug both custom and smart home skills. There is quite a bit of information available online about how to use NPM and Mocha to test Nodejs code, so I won't repeat that here. For example, refer to the Big Nerd Ranch article. It makes it a bit more complex to setup your project initially, but you'll be glad you did every time you hit a bug.
In this example, I would divide the code in half:
The first half would handle the request coming from Alexa and extract the token.
The second half would use the token to create the Google doc. I would also pass the name of the doc to create.
I would test the 2nd part first, passing in a valid token (for testing only) and a test doc name. When that is working, at least you'd know that the doc creation code was working, and any issues would have to be with the token or how you're getting it.
Once that was working, I would then create a test for the first part.
I would us a hardcoded JSON object to pass in as the 'event', with event.session.user.accesToken set to a the working test token used in the first test:
'use strict';
var token = '<valid token obtained from google account>';
let testEvent = {
'session': {
'user': {
'accessToken': token
}
}
}
I'm developing an app using NGinx + Node.js + Express + Firebase that simply takes input from a mobile app and stores it to Firebase, optionally uploading files to S3.
In its simplest terms, the "create" function does this
Validates input
Formats the input Checks if there is a file uploaded
(via the multer plugin) and stores it
If there was a file, upload
to Amazon S3 and delete the source file (it's important to note I was
encountering this issue before the inclusion of S3).
Create the item
by pushing into the items reference on Firebase
Create the item for
the user by pushing into the user_items reference on Firebase.
There are a few other functions that I have implemented as an API.
My trouble is coming from an intermittent spike in CPU usage, which is causing the nginx server to report a gateway timeout from the Node.js application.
Sometimes the server will fall over when performing authentication against a MongoDB instance, other times it will fall over when I'm recieving the input from the Mobile app. There doesn't seem to be any consistency between when it falls over. Sometimes it works fine for 15+ various requests (upload/login/list, etc), but sometimes it will fall over after just one request.
I have added error checking in the form of:
process.on('uncaughtException', function(err) {
console.error(err.stack);
});
Which will throw errors if I mistype a variable for example, but when the server crashes there are no exceptions thrown. Similarly checking my logs shows me nothing. I've tried profiling the application but the output doesn't make any sense at all to me. It doesn't point to a function or plugin in particular.
I appreciate this is a long winded problem but I'd really appreciate it if you could point me in a direction for debugging this issue, it's causing me such a headache!
This may be a bug in the Firebase library. What version are you using?
I've been having a very similar issue that has had me frustrated for days. Node.js + Express + Firebase on Heroku. Process will run for a seemingly random time then I start getting timeout errors from Heroku without the process ever actually crashing or showing an error. Higher load doesn't seem to make it happen sooner.
I just updated from Firebase 1.0.14 to latest 1.0.19 and I think it may have fixed the problem for me. Process has been up for 2 hours now where it would only last for 5-30 min previously. More testing to do, but thought I'd share my in-progress results in case they were helpful.
It seems the answer was to do with the fact that my Express app was reusing one Firebase connection for every request, and for some reason this was causing the server to lock up.
My solution was to create some basic middleware that provides a new reference to the Firebase on each API request, see below:
var Middleware = {
/*
* Initialise Firebase Refs per connection
*/
initFireBase: function(req, res, next) {
console.log('Intialising Firebase for user');
// We need a authToken
var authToken = req.param('authToken');
// Validate the auth token
if(!authToken || authToken.length === 0) {
return res.send(500, {code: 'INVALID_TOKEN', message: 'You must supply an authToken to this method.'});
}
else {
// Attempt to parse the auth token
try {
var decodedToken = JWTSimple.decode(authToken, serverToken);
}
catch(e) {
return res.send(500, {code: 'INVALID_TOKEN', message: 'Supplied token was not recognised.'});
}
// Bail out if the token is invalid
if(!decodedToken) {
return res.send(500, {code: 'INVALID_TOKEN', message: 'Supplied token was not recognised.'});
}
// Otherwise send the decoded token with the request
else {
req.auth = decodedToken.d;
}
}
// Create a root reference
var rootRef = new Firebase('my firebase url');
// Apply the references to each request
req.refs = {
root: rootRef,
user: rootRef.child('users'),
inbox: rootRef.child('inbox')
};
// Carry on to the calling function
next();
}
};
I then simply call this middleware on my routes:
/*
* Create a post
*/
router.all('/createPost', Middleware.initFireBase, function(req, res) {
var refs = req.refs;
refs.inbox.push({}) // etc
....
This middleware will soon be extended to provide Firebase.auth() on the connection to ensure that any API call made with a valid authToken would be signed to the user on Firebase's side. However for development this is acceptable.
Hopefully this helps someone.