ruby-on-rails - Facebook Messenger 机器人 : postback. 回复 webhook 与数据库查询不匹配

标签 ruby-on-rails facebook-messenger facebook-messenger-bot

我有一个正在生产中的 Messenger 聊天机器人,使用 this rails gem 。它发送一个选择加入以允许人们订阅。当他们点击订阅按钮时,Webhook 会发送一个回发有效负载“SUB_YES_PAYLOAD”,该负载允许我们保存订阅者并回复用户定义的确认消息(该消息从使用我们机器人的页面更改为另一个页面)。

但是,有时回发回复会发送另一个页面的确认消息...我摸索了几个小时,但找不到这里的问题是什么?

这是网络钩子(Hook)代码:

Bot.on :postback do |postback|
  # We get the page record with the page ID sent by Facebook
  @core_bot = CoreBot.find_by_page_id(postback.recipient['id'])
  if postback.payload == 'SUB_YES_PAYLOAD'
    # We check the subscriber is not already subscribed in our db
    if BotUser.find_by_sender_id(postback.sender['id']).present? == false
      # save to the db
      url = "https://graph.facebook.com/v2.6/" + postback.sender['id'] + "?fields=first_name,last_name,profile_pic,locale,timezone,gender&access_token=" + @core_bot.page_access_token
      resp = Net::HTTP.get_response(URI.parse(url))
      @user_data = JSON.parse(resp.body)
      @first_name = @user_data['first_name']
      @last_name = @user_data['last_name']
      @profile_pic = @user_data['profile_pic']
      @locale = @user_data['locale']
      @timezone = @user_data['timezone']
      @gender = @user_data['gender']

      @bot_user = BotUser.new(core_bot_id: @core_bot.id, sender_id: postback.sender['id'], first_name: @first_name, last_name: @last_name, profile_pic: @profile_pic, locale: @locale, timezone: @timezone, gender: @gender)
      @bot_user.save
      if @bot_user.save
        # if the user defined a confirmation message in his settings
        if @core_bot.yes_subscribe_message.present? == true
          postback.reply({
              text: @core_bot.yes_subscribe_message # That's what's wrong here sometimes
          })
        else
          postback.reply({
              text: "Welcome!"
          })
        end
      end
    end
  end
end

这是一张发送错误确认的图片: wrong message

当我调用 @core_bot.yes_subscribe_message 时,@core_bot 似乎不是正确的,但订阅者被保存到正确的 @core_bot ID,因此没有理由它在之后发生变化......

我的应用程序位于一个 Heroku 标准 Web dyno 和一个 Heroku Postgres Hobby 经典数据库上。

编辑,这是 CoreBot 模型:

#  id                    :integer          not null, primary key
#  user_id               :integer
#  page_name             :string
#  page_id               :integer
#  page_access_token     :string
#  greeting_message      :string
#  yes_subscribe_button  :string
#  no_subscribe_button   :string
#  yes_subscribe_message :string
#  no_subscribe_message  :string
#  created_at            :datetime         not null
#  updated_at            :datetime         not null
#  active                :boolean          default(TRUE)
#  picture               :string           default("https://scontent.xx.fbcdn.net/v/t1.0-1/p480x480/20729408_135562287047146_4447605348389117589_n.png?oh=ba7b4a319a002db384168f50e1ccfec5&oe=5AAE506E")
#

class CoreBot < ApplicationRecord
  validates_uniqueness_of :page_id
  validates :page_id, :presence => true
  has_secure_token

  belongs_to :user
  has_many :letters, dependent: :destroy
  has_many :bot_users, dependent: :destroy
  has_many :weekly_analytics, dependent: :destroy
  has_many :segments, dependent: :destroy
  has_many :sequences, dependent: :destroy
  has_many :invitations, dependent: :destroy
  has_one :checkbox_iframe, dependent: :destroy
  has_one :button_iframe, dependent: :destroy
end

谢谢。

最佳答案

我认为发生这种情况是因为您使用了实例变量@core_bot,并且您的机器人可能只有一个实例,每次用户进入时都会执行该 block 。因此,如果并行,一切都很好,因为 shared @core_bot 实例已设置并始终保持不变。但如果您有很多用户,则会在该 block 仍在运行时添加一个新的 @core_bot 实例。

因此,解决方案是删除所有 @ 符号,以使变量在 block 的执行范围内成为本地变量。

Bot.on :postback do |postback|
  # We get the page record with the page ID sent by Facebook
  core_bot = CoreBot.find_by_page_id(postback.recipient['id'])
  if postback.payload == 'SUB_YES_PAYLOAD'
    # We check the subscriber is not already subscribed in our db
    if BotUser.find_by_sender_id(postback.sender['id']).present? == false
      # save to the db
      url = "https://graph.facebook.com/v2.6/" + postback.sender['id'] + "?fields=first_name,last_name,profile_pic,locale,timezone,gender&access_token=" + core_bot.page_access_token
      resp = Net::HTTP.get_response(URI.parse(url))
      user_data = JSON.parse(resp.body)
      first_name = user_data['first_name']
      last_name = user_data['last_name']
      profile_pic = user_data['profile_pic']
      locale = user_data['locale']
      timezone = user_data['timezone']
      gender = user_data['gender']

      bot_user = BotUser.new(core_bot_id: core_bot.id, sender_id: postback.sender['id'], first_name: first_name, last_name: last_name, profile_pic: profile_pic, locale: locale, timezone: timezone, gender: gender)

      if bot_user.save
        # if the user defined a confirmation message in his settings
        if core_bot.yes_subscribe_message.present? == true
          postback.reply({
              text: core_bot.yes_subscribe_message 
          })
        else
          postback.reply({
              text: "Welcome!"
          })
        end
      end
    end
  end
end

关于ruby-on-rails - Facebook Messenger 机器人 : postback. 回复 webhook 与数据库查询不匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50413295/

相关文章:

javascript - 当用户点击 "quick replies"按钮时如何打开 webview?

facebook-messenger-bot - Dialogflow V2 Messenger 与多条消息的集成

ruby-on-rails - https 网站上的主宰

ruby-on-rails - 需要知道如何在 ruby​​ 中处理散列键

facebook - 如何让用户选择多个选项作为 Facebook Messenger 聊天机器人中的输入?

node.js - 如何在使用 waterfall 对话框(Node js)的同时使用微软机器人框架将英雄卡片发送到 fb 信使

ruby-on-rails - 在模型中访问Devise的current_user

ruby-on-rails - 如何以当前用户或非用户身份更新资源?

facebook-messenger - bot框架facebook多个页面

Facebook Messenger 应用程序 Webhook 订阅 - 权限不足