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
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