Receiving and responding to Twilio SMS using parse cloud module - parse-platform

I have a cloud code function that I use to send a text message to a number that is determined in my app (iOS).
The message sends fine, but I want the person who receives the message to be able to respond so that the original sender sees their response. I'm having trouble finding a way to do this using the Parse twilio module.
Here is what my cloud code function looks like right now:
Parse.Cloud.define("sendText", function(request, response) {
// Use the Twilio Cloud Module to send an SMS
twilio.sendSms({
From: "+15555555555",
To: request.params.number,
Body: request.params.message
}, {
success: function(httpResponse) { response.success("SMS sent!"); },
error: function(httpResponse) { response.error("Uh oh, something went wrong"); }
});
});
Is it possible to just call this function again from its callback with the new recipient's number (the number of the original sender)?

Twilio developer evangelist here.
It seems you're trying to create what we call the masked phone numbers feature. This is a feature in which two users communicate through a central Twilio number and never find out each others' details. There is a tutorial on how to accomplish this with both calls and SMS messages however it is in Ruby on Rails. I recommend you take a read through as it gives you a good idea of how you'll need to implement this.
Then, if you have any more Parse/Node.js related questions on how to work on it, please drop me a line at philnash#twilio.com.

Check out this question/answer I posted with a similar issue.
I use Twilio to anonymize calling and texting between users of my app. There's more info in my app about how I do this, but let me know if you have some questions.

If you want to know who sent the message you need the recipient to be able to get the sender's number, so he can call the function again himself.
There are many ways to do that, your idea seems alright, you could add the sender's phone number as a parameter in the cloud function, and use it in the call back when you use sendSMS a second time.
Here is one way to do it :
Parse.Cloud.define("sendText", function(request, response) {
// Use the Twilio Cloud Module to send an SMS
twilio.sendSms({
From: "+15555555555",
To: request.params.recipientnumber, //Notice I changed the paramter name here
Body: request.params.recipientmessage //Notice I changed the paramter name here
}, {
success: function(httpResponse) {
twilio.sendSms({
From: "+15555555555",
To: request.params.sendernumber, //Notice I changed the paramter name here
Body: request.params.sendermessage //Notice I changed the paramter name here
}, {
success: function(httpResponse) {
response.success("SMS sent!");
},
error: function(httpResponse) {
response.error("Uh oh, something went wrong");
}
});
},
error: function(httpResponse) {
response.error("Uh oh, something went wrong");
}
});
});
If the first call succeeds, make another one, if that one succeeds, return success. If either fail, return failure and never start another call.
But make sure you understand this, this will pretty much send both sms at the same time, most of the time. Your sender won't get the feeling that it was a response (or it was a fast one !).
I'm not sure I understand exactly what you're trying to achieve, that's why I posted some comments to suggest something else, but I still wanted to answer here about your exact question.

Related

Parse Cloud Code runs on client side but not on server side

I wrote this large parse code for Parse Cloud Code that queries a row based on it's objectId. I wrote this all on my client-side and tested it with my localized html code. Everything works great! But, once I push it to the server and attempt to run I get Error 141 : "An error has occured"
Clearly, this is massively unhelpful. So, I broke the code down to the most basic call I can make, shown below:
function getCardPacks(request, response)
{
var myTable = Parse.Object.extend("myTable");
var query = new Parse.Query(myTable);
query.get(request.params.tabId,
{
success:function(results)
{
response.success();
},
error:function(error)
{
response.error(error);
}
},function(error)
{
console.log(error);
});
I still get the 141. I verified that the params I send this function are not null, but maybe they are getting undefined before they reach the function? I really have no idea what is wrong here.
Has this happened to anyone else? Or, is there a way I can get debug logs from the server end so I could determine if a val is null or find out where the script stops?
Well you can check the logs on Parse.com on your app. I'm confused what you are using cloud code for. If you are just querying a table, then you should be able to do that using the Parse javascript sdk. You can see how to set that up here. https://www.parse.com/apps/quickstart?app_id=syncup-staging#parse_data/web/existing

Google javascript API returns 404's

I have the same code (more or less) working fine in Java, but when I write it in javascript, I end up with 404's. I can't figure out what I'm doing wrong and it's driving me crazy!
gapi.client.load('translate', 'v2', function () {
gapi.client.language.languages.list().execute(function (response) {
response.data.forEach(function(language){
console.log(JSON.stringify(language));
});
});
"language":
{"code":404,"message":"Not Found","data":[{"domain":"global","reason":"notFound","message":"Not Found"}],"error":{"code":404,"message":"Not Found","data":[{"domain":"global","reason":"notFound","message":"Not Found"}]}}
I can see in the console the following POST data to https://content.googleapis.com/rpc?key=MY_API_KEY:
[{"jsonrpc":"2.0","id":"gapiRpc","method":"language.languages.list","apiVersion":"v1"}]
Should that say v1?
By contrast, the REST URL is https://www.googleapis.com/language/translate/v2/languages?key=MY_API_KEY (and it's a GET) and it works fine.
You are right that this was a bug in gapi.client.load. This bug has been fixed and you should no longer run into 404s.

Seek function not working on flowplayer

I want a video to start at a specific point (say 30 seconds into it) and I have tried using the seek() function of flowplayer, according to the API documentation .
flowplayer(function (api, root) {
api.bind("ready", function () {
seek(30);
});
});
But I get the following error message on the console.
Uncaught ReferenceError: seek is not defined
Does anyone know what I might be doing wrong?
It does not look like you are calling the seek method in the correct way. When you bind to the ready event it gives you a couple of parameters. The first argument is the jQuery event object and the second provides a handle on the player API.
From the api parameter you should then be able to call seek
Example
flowplayer(function (api, root) {
api.bind("ready", function (e, api) {
api.seek(30);
});
});
For more info see flowplayer api docs

Breezejs How to debug cause of TypeError in query response

I'm attempting to use Breeze to query a ASP.Net Web API endpoint and the query fails - with the data object containing:
internalError: TypeError
arguments: Array[2]
0: "createCtor"
1: null
length: 2
__proto__: Array[0]
get message: function () { [native code] }
get stack: function () { [native code] }
set message: function () { [native code] }
set stack: function () { [native code] }
type: "non_object_property_load"
The data object has a message (and responsetext) property which contains the full json response from the query which looks ok and the metadata thats been generated matches the response - it also records status 200 for the response
So I'm guessing there is some kind of issue mapping the response to an object on the client side?
I'm using the NuGet package for Breeze version 0.85.2
I can get the sample ToDo project to run fine on the same environment
My project does use domain objects, contexts etc all from different assemblies and namespaces but I understood thats supported in this version?
Also that one of the properties is an enum - in the metadata this is defined as {\"name\":\"State\",\"type\":\"Edm.Self.State\",\"nullable\":\"false\"}] but in the response is comes through as an integer
Looking for tips on how to debug this further on the client side
Update
comparing the working sample with my code, the error looks to be coming from this function:
/**
Returns the constructor for this EntityType.
#method getEntityCtor
#return {Function} The constructor for this EntityType.
**/
ctor.prototype.getEntityCtor = function () {
if (this._ctor) return this._ctor;
var typeRegistry = this.metadataStore._typeRegistry;
var aCtor = typeRegistry[this.name] || typeRegistry[this.shortName];
if (!aCtor) {
var createCtor = v_modelLibraryDef.defaultInstance.createCtor;
if (createCtor) {
aCtor = createCtor(this);
} else {
aCtor = function() {
};
}
}
this._setCtor(aCtor);
return aCtor;
};
The defaultInstance property on v_modelLibraryDef is undefined in my running code - what am I missing on the configuration of breeze for that to happen?
Update 2 - Resolved but why
Ok so I got this working - I was missing a reference to knockout (which I was planning to use but hadn't got that far) - I was a little bit misled by the breeze prerequisites which don't mention knockout so if anyone can explain how I could have got this working without knockout and if its a bug then the points are yours
Got same error, and referencing knockout.js helped(I'm using angularjs for my app)
manager.executeQuery(query).then(function(data) {
console.log(data);
});
But.
It seems, that data-mapper works with knockout by default, so we have XHR results as K.O. model with observables.
so I added breeze.config.initializeAdapterInstance("modelLibrary", "backingStore", true);
and now I don't receive data.results as observable collection.
Hope my answer will help.
Sorry you struggled Richard. We'll try to learn from it and spare the next person the pain you endured.
FWIW, we do not say that Knockout is a prerequisite ... because KO is not a prerequisite. You can use Angular or Backbone instead and we anticipate other alternatives in future.
We don't want to drown you in configuration options when you're just learning Breeze. So we picked KO as the default model library (just as jQuery is the default AJAX provider and Web API is the default "dataservice" technology). We say so in numerous places; prerequisites looks like another good place to mention it.
As it happens, you intended to go with KO anyway so no configuration would have been necessary. Most folks start with something like the MVC template which includes KO and loads it for you in the Index.cshtml.
Apparently you started from a clean slate ("ASP Empty Web Application" perhaps?). The Breeze Web API NuGet package strives to be spare and therefore does not include KO. We figured (incorrectly) that you would add it yourself ... in the right script order ... if you wanted to use KO. Clearly we could do a better job of documenting this particular development path ... especially as we like it so much ourselves. Thanks for pointing it out.
The other problem is that the exception was not helpful. You can see from other attempts to answer your question that even folks with Breeze experience couldn't recognize what was wrong. We'll look to see if we can detect the missing script a little earlier and throw an exception with a better message.
This error looks like it has to do with one of your Entity type constructors. I'm guessing that you are calling the 'registerEntityTypeCtor' method somewhere in your code. If so, then I would put a breakpoint in the constructor that you are registering there.
Per your other comment, .NET enums are supposed to get converted into integers on the breeze client. This is the only 'primitive' datatype that could support them. They will get converted back to enums on the server when you call 'EntityManager.saveChanges'
Breeze does not require 'knockout', you can use either 'angularjs' or 'backbone' as well. We simply default the breeze client to knockout if you do not specify another library. See the 'breeze.config.initializeAdapterInstance' topic here. We do need to a better job of documenting this.
Every time I get an error at which the Message property of the response is the data in json format means I have a bug in the function that runs after getting the data.
Example:
dataservice.getPalanca(routeData.PalancaID)
.then(function (data) {
self.palanca(data.results[0]);
})
.fail(function (error) {
console.log(error); /*if I get here and error.Message == correct json almost always means error in .then function*/
toastr.error("Ha ocurrido un error al obtener los datos");
});
I hope I help you.

How sophisticated should my Ajax code be?

I have seen simple example Ajax source codes in many online tutorials. What I want to know is whether using the source code in the examples are perfectly alright or not?
Is there anything more to be added to the code that goes into a real world application?
What all steps are to be taken to make the application more robust and secure?
Here is a sample source code I got from the web:
function getChats() {
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null) {
return;
}
var url="getchat.php?latest="+latest;
xmlHttp.onreadystatechange=stateChanged;
xmlHttp.open("GET",url,true);
xmlHttp.send(null);
}
function GetXmlHttpObject() {
var xmlHttp=null;
try {
xmlHttp=new XMLHttpRequest();
} catch (e) {
try {
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
The code you posted is missing one important ingredient: the function stateChanged.
If you don't quite understand the code you posted yourself, then what happens is when the call to getchats.php is complete, a function "stateChanged" is called and that function will be responsible for handling the response. Since the script you're calling and the function itself is prefixed with "gets" then I'm pretty sure the response is something you're going to be interested in.
That aside, there are a number of ways to improve on the code you posted. I'd guess it works by declaring a single "xmlHttp" object and then making that available to every function (because if it doesn't, the stateChanged function has no way of getting the response). This is fine until you run an AJAX request before the last one (or last few) haven't replied yet, which in that case the object reference is overwritten to the latest request each time.
Also, any AJAX code worth its salt provides functionality for sucess and failure (server errors, page not found, etc.) cases so that the appriopiate message can be delivered to the user.
If you just want to use AJAX functionality on your website then I'd point you in the direction of jQuery or a similar framework.
BUT if you actually want to understand the technology and what is happening behind the scenes, I'd continue doing what you're doing and asking specific questions as you try to build a small lightweight AJAX class on your own. This is how I done it, and although I use the jQuery framework today.. I'm still glad I know how it works behind the scenes.
I would use a framework like DOMAssistant which has already done the hard work for you and will be more robust as well as adding extra useful features.
Apart from that, you code looks like it would do the job.
I would honestly recommend using one of the many libraries available for Ajax. I use prototype myself, while others prefer jQuery. I like prototype because it's pretty minimal. The Prototype Ajax tutorial explains it well. It also allows you to handle errors easily.
new Ajax.Request('/some_url',
{
method:'get',
onSuccess: function(transport){
var response = transport.responseText || "no response text";
alert("Success! \n\n" + response);
},
onFailure: function(){ alert('Something went wrong...') }
});

Resources