Attempting to create a chat bot that will hit a web service midway through and ask questions based on previous responses.
I have created a function that will return an array of people that I will then text these names and ask the user to pick one.
Twilio Function
exports.handler = function(context, event, callback) {
const employees = [{ name: 'Mark', id:15 }, { name: 'Scott', id:16 }, { name: 'Steve', id:17 }];
callback(null, employees);
};
I would hope this would return function_1.parsed values, but everything is stored in function_1.body and I can't access it the way I hoped.
Here's a view of my Log.
Anyone know how I can send this to Parsed instead of body? If I submit a simple object it will return to the parsed value.
exports.handler = function(context, event, callback) {
const employee = { name: 'Mark', id:15 };
callback(null, employee);
};
here is the trick, Wrap it in an object:
{"result":
[{ name: 'Mark', id:15 }, { name: 'Scott', id:16 }, { name: 'Steve', id:17 }]
};
Related
How i can edit asset name? its doesnt work. Thanks
let assetService = $injector.get(self.ctx.servicesMap.get('assetService'));
let activeID = self.ctx.data[0].datasource.entityId
let tenantId = self.ctx.dashboard.authUser.tenantId
let asset = {
additionalInfo: null,
createdTime: 1599121131415, // временно
customerId: {
entityType: "CUSTOMER",
id: self.ctx.dashboard.authUser.customerId
},
id: {
entityType: "ASSET",
id: activeID
},
label: null,
name: "kuku", // временно
tenantId: {
entityType: "TENANT",
id: tenantId
},
type: "справочник"
}
assetService.saveAsset(asset)
Thingsboard is built using Angular 10 currently See releases. You correctly injected the Angular service 'assetService'. You need to follow the Angular method of subscribing to the observable from assetService.
Calling
assetService.saveAsset(asset)
without subscribing means nothing happens. From the Angular University Blog
The multiple versions of the Angular HTTP module all have an RxJS Observable-based API. This means that the multiple calls to the HTTP module will all return an observable, that we need to subscribe to one way or the other.
So here's the code to 'subscribe' to the observable described above
assetService.saveAsset(asset).subscribe(
(response) => {
console.log(
"saveAsset call Success:",
response);
},
response => {
console.log(
"saveAsset call Error:",
response);
},
() => {
console.log(
"saveAsset observable Complete"
);
});
Let me know if there's a mistake in the code above, I didn't test it. And thanks for your question Anzor - it led me to a solution to make a custom Thingsboard widget along with the Widgets Development Guide.
I am using Twilio Studio for to collect messages for our small church. When someone records a voicemail, I am using a function to send the recording URL to the group members. Here is what that function looks like currently:
var groupmembers = [
{
name: 'Person1',
number: '+11111111111'
},
{
name: 'Person2',
number: '+11111111111'
}
];
exports.handler = function(context, event, callback) {
let twiml = new Twilio.twiml.MessagingResponse();
groupmembers.forEach(function(member) {
// Now, forward on the message to the group member, using the sender's name
twiml.message(`Text from ${event.senderFrom}: ${event.senderMessage}`, {
to: member.number
});
})
callback(null, twiml);
};
This gives me a '12200 Schema validation warning' with the detail: Invalid content was found starting with element 'Message'. One of '{Play
I'm fairly sure the issue is because I am trying to send an SMS during a call but I am not sure how to update my TWIML or Studio flow to accommodate for this.
Any help is appreciated!
you need the REST API rather then TwiML in this case. You could use code similar to what is shown below to do this.
Make sure to check the box below, under Function Config for your Function,
exports.handler = function(context, event, callback) {
const twilioClient = context.getTwilioClient();
let groupMembers = [
{
name: 'Person1',
number: '+14701111111'
},
{
name: 'Person2',
number: '+18082222222'
},
{
name: 'Person3',
number: '+18021111111'
}
];
function sendSMS(member) {
return twilioClient.messages.create({
from: '+13054444444',
to: member.number,
body: 'Hello World!'
});
}
let promises = [];
groupMembers.forEach((member) => {
console.log(member);
promises.push(sendSMS(member));
});
Promise.all(promises)
.then((values) => {
console.log(values);
callback(null,"Success");
})
.catch(error => {
console.log(error);
callback("Failure");
});
};
Is there a way to send email from Twilio function? I understand that we can use sendgrid. I am looking a simpler solution.
Twilio evangelist here. 👋
As of now, you can use SendGrid from within a Twilio Function. The code below does the job for me and I just sent an email via a function
exports.handler = function(context, event, callback) {
const sgMail = require('#sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
to: 'sjudis#twilio.com',
from: 'test#example.com',
subject: 'Sending with SendGrid is Fun',
text: 'and easy to do anywhere, even with Node.js',
html: '<strong>and easy to do anywhere, even with Node.js</strong>',
};
sgMail.send(msg)
.then(() => {
callback(null, 'Email sent...');
})
.catch((e) => {
console.log(e);
})
};
The above email will most like end up in spam as test#example.com is not a very trust worthy email address. If you want to send emails from your own domains additional configuration is needed.
To run the code inside of the function, you have to make sure to install the sendgrid/mail mail dependency and provide the sendgrid token in the function configuration.
If you want to use this function to power e.g. messages you have to make sure that your return valid TwiML. :) When you create a new function you will get examples showing on how to do that.
Hope that helps. :)
Another way is to use the SendGrid API
const got = require('got');
exports.handler = function(context, event, callback) {
const requestBody = {
personalizations: [{ to: [{ email: context.TO_EMAIL_ADDRESS }] }],
from: { email: context.FROM_EMAIL_ADDRESS },
subject: `New SMS message from: ${event.From}`,
content: [
{
type: 'text/plain',
value: event.Body
}
]
};
got.post('https://api.sendgrid.com/v3/mail/send', {
headers: {
Authorization: `Bearer ${context.SENDGRID_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify(requestBody)
})
.then(response => {
let twiml = new Twilio.twiml.MessagingResponse();
callback(null, twiml);
})
.catch(err => {
callback(err);
});
};
};
Source: https://www.twilio.com/blog/2017/07/forward-incoming-sms-messages-to-email-with-node-js-sendgrid-and-twilio-functions.html
I need my twilio sync documents to be deleted automatically after few minutes.
I followed the documentation for the Runtime.getSync(),
which by the way seems to be introduced here
https://www.twilio.com/docs/runtime/client and extended by the
"Documents" section here
https://www.twilio.com/docs/sync/api/documents using node.js examples,
it was so hard to piece it all toghether.
but I cannot get the ttl parameter to work
exports.handler = function(context, event, callback) {
let sync = Runtime.getSync();
let payload = {
'greeting': "bonbon!"
};
let uniqueName = "test4";
sync.documents.create({
uniqueName: uniqueName,
ttl: 5, //////////////////DOESN'T WORK!!!
data: payload
}).then(function(response) {
console.log(response);
callback(null, response);
});
}
the ttl parameter doesn't cause any effect on the expiration of the document and doesn't even cause the document's parameter "date_expires" (as seen in the https://www.twilio.com/docs/sync/api/documents ecample) to reflect the right value, in fact the date_expires parameter doesn't even appear in the returned JSON object:
{
_version: {
_domain: {
twilio: {
username: "xxxxxxxxxxxxxxxxxxxxxx",
password: "[Redacted]",
accountSid: "xxxxxxxxxxxxxxxxxxxxxx",
httpClient: { },
_sync: {
$ref: "$["_version"]["_domain"]"
}
},
baseUrl: "https://sync.twilio.com",
_v1: {
$ref: "$["_version"]"
}
},
_version: "v1"
},
sid: "xxxxxxxxxxxxxxxxxxxxxx",
uniqueName: "test4",
accountSid: "xxxxxxxxxxxxxxxxxxxxxx",
serviceSid: "xxxxxxxxxxxxxxxxxxxxxx",
url: "https://sync.twilio.com/v1/Services/xxxxxxxxxxxxxxxxxxxxxx/Documents/xxxxxxxxxxxxxxxxxxxxxx",
links: {
permissions: "https://sync.twilio.com/v1/Services/xxxxxxxxxxxxxxxxxxxxxx/Documents/xxxxxxxxxxxxxxxxxxxxxx/Permissions"
},
revision: "0",
data: {
greeting: "bonbon!"
},
dateCreated: "2018-09-19T03:30:24.000Z",
dateUpdated: "2018-09-19T03:30:24.000Z",
createdBy: "system",
_solution: {
serviceSid: "default",
sid: "xxxxxxxxxxxxxxxxxxxxxx"
}
}
is there anyone who has an explanation or a workaround?
Thank you very much in advance
Which version of twilio do you use?
https://www.twilio.com/console/runtime/functions/configure
If it is less than 3.6.10, ttl is not supported.
https://github.com/twilio/twilio-node/blob/master/CHANGES.md#2017-11-17-version-3100
[2017-11-17] Version 3.10.0
Sync
Add TTL support for Sync objects (breaking change)
The newest version is 3.21.0. Try it.
I tried to use model.save() to POST a new user. But I check request payload and found that it not only sent the data, but also sent other parts of the model. That makes my server cannot parse the payload.
The request payload generated :
{"phantom":true,"internalId":"ext-record-58","raw":{},"data":{"userId":0,"userName":"Amy"},"modified":{"userName":""},"hasListeners":{},"events":{},"stores":[],"dirty":true,"id":"AM.model.User-ext-record-58"}
But the desired request payload should be :
{"userId":0,"userName":"Amy"}
And I am aware that the "phantom" of my model is false before I call model.save(). But it becomes true in the request payload. Is it a clue?
Model:
Ext.define('AM.model.User',{
extend: 'Ext.data.Model',
fields: [
{ name: 'userId', type: 'int' },
{ name: 'userName', type: 'string' },
{ name: 'createdTime', type: 'string' },
],
idProperty: 'userId',
associations: [
{
type: 'hasOne',
model: 'AM.model.ModelA',
name:'modelA',
associationKey:'modelA',
getterName:'modelA'
},
{
type: 'hasOne',
model: 'AM.model.ModelB',
name:'modelB',
associationKey:'modelB',
getterName:'modelB'
}
],
proxy: {
type: 'rest',
success:true,
url:'../restful/users',
writer:{
type:'json',
getRecordData:function(record){ //parse createdTime to the format Y-m-d
record.set('createdTime', Ext.Date.format(new Date(record.get('createdTime')), "Y-m-d"));
return record;
}
},
reader: {
type: 'json'
}
}
});
This is the view which has the data to be posted. The view will fill the data to the model:
Ext.define('AM.view.UserRegisterForm',{
extend:'Ext.form.Panel.',
alias:'widget.userRegisterForm',
fields:new Array(), //I want to render the fields in xtemplate, so instead of adding the fields to items, I use an array to manage them.
retrieveData(model){
model.set('userName', this.fields[0].getValue());
model.set('createdTime',this.fields[1].getValue());
}
}
The function in the controller, which sends the POST request:
postUser:function(){
var userRegisterForm= this.getUserRegisterForm();
var userModel = this.getUserModel();
var user= new userModel();
var me = this;
userRegisterForm.retrieveFieldData(user);
console.log(user); //the data in console looks fine!
user.save({
success: function(response) {
//do something...
},failure:function(response) {
alert('fail');
}
});
}
You are returning the full record when you override getRecordData Where as you are just meant to return the records data. record.getData()
Some extra advice. Don't override getRecordData to set the models creation date. Use the models defaultValue property to give assign it a new Date if one doesn't exist.