I'm using Twilio Autopilot's Collect feature to collect user input via phone or SMS. At the conclusion of the collect task, I redirect via POST to an endpoint in my Spring Boot application. I'd like for my Spring Boot app to validate the user's inputs and then return the expected Action JSON back to Twilio to let the user know that their data has been successfully recorded and validated. Here is what my Collect task looks like:
{
"actions": [
{
"say": "Hello!"
},
{
"collect": {
"name": "get_prices",
"questions": [
{
"question": " Please enter the current price for 100 low led using the dial pad. When you are finished, press pound.",
"voice_digits": {
"finish_on_key": "#"
},
"name": "price_100ll",
"type": "Twilio.NUMBER",
"validate": {
"on_failure": {
"messages": [
{
"say": "Sorry, I didn't quite get that."
}
],
"repeat_question": true
},
"on_success": {
"say": "Great, we have successfully recorded your 100 low led price."
}
}
}
],
"on_complete": {
"redirect": {
"method": "POST",
"uri": "https://<ngrok url pointing at my Spring Boot app>/report"
}
}
}
}
]
}
Here is the POST endpoint in my controller in Spring Boot:
@PostMapping(value = "/report", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public ResponseEntity<Void> report(Object body) {
return ResponseEntity.ok().build();
}
I believe that I have the POST endpoint set up incorrectly. body
is always an empty object. I have the Twilio SDK as a dependency but I'm not sure which classes to use to get the Memory
body containing the user input data out of the POST request. There is Twilio documentation for using Twilio functions to use this, but not an external app. Does anyone have any ideas or advice on how to do this?
CodePudding user response:
I didn't use Autopilot but from what I see it will send the answers to your endpoint with the "Memory" parameter.
Assuming the incoming request is something like this:
https://<Ngrok URL>/report?Memory={"twilio": {...}}
You can get this request as below and then convert it to a model or key value store.
@PostMapping(value = "/report")
@CrossOrigin(origins = "*", allowedHeaders = "*")
public ResponseEntity<Void> report(@RequestParam(value = "Memory") String memory) {
try {
Map<String, Object> answer = new ObjectMapper()
.readValue(memory, Map.class);
return ResponseEntity.ok().build();
} catch (Exception e) {
return ResponseEntity.internalServerError().build();
}
}