Practice Tutorial: Dialogflow Chatbot with Ruby on Rails

In this tutorial, we will build a chatbot interaction to Stream Chat using Ruby on Rails.

Prerequisities:

  • Ruby on Rails
  • Javascript and React
  • Node
  • RVM
  • Ngrok
  • PostgreSQL

Steps:

Install Ruby on Rails

rvm install 2.6.3
# Create a gemset for isolating the dependencies
rvm use --create 2.6.3@rails-chat
gem install rails 

Build the Applicaiton Skeleton with React and PostgreSQL

rails new rails-chat --webpack=react --database=postgresql
cd rails-chat

Add the dependencies to Gemfile

gem 'webpacker'
gem 'react-rails'
gem 'stream-chat-ruby'
gem 'google-cloud-dialogflow'
gem 'bcrypt', '~> 3.1.7
bundle install
rails db:create
rails webpacker:install
rails webpacker:install:react
rails generate react:install
yarn add webpack-cli stream-chat-react

Add User to the Application

rails generate scaffold User handle:string name:string password:digest

Add User model validation in app/models/user.rb

# ...
validates :handle, presence: true, uniqueness: true
validates :name, presence: true
rails db:migrate
rails server

Add session controller for logging in and out

rails generate controller session new create destroy

app/controllers/session_controller.rb

class SessionController < ApplicationController
  def new
  end

  def create
    user = User.find_by_handle(params[:handle])
    if user && user.authenticate(params[:password])
      session[:user_id] = user.id
      session[:chat_token] = @chat.create_token(user.handle)
      redirect_to root_url, noticed: "Logged in!"
    else
      flash.now[:alert] = "Handle or password is invalid"
      render "new"
    end
    
    def destroy
      session[:user_id] = nil
      session[:chat_token] = nil
      redirect_to root_url, noticed: "Logged out!"
  end
end

app/views/sessions/new.html.erb

<p id="alert"><%= alert %></p>
<h1>Login</h1>

<%= form_tag session_path do |form| %>
  <div class="field">
    <%= label_tag :handle %>
    <%= text_field_tag :handle %>
  </div>
  <div class="field">
    <%= label_tag :password %>
    <%= password_field_tag :password %>
  </div>
  <div class="actions">
    <%= submit_tag "Login" %>
  </div>
<% end %>

config/routes.rb

get 'signup', to: 'users#new', as: 'signup'
get 'login', to: 'sessions#new', as: 'login'
get 'logout', to: 'sessions#destroy', as: 'logout'

Reference: