Is it possible to gather multiple values with Twilio IVR? - python-3.x

I have a view function that needs to gather multiple pieces of information in one call (it's a quick outbound call - the user answers and is to be immediately prompted for these data points), based on data pulled from a DB. What I'd like the view function to do is something like the following:
group_id = <get group id>
params = data_element_select_params.DataElementSelectParams(group_id=group_id)
data_elements = worker.select(params) # function I wrote which returns a list of objects, in this case objects called DataElements
vr = VoiceResponse()
say_msg = 'Enter {element}, then press star.'
for element in data_elements:
say_message = say_msg.format(element=element.name)
<Gather input with say_message and save it>
Can this be achieved without routing to the same URL over and over? I have not seen any other solution, and I'd rather not continually redirect to the same URL as we'll have to pull the list of elements from the DB again for each element.
Apologies if anything is unclear - please point it out and I'll clarify as quickly as I can.

Twilio developer evangelist here.
You can only use one <Gather> per TwiML document, so no, you can't ask multiple questions and take multiple inputs within the one webhook.
You will need to route to a URL that receives the input from each <Gather> and then asks the next question.
To avoid pulling all the elements from the DB every time, you could investigate saving the elements to the HTTP session and pulling them back out of there. Twilio is a well behaved HTTP client, so you can use things like cookies to store information about the current call/conversation.

Related

Creating an array from a get webhook response nested json

The current Zapier steps i have set up creates a GET request to an external service. that service replies with a list of data that is nested. My end step i need to do is make multiple PUT requests to another API with part of the URL being a value from the response from the GET. There is not a fixed number of id’s/times that it will need to PUT. 
Currently if i do it with just the GET then the next step is the PUT it puts all of the values of the ID i need to put at the end of the API url as just a comma separated list. I need them to make separate PUT requests for Each ID.
Any help would be greatly appreciated.
This shows the response to the GET request (Images shows only the first part. There will are more in the response)
This is the PUT request. It currently puts them as a comma separated list. which causes an error. each of the values needs to process as a separate PUT.
​
You may want to consider writing your own code step to format the nested data into an array of objects (JSON). You could then return the data to output and achieve the effect you're looking for, where the next Step runs a PUT request for each item in your output array.
Here are Zapier's notes on this strategy:
Setting the output to an array of objects will run the subsequent steps multiple times — once for each object in the array. If Code by Zapier is the Zap's trigger and an empty array is returned, nothing happens. You can think of it like a polling trigger that did not get any results in the HTTP response. This functionality is exclusive to triggers — returning an empty array in a Code by Zapier action does not have the same effect.

Parameter value filling with quick responses in messenger

I have created a bot using Dialogflow (api.ai) and integrated it with Facebook messenger. I want to get the parameter values from user: like city, date (today, tomorrow) by using the quick reply feature of messenger, where user is presented with select-box like options, and can tap on one of the options. The required parameter receives the user-tapped value, saving the user from typing it manually.
I cannot find anywhere in documentation any way to fill up parameter values (slots) using quick replies. There is an option to give quick replies in response section, but the response section is called on fulfilment, and if I take user input in response, then I have to create another follow up intent to process the user-response further, because the current intent gets fulfilled after response.
If I add quick replies in the response section, then I have to create multiple levels of follow-up intents. Ex: I take city input in one intent, and give two options to user (like New York, Delhi). Then I have to create two follow up intents, each for handling one reply (New York and Delhi), and then for each follow up intent, I will have to create more follow up intents to get more parameter inputs. Below is the flow diagram of this case. --->
This can get pretty complex when more levels are added! Amazon Lex has this feature of filling slots using quick replies. Can't I just fill up parameter values directly using the quick replies like Lex?
You don't have to go this far. There is a simple way of using entities & prompts in dialogflow.com. The workflow can be: Weather(intent)->quick reply(New york/Delhi)->City(intent) use entities here->quick reply(Today/Tomorrow)->Use different intents here for today & tomorrow as you will have different responses. You don't need to create different intents unless you have different responses. User says can have different parameters for which you can define different prompts as well. This will again reduce your complexity of creating follow-up intents. Let me know if you need more explanation on this.

Designing an express API with user-created custom paths conflicting with other api end points

In my express app, a user can create a profile, and in doing so can choose a 'CustomUrl' that will be used to generate the url for their profile (example: http://www.myapp.com/profile/customUrl). A profile can also be reviewed, the end points for which might look like:
router.get('/reviews', ...) and router.post('/reviews/new',...)
The API endpoint for fetching a profile is below:
router.get('/:customUrl',...)
While I don't think a user would pick a customUrl like 'reviews', it is possible, and as such, my API endpoint to fetch their profile would be intercepted by the route to get '/reviews'.
I have a few ideas, but I'm generally new to Express, and wasn't sure if one way was better than another. Here are some of them:
1) I can put any end-point with a customUrl path above other end points. This doesn't sound acceptable as then the customUrl path would intercept any requests that are meant for '/reviews' etc.
2) I can validate a customUrl that it is not only unique, but is not an existing end point. This does not seem satisfactory as it does not scale well (would have to update the blacklist every time I add a new end point). It would also be problematic if a user has selected a customUrl that I later want to use for another end point.
3) Separate review out of profile and into its own route. This is probably the best solution, although it would present a lot of work that I'm hoping to avoid (there are other sub-routes name-spaced under '/profiles').
4) Put router.get('/reviews'...) above customUrl, but call next() if there is no req.query ('?sortBy=dateCreate' etc).
5) I didn't mention this earlier because it feels like I'd only be hiding the problem instead of fixing it, but my client-side is in React on a separate port, and so I could configure the router to display the url as .com/profile/:customUrl, but change the API end point to be something like: router.get('/',...) with a queryString of '?customUrl=...' or something like that. The url would then be 'www.myApp.com/profile/:customUrl' but the get request would be to 'api.myApp.com/profile/?customUrl=:customUrl', and the get request for reviews would be 'api.myApp.com/profile/reviews' (or something like that).
Anyway, I have a feeling that I'm missing something pretty fundamental. Any help would be great!
You probably just need to be RESTful with your route naming, for example:
GETing profile:
router.get('/profile/:customUrl', ...)
GETting reviews for a profile
router.get('/profile/:customUrl/reviews', ...)
POSTing a new review (note you don't need a route that says "new" as this can be determined by it being a POST request)
router.post('/profile/:customUrl/reviews',...)
You should use the following verbs for the reasons listed if you are being truly RESTful:
GET - Fetching records
POST - Adding records
PUT - Editing records
PATCH - Performing partial edits (e.g. not sending the whole document)
DELETE - Removing records

Combine multiple http request or not?

Some web design questions.
Combine POST with GET?
When user clicks a button, I need to send one POST to submit a form, then need to GET a json object to replace some DOM fields. Should I combine them into one request so save one round trip time?
Multiple GET json request?
When user clicks a button, I need to GET 3 or 4 json object. Should I send 3 or 4 GET request, or just one and combine the json into one large json at back-end?
So basically, I'm not sure which is heavier: round trip time VS a little complexed back-end and front-end logic.
Any comment is welcome!
if i understood your question right...you have a dependency on your get requests...that is to say the second get depends on the first...if that is the case, obviously you need to take consecutive get operations...however, if that is not the case that is if you know the order of get request and the response won't be affected by local conditions...then i suggest you do post/get operations on server side...trigger the first one an let the server handle the rest and get the result...
of course you would not want users do multiple get requests for one simple operation...

Need recommendations for pattern for now.js object sharing in group

I have an application where I want to use node.js and now.js to share the state of an object within a nowjs "group" across any number of clients.
As an example of what I'm trying to do, let's say that within the multiroom chat example that comes with now.js, there could be any number of rooms, with the ID chosen by the user. If the user knows the ID, they can enter (or be the first to "create") that room. There is a "history" object that is maintained for each room once it is created and communication starts happening. The history object contains a property or two, and an array of comment objects, each with a user property, a comment property, and a datetime property. When a new user connects, they should immediately have access to the history.
Is there a way to store a group-scoped object variable on the server to sync with? Am I thinking about this in the wrong way? Am I crazy or a little slow?
OK...I got it.
I have a new function createHistory(groupid) on the server side, which returns a new history object if it doesn't already exist when the user enters the room(group). This would occur if this user just created the room.
This history object employs add, remove and list methods. Since I need to get at the list from the client, it's important that I use a callback like the following:
api.get = (callback) ->
callback(_history)
I assign the result:
everyone.getGroup(this.now.groupid).now.history = createHistory(this.now.groupid)
Now I can add history at the server:
api.add = (time,user,text) ->
_history.items.push {time:time, user:user,text:text}
And get to it from my client:
now.history.get (history) ->
for item in history
#do something...
The only drawback is once the room is empty, the history evaporates...I think. Although I suppose you could check for the last disconnect and persist it somewhere if you wanted.

Resources