jgorset / facebook-messenger

Definitely the best way to make Bots on Facebook Messenger with Ruby
MIT License
962 stars 211 forks source link

Postback callback not triggered on click in the persistent menu #196

Closed Guillaumejfrt closed 6 years ago

Guillaumejfrt commented 6 years ago

Hi @jgorset,

I have a bot live which has a strange behaviour. The postback callback doest not always work in the persistent menu.

Sometimes, the callback is triggered but sometimes nothing happens (no action appears in the logs).

Here is my persistent menu:

Facebook::Messenger::Profile.set({
  get_started: {
    payload: 'GET_STARTED_PAYLOAD'
  },
  greeting: [
    {
      locale: 'default',
      text: 'Welcome to Coachat!!!'
    },
    {
      locale: 'fr_FR',
      text: 'Bienvenue sur Coachat!!!'
    }
  ],
  persistent_menu:[
      {
        locale: "default",
        call_to_actions: [
          {
            title:"Parler à mon diététicien",
            type: "postback",
            payload: "TALK_TO_DIET"
          },
          {
            title: "Parler au chatbot",
            type: "postback",
            payload: "TALK_TO_BOT"
          },
          {
            title: "Mon profil nutritionnel",
            type: "postback",
            payload: "QUESTIONNAIRE"
          }
        ]
      }
    ]
}, access_token: ENV.fetch("ACCESS_TOKEN"))

Here is my postback callback which I placed just above the persistent menu (by the way, does the order of methods and callback in the bot.rb file has an importance? In other words, dhould I place the persistent menu above the postback callback?)

# Postback call back when a fbuser clicks on a postback button
Bot.on :postback do |postback|
  sender_id = postback.sender['id']
  p "sender_id: #{sender_id}"
  fb_user = find_fb_user(sender_id)
  p "#{fb_user} => #{fb_user ? fb_user.first_name : 'UNKNOWN FBUSER' }"

  p "postback before entering in choice tree: #{postback.payload}"

  if postback.payload == 'GET_STARTED_PAYLOAD'
    p "postback: #{postback.payload}"

    if !fb_user
      p "fb_user is UNKNOWN"

      new_fb_user = save_new_fb_user(sender_id)
      send_welcome_message(new_fb_user)

    elsif fb_user.is_patient
      send_welcome_again_message(fb_user)

    else
      send_welcome_message(fb_user)
    end

  elsif postback.payload == 'HAS_A_DIET'
    p "postback: #{postback.payload}"
    ask_for_access_code(fb_user)

  elsif postback.payload == 'DO_NOT_HAVE_A_DIET_YET'
    p "postback: #{postback.payload}"
    send_reminder_message(fb_user)

  elsif postback.payload == 'BOT_FEATURES'
    p "postback: #{postback.payload}"
    send_bot_features(fb_user)

  elsif postback.payload == 'QUESTIONNAIRE'
    p "postback: #{postback.payload}"
    manage_persistent_menu(fb_user, 'QUESTIONNAIRE')

  elsif postback.payload == 'TALK_TO_DIET'
    p "postback: #{postback.payload}"
    manage_persistent_menu(fb_user, 'TALK_TO_DIET')

  else
    p "postback: #{postback.payload}"
    manage_persistent_menu(fb_user, 'TALK_TO_BOT')
  end
end

Thanks a lot for your help.

Guillaume

Guillaumejfrt commented 6 years ago

@jgorset can someone help me? I still have this bug. Thanks a lot

cfurrow commented 6 years ago

by the way, does the order of methods and callback in the bot.rb file has an importance

No, the order is not important for most of the code inside of bot.rb, which is simply registering webhook event handlers. You mentioned you also are setting your persistent menu inside of bot.rb, which is fine, but know that that persistent menu code is being pushed to Facebook every time your server is started. It should not really matter, but you may want to move that code that sets your persistent menu elsewhere, and only call it when you need to change your menu in some way.

Guillaumejfrt commented 6 years ago

Hi @cfurrow ,

thanks for your answer and those precisions. I realized that if I change the code in my bot.rb file, I need to leave facebook and reload the facebook page and messenger to get my persistent menu work normally again.

cfurrow commented 6 years ago

Ah, interesting. Good to know!

Guillaumejfrt commented 6 years ago

@cfurrow do you know why I sometimes get this error?

2018-02-13T11:02:26.555559+00:00 app[web.1]: ! Unable to load application: Facebook::Messenger::Profile::Error: (#-1) Unexpected internal error
2018-02-13T11:02:26.555723+00:00 app[web.1]: bundler: failed to load command: puma (/app/vendor/bundle/ruby/2.4.0/bin/puma)
2018-02-13T11:02:26.555784+00:00 app[web.1]: Facebook::Messenger::Profile::Error: (#-1) Unexpected internal error
2018-02-13T11:02:26.555791+00:00 app[web.1]:   /app/vendor/bundle/ruby/2.4.0/bundler/gems/facebook-messenger-993cee8202d3/lib/facebook/messenger/profile.rb:22:in `set'
2018-02-13T11:02:26.555794+00:00 app[web.1]:   /app/app/bot/listen.rb:10:in `<top (required)>'
2018-02-13T11:02:26.555796+00:00 app[web.1]:   /app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.1/lib/active_support/dependencies.rb:292:in `require'
2018-02-13T11:02:26.555798+00:00 app[web.1]:   /app/vendor/bundle/ruby/2.4.0/gems/activesupport-5.1.1/lib/active_support/dependencies.rb:292:in `block in require'
...
...

When it appears my server crashes...and after a while, without any action from me, it seems to start again correctly:

2018-02-13T11:08:57.304430+00:00 heroku[web.1]: State changed from crashed to starting
2018-02-13T11:09:11.812521+00:00 heroku[web.1]: Starting process with command `bundle exec puma -C config/puma.rb`
2018-02-13T11:09:15.193292+00:00 app[web.1]: Puma starting in single mode...
2018-02-13T11:09:15.193331+00:00 app[web.1]: * Version 3.9.1 (ruby 2.4.1-p111), codename: Private Caller
2018-02-13T11:09:15.193333+00:00 app[web.1]: * Min threads: 5, max threads: 5
2018-02-13T11:09:15.193334+00:00 app[web.1]: * Environment: production
2018-02-13T11:09:22.567582+00:00 app[web.1]: * Listening on tcp://0.0.0.0:3324
2018-02-13T11:09:22.568027+00:00 app[web.1]: Use Ctrl-C to stop
2018-02-13T11:09:23.034731+00:00 heroku[web.1]: State changed from starting to up

Here is the beginning of my listen.rb file:

require "facebook/messenger"
require 'rest-client'
require 'json'

# Facebook Messenger gem integration
include Facebook::Messenger
Facebook::Messenger::Subscriptions.subscribe(access_token: ENV.fetch("ACCESS_TOKEN"))

# Messenger welcome view before starting
Facebook::Messenger::Profile.set({
  get_started: {
    payload: 'GET_STARTED_PAYLOAD'
  },
  greeting: [
    {
      locale: 'default',
      text: 'Welcome to Coachat!!!'
    },
    {
      locale: 'fr_FR',
      text: 'Bienvenue sur Coachat!!!'
    }
  ],
  persistent_menu:[
      {
        locale: "default",
        call_to_actions: [
          {
            title:"Parler à mon diététicien",
            type: "postback",
            payload: "TALK_TO_DIET"
          },
          {
            title: "Parler au chatbot",
            type: "postback",
            payload: "TALK_TO_BOT"
          },
          {
            title: "Mon profil nutritionnel",
            type: "postback",
            payload: "QUESTIONNAIRE"
          }
        ]
      }
    ]
}, access_token: ENV.fetch("ACCESS_TOKEN"))
cfurrow commented 6 years ago

That's odd. I've not seen that one before, and the error does not give a lot of information as to what may have happened.

Looks like it's happening in your live application on Heroku? I wonder it is something else in the environment? Maybe your particular Puma server version is having an issue, and is restarting for some reason?

I saw this other error that has a similar error log as you (does not use Facebook Messenger, however): https://github.com/puma/puma/issues/1354

I don't think it'll be of much help, but I thought I'd include their issue in case it had any value.

jgorset commented 6 years ago

Yeah, I'm pretty sure this comes down to something in either puma or your application. In fact, it looks like it can't find puma at all. Are you sure you've installed it correctly?

Guillaumejfrt commented 6 years ago

Hi, yes I am sure about it. I Don't know what happens. I regularly get this error.

I just relaunch the server and everything goes right.