The twilio module in Parse Cloud is missing latest APIs - parse-platform

Based on the API documentation on twilio.com, twilio.availablePhoneNumbers('COUNTRY_CODE').mobile.get() should exist. I should be able to call something like this below:
twilio.availablePhoneNumbers('US').mobile.get({
smsEnabled: true
}).then(function(searchResults) {
....
});
But when I used twilio module provided inside Parse cloud code, twilio.availablePhoneNumbers('COUNTRY_CODE').local and twilio.availablePhoneNumbers('COUNTRY_CODE').tollFree are available.
Am I wrong?
I need to programmatically acquire a phone number in the cloud code. If twilio on Parse cloud code is limited, how can I use the latest twilio APIs?

Twilio developer evangelist here.
The Twilio module on Parse is indeed outdated. I am currently working with their team to get an updated version available for developers like yourself.
In the meantime, you could use a normal HTTP request on Parse without the Twilio module to make calls like the one you are after. Something like this might work for now:
var accountSid = 'AC123...'; // your account SID
var authToken = 'xyzabc...'; // your auth token
var countryCode = 'US'; // the country code you want to search within
var url = 'https://';
url += accountSid + ':' + authToken + '#'; // add auth to URL
url += 'api.twilio.com/2010-04-01/Accounts/';
url += accountSid;
url += '/AvailablePhoneNumbers/';
url += countryCode;
url += '/Mobile.json';
Parse.Cloud.httpRequest({
url: url,
}).then(function(httpResponse) {
// success
console.log(httpResponse.text);
// httpResponse.data is the parsed JSON response
},function(httpResponse) {
// error
console.error('Request failed with response code ' + httpResponse.status);
});
You might want to check out the documentation for Parse's Parse.Cloud.httpRequest. It's available here: https://parse.com/docs/cloudcode/guide#cloud-code-advanced

Related

Capture raw axios request from AWS Lambda

I have code that calls a vendor API to do a formdata upload of a file by axios from inside an AWS Lambda. The call returns a 400 error. If I run the code locally using the same node version v14 it works. I want to capture both raw requests and compare them for differences. How do I capture both raw requests? I've tried using ngrok and pipedream but they don't show the raw but decode the request and the file.
let response = null;
try {
const newFile = fs.createReadStream(doc);
const formData = new FormData();
formData.append("file", newFile);
formData.append("url", url);
const headers = {
Authorization: "Bearer " + token,
...formData.getHeaders(),
};
console.log("Headers: ", headers);
response = await axios.post(`${APIBASE}/file/FileUpload`, formData, {
headers,
});
console.log("file upload response", response);
} catch (err) {
console.log("fileupload error at API", err);
}
You might be able to just use a custom request interceptor and interrogate at the requests that way.
https://axios-http.com/docs/interceptors
You're not able to capture the request on the network level, as this is totally controlled by AWS. Maybe there's a way to do this when running in a VPC, but I don't think so.
You could simply use a tool such as axios debug logger to print out all of the request and response contents (including headers etc) before the request is made/after the response has arrived. This might provide some more information as to where things are going wrong.
As to the cause of the problem, it is difficult to help you there since you haven't shared the error message nor do we know anything about the API you're trying to call.
There are multiple ways to debug
axios debug logger .
AWS cloud watch where you can see all the logs. you can capture the request
and response.
Use postman to call the prod lambda endpoint and verify the response.

Make requests to third-party api from Parse.com

I need to do some requests every x period of time to YouTube v3 Api and then process this data and store it in Parse.com database.
Can i do this with Cloud Code (Jobs) ?
Yes, you can do this with the Parse.Cloud.httpRequest method (documentation).
Here is an example from the Parse documentation. This itself is failry simple but the mentioned documentation has more info about how to set parameters, request headers etc.
Parse.Cloud.httpRequest({
url: 'http://www.parse.com/'
}).then(function(httpResponse) {
// success
console.log(httpResponse.text);
},function(httpResponse) {
// error
console.error('Request failed with response code ' + httpResponse.status);
});

SailsJS - using sails.io.js with JWT

I have implemented an AngularJS app, communicating with Sails backend through websockets, using sails.io.js.
Since the backend is basically a pure API and will be connected to from other apps as well, I'm trying to disable sessions completely and use JWT.
I have set up express-jwt and can use regular HTTP requests quite nicely, but when I send a request through sails.io.js, nothing happens at all - websocket request keeps pending on the client, and there's nothing happening on the server (with "silly" log level).
I've tried patching sails.io.js to support the query parameter, and when connecting, I send the token from Angular, but in the best case, I get a response with error message coming from express-jwt saying credentials are missing...
I've also seen some hints that socket.js in sails needs to be modified with beforeConnect, I've seen socketio-jwt, but have no idea where and how to plug that in, in Sails.
Has anyone implemented this and is using JWT with Sails and sockets? I'd appreciate any kind of hint in what direction to go :)
I realised that policy I've put in place and that was using express-jwt abstracted too much away from me, so I didn't figure out what exactly was happening. Once I looked at other examples, I've figured out that I only needed to check what's different for websocket requests than regular, and I quickly found a way around the problem.
So:
set up token signing and sending on login
Angular takes the token and saves to local storage
Create an interceptor for HTTP requests to add authorization header and token
Fix up sails.io.js to forward query parameters provided through options (as mentioned in the question)
When connecting using sails.io.js, send token as query parameter, i.e. url + '?token=' + token
In sails policy, check all combinations for token, including req.socket.handshake.query, as below:
module.exports = function (req, res, next) {
var token;
if (req.headers && req.headers.authorization) {
var parts = req.headers.authorization.split(' ');
if (parts.length == 2) {
var scheme = parts[0],
credentials = parts[1];
if (/^Bearer$/i.test(scheme)) {
token = credentials;
}
} else {
return res.json(401, {err: 'Format is Authorization: Bearer [token]'});
}
} else if (req.param('token')) {
token = req.param('token');
// We delete the token from param to not mess with blueprints
delete req.query.token;
}
// If connection from socket
else if (req.socket && req.socket.handshake && req.socket.handshake.query && req.socket.handshake.query.token) {
token = req.socket.handshake.query.token;
} else {
sails.log(req.socket.handshake);
return res.json(401, {err: 'No Authorization header was found'});
}
JWTService.verifyToken(token, function (err, token) {
if (err) {
return res.json(401, {err: 'The token is not valid'});
}
sails.log('Token valid');
req.token = token;
return next();
});
};
It works well! :)

Backbone/JS: looking to access the Twilio SMS API via an AJAX call

Looking to set up Twilio's SMS service so that when a user presses a certain button, it leverages my account with Twilio to send a text.
Using Backbone.js with coffeescript, and this has to be done client-side for the moment, so I'm doing something like this:
events: {
"click .button": "sendText"
}
and then sendText looks like this:
sendText: ()->
accountSid = '{my account sid}'
authToken = '{my auth token}'
ToNumber = "{string of a number to text to}"
FromNumber = "{string of my Twilio number}"
Body = escape("Hey, this is working.")
myJSONData = "To=%2B1" + ToNumber + ", From=%2B1" + FromNumber + ", Body=" + Body
$.ajax({
type: 'POST',
url: 'https://api.twilio.com/2010-04-01/Accounts/'+ accountSid + '/SMS/Messages',
data: myJSONData,
success: (data) -> {
console.log('SMS sent successfully!')
}
})
Is this heading in the right direction? I know that I haven't entered my auth credentials anywhere yet, but I'm not certain where to do that yet.
You shouldn't, under any circumstance, have your authToken (and the situation is worse as you're also including your account sid) available for anyone who wants to see you source code.
With that info, I can provision numbers on your behalf, make calls, return numbers... You just can't do it on the client side.
You should connect (using Ajax if you want) to your server, which in turn would connect to twilio passing your credentials. That way, the only one who knows them is your server.

Making jQuery $.ajax call to Twitter API 1.1 search

Here is a very simple example of a call to Twitter's search API to get all tweets from a tag known to have tweets, #fml.
I believe I am correctly using the application-only authentication as explained here: https://dev.twitter.com/docs/auth/application-only-auth (see Step 3 for example of a call)
I am being asked for a solution that does not involve any server-side code so I am including the bearer code in the javascript, which isn't good to begin with, but....
I would expect this code to work. Instead it produces the error '400 (Bad Request)'. Any ideas?
$.ajax({
url: "https://api.twitter.com/1.1/search/tweets.json",
dataType: "jsonp",
data: "q=%23fml",
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Bearer XXmyBearerCodeXX");
},
success: function(json){ alert(json); }
});
EDIT 1 - Validated Twitter call
Using hurl.eu I was able to get a successful response from the API with the above query and Authorization header, so I assume this means my Twitter call is correct, just not set up correctly within jQuery.ajax(), but I just don't see what is missing.
You cannot set request headers using AJAX calls with dataType JSONP.
See this question: Set Headers with jQuery.ajax and JSONP?
The best solution is to use a server-side proxy to do the search for you. I know you are looking for a client only solution, but with this restriction, and with no way around CORS, this is how it seems to be done today for the Twitter API.
Edit It may be possible using a proxy like Yahoo's YQL if you don't have access to one.
on your severside create a jsp or servlet and from the client side make a JSON call to the .jsp/servlet and that will return back the json object to the javascript. In serverside use the twitter4j api.
sample code:
`
$.getJSON(http://localhost:8080/test.jsp?callback=?",
{
jspqueryStr : queryStr,
jspgeocodeStr : geocodeStr,
lat:latStr,
lan:lngStr,
radius:radiusStr,
}, displayResult);
//This function returns the data as json object from server.
function displayResult(data) {}
In the jsp the code is like below
<%
String jspqueryStr = request.getParameter("jspqueryStr");
String jspgeocodeStr = request.getParameter("jspgeocodeStr");
String diseasename = request.getParameter("jspqueryStr");
String lat = request.getParameter("lat");
String lan = request.getParameter("lan");
String radius = request.getParameter("radius");
Gson gson = new Gson();
String json = gson.toJson(tweetList);
json = request.getParameter("callback") + "(" + json + ");";
out.println(json);
public List<Status> searchstream(){
//here all the twitter4j api code to get the data
retrun tweetList;
}
%>
`

Resources