Skip to content

Events

BotKit provides a way to handle events that are emitted from the fediverse. You can handle events by setting event handlers on the bot instance. Event handlers are properties of the Bot instance with the on prefix followed by the event name. For example, to handle a mention event, you can set the onMention property of the bot instance:

typescript
bot.onMention = async (session, message) => {
  await message.reply(text`Hi, ${message.actor}!`);
};

Every event handler receives a session object as the first argument, and the event-specific object as the second argument.

The following is a list of events that BotKit supports:

Follow

The onFollow event handler is called when someone follows your bot. It receives an FollowRequest object, which allows you to accept() or reject() the follow request, as the second argument.

The following is an example of a follow event handler that accepts all follow requests and sends a direct message to new followers:

typescript
bot.onFollow = async (session, followRequest) => {
  await followRequest.accept();
  await session.publish(
    text`Thanks for following me, ${followRequest.follower}!`,
    { visibility: "direct" },
  );
};

TIP

The manual invocation of accept() or reject() is preceded by the followerPolicy option. Even if your bot has configured the followerPolicy option to "accept" or "reject", you can still manually accept() or reject() in the onFollow event handler, and the configured policy is ignored for the specific follow request.

TIP

The passed FollowRequest object can outlive the event handler if your bot is configured the followerPolicy option to "manual". The following example shows how to accept a follow request after an hour:

typescript
bot.onFollow = async (session, followRequest) => {
  setTimeout(async () => {
    await followRequest.accept();
  }, 1000 * 60 * 60);
};

Unfollow

The onUnfollow event handler is called when some follower unfollows your bot. It receives an Actor object, who just unfollowed your bot, as the second argument.

The following is an example of an unfollow event handler that sends a direct message when someone unfollows your bot:

typescript
bot.onUnfollow = async (session, follower) => {
  await session.publish(text`Goodbye, ${follower}!`, {
    visibility: "direct",
  });
};

Accept follow

The onAcceptFollow event handler is called when someone accepts your bot's follow request. It receives an Actor object, who just accepted your bot's follow request, as the second argument.

The following is an example of an accept event handler that sends a direct message when someone accepts your bot's follow request:

typescript
bot.onAcceptFollow = async (session, accepter) => {
  await session.publish(
    text`Thanks for accepting my follow request, ${accepter}!`,
    { visibility: "direct" },
  );
};

Reject follow

The onRejectFollow event handler is called when someone rejects your bot's follow request. It receives an Actor object, who just rejected your bot's follow request, as the second argument.

The following is an example of a reject event handler that sends a direct message when someone rejects your bot's follow request:

typescript
bot.onRejectFollow = async (session, rejecter) => {
  await session.publish(
    text`I'm sorry to hear that you rejected my follow request, ${rejecter}.`,
    { visibility: "direct" },
  );
};

Mention

The onMention event handler is called when someone mentions your bot. It receives a Message object, which represents the message that mentions your bot, as the second argument.

The following is an example of a mention event handler that replies to a message that mentions your bot:

typescript
bot.onMention = async (session, message) => {
  await message.reply(text`You called me, ${message.actor}?`);
};

Reply

The onReply event handler is called when someone replies to your bot's message. It receives a Message object, which represents the reply message, as the second argument.

The following is an example of a reply event handler that sends a second reply message when someone replies to your bot's message:

typescript
bot.onReply = async (session, reply) => {
  await reply.reply(text`Thanks for your reply, ${reply.actor}!`);
};

If you want to get the parent message of a reply message, you can use the replyTarget property. See also the Traversing the conversation section in the Message concept document.

CAUTION

In many ActivityPub implementations including Mastodon, reply messages often contain the mention of the original author. In such cases, both onMention and onReply event handlers are called. You should be careful not to perform unexpected actions.

The below example shows how to avoid the onMention event handler from being called when a reply message is received:

typescript
bot.onReply = async (session, reply) => {
  await reply.reply(text`Thanks for your reply, ${reply.actor}!`);
};

bot.onMention = async (session, message) => {
  if (message.replyTarget == null) {  
    await message.reply(text`You called me, ${message.actor}?`);
  }
};

Or the other way around, you can avoid the onReply event handler from being called when a reply message mentioning the bot is received:

typescript
bot.onMention = async (session, message) => {
  await message.reply(text`You called me, ${message.actor}?`);
};

bot.onReply = async (session, reply) => {
  if (!reply.mentions.some(m => m.href.href === session.actorId.href)) {
    await reply.reply(text`Thanks for your reply, ${reply.actor}!`);
  }
};

Message

The onMessage event handler is called when any message is received by your bot, which includes normal messages on the bot's timeline, mentions, replies, direct messages, and so on. It receives a Message object, which represents the received message, as the second argument.

The following is an example of a message event handler that replies to a message that contains the word BotKit:

typescript
bot.onMessage = async (session, message) => {
  if (message.text.match(/\bbotkit\b/i)) {
    await message.reply(text`You mentioned ${em("BotKit")}!`);
  }
};

NOTE

If your bot does not follow anyone, the onMessage event handler is called only when your bot receives mentions, replies, and direct messages.

To learn more about following others, see the Following an actor section in the Session concept document.

CAUTION

The onMessage event handler is called for every message that your bot receives, which includes mentions and replies. If your bot listens to the onMention or onReply event with the onMessage event handler, the onMention or onReply event handler is called first. You should be careful not to perform unexpected actions.

The below example shows how to avoid the onMessage event handler from being called when a mention message is received:

typescript
bot.onMention = async (session, message) => {
  await message.reply(text`You called me, ${message.actor}?`);
};

bot.onMessage = async (session, message) => {
  if (message.mentions.some(m => m.href.href === session.actorId.href)) {
    return;
  }
  if (message.text.match(/\bbotkit\b/i)) {
    await message.reply(text`You mentioned ${em("BotKit")}!`);
  }
};

Shared message

The onSharedMessage event handler is called when someone shares (i.e., boosts) a message on your bot. It receives a SharedMessage object, which represents the shared message, as the second argument.

The following is an example of a shared message event handler that re-shares the shared message:

typescript
bot.onSharedMessage = async (session, sharedMessage) => {
  await sharedMessage.original.share();
};

TIP

The onSharedMessage event handler can be called when someone your bot does not follow shares a message on your bot.

Like

The onLike event handler is called when someone likes messages on your bot or actors your bot follows. It receives a Like object, which represents the like activity, as the second argument.

The following is an example of a like event handler that sends a direct message when someone likes a message on your bot:

typescript
bot.onLike = async (session, like) => {
  if (like.message.actor.id?.href !== session.actorId.href) return;
  await session.publish(
    text`Thanks for liking my message, ${like.actor}!`,
    { visibility: "direct" },
  );
};

Unlike

The onUnlike event handler is called when someone undoes a Like activity on messages on your bot or actors your bot follows. It receives a Like object, which represents the Like activity which was undone, as the second argument.

The following is an example of an unlike event handler that sends a direct message when someone undoes a like activity on a message on your bot:

typescript
bot.onUnlike = async (session, like) => {
  if (like.message.actor.id?.href !== session.actorId.href) return;
  await session.publish(
    text`I'm sorry to hear that you unliked my message, ${like.actor}.`,
    { visibility: "direct" },
  );
};