• Resolved brzadzki

    (@brzadzki)


    Do videos work?

    I have My Chatbot setup as Facebook Messenger and a DialogFlow intent returning a Facebook video payload. No video appears in the chat.

Viewing 5 replies - 1 through 5 (of 5 total)
  • Thread Starter brzadzki

    (@brzadzki)

    Update:

    I just noticed in the docs that video is not supported, but it was a quick add. This works well with Facebook-style video payloads like this one:

    
    {
      "facebook": {
        "attachment": {
          "type": "video",
          "payload": {
            "url": "https://url.of.your/video.mp4"
          }
        }
      }
    }
    

    Replace assets/js/frontend.js with this to get it working:

    
    // Based on blog post: https://www.sitepoint.com/how-to-build-your-own-ai-assistant-using-api-ai/
    // Source code: https://github.com/sitepoint-editors/Api-AI-Personal-Assistant-Demo/blob/master/index.html.
    // Demo: https://devdiner.com/demos/barry/
    
    // When ready :)
    jQuery(document).ready(function() {
    
        /*
         * When the user enters text in the text input text field and then the presses Enter key
         */
        jQuery("input#myc-text").keypress(function(event) {
            if (event.which == 13) {
                event.preventDefault();
                jQuery("#myc-conversation-area .myc-conversation-request").removeClass("myc-is-active");
                var text = jQuery("input#myc-text").val();
                var date = new Date();
                var innerHTML = "<div class=\"myc-conversation-bubble-container myc-conversation-bubble-container-request\"><div class=\"myc-conversation-bubble myc-conversation-request myc-is-active\">" + text + "</div>";
                if (myc_script_vars.show_time) {
                    innerHTML += "<div class=\"myc-datetime\">" + date.toLocaleTimeString() + "</div>";
                }
                innerHTML += "</div>";
                if (myc_script_vars.show_loading) {
                    innerHTML += "<div class=\"myc-loading\"><i class=\"myc-icon-loading-dot\" /><i class=\"myc-icon-loading-dot\" /><i class=\"myc-icon-loading-dot\" /></div>";
                }
                jQuery("#myc-conversation-area").append(innerHTML);
                jQuery("input#myc-text").val("");
                jQuery("#myc-conversation-area").scrollTop(jQuery("#myc-conversation-area").prop("scrollHeight"));
                textQuery(text);
            }
        });
    
        /*
         * Welcome
         */
        if (myc_script_vars.enable_welcome_event) {
            jQuery.ajax({
                type : "POST",
                url : myc_script_vars.base_url + "query?v=" + myc_script_vars.version_date,
                contentType : "application/json; charset=utf-8",
                dataType : "json",
                headers : {
                    "Authorization" : "Bearer " + myc_script_vars.access_token
                },
                data : JSON.stringify( {
                    event : {
                        name : "WELCOME"
                    },
                    lang : "en",
                    sessionId : myc_script_vars.session_id,
                } ),
                success : function(response) {
                    prepareResponse(response);
                },
                error : function(response) {
                    textResponse(myc_script_vars.messages.internal_error);
                    jQuery("#myc-conversation-area").scrollTop(jQuery("#myc-conversation-area").prop("scrollHeight"));
                }
            });
        }
    
        /* Overlay slide toggle */
        jQuery(".myc-content-overlay .myc-content-overlay-header").click(function(event){
    
            if (jQuery(this).find(".myc-icon-toggle-up").css("display") !== "none") {
                jQuery(this).find(".myc-icon-toggle-up").hide();
                jQuery(this).parent().removeClass("myc-toggle-closed");
                jQuery(this).parent().addClass("myc-toggle-open");
                jQuery(this).find(".myc-icon-toggle-down").show();
                jQuery(this).siblings(".myc-content-overlay-container, .myc-content-overlay-powered-by").slideToggle("slow", function() {});
            } else {
                jQuery(this).find(".myc-icon-toggle-down").hide();
                jQuery(this).parent().removeClass("myc-toggle-open");
                jQuery(this).parent().addClass("myc-toggle-closed");
                jQuery(this).find(".myc-icon-toggle-up").show();
                jQuery(this).siblings(".myc-content-overlay-container, .myc-content-overlay-powered-by").slideToggle("slow", function() {});
            }
        });
    
    });
    
    /**
     * Send Dialogflow query
     *
     * @param text
     * @returns
     */
    function textQuery(text) {
    
        jQuery.ajax({
            type : "POST",
            url : myc_script_vars.base_url + "query?v=" + myc_script_vars.version_date,
            contentType : "application/json; charset=utf-8",
            dataType : "json",
            headers : {
                "Authorization" : "Bearer " + myc_script_vars.access_token
            },
            data: JSON.stringify( {
                query: text,
                lang: "en",
                sessionId: myc_script_vars.session_id
            } ),
            success : function(response) {
                setTimeout(function(){
                    if (myc_script_vars.show_loading) {
                        jQuery(".myc-loading").empty();
                    }
                    prepareResponse(response);
                }, myc_script_vars.response_delay);
    
            },
            error : function(response) {
                if (myc_script_vars.show_loading) {
                    jQuery(".myc-loading").empty();
                }
                textResponse(myc_script_vars.messages.internal_error);
                jQuery("#myc-conversation-area").scrollTop(jQuery("#myc-conversation-area").prop("scrollHeight"));
            }
        });
    }
    
    /**
     * Handle Dialogflow response
     *
     * @param response
     */
    function prepareResponse(response) {
    
        if (response.status.code == "200" ) {
    
            jQuery(window).trigger("myc_response_success", response);
    
            jQuery("#myc-conversation-area .myc-conversation-response").removeClass("myc-is-active");
    
            var messages = response.result.fulfillment.messages;
            var numMessages = messages.length;
            var index = 0;
            for (index; index<numMessages; index++) {
                var message = messages[index];
    
                if (myc_script_vars.messaging_platform == message.platform
                        || myc_script_vars.messaging_platform == "default" && message.platform === undefined
                        || message.platform === undefined && ! hasPlatform(messages, myc_script_vars.messaging_platform) ) {
    
                    switch (message.type) {
                        case 0: // text response
                            textResponse(message.speech);
                            break;
                        case 1: // card response
                            cardResponse(message.title, message.subtitle, message.buttons, message.text, message.postback);
                            break;
                        case 2: // quick replies
                            quickRepliesResponse(message.title, message.replies);
                            break;
                        case 3: // image response
                            imageResponse(message.imageUrl);
                            break;
                        case 3: // custom payload
    
                            break;
                        case 4: // video response
                            videoResponse(message.payload.facebook.attachment.payload.url);
                            break;
                        default:
                    }
                }
            }
    
        } else {
            textResponse(myc_script_vars.messages.internal_error);
        }
    
        jQuery("#myc-conversation-area").scrollTop(jQuery("#myc-conversation-area").prop("scrollHeight"));
    
        if (jQuery("#myc-debug-data").length) {
            var debugData = JSON.stringify(response, undefined, 2);
            jQuery("#myc-debug-data").text(debugData);
        }
    }
    
    /**
     * Checks if messages support a specific platform
     *
     * @param messages
     * @param platform
     * @returns {Boolean}
     */
    function hasPlatform(messages, platform) {
        var numMessages = messages.length;
        var index = 0;
        for (index; index<numMessages; index++) {
            var message = messages[index];
            if (message.platform === platform) {
                return true;
            }
        }
    
        return false;
    }
    
    /**
     * Displays a text response
     *
     * @param text
     * @returns
     */
    function textResponse(text) {
        if (text === "") {
            text = myc_script_vars.messages.internal_error;
        }
        var date = new Date();
        var innerHTML = "<div class=\"myc-conversation-bubble-container myc-conversation-bubble-container-response\"><div class=\"myc-conversation-bubble myc-conversation-response myc-is-active myc-text-response\">" + text + "</div>";
        if (myc_script_vars.show_time) {
            innerHTML += "<div class=\"myc-datetime\">" + date.toLocaleTimeString() + "</div>";
        }
        innerHTML += "</div>";
        jQuery("#myc-conversation-area").append(innerHTML);
    }
    
    /**
     * Displays a image response
     *
     * @param imageUrl
     * @returns
     */
    function imageResponse(imageUrl) {
        if (imageUrl === "") {
            textResponse(myc_script_vars.messages.internal_error)
        } else {
            // FIXME wait for image to load by creating HTML first
            var date = new Date();
            var innerHTML = "<div class=\"myc-conversation-bubble-container myc-conversation-bubble-container-response\"><div class=\"myc-conversation-bubble myc-conversation-response myc-is-active myc-image-response\"><img src=\"" + imageUrl + "\"/></div>";
            if (myc_script_vars.show_time) {
                innerHTML += "<div class=\"myc-datetime\">" + date.toLocaleTimeString() + "</div>";
            }
            innerHTML += "</div>";
            jQuery("#myc-conversation-area").append(innerHTML);
        }
    }
    
    /**
     * Card response
     *
     * @param title
     * @param subtitle
     * @param buttons
     * @param text
     * @param postback
     */
    function cardResponse(title, subtitle, buttons, text, postback) {
        var html = "<div class=\"myc-card-title\">" + title + "</div>";
        html += "<div class=\"myc-card-subtitle\">" + subtitle + "</div>";
        // TODO
    }
    
    /**
     * Quick replies response
     *
     * @param title
     * @param replies
     */
    function quickRepliesResponse(title, replies) {
    
        var html = "<div class=\"myc-quick-replies-title\">" + title + "</div>";
    
        var index = 0;
        for (index; index<replies.length; index++) {
            html += "<input type=\"button\" class=\"myc-quick-reply\" value=\"" + replies[index] + "\" />";
        }
    
        var date = new Date();
        var innerHTML = "<div class=\"myc-conversation-bubble-container myc-conversation-bubble-container-response\"><div class=\"myc-conversation-bubble myc-conversation-response myc-is-active myc-quick-replies-response\">" + html + "</div>";
        if (myc_script_vars.show_time) {
            innerHTML += "<div class=\"myc-datetime\">" + date.toLocaleTimeString() + "</div>";
        }
        innerHTML += "</div>";
        jQuery("#myc-conversation-area").append(innerHTML);
    
        jQuery("#myc-conversation-area .myc-is-active .myc-quick-reply").click(function(event) {
            event.preventDefault();
            jQuery("#myc-conversation-area .myc-conversation-request").removeClass("myc-is-active");
            var text = jQuery(this).val()
            var date = new Date();
            var innerHTML = "<div class=\"myc-conversation-bubble-container myc-conversation-bubble-container-request\"><div class=\"myc-conversation-bubble myc-conversation-request myc-is-active\">" + text + "</div>";
            if (myc_script_vars.show_time) {
                innerHTML += "<div class=\"myc-datetime\">" + date.toLocaleTimeString() + "</div>";
            }
            if (myc_script_vars.show_loading) {
                innerHTML += "<div class=\"myc-loading\"><i class=\"myc-icon-loading-dot\" /><i class=\"myc-icon-loading-dot\" /><i class=\"myc-icon-loading-dot\" /></div>";
            }
            innerHTML += "</div>";
            jQuery("#myc-conversation-area").append(innerHTML);
            textQuery(text);
        });
    
    }
    
    /**
     * Displays a video response
     * Added by Bob Rzadzki Feb 14, 2018
     *
     * @param videoUrl
     * @returns
     */
    function videoResponse(videoUrl) {
        if (videoUrl === "") {
            textResponse(myc_script_vars.messages.internal_error)
        } else {
            // FIXME wait for image to load by creating HTML first
            var date = new Date();
            var innerHTML = "<div class=\"myc-conversation-bubble-container myc-conversation-bubble-container-response\"><div class=\"myc-conversation-bubble myc-conversation-response myc-is-active myc-image-response\"><video controls autoplay src=\"" + videoUrl + "\"/></div>";
            if (myc_script_vars.show_time) {
                innerHTML += "<div class=\"myc-datetime\">" + date.toLocaleTimeString() + "</div>";
            }
            innerHTML += "</div>";
            jQuery("#myc-conversation-area").append(innerHTML);
        }
    }
    
    /**
     * Custom payload
     *
     * @param payload
     */
    function customPayload(payload) {
    
    }
    
    Plugin Author dpowney

    (@dpowney)

    Thanks for the code sample. Appreciated.

    To include this functionality into the plugin it would need to be done generically. So case 4 passing the message.payload.facebook.attachment.payload.url value to the videoResponse() function would need to be done a different way. Any ideas?

    Thanks,
    Daniel

    Thread Starter brzadzki

    (@brzadzki)

    Hey Daniel, thanks for checking it out. And for the plugin — works great and the code is very clean and easy to augment.

    Best I can think of to generify it would be to switch again inside case 4 looking for the platform and then the payload according to their APIs. This is kind of sticky because I did this one mimicking a Facebook video payload, which DialogFlow only allows as a custom payload… So it’s compliant with the Send API, but it’s not perfectly obvious how it’s done on the DialogFlow side.

    This is the full contents of the custom payload I added to DialogFlow under my Facebook responses, for reference:

    
    {
      "facebook": {
        "attachment": {
          "type": "video",
          "payload": {
            "url": "https://domain.com/video.mp4"
          }
        }
      }
    }
    

    I suppose the other way to do this, maybe a bit cleaner, would be to process each message as it’s coming in and normalize out its platform-specific fields into generic ones. I might be missing some additional complexity; I ended up hard-wiring everything for my application to use FB-style messages.

    By the way, unrelated fix: I found that the chat balloons were stretching past the right edge of the chat window (and the browser window) in Safari. I removed line 3 of assets/css/frontend.css — min-width: 500px; — and it now looks consistent across every browser I’ve tried. Even works perfectly in IE which… Well I was impressed.

    Thanks again for a great batch of code.

    Best,
    Bob

    Plugin Author dpowney

    (@dpowney)

    Thanks. I will need to ponder that. Feel free to leave a review. πŸ™‚ Cheers, Daniel

    We can user Youtube iframe in text response

    Like:

    See:
    <iframe width=”560″ height=”315″ src=”https://www.youtube.com/embed/JtHjsrvP-wU&#8221; frameborder=”0″ allow=”autoplay; encrypted-media” allowfullscreen></iframe>

Viewing 5 replies - 1 through 5 (of 5 total)

The topic ‘Video support?’ is closed to new replies.