memo about Botkit v4 (4.10.0)

Botkit Mock

It only works with newer versions of Botkit. Upgrade if you were in the same boat as I was.

storage (Redis)

At least as of this writing, there is no Redis storage backend for v4. Write your own. Use MemoryStorage until you are ready.

Writing the event handlers in Typescript

If you are using Typescript to write the event handlers, you are going to need to somehow give the handler object parameters some type information. That is, this won’t work:

controller.hears("foo", "message", async(bot, message) => {
import { Botkit, BotWorker, BotkitMessage } from 'botkit';controller.hears("foo", "message", async(bot :BotWorker, message :BotkitMessage) => {

controller.on and controller.hears

controller.on responds to event type names. controller.hears responds to the message text that was received.

controller.hears('^hello', 'message', ....);
controller.on('message', ...);

Matching against ‘app_mention’ events

You can’t. Typing @bot foo in Slack generates two events, one for an app_mention event type and one for message . The message type can be matched using controller.hears('foo', 'message', ...) but notice that the first string (the string that matches against the message text) is not anchored to the beginning of the string. This is because the message payload actually contains the bot’s user ID in the form of "<@U********> foo" and therefore you cannot safely anchor the pattern to the beginning of the line.

controller.on('event', async(bot :BotWorker, message :BotkitMessage) => {
// message.incoming_message.channelData contains the raw
// data from the incoming message
let chData = message.incoming_message.channelData;
if (chData.type == 'app_mention') {
// Inspecting the message object reveals that when
// "@bot foo" is issued in Slack, this hook receives a
// message with message.text == null
// So we extract the raw text from and remove the
// bot's user ID from the beginning of the text so
// it's easier to match against the text pattern
let botID =;
let text = chData.text;
if (text.startsWith('<@' + botID + '> ')) {
text = text.slice(botID.length + 4);
message.text = text; // Overwrite
// now match against message.text, do whatever

Starting Slack Thread Conversations

As of this writing, no document properly explains this.

import { Botkit, BotWorker, BotkitMessage } from 'botkit';
import { SlackBotWorker } from 'botbuilder-adapter-slack';
controller.on(..., (bot :BotWorker, message :BotkitMessage) => {
let sbot = bot as SlackBotWorker;
await sbot.startConversationInThread(...);
await sbot.reply(...)



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Daisuke Maki

Daisuke Maki


Go/perl hacker; author of peco; works @ Mercari; ex-mastermind of builderscon; Proud father of three boys;