-
Notifications
You must be signed in to change notification settings - Fork 3
Integrate with Message Bus
Creating a web-based chat app is somewhat confusing to figure out (even with wit.ai), which is why I've made a wiki page about it. Yay!
First, you should familiarize yourself both with wit.ai's concepts, and the concepts in wit_bot, including bots and conversations.
If you're on Rails or many other frameworks that work with message_bus, and you want to make your app able to respond to messages, read on! You'll learn a lot about how wit_bot works.
If you don't feel like learning, you can run the generators. The generators below are equivalent.
To generate the message_bus listener:
$ rails generate wit_bot:message_bus BotName
$ rails generate wit_bot:message_bus BotName User
$ rails generate wit_bot:message_bus BotName User /witbot
First, create your bot, I recommend placing it in the app/wit_bot
directory. You'll probably want to initialize the bot with the user, to be able to access the user's data in your responses. Here's the documentation, read up on it and create a bot.
Now, you'll need the message_bus gem for this tutorial. Add it to your Gemfile
, and bundle
.
# For messages
gem 'message_bus', '~> 2.0.0.beta.5'
Side Note: With it's default configuration, message_bus requires redis. You should either read up on the docs for message_bus to use a different storage solution, or add the redis gem to your Gemfile.
You'll want to create a model for storing conversations if you haven't already - here's the guide for that.
Now, let's setup a way for the server to send input and output. For this, we'll be using WitBot's WitBot::Bot::Conversation::Participant
class, which allows us to create a listener and a speaker that participates (thus the name) in the conversation.
class MessageBusListener < WitBot::Bot::Conversation::Participant
attr_accessor :conversation_model, :user
# Initialize the conversation, set the local user, and add the bot to the message
def initialize(conversation, user)
# Send the conversation object to the parent class
super conversation.object
# Set instance variables (@conversation is the actual conversation object)
@conversation_model = conversation
@user = user
# Add the bot to the conversation
YourBot.new @conversation, @user
end
# A method that saves the conversation.
def save
@conversation_model.object = @conversation
@conversation_model.save
end
class << self
# A method to retrieve a listener from a user.
def from_user(user)
unless user.conversation # If the user doesn't have a conversation...
user.conversation = Conversation.new # Create one
user.save! # Save the user
end
MessageBusListener.new user.conversation, user # Create a new listener from the conversation and the user.
end
end
def bot?
false # Tell wit_bot that this class handles messages for a user.
end
# A method that's call on output of a message automatically by wit_bot
def on_output(message)
save # Once we output a message, save the user.
msg_hash = {text: message.text, bot: message.bot?} # Create a hash to send to the user
MessageBus.publish '/yourbotchannel', msg_hash, user_ids: [@user.id] # Send the message to the user.
end
end
Now, let's add a way for a user to send a message to the conversation. For this, we'll use a simple HTTP POST request, with the :text
param used for sending the message's text. We'll be using a background job to process the message, so all this controller will do is enqueue the MessageBusJob. Make sure to setup a route that points to this controller.
class MessageBusController < ApplicationController
before_action(only: [:send_message]){ doorkeeper_authorize! } # Make sure the user is authorized (replace with your own authentication logic)
def send_message
MessageBusJob.perform_later current_user.id, params[:text] # Enqueue
head :accepted # Respond the with the HTTP Accepted status code.
end
end
Now, we'll setup the job in your app/jobs
folder. The job will retrieve the student from the database, get the MessageBusListener, and send the message as an input. WitBot will work it's magic, and send the user it's message once it's done.
class MessageBusJob < ActiveJob::Base
queue_as :high
def perform(user_id, text)
# Make sure the user still exists
if (user = User.find_by_id user_id)
# Get the listener
listener = MessageBusListener.from_user user
# And send the message
listener.send_message text
end
end
end
And... boom! Your bot can now accept and respond to messages! Awesome!
You're done. You've made it so that your app can accept a message, create a response, and send it back to the user. Awesome! You should give yourself a pat on the back.
What's next?
- Setup your client: Send an ajax request to your MessageBusController endpoint with the text of the message in
params[:text]
. Your message hash will be transmitted back to the client using message_bus. You should go to message_bus, and setup your client based on their guides. - You should setup a background job library if you don't already have one, for that purpose, I recommend GitHub's resque.
Down here?
Cool.
I should add something somewhat interesting for you to read...
Here's how to get started with wit_bot in 3 steps:
- Learn how to use wit.ai
- Learn how to setup the gem
- Learn how to send a message
- Learn how to use message threads
- Learn how to use context
- Learn how to use conversations
- Learn to use the REPL
- Learn how to use conversations
- Learn how to use participants
- Learn how to use bots