How to add a UTF-8 String of JSON within JSON in C

2019-07-29 16:40发布

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()))))

0条回答
登录 后发表回答