Search code examples
ruby-on-railsfacebook-messengerfacebook-messenger-bot

Rails: Shorturl to track clicks for Facebook Messenger chatbot is saving way too many clicks


I use the Facebook-Messenger gem in order to create a chatbot allowing me to send messages out of the blue to my subscribers.

I want to save in my rails database every click on the url button of the generic model. For that, I create a special url directing to a shorturl controller that redirects to the final url after saving the data.

The send request in a worker:

def perform(sender, title, image_url, subtitle, cta_url, cta_text, access_token, letter_id)
    Bot.deliver({
      recipient: {
        id: sender
      },
      message: {
        "metadata": letter_id,
        "attachment":{
          "type": "template",
          "payload":{
            "template_type": "generic",
            "elements":[
            {
              "title": title,
              "image_url": image_url.html_safe,
              "subtitle": subtitle,
              "default_action": {
                "type": "web_url",
                "url": cta_url.html_safe
              },
              "buttons": [
              {
              "type": "web_url",
              "url": cta_url.html_safe,
              "title": cta_text
              },
              {
                "type": "element_share"
              }
            ]
            }
          ]
          }
        }
      }
    }, access_token: access_token)
  end

The shorturl controller:

class ShorturlController < ApplicationController
  def show
    @shorturl = ShortUrl.find_by_token(params[:id])
    @card = Card.find(@shorturl.card_id)
    @subscriber = BotUser.find_by_sender_id(params['u'])

    analytic_clic.increment!(:click_count, by = 1)

    @final_url = @card.cta_button_url

    redirect_to @final_url, :status => 301
  end

private

  def analytic_clic
    @analytic_clic ||= AnalyticClic.find_or_create_by(
      card_id: @card.id, 
      short_url_id: @shorturl.id, 
      bot_user_id: @subscriber.id
    )
  end

end

The route associated with the shorturl controller:

get 's/:id' => "shorturl#show"

Unfortunately, when I send the message in production to around 200 subscribers, it saves around 100 clicks immediately. I have no idea why, as Facebook does not "test" the url by sending a http request. The logs are fine, I have many get requests for the shorturl but no errors before that.

Any idea why it's performing all these get requests to my shorturl even if the subscribers haven't clicked on the link yet?

Here is an example of a shorturl I created: https://www.botletter.com/s/qsKcsm7NCRp4qkRGUqfPx7Sp?u=1451521288246029


Solution

  • The problem was the Facebook crawler, I added the following condition to avoid saving clicks when Facebook is visiting the url:

    if request.user_agent == "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)"
          puts "Facebook crawl"
        else
          # save to db
        end