2

Had written bot on ms bot frameworks for Facebook Messenger which creates carousel using custom channel data attachment with web_url which enables messenger extensions: "messenger_extensions": true. We have Added Messenger Extensions on a webview page but it is not clear how to send message with an attachment from this webview page back to messenger and therefore to bot framework.

<!DOCTYPE html>
<html>

<body>
    <style type="text/css">
        .button {
            background-color: #4CAF50;
            /* Green */
            border: none;
            color: white;
            padding: 15px 32px;
            text-align: center;
            text-decoration: none;
            display: inline-block;
            font-size: 16px;
            width: 50%;
            margin: 25%;
        }
    </style>

    <button type="button" class="button" onclick="sendMessage();">Complete Booking</button>

    <script type="text/javascript">
        function sendMessage() {
            alert('Booking completed. What to do now? How to send the message back to bot?')
            /// how to return? the facebook docs don't say anything
            /// you HAVE to make a server round trip.. https://stackoverflow.com/questions/43956045/messengerextensions-how-to-send-a-message-by-messenger-to-users
            return {
                text: "HOTEL_SERVICE_PAYLOAD",
                attachments: [
                    {
                        email: "some@email.com",
                        hotelName: "Hotel marriott",
                        confirmNumber: "1234567"
                    }
                ]
            }
            MessengerExtensions.requestCloseBrowser(function success() {

            }, function error(err) {

            });
        }

        (function (d, s, id) {
            var js, fjs = d.getElementsByTagName(s)[0];
            if (d.getElementById(id)) { return; }
            js = d.createElement(s); js.id = id;
            js.src = "//connect.facebook.com/en_US/messenger.Extensions.js";
            fjs.parentNode.insertBefore(js, fjs);
        }(document, "script", "Messenger"));

        window.extAsyncInit = function () {
            // the Messenger Extensions JS SDK is done loading
            MessengerExtensions.getUserID(function success(uids) {
                var psid = uids.psid;//This is your page scoped sender_id
                alert("Getting PSID")
                alert("This is the user's psid " + psid);
            }, function error(err) {
                alert("Messenger Extension Error: " + err);
            });
        };
    </script>
</body>
</html>

Have read tons of documentation and blogs including stackoverflow: https://stackoverflow.com/a/44536739/630169.

Is there simple example of JavaScript script embedded on a page? Thanks!

Aleksey Kontsevich
  • 4,671
  • 4
  • 46
  • 101

2 Answers2

3

If I'm understand the question right, you could set up an API endpoint that triggers a message send, and hit that endpoint in the success callback of ` MessengerExtensions.requestCloseBrowser().

Example using jQuery and node's express module:

Webview:

window.extAsyncInit = function () {
    // the Messenger Extensions JS SDK is done loading
    MessengerExtensions.getUserID(function success(uids) {
        var psid = uids.psid;//This is your page scoped sender_id
        $.post('https://myapi.com/sendOnWebviewClose', {"psid": psid})
    }, function error(err) {
        alert("Messenger Extension Error: " + err);
    });
};

Server:

app.post('/sendOnWebviewClose', (req, res) => {
  let psid = req.body.psid;
  sendMessage(psid);
})
amuramoto
  • 2,838
  • 1
  • 11
  • 15
  • 1
    Probably it is possible, but question how to convert this `psid` to bot builder `message.address` object (`IAddress`): ```{ "address": { "id": "mi888mlbigbg4d469", "channelId": "emulator", "user": { "id": "default-user", "name": "User" }, "conversation": { "id": "dehg2kfnh9703g94c" }, "bot": { "id": "default-bot", "name": "Bot" }, "serviceUrl": "http://127.0.0.1:46839" } }``` to send message back to user??? – Aleksey Kontsevich Aug 28 '17 at 17:43
  • So summarizing: problem is in Your `sendMessage(psid);` - how to implement this? Ms Bot Framework code for sending messages is: var `reply = new builder.Message() .address(address) .text("Hi!"); bot.send(reply);` How to make `IAddress` object from `PSID` in this case? – Aleksey Kontsevich Aug 28 '17 at 17:51
  • 1
    Ok, I see. In that case you wouldn't pass PSID back to your back end. One option could be to pass the id from the conversation data as a query param when you open the webview. So, for example, if you were opening the webview with a url button: "buttons":[ { "type":"web_url", "url":"https://mywebviewurl.com/?conversationID=", "title":"View Item", } ] Then you could parse the id out and pass it back tot he backend when the webview is closed: $.post('https://myapi.com/sendOnWebviewClose', {"id": idFromURLQuery}) – amuramoto Aug 28 '17 at 18:24
  • I'm not very familiar with bot builder, but that seems like it would be a possible way to persist the conversation id from the webview back to the server – amuramoto Aug 28 '17 at 18:25
  • Ok, this could work, however not sure FB allows to send request parameters in url - hope it can (they said only port number is not allowed). However if can send some postback directly to messenger and bot from webview - that would be better more smooth way. – Aleksey Kontsevich Aug 28 '17 at 19:02
  • We discovered today: PSID equivalent to is Facebook user Id and User Id in `IAddress` structure in `message.address` in bot framework. So it is possible to send message back by bot builder methods using cached `address` object for this user. – Aleksey Kontsevich Aug 29 '17 at 22:03
  • 1
    Security concern: if a user chats on the web Messenger, the code is easily inspectable via developer tools. Your `/sendOnWebviewClose` endpoint would be exposed, and anybody could be able to send messages on behalf of the bot. – gsid Jun 07 '18 at 15:13
  • There is a Security issue with above solution. Exposing a public endpoint and no way to check the authenticity – Gaurav Singla Sep 18 '18 at 06:32
2

It is possible to send parameters with the get request, (https://someurl?userChannelID=) and then use them in your js code, to triger a message from your sever (we use directline)

Yochai Lehman
  • 323
  • 3
  • 8