I'm creating a menu for my Facebook bot by posting some JSON to their API. The payload is required to be a UTF-8 string. I would like this string to be JSON such that my server can read it easily. The following results in the error "setting_type" is required which indicates something is not being escaped properly:
curl -X POST -H "Content-Type: application/json" -d '{
"setting_type" : "call_to_actions",
"thread_state" : "existing_thread",
"call_to_actions":[
{
"type":"postback",
"title":"Schedule",
"payload":"{"action":"schedule"}"
},
{
"type":"postback",
"title":"Cancel",
"payload":"{"action":"cancel"}"
},
{
"type":"postback",
"title":"View",
"payload":"{"action":"view"}"
}
]
}' "https://graph.facebook.com/v2.6/me/thread_settings?access_token=TOKEN"
A solution is to escape the double quotes inside the payload:
curl -X POST -H "Content-Type: application/json" -d '{
"setting_type" : "call_to_actions",
"thread_state" : "existing_thread",
"call_to_actions":[
{
"type":"postback",
"title":"Schedule",
"payload":"{\"action\":\"schedule\"}"
},
{
"type":"postback",
"title":"Cancel",
"payload":"{\"action\":\"cancel\"}"
},
{
"type":"postback",
"title":"View",
"payload":"{\"action\":\"view\"}"
}
]
}' "https://graph.facebook.com/v2.6/me/thread_settings?access_token=TOKEN"
This succeeds. However when the payload is sent to me it looks like this:
"payload":"{\"action\":\"schedule\"}"}
and thus does not parse properly.
UPDATE
I've written the same procedure in Scala using the Play! framework:
def getMenuJson(greeting: String, schedule: String, cancel: String, view: String)(implicit sd: String): JsValue = {
log.info(Json.toJson(BotPayload("schedule", None)).toString())
val menu = Outgoing(
Recipient(sd),
OutMessage(
Some(OutAttachment(
"template",
Payload("button", greeting, List(
Button("postback", None, Some(schedule), Some(Json.toJson(BotPayload("schedule", None)).toString())),
Button("postback", None, Some(cancel), Some(Json.toJson(BotPayload("cancel", None)).toString())),
Button("postback", None, Some(view), Some(Json.toJson(BotPayload("view", None)).toString()))
))
)), None)
)
Json.toJson(menu)
}
The log statement that appears at the top of the function outputs:
{"action":"schedule"}
which implies the JSON in payload is correctly being formatted as a string. Now when a user presses the schedule button from Facebook I get back for the payload:
"payload":"{\"action\":\"schedule\"}"
So perhaps the second Curl command was fine and I just need to deal with parsing the JSON with escaped quotes.
UPDATE 2
Working on parsing the result. This isn't quite working:
implicit val botPayloadReads: Reads[BotPayload] = (
(JsPath \ """\"action\"""").read[String] and
(JsPath \ """"\"returnToAction\"""").readNullable[String]
)(BotPayload.apply _)
Error:
List((/entry(0)/messaging(0)/postback/payload/\"action\",List(ValidationError(List(error.path.missing),WrappedArray()))))