Building a fully functional and scalable chat platform is time-consuming. Luckily, Stream can help you build one in minutes!
In this tutorial, we are going to use the Stream API to build a chat messaging platform in PHP.
Prerequisites
To follow along with this tutorial, you need to have a basic understanding
of PHP and JavaScript.
You'll also want to make sure you have PHP and Composer installed on your system.
To check if you already have PHP installed on your system, run this command in your terminal:
$ php -v
If PHP is installed on your system, the version installed will be returned; otherwise, you will see “command not found: php
”.
To check if you have Composer installed, run:
$ composer -v
Once you've confirmed you have the necessary languages/packages installed, let’s dive in!
Creating a Stream Account
To be able to use the Stream API, you'll need to create an account. Visit the Stream Chat website and then click on the "SIGNUP" button.
On the popup page that appears, fill in your desired username and password, along with your email address, and then click on the "CREATE FREE ACCOUNT" button:
After creating your account, you will be taken to your Dashboard, where you'll find your APP ID
, API KEY
, and SECRET
keys, which we’ll use to authenticate the SDK. Take note of these keys, as we will be using them in a bit:
Creating the Project
Now that we've gathered all of our "tools", create a folder named stream-chat-php
in the directory where you store your code; this will be the home for all of our project files. Inside of your new stream-chat-php
directory, create the following files:
custom.js
- this will contain our JavaScript codepage.php
- this will contain our chat interfaceserver.php
- this will contain our chat server logicstyle.css
- this will contain our chat styling
Generating Tokens
We’ll be using the PHP SDK on the server and the JavaScript SDK on the client end to get realtime updates of what is happening on the chat, which includes realtime messages. To use the JavaScript SDK, we need to get a valid token, which we can generate from our PHP server.
To start, open your terminal and cd
into your project root directory (stream-chat-php
), then install the PHP SDK using composer:
$ composer require get-stream/stream-chat
On the prompt that appears - No composer.json in current directory, do you want to use the one at …? [Y,n]?
, input n
and press Enter.
Now that we have the SDK installed, we can add the following to the server.php
file:
<?php
require_once(__DIR__ . "/vendor/autoload.php");
$STREAM_API_KEY = "<STREAM_APP_KEY>";
$STREAM_API_SECRET = "<STREAM_API_SECRET>";
// Initialize the SDK
$client = new \GetStream\StreamChat\Client(
$STREAM_API_KEY,
$STREAM_API_SECRET
);
if (isset($_REQUEST["create-token"])) {
die(json_encode([
"status" => "success",
"token" => $client->createToken($_REQUEST["create-token"])
]));
}
Make sure to update the
<STREAM_API_KEY>
and<STREAM_API_SECRET>
placeholders with your correctAPI KEY
andSECRET
respectively (which we grabbed from our Stream Dashboard).
In the above code, after initializing the PHP SDK, with the if (isset($_REQUEST["create-token"])) {
block, we check the request for a user's create-token
variable, so we can create a token
with it by calling the $client->createToken(…
function.
Now that we've initiated the code for our server, we can start up the server by running:
$ php -S localhost:6060
Creating the Chat Interface
Add the below code to the page.php
file to create your chat interface:
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="./style.css" />
<title>Vanilla PHP and JavaScript Stream Group Chat</title>
</head>
<body>
<div class="main-container">
<div class="login" id="login-block">
<input
type="text"
id="user-login-input"
placeholder="Enter your username (should be unique)"
You may have noticed that we include a few script tags at the end of this code:
- The JavaScript Stream SDK allows us to use Stream in our app
- Axios enables us to make http requests
- The script tag for our custom JavaScript code will be how we connect in the magic we'll create below
Making Our App Beautiful
You are welcome to add your own flair to your app, but you can get started by adding the following to the style.css
file:
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body,
html {
max-width: 100vw;
max-height: 100vh;
overflow: hidden;
background-color: #f5f5f5;
}
.main-container {
display: grid;
}
If you visit the project now, you will notice the page is blank: localhost:6060/page.php
; we’ll be fixing this in the next step.
Initializing the JavaScript SDK
Let's get started with the client side of our app by initializing the Javascript SDK! Add the below code to your custom.js
file (which, you'll remember, we referenced in the final script tag on our page.php
file):
let client, channel, username;
async function generateToken(username) {
const { token } = (
await axios.get(`/server.php?create-token=${username}`)
).data;
return token;
}
// Initialize the JavaScript chat SDK
client = new StreamChat('<STREAM_APP_KEY>');
Note: Make sure to change the
<STREAM_APP_KEY>
placeholder with your correct key.
Then, add the below function to the custom.js
file, so that we can initialize the chat when the page is ready:
async function initializeClient(username) {
const token = await generateToken(username);
// Set the current logged user
client.setUser(
{
id: username,
name: 'Jon Snow', // Update this name dynamically
image: 'https://bit.ly/2u9Vc0r'
},
token
); // token generated from our PHP server
// create or initialize the channel
channel = client.channel('messaging', 'general-channel1', {
Getting a User's ID
Each user needs to have a unique id that we can use to identify them. Add the below code to the custom.js
file:
function checkAuthState() {
if (!user.value) {
document.getElementById('login-block').style.display = 'grid';
document.getElementsByClassName('message-container')[0].style.display =
'none';
} else {
document.getElementsByClassName('message-container')[0].style.display =
'grid';
document.getElementById('login-block').style.display = 'none';
username = user.value;
initializeClient(username);
}
}
The above allows us to display the chat page and initalize the JavaScript SDK when an valid user enters their username and password. To trigger this, we'll need to listen for when the user hits Enter; add the code below to the custom.js
file:
const user = document.getElementById('user-login-input');
user.addEventListener('keyup', function(event) {
if (event.key === 'Enter') {
checkAuthState();
}
});
checkAuthState();
Appending New Messages
In order to add each new message that comes in to the chat, add the below function to the custom.js
file:
// [...]
function appendMessage(message) {
const messageContainer = document.getElementById('messages');
// Create and append the message div
const messageDiv = document.createElement('div');
messageDiv.className = `message ${
message.user.id === username ? 'message-right' : 'message-left'
}`;
// Create the username div
const usernameDiv = document.createElement('div');
usernameDiv.className = 'message-username';
usernameDiv.textContent = `${message.user.id}:`;
// Append the username div to the MessageDiv
This function will take in the message payload (that contains the user's username
and message
), create a new Node element that holds the username
and message
, and then attach the message
to the page using the message
's id
.
In the UI, that will look something like this:
Juggling New and Old Messages
Let's start by listening for new messages coming to the channel! Add the below code to the initializeClient(username)
function at the top of custom.js
:
async function initializeClient() {
// [...]
channel.on('message.new', event => {
appendMessage(event.message);
});
}
Now, what about old messages on the channel already? We need to render those as well... To accomplish this, add the following to the initializeClient()
function:
async function initializeClient() {
// [...]
channel.state.messages.forEach(message => {
appendMessage(message);
});
}
Sending Messages
So far, we can see previous messages and new messages added to the channel. Next, we will add functionality to allow users to send a new message to the channel.
Add the below function to the custom.js
file:
async function sendMessage(message) {
return await channel.sendMessage({
text: message
});
}
Next, listen for the message-input
and for when the user hits Enter, so we can send the message to the channel:
const inputElement = document.getElementById('message-input');
inputElement.addEventListener('keyup', function(event) {
if (event.key === 'Enter') {
sendMessage(inputElement.value);
inputElement.value = '';
}
});
Testing It Out
To test out the chat:
- Open the application in two different tabs or browsers.
- Type in a username and hit Enter, in each.
- Exchange messages!
Conclusion
We have covered the basics of getting started with Stream Chat using the PHP SDK to power your chat. There are lots of amazing chat features that you can add to your chat, like the "is typing" indicator, online presence, and much more!
Please reach out and share your incredible creations with us; until then, happy coding!