TNS
VOXPOP
As a JavaScript developer, what non-React tools do you use most often?
Angular
0%
Astro
0%
Svelte
0%
Vue.js
0%
Other
0%
I only use React
0%
I don't use JavaScript
0%
NEW! Try Stackie AI
AI / AI Engineering / CI/CD / Operations

Build an AI Chat Assistant With Stream and OpenAI

Build an AI chat assistant that lives on your website, knows your business and helps users with their queries in real time.
May 23rd, 2025 12:00pm by
Featued image for: Build an AI Chat Assistant With Stream and OpenAI
Image from Zero_wing on Shutterstock

Have you ever visited a website and found yourself chatting with an AI assistant that feels almost human? You can build an AI chat assistant that lives on your website, knows the business and helps users with their queries in real time.

It will integrate Stream for chat infrastructure and UI, and the OpenAI API for AI-powered conversations. This fully functional AI assistant will be tailored to a company’s knowledge base, complete with a sleek UI and a floating chat widget.

The entire code repository can be found here.

Project Setup

1. Create the Frontend

Use Vite to quickly scaffold a React + TypeScript app.

2. Install Dependencies

These packages set up the chat functionality and handle unique IDs for chat sessions.

  • stream-chat: Core Stream Chat SDK.
  • stream-chat-react: Prebuilt React components for chat UIs.
  • uuid: Used to generate unique channel names or user IDs.

Start the development server:

yarn dev

3. Set Up Stream API Access

Create a free account at Stream and set up a new app in the dashboard.

Image 1

Image 2

From Chat Messaging > Overview, copy your App Access Key.

Image 3

Create a .env file in your frontend folder and add the key:

VITE_STREAM_API_KEY=<your_key>

📌 Note: Vite requires environment variables accessible to the frontend to be prefixed with VITE_.

Creating the Stream Client

With the frontend project set up and your API key ready, the project is ready to initialize the Stream Chat client and render the chat UI.

1. Replace src/App.tsx

Start by replacing the default content in App.tsx with a basic layout and a placeholder for the chat component:

2. Create AIChat.tsx

Create a new file at src/components/AIChat/AIChat.tsx. This will initialize the Stream client using the API key and connect it to the React SDK.


Here’s what’s happening:

  • It initalizes a StreamChat instance using the API key.
  • If the client is not ready, it shows a loading message.
  • Once the client is set, it is passed to the Chat component from stream-chat-react.

This setup prepares the app to connect to the chat backend, the user and channel have not been created yet. Next build the chat interface and connect a guest user to a temporary channel to talk to the assistant.

Creating the UI

Build the chat interface using Stream’s prebuilt React components.

1. Update AIChat.tsx

Replace the contents of AIChat.tsx with the following. This will handle setting up a guest user, creating a temporary channel and rendering the complete chat interface.

What’s Happening Here?

  • A guest user is created so visitors don’t need to log in to use the chat.
  • A unique chat channel is created using uuidv4() to avoid conflicts.
  • The Stream React components render the complete chat interface:
    • ChannelHeader – Header area for the chat window.
    • MessageList – Displays the conversation.
    • MessageInput – Input field for sending new messages.
    • AIStateIndicator – Shows AI activity like “thinking…” animations.
    • Thread – Supports threaded conversations.

At this point, the UI is in place, but an error message might appear: 

Error: StreamChat error code 17: GetOrCreateChannel failed with error: “User ‘guest-586486fd-d52e-4626-af0e-a480c83f95c6-guest_user’ with role ‘guest’ is not allowed to perform action CreateChannel in scope ‘messaging'”

This means guest users are not permitted to create message channels (or “chat rooms”). So, in the Stream dashboard, go to “Roles and Permissions”:

Image 4

For the “guest” Role and “messaging” Scope, add the following permissions:

  • Read Channel
  • Create Message
  • Create Channel

With permissions updated, the chat UI should now load successfully, and guests will have a working chat interface:

Image 5

Setting Up the Server

To connect the chat frontend to an AI model like OpenAI, a backend is required that can handle requests, authenticate securely with third-party APIs and trigger the AI agent to join the chat.

Stream provides a ready-to-use Node.js backend for this.

1. Clone the Example Server

From the project root:


This backend is preconfigured to work with Stream and supports OpenAI and Anthropic. To use OpenAI:

2. Get Your OpenAI API Key

​​3. Create an .env File

In the ai-assistant-nodejs folder, create an .env file and add the following:

4. Switch the Backend To Use OpenAI

By default, the backend uses Anthropic. To switch to OpenAI, find this route in index.ts or app.ts:


Ensure platform = 'openai'.

5. Start the Server

Now the backend can run locally:

yarn dev

This will start the server on http://localhost:3000 by default. The frontend will call this server when it needs to add the AI bot to a chat channel.

Next, wire this up in the frontend so the AI joins automatically when a new user opens the chat.

Checking if AI Is in the Chat

To ensure the AI agent automatically joins the chat when needed, create a custom React hook to monitor the channel’s watchers and check whether the AI bot is present. If not, trigger the backend to add it.

1. Create a useWatchers Hook

Create a new file at frontend/src/custom-hooks/useWatchers.ts:

2. Create a Custom Channel Header

Now create a new channel header that checks whether the AI is in the channel, and if not, calls the backend to add it.

3. Update AIChat.tsx

In AIChat.tsx, replace the default ChannelHeader with the new one:


Now, whenever a user opens the chat, the app checks whether the AI agent is present. If not, it calls the backend and automatically invites the AI into the chat channel.

Let’s test things out:

Image 6

Amazing — an AI chat!

However, this wasn’t the end goal. To do yet:

  • Make this actually look like an AI assistant.
  • Teach the AI assistant about our company and instruct it on how to respond to users’ messages so it actually addresses users’ questions and problems.

First, to address styling…

Styling Our Chat Assistant

A button in the bottom right corner of each page of our website will open AI chat when clicked.

First, create the button that will toggle the chat display:


Add the css to AIChat/AIChat.module.css:


Now create a new component, at src/components/AIChat/AIChatWidget.tsx, to conditionally display the AI chat:


Add the following classes to AIChat.module.css:


Image 7

Now there’s a button at the bottom of each page.

When clicked, it toggles the AI chat.

Great! Things are looking better. But this is still just some generic AI chat, like ChatGPT. We want it to respond as though it is an expert for Stream.

Instructing AI To Be a Stream Expert

Go to your OpenAIAgent.ts in the backend, change the assistant’s name and instruct it on how to behave:


Restart the server with yarn dev, and let’s see what happens:

Image 8

And just like that, Stream has an AI assistant.

Conclusion

You now have a working example that handles guest users, manages chat channels and connects to an AI backend.

With this foundation, you can bring your own AI assistant to life and embed intelligent conversations directly into your website.

Created with Sketch.
TNS DAILY NEWSLETTER Receive a free roundup of the most recent TNS articles in your inbox each day.