Skip to main content

Telegram Platform

The @machinat/telegram platform enable your app to receive/send messages as a Telegram bot.

Install

Install the core, http and telegram packages:

npm install @machinat/core @machinat/http @machinat/telegram

Steup

tip

You can check setup section in the tutorial. It brings you to set up everything step by step. :::

First, you need to apply a Telegram bot from @Botfather. Follow the official guide for the setup procedures.

Then set up the http and telegram module like this:

import Machinat from '@machinat/core';
import Http from '@machinat/http';
import Telegram from '@machinat/telegram';

const {
TELEGRAM_BOT_NAME,
TELEGRAM_BOT_TOKEN,
TELEGRAM_SECRET_PATH,
} = process.env;

const app = Machinat.createApp({
modules: [
Http.initModule({ port: 8080 }),
],
platforms: [
Telegram.intiModule({
webhookPath: '/webhook/telegram', // webhook path
botName: TELEGRAM_BOT_NAME, // bot name
botToken: TELEGRAM_BOT_TOKEN, // bot token
secretPath: TELEGRAM_SECRET_PATH, // secret path for webhook
}),
],
});

Finally, you have to register the webhook to subscribe to events from Telegram. You can use these codes to do that:

import { TelegramBot } from '@machinat/telegram';
const { DOMAIN, TELEGRAM_BOT_TOKEN, TELEGRAM_SECRET_PATH } = process.env;

const bot = new TelegramBot({ token: TELEGRAM_BOT_TOKEN });
bot
.start()
.then(() =>
bot.makeApiCall('setWebhook', {
// webhook url with trailing secretPath
url: `https://${DOMAIN}/webhook/telegram/${TELEGRAM_SECRET_PATH}`,
})
);

Usage

Here is an example to receive events and send replies back:

import Machinat from '@machinat/core';
import * as Telegram from '@machinat/telegram/components';
import app from './app';

app.onEvent(async ({ platform, event, reply }) => {
if (platform === 'telegram' && event.type === 'text') {
await reply(
<Telegram.Expression
disableNotification
replyMarkup={
<Telegram.ReplyKeyboard resizeKeyboard oneTimeKeyboard>
<Telegram.TextReply title="More 🐱" payload="catto" />
<Telegram.TextReply text="I want 🐶" data="doggo" />
</Telegram.ReplyKeyboard>
}
>
<p>Hello Telegram! 👋</p>
<p>It's your daily 🐱</p>
<img src="https://cataas.com/cat" />
</Telegram.Expression>
);
}
});

Check the API reference for the details of events and components.

Webview

Auth Setup

To use webviews in Telegram, configure the app with these steps:

  1. Send /setdomain command to @Botfather to register the domain of your bot.
  2. Add the auth provider to the webview platform. Like:
import Webview from '@machinat/webview';
import TelegramAuth from '@machinat/telegram/webview';

const app = Machinat.createApp({
platforms: [
Webview.intiModule({
authPlatforms: [
TelegramAuth
],
// ...
}),
],
});
  1. Expose your bot name in next.config.js:
const { TELEGRAM_BOT_NAME } = process.env;

module.exports = {
publicRuntimeConfig: {
TELEGRAM_BOT_NAME,
},
};
  1. Set up the WebviewClient in the webview:
import getConfig from 'next/config';
import WebviewClient from '@machinat/webview/client';
import TelegramAuth from '@machinat/telegram/webview/client';

const {
publicRuntimeConfig: { TELEGRAM_BOT_NAME },
} = getConfig();

const client = new WebviewClient({
authPlatforms: [
new TelegramAuth({ botName: TELEGRAM_BOT_NAME }),
],
});

Open the Webview

The webview can be opened by a WebviewButton in the chatroom. Like:

import * as Telegram from '@machinat/telegram/components';
import { WebviewButton as TelegramWebviewButton } from '@machinat/telegram/webview';

app.onEvent(async ({ reply }) => {
await reply(
<Telegram.Expression
replyMarkup={
<Telegram.InlineKeyboard>
<TelegramWebviewButton text="Open 📤" />
</Telegram.InlineKeyboard>
}
>
Hello Webview!
</Telegram.Expression>
);
});

The users will be logged in with Telegram account in the webview. Check the webview document to learn more.

Assets Manager

TelegramAssetsManager service helps you to manage resources on Telegram platform, like files.

To use it, you have to install a state provider first. Then register TelegramAssetsManager like this:

import { FileState } from '@machinat/dev-tools';
import TelegramAssetsManager, { saveUplodedFile } from '@machinat/telegram/asssets';

const app = Machinat.createApp({
services: [
TelegramAssetsManager,
],
platforms: [
Telegram.initModule({
dispatchMiddlewares: [
saveUplodedFile,
],
// ...
}),
],
modules: [
RedisState.initModule({
clientOptions: { url: REDIS_URL },
}),
],
});

Here's an example to upload an image message and reuse it:

import fs from 'fs';
import { makeContainer } from '@machinat/core';
import * as Telegram from '@machinat/telegram/components';
import TelegramAssetsManager from '@machinat/telegram/asssets';

app.onEvent(makeContainer({ deps: [TelegramAssetsManager] })(
(assetsManager) =>
async ({ reply }) => {
const fooImageId = await assetsManager.getFile('foo.image');

if (fooImageId) {
await reply(
<Telegram.Image fileId={fooImageId} />
);
} else {
await reply(
<Telegram.Image
assetTag="foo.image"
fileData={fs.createReadStream('./assets/foo.jpg')}
/>
);
}
}
));

If you upload a file with assetTag prop, saveUplodedFile middleware will save the returned file id. You can reuse the stored id for the next time.

Resources

Here are some resources for further reading: