How to format this map to be encoded into JSON like Facebook's Messenger API?

I’m storing some state in Agents to output a map to be encoded into JSON, the Messenger API has this JSON:

...
"message":{
    "attachment":{
      "type":"template",
      "payload":{
        "template_type":"generic",
        "elements":[
           {
            "title":"Welcome to Peter\'s Hats",
            "image_url":"https://petersfancybrownhats.com/company_image.png",
            "subtitle":"We\'ve got the right hat for everyone.",
            "default_action": {
              "type": "web_url",
              "url": "https://peterssendreceiveapp.ngrok.io/view?item=103",
              "messenger_extensions": true,
              "webview_height_ratio": "tall",
              "fallback_url": "https://peterssendreceiveapp.ngrok.io/"
            },
            "buttons":[
              {
                "type":"web_url",
                "url":"https://petersfancybrownhats.com",
                "title":"View Website"
              },{
                "type":"postback",
                "title":"Start Chatting",
                "payload":"DEVELOPER_DEFINED_PAYLOAD"
              }              
            ]      
          }
        ]
      }
    }
  }
...

The problem I’m having is with this section here:

...
"elements":[
       {
        "title":"Welcome to Peter\'s Hats",
        "image_url":"https://petersfancybrownhats.com/company_image.png",
        "subtitle":"We\'ve got the right hat for everyone.",
        "default_action": {
          "type": "web_url",
          "url": "https://peterssendreceiveapp.ngrok.io/view?item=103",
          "messenger_extensions": true,
          "webview_height_ratio": "tall",
          "fallback_url": "https://peterssendreceiveapp.ngrok.io/"
        },
        "buttons":[
          {
            "type":"web_url",
            "url":"https://petersfancybrownhats.com",
            "title":"View Website"
          }
...

In my understanding, from "elements" that’s a list then a map and on "buttons" a list with another map or maps and I’m building the map like this:

[
  elements, # Here the list is [%{something: true, title: "something"}]
  buttons: buttons # And here is another list
]

After what’s above I’m using List.flatten and the output is like below.

%{message: %{attachment: %{payload: %{elements: [%{something: true,
           title: "something"},
         {:buttons,
          [%{title: "Go to Google", type: "web_url", url: "https://google.com"},
           %{title: "Go to Facebook", type: "web_url",
             url: "https://facebook.com"}]}], template_type: "generic"},
      type: "template"}}, recipient: %{id: 123}}

The thing here is that on the :elements list there’s a tuple on the :buttons field which results in an error from Poison.encode and I don’t know how to format the output of the function to be correctly encoded into the JSON expected from Facebook’s side.

That is entirely wrong JSON and is definitely not what it is wanting. ^.^

That’s what’s on Facebook’s example and I ran that example on JSONlint and it was valid.

Forgive me if I’m wrong, but this is just a trick of the eye. What LOOKS like a list with its first element being an object, and the second being “"buttons":[...]” is actually just a list with one object in it (which "buttons" is a part of.) The brace that looks like it closes the object actually closes "default_action".

So just put the buttons key inside your object and you should be golden.

1 Like

OOOH, you’re totally right, I completely missed that curly brace! Thank you!

1 Like