Skip to content

Instantly share code, notes, and snippets.

@M-Younes
Created June 28, 2017 04:05
Show Gist options
  • Save M-Younes/565e67cb10517eb3290786a23e39caab to your computer and use it in GitHub Desktop.
Save M-Younes/565e67cb10517eb3290786a23e39caab to your computer and use it in GitHub Desktop.
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