A Beginner’s Guide to Building a Slack Bot in PHP

As one of the most popular instant messaging platforms, Slack has built a name for itself in the ChatOps space thanks to its existing popularity and an extensive list of integrations. So, how easy is it to build your own bot? In this article, we’ll walk you through the basics of building a Slack bot using PHP. Not only that, but we’ll also discuss some of the many functionalities you can include in your bot. Finally, we’ll look at a brief comparison of the Telegram and Slack developer experiences when it comes to building chatbots.

First Things First

The first step in building a Slack bot is to register it. On Slack, bots fall under the broader category of “apps,” which can be registered at api.slack.com/apps. Just click “Create New App,” give your app a name, and choose the Slack workspace where you’ll want to test your bot during development.

The basis of any chatbot is being able to read incoming messages, so let’s get started with setting that up. Unlike other instant messaging service APIs — which send an update object whenever anything happens in a chat — the Slack API informs you about only the events you subscribe to. To subscribe to an event, open the “Add features and functionality” section on your app’s page and click on “Event Subscriptions.”

Before you can subscribe to any events, you’ll need to choose and verify the URL at which you wish to be notified. Simply enter your desired URL in the format of https://www.YourDomain.com/YourCodeFile.php. Slack will send a JSON payload containing a challenge parameter to that URL and your job is to send that value right back to them.

Here’s the code we used to accomplish this:

$event = file_get_contents("php://input"); $eventArray = json_decode($event, TRUE); echo $eventArray[challenge];

Subscribing to Events

Once you’ve successfully verified the URL, open the “Subscribe to bot events” section. This is where you can turn your “app” into a “bot” by giving it a display name and username.

Next, you’ll be able to choose which events to subscribe to. For now, just add the message.channels event, which is triggered whenever a message is sent to a channel, and press “Save changes” at the bottom of the page.

Now, there’s one other thing to do before those message events are sent to our chosen URL. That is: you need to request some OAuth scopes. Using the menu on the left-hand side, navigate to “OAuth & Permissions.” Halfway down the page, you can add the scopes your application will need.

After referring to the documentation for the message.channels event, you’ll need to request the channels:read scope to be able to read incoming messages. While you’re at it, request the chat:write:bot scope, which will allow you to send messages later on.

On that same page, click to reinstall your app to the workspace, which will take you through an OAuth delegation process and ultimately give your bot the permissions you just asked for. Finally, make a note of the access token provided on that page.

Replying to a Message

With all that prep done, let’s start building our bot. Just a second ago, we subscribed to the message.channels event, which sends us a JSON payload of the following format every time a new message is sent:

{
    "token": "one-long-verification-token",
    "team_id": "T061EG9R6",
    "api_app_id": "A0PNCHHK2",
    "event": {
        "type": "message",
        "channel": "C024BE91L",
        "user": "U2147483697",
        "text": "Live long and prospect.",
        "ts": "1355517523.000005",
        "event_ts": "1355517523.000005",
        "channel_type": "channel"
    },
    "type": "event_callback",
    "authed_teams": [
        "T061EG9R6"
    ],
    "event_id": "Ev0PV52K21",
    "event_time": 1355517523
}

At least for now, this response only really contains two interesting fields: channel and text. channel tells us which channel the message was sent to, and text tells us the contents of that message.

To test out what I had to work with, I used the chat.postMessage endpoint to create a simple script that would repeat whatever a user said. Here’s what that code looks like:

$event = file_get_contents("php://input"); $eventArray = json_decode($event, TRUE); file_get_contents("https://slack.com/api/chat.postMessage?token=one-long-verification-token&channel=".$eventArray["event"]["channel"]."&text=".$eventArray["event"]["text"]);

…and it worked! The only issue was that this code was triggered by all messages sent to a channel, including those sent by the bot itself:

After listening to five minutes of pinging, I ended up editing an error into my code file to kill the never-ending cycle. Certainly not my proudest moment!

Where to Go Next

In this guide, we won’t go through the process of building a “useful” bot just for the sake of it. You’ve seen how to get notified about new messages and how to reply to them; it’s up to you to fill in the blanks with your business logic.

What we will do is talk about some of the other functionalities you can incorporate into your bot. For starters, there are a whole variety of events you can use to trigger business logic: member_joined_channel tells you when a new user joins a channel, file_created tells you when a file is uploaded to a channel, and reaction_added tells you when a user reacts to something. See the full list of events you can hook into here.

You’ll also want to know the different methods you can call to interact with Slack. chat.postMessage is definitely the most useful, but there are plenty more you might want to experiment with: chat.postEphemeral sends a message visible to just one user, dnd.setSnooze sets a user’s status to “Do Not Disturb,” and im.open starts a direct conversation.

Telegram API vs Slack API: Developer Experience

One thing we were curious about going into this walkthrough was how Slack would compare to Telegram in terms of developer experience. Personally, we found it easier (and faster) to launch a Telegram bot. This was largely the result of all the authentication which Slack requires: every time you want to subscribe to a new event or call a new endpoint, you have to find and add all the appropriate scopes and then reinstall your app.

We do have to commend Slack for their documentation, which provides exactly what you need (in an easy-to-consume format) when it comes to event and method definitions.

Final Thoughts

Building a Slack bot is just like building a Telegram bot: you set yourself up to receive updates/events, process them, and then shoot some kind of request back to the API. Although we didn’t build a fully-functioning, “useful” bot for the purposes of this tutorial, it still shows you just how easy it is to integrate your business logic into a modern-day instant messaging service. Good luck building!