I am looking for a way to say 'Thank you' and also make an API call at the end of function execution in Twilio.
Something like this:
responseObject = {
"actions": [
{
"say": "Thank you!"
},
{
"redirect": {
"uri": "API_LINK",
"method": "POST"
}
}
]
}
Sadly, twilio ignores every other message if you have a redirect. I tried to solve this by redirecting to TwiML first:
<?xml version="1.0" encoding="UTF-8"?>
<Response>
<Say>Thank you!</Say>
<Redirect method="POST">API_LINK</Redirect>
</Response>
But the above also does not work - It says application error after 'Thank you!' at the end. Also, I am passing query parameters along with API call: https://example.link?a=value&b=value. Not sure, how to pass that with TwiML.
This API request is supposed to send message to microsoft teams channel.
Twilio developer evangelist here.
To start with, it seems like you are talking about the end of an Autopilot dialogue, not the end of function execution. If that is the case, you are getting errors because you are mixing Autopilot Actions and TwiML. When you are interacting with an Autopilot assistant you should only respond to it with Actions JSON, not with TwiML.
Also, Autopilot will expect all responses to requests that it makes, including via redirect, to respond with Actions JSON. So it's not recommended to make API requests using a redirect action.
Instead, I would recommend that you use a Twilio Function (or your own back-end) to make your API request from JavaScript and respond with the "say" action.
A Twilio Function might look something like this:
exports.handler = function (context, event, callback) {
// make request to Teams API
// I'm not sure the API method you are using, but use an http client like got, superagent or node-fetch, or a dedicated API client if there is one available
// create your actions
const actions = {
actions: [
{
"say": "Thank you!"
}
]
};
// return the actions JSON
callback(null, actions);
});
Alternatively, you can set up to receive an Autopilot webhook when a dialogue ends. This way you can respond to Autopilot with just the "say" action which will cause the end of the dialogue and trigger the webhook. Then in your webhook handler you can make the API request to Teams.
Let me know if that helps at all.
Related
I am setting up a appScript to run on a webhook that has been registered to a Trello api. I want the doPost function in to run every time the specific trello board performs a post.
Steps I have done to setup
Published as web app, selected "Anyone" as who is able to run
Used the code below to register the webhook with the proper keys, this successfully creates a webhook for trello
fetch('https://api.trello.com/1/webhooks/?key=XXX&token=XXX&callbackURL=https://script.google.com/macros/s/XXX/exec&idModel=XXX&description=Description', {
method: 'POST',
headers: {
'Accept': 'application/json'
}
})
.then(response => {
console.log(
`Response: ${response.status} ${response.statusText}`
);
return response.text();
})
.then(text => console.log(text))
.catch(err => console.error(err));
Republished web app, selected "Anyone, even anonymous" to be able to run
Other Notes:
I have created a doPost function and a doGet function, both have logging in them
I am using the "exec" callback URL in the webhook, this seemed to be the only thing that would be able to trigger the doPost function
When a post is performed by the trello api, the doPost function is properly triggered, but even with the logging present in the doPost, I am not able to see any results that the doPost function has actually been run. See
doPostCompletion
Am I missing something that needs to be deployed or adjusted?
Turns out Logger.log is properly respected in a synchronous manner with doPost.
Webhook was functional all along.
Sources:
doPost not working in Google app script
https://github.com/tanaikech/taking-advantage-of-Web-Apps-with-google-apps-script#corsinwebapps
This question already has an answer here:
Making an HTTP POST request from fulfillment in Dialogflow
(1 answer)
Closed 4 years ago.
We are creating an action that will take user's input and create an entity in our database (datastore).
Ideally, we would like to be able to access the user's raw input audio, but it doesn't seem that is possible.
As a work around we are going to send the speech-to-text of user's utterance to our backend services. We are using firebase cloud functions for our fulfillment and an external rest api for our crud operations.
We are trying to make a post request in a webhook to create an entity based on user's input, but when I check my logs it doesn't seem like the post request is reaching our service. I'm not able to debug what or if we are getting a response back
app.intent('favorite color', (conv, {color}) => {
const options = {
// options
};
function callback(error, response, body) {
// log response or error
}
request(options, callback);
const luckyNumber = color.length;
// Respond with the user's lucky number and end the conversation.
conv.close('This word has ' + luckyNumber + ' letters.');
});
// Set the DialogflowApp object to handle the HTTPS POST request.
exports.dialogflowFirebaseFulfillment = functions.https.onRequest(app);
This question is not the same as the one that it was marked as a duplicate because the solution was the account type not supporting POST requests to an external API and not the HTTP Client we were using
The Inline Editor in the Dialogflow console uses Firebase Cloud Functions, as you already know.
Unfortunately, Firebase Cloud Functions DOESN'T support external API calls in it's free plan. You may need to switch to blaze plan or deploy your fulfillment elsewhere.
Am using chrome.webRequest API to modify incoming requests and responses. However, I recently encountered a scenario where am required to intercept a POST call and change it to a GET call. I tried changing the method in object that I get in the callback, but in vain.
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
details.method='GET';
console.log('onBeforeRequest', details);
},
{urls: ['http://localhost/*']},
["requestBody"]
);
Any idea what I should be doing to be able to change http method using Chrome Web Request API?
Thanks
K
Is there a way that I can get the API.ai agent information from the fulfillment request?
I am trying to capture any unique parameter from Node.js code that can be passed from Agent. This will be utilized for proceeding with the logic for multiple agents using a single code base.
For Amazon Alexa I could get the Skill Application Id from the session. Is there something similar in API.ai?
If you want to get agent id you can make something like this (using express framework):
app.post(`/:agent_id/webhook`, (req, res) => {
const apiai_agent_id = req.params.agent_id;
// webhook code...
});
And on fulfillment page in this case for each agent you have to specify it's own webhook URL like
https://mywebhooks.com/55982e7c-db17-47ee-92bb-176476228942/webhook
(you can get agent id for webhook URL from browser's address bar)
You can use the API.AI's sessionId or intentId which will be unique across agents. The sessionId and intentId* is sent with every fulfillment webhook request. The of the JSON sent are similar to this:
{
"id": "1a4b6209-51ec-47a1-a797-2e2f71926ac8",
"sessionId": "1503343146047"
...
}
but will contain other elements as well.
*intentId may include additional numeric identifier after the intent ID if you are using slot filling
Source: https://api.ai/docs/fulfillment#request
I have to make two outbound calls to two random mobile numbers and join both of them in conference using node.js. Is there a way to make it possible using twilio and node.js.
Twilio developer evangelist here.
You say you are getting two numbers provided to you and you need to make calls to both of them, joining them up in a conference. You can use the REST API to make the calls and here's a basic example of a function that would create those calls using the Node.js Twilio module:
const accountSid = 'your_account_sid';
const authToken = 'your_auth_token';
const client = require('twilio')(accountSid, authToken);
function connectNumbers(number1, number2) {
[number1, number2].forEach(function(number) {
client.calls.create({
url: 'https://example.com/conference',
to: number,
from: 'YOUR_TWILIO_NUMBER',
})
.then((call) => process.stdout.write(`Called ${number}`));
})
}
When the calls connect, Twilio will make an HTTP request to the URL supplied.
You would then need a server application on your own URL (in place of example.com in the function above) that could return the TwiML to set up the conference.
<Response>
<Dial>
<Conference>Room Name</Conference>
</Dial>
</Response>
[edit]
If you want to play a message before users join the conference, you just need to use the <Say> TwiML verb before you <Dial>. Like this:
<Response>
<Say voice="alice">This is a call from xyz.org</Say>
<Dial>
<Conference>Room Name</Conference>
</Dial>
</Response>
Let me know if that helps at all.