Skip to main content

Event and Reply

Replying messages is the most basic function in chat. In this lesson, you will learn how to receive events and make the response.

Time to accomplish: 10 minutes

Reply Simple Message

Let's change the reply a little bit. Open file src/handlers/handleChat.tsx and edit the handler function to this:

src/handlers/handleChat.tsx
// ...
async (
ctx: ChatEventContext & { event: { category: 'message' | 'postback' } }
) => {
const { event, reply } = ctx;

return reply("Hello! I'm a Todo Bot 🤖");
}
// ...

Try interacting with the bot, and it should reply with the string in reply("...").

The context.reply function sends messages back to the chat. Replying with a string is the simplest way to use it.

JSX Syntax

In this tutorial, we'll use a more powerful way to send messages. That's JSX.

Try editing the content of reply to this:

  return reply(<p>Hello! I'm a <b>Todo Bot</b> 🤖</p>);

The html alike syntax is a JSX expression. It represents a section of chat UI in a conversation. For example, the <p>...</p> element displays a message bubble containing the inner text.

You'll learn more useful JSX features in the lessons.

info

To use the JSX syntax in typescript, the file extension has to be .tsx. Also you need to import Machinat at the beginning of the file like:

import Machinat from '@machinat/core';

Formatting Text

info

Messenger and LINE don't support text format, it shows plain text on them.

In the code above, <b>...</b> element makes the inner text bold if the platform supports it. There are more text formatting tags like i, s and code. You can check the full list of them here.

For example, <p><b>Hello!</b> <s>I'm a</s> <i>Todo</i> <code>Bot 🤖</code></p> might look like this:

Listen to Event

Handle Text Message

Text messages are the most common message type you would receive. Let's enable the bot to handle an "add todo <todo name>" command.

Edit the handleChat function like this:

src/handlers/handleChat.tsx
// ...
async (
ctx: ChatEventContext & { event: { category: 'message' | 'postback' } }
) => {
const { event, reply } = ctx;

if (event.type === 'text') {
const matchingAddTodo = event.text.match(/add(\s+todo)?(.*)/i);

if (matchingAddTodo) {
const todoName = matchingAddTodo[2].trim();
return reply(<p>Todo "<b>{todoName}</b>" is added!</p>);
}
}

return reply(<p>Hello! I'm a <b>Todo Bot</b> 🤖</p>);
}
// ...

Now your bot can accept add todo <name> command like:

Event Object

When a user sends a message to your bot, handleChat handler receives an event context object. We can get the event information at context.event.

Here's the common properties of an event:

{
platform: 'messenger', // chat platform
category: 'message', // event category
type: 'text', // event type
payload: {/*...*/}, // raw data from chat platform
user: {/*...*/}, // user object
channel: {/*...*/}, // chat object
}

We can use the platform, category and type to identify what's happening. An event with 'text' type always implements the event.text interface. So we can extract the todo name with a regular expression safely.

if (event.type === 'text') {
console.log(event.text); // must be string
}

Advanced JSX

Use Expression in JSX

The {todoName} syntax above can be used to put any expression in the JSX. For example, change it to {todoName.toUpperCase()} and see what happens.

Grouped Messages

Let's add some details after adding a todo. Edit the result message like this:

src/handlers/handleChat.tsx
// ...
if (matchingAddTodo) {
const todoName = matchingAddTodo[2].trim();
return reply(
<>
<p>Todo "<b>{todoName}</b>" is added!</p>
<p>You have <b>{3}</b> todos now.</p>
</>
);
}
// ...

The element <>...</> with empty tag is a Fragment. You can use it to group several messages together and send them once. The result would look like:

Adding a Pause

When sending a series of messages, you might want to shortly break between them. We can use the Machinat.Pause tag to do that.

src/handlers/handleChat.tsx
// ...
<>
<p>Todo "<b>{todoName}</b>" is added!</p>
<Machinat.Pause time={1500} />
<p>You have <b>{3}</b> todos now.</p>
</>
// ...

The code above adds a 1.5 second pause between two messages.


Our bot can receive events in the chatroom and answer simple messages. Next, we'll learn how to interact with users using in-chat widgets.