This repository contains a concept for a MiniApp within Telegram that allows users to send saved answers.
Participating in MiniApp Contest October 2023.
- Motivation 🌟
- Demo
▶️ - Overview of MiniApp 📱
- Overview of Inline mode 🤖
- Mocked data 🎭
- Overview of theme 🎨
- Compatibility and Potential Errors
⚠️ - Developers guide 👩💻
- License 🥂
In many popular messengers and social media platforms, there is a feature to send saved answers. Currently, Telegram does not have this functionality.
😊 Business Communication: In business, people use prepared responses for common queries, enabling quick replies in customer support.
⏰ Time Efficiency: Quick messages save time for users handling repetitive queries or messages.
🤝 Limited Abilities: Pre-set messages simplify communication for people with physical limitations.
✔️ Error Reduction: Prepared messages decrease communication errors, ensuring accuracy.
The demo bot is available at @savedanswers_bot.
To launch in inline mode
, enter @savedanswers_bot
in any chat dialogue.
Overview of Inline mode
The web application is hosted on GitHub Pages and can be accessed at vkruglikov.github.io/my-saved-answers
🎭 The app uses Mocked Data
With MiniApp, you can view saved answers and filter them by tags.
You can easily send these saved answers without leaving the conversation with the user.
The menu button can open any MiniApp link.
To set it up, use the command /setmenubutton
via @BotFather
In this app, it opens the link vkruglikov.github.io/my-saved-answers
The active area of the application, clicking on which opens a page with a preview of the saved message.
We are still inside the MiniApp, and the transition to another page is implemented using react-router-dom
Title for describing saved message, opens in inline mode when clicked.
When clicked, the app performs two actions:
- Calls HapticFeedback.notificationOccurred('success') - gives a vibration feedback.
- Calls WebApp.switchInlineQuery with the string we want to insert in the input field. This method closes the MiniApp and opens inline mode.
Here are the filter buttons for tags.
They speed up navigation through saved answers and allow grouping of messages.
The "Add" button directs the user to the bot, where the functionality to add a new response can be implemented on the backend later.
Since this application operates entirely on mocked data, this feature has not been implemented yet.
You will see a placeholder response from the bot.
A button on the message preview page, opens in inline mode when clicked. Read more about WebApp.MainButton.
In the react
app, I'm using the component from the package vkruglikov/react-telegram-web-app.
When clicked, the app performs two actions:
- Triggers HapticFeedback.notificationOccurred('success') - gives a vibration feedback.
- Calls WebApp.switchInlineQuery with the string we want to insert in the input field. This method closes the MiniApp and opens inline mode.
Preview of inline query for a quick response.
Upon clicking, it copies the inline query to the clipboard.
When creating a multi-page web application, you need UI components to allow users to go back. MiniApp provides an object that allows displaying, hiding, and handling clicks on the native "Back" button.
Official documentation can be found here.
In the react
app, I'm using the component from the vkruglikov/react-telegram-web-app package.
In Telegram MiniApp, the inline mode is activated using the API WebApp.switchInlineQuery. This mode allows sending messages in a chat on behalf of the user.
Learn more about inline mode by reading Introducing Inline Bots.
After calling WebApp.switchInlineQuery, the MiniApp closes, and the query string is inserted into the inline mode input field.
The server processes the inline_query
request and returns a response using the answerInlineQuery method.
I use node-telegram-bot-api to work with the Telegram API in Node.js.
The query result will display a list of saved answers available for sending, presented as InlineQueryResult.
Clicking on it will send the message to the chat.
Starting from version 6.7, you can launch MiniApps from inline_query
results. To do this, there's a field called button
in the answerInlineQuery method. To learn more about it, visit the InlineQueryResultsButton page.
In this app, I open the link vkruglikov.github.io/my-saved-answers?inline to determine the app's launch location based on the inline
query parameter.
You can build your logic depending on where the app is launched.
To activate inline mode, you need to enter the bot's full name @savedanswers_bot
in the user's chat.
This might seem inconvenient and could reduce the effectiveness of quick responses.
However, after a few inputs, Telegram will suggest using the bot by simply entering the @
symbol. This makes access to quick messages instantaneous.
In this project, we use mocked saved answers. These data are used both in MiniApp and inline mode to send messages.
You can modify or add any messages, but they will remain static. The file answers.js
is located in the project's root folder, and the descriptions of types are in answers.d.ts
.
To add functionality for adding/saving/deleting saved answers, the backend needs to be enhanced.
MiniApp uses CSS variables available within the bot. This makes the application look completely native inside Telegram and supports custom themes.
For more details about styles, read the documentation page ThemeParams.
var(--tg-theme-bg-color)
var(--tg-theme-secondary-bg-color)
var(--tg-theme-text-color)
var(--tg-theme-hint-color)
var(--tg-theme-button-color)
var(--tg-theme-button-text-color)
To configure the header color and background color of the application, you can use the methods setHeaderColor
and setBackgroundColor
.
WebApp.setHeaderColor('secondary_bg_color');
WebApp.setBackgroundColor('secondary_bg_color');
In this project, I am ignoring such checks and expecting that the client will have the latest version of the API at the time of writing, which is Bot API 6.9.
/setmenubutton
. Please take this into account when making modifications.
✅ I conducted the final testing and development on version 10.1.2(27198)
of the Telegram application, on IPhone 14 IOS 16.6.1
.
First, we need to create a bot.
Creating a bot is possible by following the instructions from @BotFather.
To work in inline mode, activate it with the command /setinline
.
For configuring the menu button, use the command /setmenubutton
.
Installing dependencies and running the local server:
npm install && npm run dev
And open http://localhost:9000/
The npm run dev
command starts a local server for the bot in polling mode and a local webpack server for the React application.
Building the MiniApp static to folder dist
npm run build
Additionally, there is a workflow set up in the project to deploy static files to Github Pages.
The project has few main dependencies:
- NodeJS 20 .nvmrc
- Typescript
client
React JS ^18client
react-telegram-web-appserver
node-telegram-bot-api
You can see the full list of dependencies in the package.json file
name | description | required |
---|---|---|
TELEGRAM_BOT_TOKEN | You can get a token at @BotFather | yes |
TELEGRAM_WEBAPP_URL | Full URL address for WebApp, needed for creating links to assets in inline mode. | yes |
TELEGRAM_BOT_NAME | Telegram bot username | yes |
TELEGRAM_API_TEST_ENVIRONMENT | true or empty |
no |
DEV_HTTPS_HOST | hostname for local development, when you want to use https | no |
DEV_PATH_KEY | Relative path to https key | no (yes for https) |
DEV_PATH_CERT | Relative path to https cert | no (yes for https) |
Project structure overview without going into details
.
├── public/
│ ├── assets # In this folder, there are assets for the bot's operation
│ └── index.html # Index page for MiniAPP where telegram-web-app.js is included
├── src/
│ ├── components # Some React UI components
│ ├── icons # Icons
│ ├── pages/
│ │ ├── AnswersPage.tsx # Main page of MiniAPP with viewing all saved answers
│ │ └── PreviewPage.tsx # Preview page for answers
│ │ ├── NotFoundPage.tsx
│ ├── WebApp.tsx # Main root component for MiniAPP
│ └── WebApp.module.css
├── server/
│ └── index.mjs # Server-side component in Node.js for the bot
├── answers.js # Mocked data of saved answers
├── answers.d.ts
├── webpack.config.js
└── .env
When you're developing a MiniApp, you might need to test your application in a real environment like Telegram Desktop.
To run the app in MiniApp, we have to use an HTTPS connection.
You can use mksert to generate a certificate for local development, and set .env
variables.
DEV_HTTPS_HOST=local.my-saved-answers.app
DEV_PATH_KEY=local.my-saved-answers.app-key.pem
DEV_PATH_CERT=local.my-saved-answers.app.pem
Add domain to /etc/hosts
127.0.0.1 local.my-saved-answers.app
Now your local development server will run via HTTPS, and you can use it as the URL for your Telegram MiniApp
To deploy the bot on the server, only certain files are needed.
├── server/
├── answers.js
├── package.json
├── package-lock.json
└── .env
Installing dependencies
npm install --production
Server startup
npm run server