Building a Simple Chatbot with Ruby on Rails and Turbo Streams

November 26, 2024

In this article, we will guide you through the process of building a simple chatbot using Ruby on Rails, Turbo Streams, and OpenAI’s API. The chatbot will allow users to interact with each other by storing chat messages in a database and displaying them dynamically on the web page. We’ll also introduce the concept of background jobs to handle API requests asynchronously for a smoother user experience.


🚀 Need Expert Ruby on Rails Developers to Elevate Your Project?

Fill out our form! >>


Introduction

Creating a chatbot can be a fun and rewarding project. In this tutorial, we will leverage the power of Ruby on Rails, Turbo Streams, and OpenAI to build a chatbot that simulates communication with an AI, similar to ChatGPT. We’ll cover everything from setting up models and controllers to integrating OpenAI’s API for generating responses.

Step 1: Setting Up the Rails Project

We begin by generating the necessary components for our chat application. Using the Rails generator, we create a ChatsController with index, show, and create methods, along with a Chat model that stores a session ID. This session ID will act as a unique identifier for each conversation.

rails G controller chats
rails G model chat session_id:string

In the model, we set the session_id to a random string using the SecureRandom.hex method. This ID will be used to reference and manage each chat session.

Step 2: Implementing the Chat Interface

Once the basic models and controllers are set up, we can define the chat interface. In the chats/index view, we display a list of chat sessions, showing their session IDs and a button to create a new chat.

<% @chats.each do |chat| %>
  <div><%= chat.session_id %></div>
  <%= button_to 'Create Chat', chat_path(chat), method: :post, data: { turbo: false } %>
<% end %>

The create action in the ChatsController generates a new chat session and redirects to the show page.

Step 3: Storing Messages

To store and display messages, we generate a ChatMessage model, which belongs to the Chat model. Each message has content and a role, which could represent either a user or an AI assistant.

rails G model chat_message chat:references content:text role:string

We also need a controller for creating new chat messages, which will be handled via the ChatMessagesController. The create action will accept a message’s content and save it to the database.

Step 4: Displaying Messages

On the chat/show page, we iterate over the chat_messages associated with the current chat. Using Turbo Streams, we can dynamically update the chat window in real-time as new messages are added.

<%= turbo_stream_from "chat_messages_#{chat.id}" %>
<%= form_with model: [chat, ChatMessage.new], local: false do |form| %>
  <%= form.text_area :content %>
  <%= form.submit 'Send' %>
<% end %>

The form sends the message asynchronously, and the message is appended to the chat without reloading the page.

Step 5: Integrating OpenAI

To make the chatbot more interactive, we integrate OpenAI’s API. When a user sends a message, we use a background job to send the conversation to OpenAI, receive the response, and then display the AI’s reply in the chat.

rails G job chat_message_created

In the job, we collect all messages in the chat, send them to OpenAI for processing, and store the AI’s response as a new message.

class ChatMessageCreatedJob < ApplicationJob
  queue_as :default

  def perform(chat_message)
    chat = chat_message.chat
    messages = chat.chat_messages.order(:created_at).map do |message|
      { role: message.role, content: message.content }
    end
    # Send messages to OpenAI and store the response
  end
end

Step 6: Improving User Experience

To enhance the user experience, we add some frontend improvements. The message form resets after submission using Stimulus.js, and we apply some basic CSS to make the chat interface more user-friendly. The messages are displayed in a clear, readable format, and new messages are automatically added without causing the page to reload.


Conclusion

By following this tutorial, you’ve learned how to build a simple chatbot using Ruby on Rails and Turbo Streams. You’ve also seen how to store and retrieve messages from a database, integrate OpenAI for dynamic AI responses, and improve the user experience with Stimulus and Turbo Streams.

This is just the beginning, and there are many ways you can extend this project. For example, you could add authentication for users, improve the UI, or implement more advanced AI features. With Rails and Turbo Streams, you have a solid foundation for building real-time, interactive applications.

Leave a comment