Created
June 28, 2017 04:05
-
-
Save M-Younes/565e67cb10517eb3290786a23e39caab to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class MessengerController < Messenger::MessengerController | |
require 'rest-client' | |
def webhook | |
if fb_params.first_entry.callback.message? | |
unless params["entry"].first["messaging"][0]["message"]["is_echo"] # so the response from wit.ai won't be sent to wit.ai | |
create_user(fb_params.first_entry.sender_id) | |
message(fb_params.first_entry.callback.text, fb_params.first_entry.sender_id) | |
end | |
end | |
head :ok | |
end | |
def create_user sender_id | |
user = User.find_or_initialize_by(fb_user_id: sender_id) | |
if user.new_record? | |
send_new_user_greetings(user) | |
user.save! | |
end | |
user | |
end | |
def find_or_create_session(sender_id, max_age: 5.minutes) | |
Session.find_by(["fb_user_id = ? AND last_exchange >= ?", sender_id, max_age.ago]) || | |
Session.create(fb_user_id: sender_id, context: {}) | |
end | |
def message(text, sender_id) | |
session = find_or_create_session(sender_id) | |
session.update(last_exchange: Time.now) | |
client = wit_request(session, sender_id) | |
client.run_actions session.id, text, session.context | |
end | |
def wit_request(session, sender_id) | |
actions = { | |
send: -> (request, response) { | |
if response["quickreplies"] | |
send_quick_replies response["quickreplies"], response['text'], sender_id | |
else | |
Messenger::Client.send(Messenger::Request.new(Messenger::Elements::Text.new(text: response['text']),sender_id)) | |
end | |
}, | |
:error => -> (error) { | |
Messenger::Client.send(Messenger::Request.new(Messenger::Elements::Text.new(text: 'Oops, I don\'t know what to do.'),sender_id)) | |
}, | |
getWeather: -> (request) { | |
context = request["context"] | |
entities = request["entities"] | |
location = first_entity_value(entities, "location") || context["location"] | |
if location | |
context["location"] = location | |
weather = get_weather(location) | |
context["tmp"] = weather["main"]["temp"] | |
context["des"] = weather["weather"][0]["description"] | |
context.delete("missingLocation") | |
new_context = {} | |
else | |
context["missingLocation"] = true | |
new_context = context | |
end | |
session.update(context: new_context) | |
return context | |
}, | |
greetings: -> (request) { | |
context = request["context"] | |
entities = request["entities"] | |
context["greet"] = User::GREETS.sample | |
context["userName"] = get_user_name(sender_id) | |
session.update(context: {}) | |
return context | |
}, | |
getTopStories: -> (request) { | |
context = request["context"] | |
entities = request["entities"] | |
send_stories sender_id | |
session.update(context: {}) | |
return context | |
}, | |
search: -> (request) { | |
context = request["context"] | |
entities = request["entities"] | |
search_q = first_entity_value(entities, "query") || context["query"] | |
says_search search_q, sender_id | |
session.update(context: {}) | |
return context | |
} | |
} | |
client = Wit.new(access_token: Settings.wit_access_token, actions: actions) | |
end | |
def get_user_name fb_user_id | |
user = create_user fb_user_id | |
return user.name if user.name | |
first_name = Messenger::Client.get_user_profile(fb_user_id)["first_name"] rescue "" | |
if first_name | |
user.name = first_name | |
user.save! | |
end | |
first_name | |
end | |
def get_weather location | |
HTTParty.get(Settings.weather_api_url, query: {q: location, units: "metric", APPID: Settings.weather_api_key}).parsed_response | |
end | |
def first_entity_value entities, entity | |
return nil unless entities.has_key? entity | |
val = entities[entity][0]['value'] | |
return nil if val.nil? | |
return val.is_a?(Hash) ? val['value'] : val | |
end | |
def send_new_user_greetings user | |
User::GREETINGS.each do |text| | |
Messenger::Client.send(Messenger::Request.new(Messenger::Elements::Text.new(text: text),user.fb_user_id)) | |
end | |
end | |
def says_search query, sender_id | |
response = HTTParty.get(Settings.says_search_url, query: {q: query, bot: true}) | |
stories = bubbles(response.parsed_response.to_a.first(3)) rescue nil | |
send_stories(sender_id, true, stories, query) | |
end | |
def send_quick_replies quickreplies, text, sender_id | |
quick_replies = Array.new | |
quickreplies.each do |reply| | |
quick_replies << Messenger::Elements::QuickReply.new(content_type: 'text',title: reply, payload: reply.upcase) | |
end | |
Messenger::Client.send( Messenger::Request.new(Messenger::Templates::QuickReplies.new(text: text, quick_replies: quick_replies), sender_id)) | |
end | |
private | |
def send_stories sender_id, search=false, stories=nil, query="" | |
if search | |
if stories | |
Messenger::Client.send(Messenger::Request.new(Messenger::Elements::Text.new(text: "Hmm, Let me see what #{query} stories I can get you.."),sender_id)) | |
Messenger::Client.send( | |
Messenger::Request.new(Messenger::Templates::Generic.new( | |
elements: stories | |
), sender_id)) | |
else | |
Messenger::Client.send(Messenger::Request.new(Messenger::Elements::Text.new(text: 'Oops, I couldn\'t find anything on Says.com about #{query}.'),sender_id)) | |
end | |
else | |
Messenger::Client.send( | |
Messenger::Request.new(Messenger::Templates::Generic.new( | |
elements: bubbles | |
), sender_id)) | |
end | |
end | |
def bubbles(stories=[]) | |
stories_bubbles = Array.new | |
stories = says_top_stories if stories.empty? | |
stories.each do |story| | |
bubble = Messenger::Elements::Bubble.new( | |
title: story_title(story['title']), | |
image_url: story['cover_image_mobile'] ? story['cover_image_mobile'] : story['cover_image_source_url'], | |
subtitle: story_title(story['description']), | |
buttons: [ | |
Messenger::Elements::Button.new( | |
type: 'web_url', | |
value: story_url(story), | |
title: 'Read story' | |
) | |
] | |
) | |
stories_bubbles << bubble | |
end | |
stories_bubbles | |
end | |
def story_title(str) | |
if str.length > 80 | |
str[0..75]+"..." | |
else | |
str | |
end | |
end | |
def story_url(story) | |
channel = story['channel'] ? story['channel'] : story['channel_slug'] | |
Settings.says_domain+channel+"/"+story['slug']+"?bot=true" | |
end | |
def says_top_stories | |
begin | |
response = HTTParty.get(Settings.says_top_stories) | |
response.parsed_response.to_a | |
rescue | |
Array.new | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment