Facebook Messenger Integration Help!


(Jake) #1

Hi All,

Following on from Mark Zuckerberg’s home automation project and integration with Facebook messenger as a chat bot, I thought I’d try to do it myself… I’ve got as far as getting facebook messenger to authorise and to send events to ST… but my coding ability is limited… and can’t work out how to process the values in the POST request being sent to ST, which someone on here I expect could work out in 5 minutes?

Basically I’m at point 5 in this guide

https://developers.facebook.com/docs/messenger-platform/guides/quick-start

And some data info here:

https://developers.facebook.com/docs/messenger-platform/webhook-reference/message

And have the below code to receive the event:

mappings {
      path("/m") { action: [GET: "messengerGetHandler", POST: "messengerPostHandler"] }
}

def messengerPostHandler(){
      //somecode
}

Any help or collaboration would be sincerely welcomed…


(Jake) #2

Full code here, in case someone wants to play…:

definition(
    name: "Facebook Bot",
    namespace: "jebbett",
    author: "Jake Tebbett",
    description: "Facebook Bot",
    category: "My Apps",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png"
)

preferences {
	page name: "mainPage"
  
}

private mainPage() {
	dynamicPage(name: "mainPage", title: "", install: true, uninstall: true) {
		section ("What's My Name Sir?") { 
            input "verifyToken", "text", title: "Verify Token:", required: true
        }

        section(title: "Debugging") {
			input "debugLogging", "bool", title: "Enable Debug Logging", defaultValue: false, submitOnChange: true, required: false
        }
	}
}

mappings {
      path("/m") { action: [GET: "messengerGetHandler", POST: "messengerPostHandler"] }
}

def messengerGetHandler(){
    log.warn "FB MESSENGER GET EVENT: ${params}"
    if (params.hub.mode == 'subscribe' && params.hub.verify_token == settings.verifyToken) {
        log.debug "Validating webhook"
        render contentType: "text/html", data: params.hub.challenge, status: 200
    } else {
        log.debug "Failed validation. Make sure the validation tokens match."
        render contentType: "text/html", data: params.hub.challenge, status: 403        
    }
}

def messengerPostHandler(){

    log.warn "FB MESSENGER POST EVENT ${params}"
    
}




def installed() {
    initialize()
}

def updated() {
    unsubscribe()
    initialize()
}

def initialize() {
	// Create Access Token
	if (!state.accessToken) {
    	try {
		createAccessToken()
			logWriter("Created Access Token")
		} catch (e) {
			logWriter("Please enable OAuth in the IDE")
		}
    }
    // publish app ID and token to debug logging
    logWriter("STappID = '${app.id}' , STtoken = '${state.accessToken}'")
    
}

// Debug Logging
def logWriter(value) {
	if(debugLogging) {log.debug "${app.label} >> ${value}"}
}

// URL for use in developers.facebook.com.. remember to update below URL to match your IDE URL
//  https://graph-eu01-euwest1.api.smartthings.com/api/smartapps/installations/XXXXXXXXXX_APP_ID_XXXXXXXXXXXXXXX/m?access_token=XXXXXXXXXX_TOKEN_XXXXXXXXXXXXXXX

(Jake) #3

Managed to figure it all out! It’s alive!!


(Mark Trott) #4

Hi so what can you do with this exactly?


(Jake) #5

Basically whatever you want, it’ll sent the sent text to your app…

I have mine triggering child apps in another home automation app I wrote… so I can control my house like Mark Zuckerberg :slight_smile:

I’ll post some code once I’ve finished writing it…


(Jake) #6

Here’s the basic code outline for anyone to use, you will need to validate the user ID in your code to stop just anyone sending messages in to your home:

Feel free to grab and use the code as you all want in your own apps…

definition(
    name: "Facebook Bot",
    namespace: "jebbett",
    author: "Jake Tebbett",
    description: "Facebook Bot",
    category: "My Apps",
	iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png"
)

preferences {
	page name: "mainPage"
}

private mainPage() {
	dynamicPage(name: "mainPage", title: "", install: true, uninstall: true) {
		section ("Facebook Messenger Linking") { 
            input "verifyToken", "password", title: "Verify Token", description:"", required: true
            input "fbAccessToken", "password", title: "FB Page Access Token", description:"", required: true
            paragraph "Verify Token: Used to setup link to FB bot (You make up this value)\nAccess Token: To allow ST to send messages via FB Messenger (From developers.facebook.com)"
        }
	}
}

mappings {
      path("/m") { action: [GET: "messengerGetHandler", POST: "messengerPostHandler"] }
}

def messengerGetHandler(){
    log.warn "FB MESSENGER GET EVENT: ${params}"
    if (params.hub.mode == 'subscribe' && params.hub.verify_token == settings.verifyToken) {
        log.debug "Validating webhook"
        render contentType: "text/html", data: params.hub.challenge, status: 200
    } else {
        log.debug "Failed validation. Make sure the Verify Tokens match."
        render contentType: "text/html", data: params.hub.challenge, status: 403        
    }
}

def messengerPostHandler(){
    def fbJSON = request.JSON
    log.debug "FB MESSENGER POST EVENT: ${params}"
    log.debug "FB MESSENGER POST EVENT - JSONREQUEST:  ${fbJSON}"
    log.debug "FB MESSENGER POST EVENT - MESSAGE:  ${fbJSON.entry.messaging.message.text[0][0]}"
    log.debug "FB MESSENGER POST EVENT - SENDER_ID:  ${fbJSON.entry.messaging.sender.id[0][0]}"
    
    def params = [
        uri: "https://graph.facebook.com/v2.6/me/messages?access_token=$fbAccessToken",
        body: [
            recipient: [id: fbJSON.entry.messaging.sender.id[0][0]],
            message: [text: "hello, world!"]
        ]
    ]

    try {
        httpPostJson(params) { resp ->
            resp.headers.each {
                log.debug "${it.name} : ${it.value}"
            }
            log.debug "response contentType: ${resp.contentType}"
        }
    } catch (e) {
        log.debug "something went wrong: $e"
    }
}

def installed() {
    initialize()
}

def updated() {
    unsubscribe()
    initialize()
}

def initialize() {
	// Create Access Token
	if (!state.accessToken) {
    	try {
		createAccessToken()
			log.debug "Created Access Token"
		} catch (e) {
			log.debug "Please enable OAuth in the IDE"
		}
    }
    // publish app ID and token to debug logging
    log.debug "URL FOR USE AT DEVELOPERS.FACEBOOK.COM:  ${getApiServerUrl()}/api/smartapps/installations/${app.id}/m?access_token=${state.accessToken}"
}

(Activation Required) #7

Could the same type of integration be done using Microsoft’s Bot Framework? I am interested in having Cortana send and receive notifications to/from ST. Ideas?


(Jake) #8

It seems possible, slightly more complicated than facebook, but not hugely so… the method is very similar to facebook…

Details here for anyone who has time to look in to it…

https://docs.botframework.com/en-us/restapi/connector/#!/Conversations/Conversations_GetConversationMembers

For the Facebook bot I now have it returning buttons to trigger actions, so if I send “List” it’ll return buttons for actions I can trigger, although the API limits it to 11 buttons which is a shame…


#9

are you going to post any more code? I’d be curious to see what your facebook bot actually does :slight_smile: thank you for posting the smartapp code.


(Jake) #10

The only integration I have written is with my SmarterHome app, I can also trigger CoRE pistons with a work around although I’d like to make that official I haven’t had the time to discuss it with the project… I don’t have anything to integrate with standard ST devices… but I don’t think there’s a lot of demand based on activity on this thread :slight_smile:


#11

Aww, thanks for the response. I got something working with https://rundexter.com and the JSON smart app… works pretty well :slight_smile:


(Jake) #12

Cool would be good to see what you’ve done! Mine is available on my GitHub it’s called Barker and does both Facebook and Echo integration but again really only works today with SmarterHome, Echosistant will likely add the same functionality in the future as well… but they have other more important things going on at the moment :slight_smile:


(Luis Alonzo) #13

Could you detail a little more the required setup? I install the smartapp above but cant pass the first page while config, not sure which number i need for Access Token, got into developers.facebook.com, create an app, and there i have ID and secret key from the app in basic info, which one is the access token and fb page access token? Can you help me with this, i’m not familiarize with it. Thanks,


(Jake) #14

Have you enabled OAuth in the IDE? If you do that then that should give you the detail to link the two…

To add if you enable OAuth, log in to live logging go in to the app and press done, it should return the URL to drop in to facebook


(Luis Alonzo) #15

I did enable oauth in the smartapp settings, just click enable, didnt fill any textbox. However on the live long i got this after hit ‘done’:

4e9c25be-ad96-4aac-8926-b31199ac11c1 10:22:06 AM: error groovy.lang.MissingMethodException: No signature of method: script14975435725981329063166.logWriter() is applicable for argument types: (java.lang.String) values: [Please enable OAuth in the IDE] @ line 84

on the smartapp i fill verify token with random numbers, and for Access token i use the secret key i got from facebook, looks something like this: 945d306c16ab2b462a1dda9a23b1b299, is that the value or do i need to use secret key from smartapp?


(Jake) #16

Hey sorry, I’ve just updated my code above, I left a bit in from my code that shouldn’t have been in the code above… update and try again… should be fine then…


(Luis Alonzo) #17

That worked, thanks, i no longer had issues to setup. On live logging got link like this:
https://graph-na02-useast1.api.smartthings.com:443/api/smartapps/installations/46516584561c-8926-b31199acdas/m?access_token=56a

What do i do with link? How do i test this? i believe not fully understand how to link smartapp with fb.

Btw, after hit done, i get this after a few seconds:

4e9c25be-ad96-4aac-8926-b31199ac11c1 12:58:38 PM: error java.lang.NullPointerException: Cannot get property ‘mode’ on null object @ line 32

Thanks for the help and patience, i’m new on this kind of integrations.


(Jake) #18

Firstly edit your above post to remove that link, you don’t want to share that!

Secondly that link you need to setup in Facebook dev along with the verify token that you have put in the smart app… Facebook dev will then give you the Facebook access token and then you can paste that in the app…


(Jake) #19

By the way the post handler portion of the code is where your message is received in to ST.

The below will contain the message, you can see in the code all this is doing currently is posting the values to live logging

fbJSON.entry.messaging.message.text[0][0]

hello, world! is the response that should come back in to facebook, obviously you could change the code to update this to something more dynamic.