Search code examples
botframework

Bot Composer and BotBuilder FacebookAdapter resulting in "Object reference not set to an instance of an object"


I am using MS Bot Composer combined with BotBuilder Facebook Adapter in order to post my bot following the "new" rules of Facebook Workplace - important to remember that I've already tried to use this directly on Facebook Messenge, same situation applies.

The integration and connection works fine, the problem now is to understand how to post anything apart from text.

An example below of an attempt to get the correct template

# channelData
-```{
    "attachment":{
      "type":"template",
      "payload":{
        "template_type":"button",
        "text":"What do you want to do next?",
        "buttons":[
          {
            "type":"web_url",
            "url":"https://www.messenger.com",
            "title":"Visit Messenger"
          }
        ]
      }
    }
}```

enter image description here

And then, the bot's answer:

enter image description here


Solution

  • If you go the channel data route, the Facebook adapter expects you to provide a full FacebookMessage object as the channel data. That's one level up from the JSON you've provided, so it would look like this:

    {
      "message":{
        "attachment":{
          "type":"template",
          "payload":{
            "template_type":"button",
            "text":"What do you want to do next?",
            "buttons":[
              {
                "type":"web_url",
                "url":"https://www.messenger.com",
                "title":"Visit Messenger"
              }
            ]
          }
        }
      }
    }
    

    However, that won't work because it's missing the other properties a FacebookMessage needs, like sender. Rather than trying to populate the full Facebook message, it may be easier to just go the attachment route instead of the channel data route. You can see how to do that in the Facebook adapter sample:

    private static Attachment CreateTemplateAttachment(string filePath)
    {
        var templateAttachmentJson = File.ReadAllText(filePath);
        var templateAttachment = new Attachment()
        {
            ContentType = "template",
            Content = JsonConvert.DeserializeObject(templateAttachmentJson),
        };
        return templateAttachment;
    }
    

    In Composer, you can set the activity's attachments instead of its channel data. Just set the content type to "template" and the content to the payload of the attachment you have now, using the Facebook adapter sample's resources as a guide:

    # attachment
    - ```
    {
      "contentType": "template",
      "content": {
        "template_type": "button",
        "text": "What do you want to do next?",
        "buttons": [
          {
            "type": "web_url",
            "url": "https://www.messenger.com",
            "title": "Visit Messenger"
          }
        ]
      }
    }
    ```
    

    You can see how the Facebook adapter treats both channel data and attachments by having a look at the FacebookHelper class.