Как написать телеграм бота c
Перейти к содержимому

Как написать телеграм бота c

  • автор:

From BotFather to 'Hello World'

This guide will walk you through everything you need to know to build your first Telegram Bot.
If you already know your way around some of the basic steps, you can jump directly to the part you're missing. Equivalent examples are available in C#, Python, Go and TypeScript .

Introduction

At its core, you can think of the Telegram Bot API as software that provides JSON-encoded responses to your queries.

A bot, on the other hand, is essentially a routine, software or script that queries the API by means of an HTTPS request and waits for a response. There are several types of requests you can make, as well as many different objects that you can use and receive as responses.

Since your browser is capable of sending HTTPS requests, you can use it to quickly try out the API. After obtaining your token, try pasting this string into your browser:

In theory, you could interact with the API with basic requests like this, either via your browser or other tailor-made tools like cURL. While this can work for simple requests like the example above, it's not practical for larger applications and doesn't scale well.
For that reason, this guide will show you how to use libraries and frameworks, along with some basic programming skills, to build a more robust and scalable project.

If you know how to code, you'll fly right through each step in no time – and if you're just starting out, this guide will show you everything you need to learn.

We will use Java throughout this guide as it's one of the most popular programming languages, however, you can follow along with any language as all the steps are fundamentally the same.
Since Java is fully cross-platform, each code example will work with any operating system.
If you pick another language, equivalent examples are available in C#, Python, Go and TypeScript .

Getting Ready

First, we will briefly cover how to create your first project, obtain your API token and download all necessary dependencies and libraries.

For the purposes of this guide, a copy of the bot you will be creating is also live at @TutorialBot – feel free to check it out along the way to see how your own implementation should look after each step.

Obtain Your Bot Token

In this context, a token is a string that authenticates your bot (not your account) on the bot API. Each bot has a unique token which can also be revoked at any time via @BotFather.

Obtaining a token is as simple as contacting @BotFather, issuing the /newbot command and following the steps until you're given a new token. You can find a step-by-step guide here.

Your token will look something like this:

Make sure to save your token in a secure place, treat it like a password and don't share it with anyone.

Download an IDE

To program in Java you'll need an IDE – a special text editor that will let you write, compile and run your code.
In this tutorial, we'll use IntelliJ – there are several free, open source alternatives like Eclipse or NetBeans which work in the exact same way.

You will also need a JDK, a software kit that allows your Java code to run.
Most IDEs don't include a JDK, so you should download a version compatible with your operating system separately. You can find a free, open source version here.

If you use another language, the steps are identical. You will just have to download a different IDE and software development kit.

Pick a Framework or Library

You can think of a framework as software that handles all the low-level logic for you, including the API calls, and lets you focus on your bot-specific logic.

In this tutorial, we'll use TelegramBots, but you can follow along with any equivalent implementation, since all the underlying methods are either similar or exactly the same.

You can find many frameworks, along with code examples, in our dedicated list.

Create Your Project

In IntelliJ, go to File > New > Project .

Fill in the fields accordingly:

  • Name — The name of your project. For example, BotTutorial.
  • Location — Where to store your project. You can use the default value.
  • Language — Java
  • Build System — The framework that will handle your dependencies. Pick Maven.
  • JDK — Pick whichever version you downloaded. We'll be using version 17.
  • Add Sample Code — Leave this selected, it will generate some needed files for you.
  • Advanced Settings > GroupId — We suggest tutorial.
  • Advanced Settings > ArtifactId — You can use the default value.

After hitting Create, if you did everything correctly, your Project view in the top left should show a project structure along these lines:

Other IDEs will follow a similar pattern. Your dependency management system will have a different name (or no name at all if it's built-in) depending on the language you chose.

If this looks scary, don't worry. We will only be using the Main file and the pom.xml file.
In fact, to check that everything is working so far, double click on Main and click on the small green arrow on the left of public class Main, then select the first option.
If you followed the steps correctly, Hello world! should appear in the console below.

Add Framework Dependency

We will now instruct the IDE to download and configure everything needed to work with the API.
This is very easy and happens automatically behind the scenes.

First, locate your pom.xml file on the left side of the screen.
Open it by double-clicking and simply add:

right after the </properties> tag.

When you're done, your pom.xml should look something like this.

Start Coding

We are ready to start coding. If you're a beginner, consider that being familiar with your language of choice will greatly help. With this tutorial, you'll be able to teach your bot basic behaviors, though more advanced features will require some coding experience.

Creating a Bot Class

If you're familiar with object-oriented programming, you'll know what a class is.
If you've never heard of it before, consider a class as a file where you write some logic.

To create the class that will contain the bot logic, right click on tutorial from the project tree on the left and select New > Java Class. Name it Bot and hit enter.

Now we have to connect this class to the bot framework. In other words, we must make sure it extends TelegramLongPollingBot . To do that, just add extends TelegramLongPollingBot right after Bot.
A red line will appear – it simply means we're missing some important methods.

To fix this, hover over the red line, click on implement methods, then hit OK.
Depending on the IDE, this option may be called implement missing methods or something similar.

You should end up with this – if something went wrong, feel free to copy it from here and paste it in your class:

If you get a red line under TelegramLongPollingBot, it means you didn't set up your pom.xml correctly. If this is the case, restart from here.

Available Methods

Let's look into these 3 methods one by one.

  • getBotUsername — This method must be edited to always return your bot's username. You should replace the null return value with it.
  • getBotToken — This method will be used by the framework to retrieve your bot token. You should replace the null return value with the token.
  • onUpdateReceived — This is the most important method. It will be called automatically whenever a new Update is available. Let's add a System.out.println(update); call in there to quickly show what we are getting.

After you've replaced all the strings, you should end up with this:

At this point, the bot is configured and ready to go – time to register it on the API and start processing updates.

In the future, you should consider storing your token in a dedicated settings file or in environment variables. Keeping it in the code is fine for the scope of this tutorial, however, it's not very versatile and is generally considered bad practice.

Registering the Bot

To register the bot on the API, simply add a couple of lines in the main method that will launch the application. If you named your class Bot , this is what your main method should look like:

You can place this method in any class. Since we have an auto-generated main method in the Main class, we'll be using that one for this tutorial.

First Run

It's time to run your bot for the first time.
Hit the green arrow to the left of public static void main and select the first option.

And then there was nothing. Yes, a bit anticlimactic.
This is because your bot has nothing to print – there are no new updates because nobody messaged it yet.

If you try messaging the bot on Telegram, you'll then see new updates pop up in the console. At this point, you have your very own Telegram Bot – quite the achievement. Now, on to making it a bit more intelligent.

If nothing pops up, make sure you messaged the right bot and that the token you pasted in the code is correct.

Receiving Messages

Every time someone sends a private message to your bot, your onUpdateReceived method will be called automatically and you'll be able to handle the update parameter, which contains the message, along with a great deal of other info which you can see detailed here.

Let's focus on two values for now:

  • The user — Who sent the message. Access it via update.getMessage().getFrom() .
  • The message — What was sent. Access it via update.getMessage() .

Knowing this, we can make it a bit more clear in the console output.

This is just a basic example – you can now play around with all the methods to see everything you can pull out of these objects. You can try getUsername , getLanguageCode , and dozens more.

Knowing how to receive, process and print incoming messages, now it's time to learn how to answer them.

Remember to stop and re-launch your bot after each change to the code.

Sending Messages

To send a private text message, you generally need three things:

  • The user must have contacted your bot first. (Unless the user sent a join request to a group where your bot is an admin, but that's a more advanced scenario).
  • You must have previously saved the User ID ( user.getId() )
  • A String object containing the message text, 1-4096 characters.

With that out of the way, let's create a new method to send the first message:

And proceed to run this in the main method, right after registering the bot.
For this example, we'll assume your User ID is 1234 .

If you did everything correctly, your bot should text you Hello World! every time you launch your code. Sending messages to groups or channels – assuming you have the relevant permissions – is as simple as replacing 1234 with the ID of the respective chat.

Try experimenting with other types of messages, like SendPhoto, SendSticker, SendDice…
A full list is available starting here.

Echo Bot

Let's practice everything we tried so far by coding an Echo Bot.
Its functionality will be rather simple: every text message it receives will be sent right back to the user.

Copying Text

The most intuitive way of coding this is saving the User ID and calling sendText right after each update.

This works for text but can be extended to stickers, media and files.

Copying Everything

There are more specific functions that can be used to copy messages and send them back.
Let's build a method to do just that:

After replacing the method call in onUpdateReceived , running the code will result in a fully functional Echo Bot.

This tutorial assumes that updates always contain messages for the sake of simplicity. This may not always be true – be sure to implement all the proper checks in your code to handle every type of update with the appropriate methods.

Executing Commands

To learn what a command is and how it works, we recommend reading this dedicated summary.
In this guide, we'll focus on the technical side of things.

Creating Your Command

Begin by opening @BotFather.
Type /mybots > Your_Bot_Name > Edit Bot > Edit Commands.

Now send a new command, followed by a brief description.
For the purpose of this tutorial, we'll implement two simple commands:

Command Logic

We want the Echo Bot to reply in uppercase when it's in scream mode and normally otherwise.

First, let's create a variable to store the current mode.

Then, let's change some logic to account for this mode.

Finally, let's add a couple more lines to the onUpdateReceived method to process each command before replying.

As you can see, it checks if the message is a command. If it is, the bot enters scream mode.
In the update method, we check which mode we are in and either copy the message or convert it to upper case before sending it back.

And that's it. Now the bot can execute commands and change its behavior accordingly.

Naturally, this simplified logic will change the bot's behavior for everyone – not just the person who sent the command. This can be fun for this tutorial but won't work in a production environment – consider using a Map, dictionary or equivalent data structure to assign settings for individual users.

Remember to always implement a few basic global commands.
You can practice by implementing a simple feedback to the /start command, which we intentionally left out.

Buttons and Keyboards

To streamline and simplify user interaction with your bot, you can replace many text-based exchanges with handy buttons. These buttons can perform a wide variety of actions and can be customized for each user.

Button Types

There are two main types of buttons:

  • Reply Buttons — used to provide a list of predefined text reply options.
  • Inline Buttons — used to offer quick navigation, shortcuts, URLs, games and so much more.

Using these buttons is as easy as attaching a ReplyKeyboardMarkup or an InlineKeyboardMarkup to your SendMessage object.

This guide will focus on inline buttons since they only require a few extra lines of code.

Creating Buttons

First of all, let's create some buttons.

Let's go back through the fields we specified:

  • Text — This is what the user will see, the text that appears on the button
  • Callback Data — This will be sent back to the code instance as part of a new Update , so we can quickly identify what button was clicked.
  • Url — A button that specifies a URL doesn't specify callbackdata since its behavior is predefined – it will open the given link when tapped.
Creating Keyboards

The buttons we created can be assembled into two keyboards, which will then be used to navigate back and forth between two sample menus.

First, add two fields to store the necessary keyboards.

Then, build and assign them.

You can place this code wherever you prefer, the important thing is making sure that keyboard variables are accessible from the method call that will send the new menu. If you're confused by this concept and don't know where to put them, just paste them above the command processing flow.

Sending Keyboards

Sending a keyboard only requires specifying a reply markup for the message.

You may have noticed that we also added a new parameter, HTML .
This is called a formatting option and will allow us to use HTML tags and add formatting to the text later on.

Menu Trigger

We could send a new menu for each new user, but for simplicity let's add a new command that will spawn a menu. We can achieve this by adding a new else clause to the previous command flow.

Try sending /menu to your bot now. If you did everything correctly, you should see a brand new menu pop up.

In a production environment, commands should be handled with an appropriate design pattern that isolates them into different executor classes – modular and separated from the main logic.

Navigation

When building complex bots, navigation is essential. Your users must be able to move seamlessly from one menu to the next.

In this example, we want the Next button to lead the user to the second menu.
The Back button will send us back.
To do that, we will start processing incoming CallbackQueries , which are the results we get after the user taps on a button.

A CallbackQuery is essentially composed of three main parameters:

  • queryId — Needed to close the query. You must always close new queries after processing them – if you don't, a loading symbol will keep showing on the user's side on top of each button.
  • data — This identifies which button was pressed.
  • from — The user who pressed the button.

Processing in this context just means executing the action uniquely identified by the button, then closing the query.

A very basic button handler could look something like:

With this handler, whenever a button is tapped, your bot will automatically navigate between inline menus.
Expanding on this concept allows for endless combinations of navigable submenus, settings and dynamic pages.

Database

Telegram does not host an update database for you – once you process and consume an update, it will no longer be available. This means that features like user lists, message lists, current user inline menu, settings, etc. have to be implemented and maintained by bot developers.

If your bot needs one of these features and you want to get started on data persistence, we recommend that you look into serialization practices and libraries for your language of choice, as well as available databases.

Implementing a database is out of scope for this guide, however, several guides are available online for simple embedded open source software solutions like SQLite, HyperSQL, Derby and many more.

Your language of choice will also influence which databases are available and supported – the list above assumes you followed this Java tutorial.

Hosting

So far, your bot has been running on your local machine – your PC. While this may be good for developing, testing and debugging, it is not ideal for a production environment.
You'll want your bot to be available and responsive at all times, but your computer might not always be online.

This can be done in four steps:

Package your code
Making your bot easy to move and runnable outside of an IDE is essential to host it elsewhere.
If you followed this tutorial, this standard guide will work for you. If you didn't, look into export or packaging guides for your IDE and language of choice – procedures may vary but the end result is the same.

Purchase a VPS or equivalent service
A server is essentially a machine that is always online and running, without you having to worry about anything. To host your bot, you can opt for a VPS which serves this purpose and can be rented from several different providers.
Another option would be to purchase a network-capable microcontroller, which come in all different specs and sizes depending on your needs.

You should ensure that all user data remains heavily encrypted at all times in your database to guarantee the privacy of your users. The same concept applies to your local instance, however, this becomes especially important once you transfer your database to a remote server.

  • Upload your executable/package

Once you have a working ssh connection between your machine and your new server, you should upload your executable and all associated files.
We will assume the runnable jar TutorialBot.jar and its database dbase.db are currently in the /TBot folder.

  • Run your application

Depending on which language you chose, you might have to configure your server environment differently. If you chose Java, you just need to install a compatible JDK.

If you did everything correctly, you should see a Java version as the output, along with a few other values. This means you're ready to run your application.

Now, to run the executable:

Your bot is now online and users can interact with it at any time.

To streamline and modularize this process, you could employ a specialized docker container or equivalent service.
If you followed along in one of the equivalent examples (C#, Python, Go and TypeScript) you can find a detailed set of instructions to export and run your code here.

Further Reading

If you got this far, you might be interested in these additional guides and docs:

If you encounter any issues while following this guide, you can contact us on Telegram at @BotSupport.

Как создать telegram бот на C# быстро?

В этой статье мы рассмотрим заготовку для создания телеграм бота на C#. В связи с последними обновлениями TelegramBotAPI, большая часть удачных с моей точки зрения публикаций на эту тему несколько устарело. Потому я принял решение написать статью на эту тему.

Процесс создания и отладки бота был записан и освещен в видеоролике в статье ниже. В телеграм группе можно задать вопрос по данной тематике.

Чуть подробнее

Мы будем пользоваться библиотеками Telegram.Bot и Telegram.Bot.Extentions.Polling, обновления будем получать периодически опрашивая Telegram сервер на наличие новых обновлений. Webhook’и мы использовать не будем. Тпру, подождите меня забрасывать гнилыми помидорами, матерые кодеры! Да, метод получения обновлений основанный на Webhook’ах лучше, но Polling проще в реализации поскольку не нужно получать SSL-сертификат и бот можно запустить сразу после написания кода без дополнительных заморочек. На этом новичок может застопориться. К тому же есть ряд нюансов при использовании Webhook’ов на моем сервере. Если они есть у меня, значит они могут быть и у Вас. Потому используем метод периодического опроса сервера Телеграма на наличие новых обновлений. Ладно, уважаемый читатель, если Вы все еще со мной не согласны и желаете получить сертификат и работать на Webhook’ах, можешь почитать о получении сертификата в этой статье.

Существующие схемы работы telegram бота

Мне нравится схема работы telegram бота на C#, описанная в этой статье. Считаю ее хорошим примером. Вот код:

Там ничего лишнего. Создаем объект TelegramBotClient чтобы взаимодействовать с нашим ботом с помощью библиотеки, прописываем ему токен, который выдал нам BotFather. Далее создаем событие OnMessage, обрабатываем его методом BotOnMessageReceived и запускаем клиент.

Однако с выходом более новых версий TelegramBotAPI оказалось, что такая схема больше не работает. Более того, боты, написанные на более ранних версиях Telegram.Bot перестают работать после обновления библиотеки.

Нужно использовать другую схему. Давайте попробуем в этом разобраться.

Пошаговая инструкция

Итак ниже я набросал следующий список шагов, которые приведут вас к рабочему telegram боту.

1. Запускаем Visual Studio Community, создаем консольное приложение.

Если у Вас отсутствует Visual Studio Community, Вы можете установить ее используя статью или несколько устаревшее видео. При этом желательно выбирать установку Visual Studio Community 2022 как наиболее актуальную версию на текущий момент.

Создаем проектСоздаем проект Называем проект как нам удобноНазываем проект как нам удобно Выбираем платформу .NET 3.1Выбираем платформу .NET 3.1 Проект создан!Проект создан!

2. Добавляем в консольное приложение библиотеку Telegram.Bot, Telegram.Bot.Extentions.Polling и Netonsoft.Json

Открытие NuGetОткрытие NuGet Поиск библиотекиПоиск библиотеки Установка пакетаУстановка пакета

По завершению у Вас должны быть установлены и отображены названия пакетов, которые мы установили.

Netonsoft.Json применимо к нашей заготовке нужна для того, чтобы у нас была возможность вывести на консоль сообщение от пользователя.

3. Создаем telegram бот в BotFather. Копируем его api key для работы.

Находим в telegram BotFather, отправляем ему /newbot, название и логин бота

BotFather должен нам предоставить API key, который мы должны вставить в код-каркас в следующем шаге в строке

static ITelegramBotClient bot = new TelegramBotClient(«TOKEN»);

4. В файл Program.cs вставляем следующий код-каркас:

5. Редактируем код под свои нужды и задачи.

Главное задачей, которую должен выполнять бот — это реагировать на сообщения, которые отправляет ему пользователь. Конечно, разработчики telegram’a заложили возможность отслеживания и реагирования на много других событий.

К важным я бы отнес еще нажатие кнопки inline клавиатуры пользователем, inline mode — когда пользователь вводит логин бота и поисковой запрос в текстовое поле и бот предоставляет список найденных объектов по этому запросу. Также интересно было бы рассмотреть событие публикации нового поста на канале. Получение от пользователя его номера телефона, файла или геолокации. Но это материал для следующих видеороликов и статей. Если Вам интересно увидеть этот материал на YouTube канале или в статье, ставьте лайки, делитесь статьей с друзьями. При достижении 200 лайков и 20 комментариев я буду знать, что вам нравится данная тема и напишу продолжение.

Итак что мы можем сделать когда пользователь отправил нашему боту сообщение?
Во-первых мы можем вывести ее на консоль. Для этого в Nuget установим либу Newtonsoft и пропишем в методе HandleUpdateAsync.

Конечно, мы можем проверить что он нам прислал. И если текст сообщения будет тем, который мы ждем, выполнить определенные действия.Например если пользователь нажал кнопку Start и тем самым отправил боту текст «/start», мы можем отправить ему в ответ «Добро пожаловать на борт, добрый путник!».

if (update.Type == Telegram.Bot.Types.Enums.UpdateType.Message)
Здесь мы проверяем тип обновления. Если пользователь отправил нам сообщение, выполняем ниже описанные действия.

var message = update.Message;
Создаем новую переменную для удобства и записываем в нее всю информацию о пришедшем сообщении.

if (message.Text.ToLower() == «/start»)
Проверяем какой текст отправил пользователь. Если текст сообщения в нижнем регистре (.ToLower()) является словом «/start», то пишем ему сообщение «Добро пожаловать на борт, добрый путник!». И останавливаем выполнение метода командой return.

Целесообразно также данные этого пользователя записать в какую-нибудь базу данных. Например MySQL, PostgreSQL или еще какую-то. Или просто в файл. Напишите в комментариях если Вам это интересно.

А если пользователь отправит боту другое сообщение, например «Здравствуй», мы можем написать боту, например, «Здоров, братан! И тебе не хворать»

await botClient.SendTextMessageAsync(message.Chat, «Здоров, братан! И тебе не хворать!»);

Думаю принцип вы поняли.

Полный код ниже:

Не забудьте вставить в код API key от Вашего бота там, где написано TOKEN.

Для удобства записал видео.

Заключение

Итак в этой статье мы с вами создали telegram бот с нуля и протестировали его на работоспособность. Созданную заготовку можно будет использовать в дальнейшем для создания полномасштабных коммерческих проектов.

.NET Core в действии: пишем бота для telegram.

В предыдущей статье я немного затронул .NET Core и ввел некоторые определения. Этой статьей я хочу показать как с ним работать и что из этого может получиться. Примером — будет простой бот для telegram. Помимо самого кода, в этой статье я постараюсь объяснить некоторые принципы проектирования Web приложений на C# и .NET Core 2.0, а также рассказать о некоторых особенностях telegram, и дать некоторую литературу по данному направлению. Для всех ГУРУ и тех кому не терпится посмотреть: смотрите вот этот репозиторий на github. Тут уже находится необходимый шаблон для написания бота (кстати лежит он у меня довольно давно и эта и предыдущая статьи должны были выйти раньше, но время. его как всегда не хватает). Ну хватит лирики. Погнали кодить!

Шаг 1: Теория.

Тут я расскажу о ASP.NET Core 2.0, немного затрону его отличия от обычного человеческого ASP.NET, расскажу о паттерне проектирования MVC. Знающие люди смело могут перейти к шагу 2. Вся литература все равно будет продублирована в конце. Вы ничего не пропустите.

Еще немного теории о .NET Core…

Платформа ASP.NET Core представляет технологию от компании Microsoft, предназначенную для создания различного рода веб-приложений: от небольших веб-сайтов до крупных веб-порталов и веб-сервисов.

С одной стороны, ASP.NET Core является продолжением развития платформы ASP.NET. Но с другой стороны, это не просто очередной релиз. ASP.NET Core фактически делает революцию всей платформы, ее качественное изменение. Как вы уже поняли, ASP.NET Core работает поверх кросс-платформенной среды .NET Core, которая может быть развернута на основных популярных ОС: Windows , Mac OS X , Linux .

Как следует из примера 2 прошлой статьи — теперь развертывания сайта на ASP.NET Core может производится внутри самого приложения. Для этого используется кросс-платформенный веб-сервер Kestrel , который уже строен “из коробки”, однако традиционный IIS — никто не отменял. Это позволяет осуществлять более гибкую настройку: пользуетесь Linux и хотите демонезировать приложение (обернуть в Service) — пожалуйста, обернуть сайт в docker — никаких проблем. С .NET Core все стало гораздо прозрачнее и понятней.

Благодаря модульности фреймворка все необходимые компоненты веб-приложения могут загружаться как отдельные модули через Nuget (он к стати совсем недавно стал работать намного быстрее, хотя иногда он тупит и тогда приходится идти пить чай после команды restore). В добавок, в .NET Core 2.0, в отличие от 1.0 больше не обязательно использовать библиотеку System.Web.dll .

ASP.NET Core включает в себя фреймворк MVC , который объединяет функциональность MVC, Web API и Web Pages. В предыдущих версии платформы данные технологии реализовались отдельно и поэтому содержали много дублирующей функциональности. Сейчас же они объединены в одну программную модель ASP.NET Core MVC. А Web Forms полностью ушли в прошлое.

Кроме объединения вышеупомянутых технологий в одну модель в MVC был добавлен ряд дополнительных функций.

Одной из таких функций являются тэг-хелперы (tag helper), которые позволяют более органично соединять синтаксис html с кодом С#. Да, в отличии от ASP.NET хтмл фойлы тепеть хранятся в новом формате CSHTML. Признаюсь, когда я впервые увидел tag helper-ы с их @ и < - у меня потекла кровь из глаз. почему-то сразу вспомнился qBASIC , 1С , template-ы в крестах и GOTO (Никогда не пишите на qBASIC))). Но после пары часов я понял, что это в прицепе помогает (хотя нет, это ужасно и я стараюсь их избегать). И напоследок, для обработки запросов теперь используется новый конвейер HTTP, который основан на компонентах Katana и спецификации OWIN . А его модульность позволяет легко добавить свои собственные компоненты. Да, web-api стало писать намного удобнее.

Резюмируя, можно выделить следующие ключевые отличия ASP.NET Core от предыдущих версий ASP.NET:

  • Новый легковесный и модульный конвейер HTTP-запросов
  • Возможность развертывать приложение как на IIS, так и в рамках своего собственного процесса
  • Использование платформы .NET Core и ее функциональности
  • Распространение пакетов платформы через NuGet
  • Интегрированная поддержка для создания и использования пакетов NuGet
  • Единый стек веб-разработки, сочетающий Web UI и Web API
  • Конфигурация для упрощенного использования в облаке
  • Встроенная поддержка для внедрения зависимостей
  • Расширяемость
  • Кроссплатформенность: возможность разработки и развертывания приложений ASP.NET на Windows, Mac и Linux
  • Развитие как open source, открытость к изменениям

Паттерн MVC и с чем его едят.

По словам Википедии, паттерн (англ. design pattern) — повторимая архитектурная конструкция, представляющая собой решение проблемы проектирования в рамках некоторого часто возникающего контекста. Например способ проектирования «сверху вниз» можно отнести к одним из первых паттернов проектирования.

Model-View-Controller. MVC — это фундаментальный паттерн, который нашел применение во многих технологиях, дал развитие новым технологиям и каждый день облегчает жизнь разработчикам.

Впервые паттерн MVC появился в языке SmallTalk . Разработчики должны были придумать архитектурное решение, которое позволяло бы отделить графический интерфейс от бизнес логики, а бизнес логику от данных. Таким образом, в классическом варианте, MVC состоит из трех частей, которые и дали ему название.

Model.

Под Моделью, обычно понимается часть содержащая в себе функциональную бизнес-логику приложения. Модель должна быть полностью независима от остальных частей продукта. Модельный слой ничего не должен знать об элементах дизайна, и каким образом он будет отображаться. Достигается результат, позволяющий менять представление данных, то как они отображаются, не трогая саму Модель.

Модель обладает следующими признаками:

  • Модель — это бизнес-логика приложения;
  • Модель обладает знаниями о себе самой и не знает о контроллерах и представлениях;
  • Для некоторых проектов модель — это просто слой данных (DAO, база данных, XML-файл);
  • Для других проектов модель — это менеджер базы данных, набор объектов или просто логика приложения;

В обязанности Представления входит отображение данных полученных от Модели. Однако, представление не может напрямую влиять на модель. Можно говорить, что представление обладает доступом «только на чтение» к данным.

Представление обладает следующими признаками:

  • В представлении реализуется отображение данных, которые получаются от модели любым способом;
  • В некоторых случаях, представление может иметь код, который реализует некоторую бизнес-логику. Но только в некоторых случаях(!) и вообще я этого не говорил:-)

Примеры представления: HTML-страница, WPF форма, Windows Form.

Controller.

Контроллер обеспечивает «связи» между пользователем и системой . Контролирует и направляет данные от пользователя к системе и наоборот. Использует модель и представление для реализации необходимого действия.

  • Контроллер определяет, какие представление должно быть отображено в данный момент;
  • События представления могут повлиять только на контроллер.контроллер может повлиять на модель и определить другое представление.
  • Возможно несколько представлений только для одного контроллера;

Основная идея этого паттерна в том, что и контроллер и представление зависят от модели, но модель никак не зависит от этих двух компонент.

Итак, контроллер перехватывает событие извне и в соответствии с заложенной в него логикой, реагирует на это событие изменяя Mодель, посредством вызова соответствующего метода. После изменения Модель использует событие о том что она изменилась, и все подписанные на это события Представления, получив его, обращаются к Модели за обновленными данными, после чего их и отображают.

Начинающие программисты очень часто трактуют архитектурную модель MVC как пассивную модель MVC: модель выступает исключительно совокупностью функций для доступа к данным, а контроллер содержит бизнес-логику. В результате — код моделей по факту является средством получения данных из СУБД, а контроллер — типичным модулем, наполненным бизнес-логикой. В результате такого понимания — MVC-разработчики стали писать код, который Pádraic Brady (известный в кругах сообщества «Zend Framework» (Толстые, тупые, уродливые контроллеры или ТТУК).

Наиболее наглядно эта проблема описана статье The M in MVC: Why Models are Misunderstood and Unappreciated Pádraic Brady. Вот перевод этой статьи.

Но в объектно-ориентированном программировании используется активная модель MVC, где модельэто не только совокупность кода доступа к данным и СУБД, но и вся бизнес-логика; также, модели могут инкапсулировать в себе другие модели. Контроллеры же, — как элементы информационной системы, — ответственны лишь за:

  • приём запроса от пользователя;
  • анализ запроса;
  • выбор следующего действия системы, соответственно результатам анализа (например, передача запроса другим элементам системы).

Только в этом случае контроллер становится «тонким» и выполняет исключительно функцию связующего звена (glue layer) между отдельными компонентами информационной системы.

Ох уж эти паттерны… Я надеюсь что мои формулировки не взорвали моит немногочисленным читателям мозг. Если вы не поняли то, что я писал — не переживайте. Паттерны вообще не самая простая тема, а среди всех MV- паттернов — MVC, на мой взгляд, вообще является одним из самых сложных для понимания. Так или иначе я постарался доступно объяснить его суть. Это одна из тех вещей, которая коде выглядит не так страшно и более понятно. По этому погнали!

Шаг 2: Практика.

И так запускаем нашу любимую Visual Studio 2017 — создаем новый проект с названием TelegrammAspMvcDotNetCoreBo t: .NET Core -> Веб приложение .NET Core. Тип приложения: WebAPI, Версия платформы: .NET Core 2.0.

Web API в ASP.NET Core

Проект, который создается в Visual Studio, будет во многом напоминать проект для MVC за тем исключением, что в нем не будет представлений.

Web API в ASP.NET Core

Первым делом переименуем ValuesController.cs в MessageController , и выпилим оттуда все. Оставим пустой класс с обработкой GET -запроса:

Запустим нашу прилку и перейдем по ссылке localhost:XXXX/api/message/update . Получили результат Method GET unuvalable (ура мы крутые прогеры!).

Model first.

Для написания проекта будем использовать подход “model first”. Он заключается в том, что сначала необходимо разработать модель приложения и написать логику, затем нарисовать Представление, а уже потом склеить это дело контроллером.

Итак, нам нужен сам бот для телеги. Давайте опишем его модель. Пошли кодить? Неет. Сначала обдумаем а как эту модель реализовать.

У бота есть несколько параметров конфигурации: токен, имя, и url сайта, где он лежит. Значит это настройки бота. и их можно описать в отдельном классе. Создадим папку Models а в ней класс AppSettings.cs:

Отлично! Теперь опишем бота? Подождите. Бот такая сущность которая должна содержать команды и выполнять их. А значит нам нудны еще эти самые команды. Как должна выглядеть команда? Каждая команда как-то называется, значит содержит свойство Name. Команда должна определять вызвали ее или нет: содержать булеву функцию Contains(. ) . И уметь выполнять себя — Execute(. ) . И последнее: команд может быть много, значит нужен какой то абстрактный класс.

Теперь создадим папку Commands внутри папки Models и запихнем туда класс Command.cs:

Здесь Execute возвращает не void, а Task, так как команда может выполняться и асинхронно.

Ну что же, пришла пора писать бота. Любой телеграм бот должен содержать клиента TelegramBotClient, а также наш бот должен содержать команды. Их будет много, а значит нам нужна их коллекция. К томуже бот должен уметь возвращать TelegramBotClient-а для вызова его из команд.

Создаем класс Bot.cs:

Я думаю, комментарии излишни.

Теперь научим его приветствовать нас. Добавим класс StartCommand.cs:

Осталось сконфигурировать бота, и сказать нашему приложению, что бот у нас есть. Идем в класс Startup и в методе Configure приписываем в конец:

Финальный аккорд. Добавим клея!

Теперь наш контроллер научился обрабатывать сообщения из телеги. Осталось только залить это дело на сервер, и получить ключ от botFather.

В нашем боте мы используем WebHook и для него необходимы HTTPS соединение + Домен. Если вам лень замораживаться, то вы всегда можете задиплоить его на Azure. Не забудьте задать ему URL перед заливкой.

Литература

.Net Core 2.0 вышла совсем недавно, а по этому по ней нет русскоязычной литературы. Честно обошел весь дом книги на Невском, и библиоглобус в Москве. В первом случае вообще нет какой-то внятной литературы (удивление), удалось найти только по .Net Core 1.0, да и то сомнительного качества (я надеюсь Петербуржцы не будут кидать в меня камнями). В Москве выбор чуть больше, но вся русскоязычная литература опять же по версии 1.0. Возможно, я не там искал, тогда буду рад какой-либо информации.

Вот скромный список того, что удалось найти:

Как видите список даже англоязычной литературы ограничивается тремя книгами. А официальных книг от MS нет даже по первой версии. Но метод научного тыка никто не отменял!

Introduction

The increasing popularity of alternative messaging apps like Telegram, Signal, Tox and many others, has led to a rapid development in a variety of aspects in these social platforms. More capabilities have been added in order to stay competitive in the market; APIs have been gradually broadening their features.

This development expansion has given both users and developers a vast range of opportunities to implement their own systems on-top of these APIs.

In this article I will be describing the process of creating a simple telegram bot service using a specialized C/C++ library and systemd services on Linux.

The TgBot-cpp Library

This library gives the programmer a wide variety of classes and functions which communicate with the Telegram API. The library can be found on GitHub, as well as documentation here.

The library consists of 3 modules:

  • General — The API class, the Bot class, EventBroadcaster class [event management is done here] and the TelegramBotException class
  • Types — Basic types like, TextMessage, AuidoMessage, FileMessage, Chat, …
  • Net — takes care of the HTTP communication as well as the SSL encryption

These 3 modules lay the foundation to all Telegram Bots that use this library. The usual process of creating a bot object and binding it to a real Telegram Bot is simple.

  1. A Telegram Bot object is instantiated with a token parameter
  2. Various event handlers are bind to the bot object depending on the situation and the event type.
  3. The bot object enters the main loop where it waits for event and executes callbacks respectively.

Creating a Telegram Bot

As show in the official website here, creating a Telegram Bot does not require any special programming skills. The process is quite simple, and anyone with an active Telegram account can create a number of bots.

As described in the Bot Father section, the first step in creating a Bot is to open a chat with Bot Father — Telegrams specialized Frond-end for creating other bots. Then send the command /newbot (strings starting with “/” represent commands to be executed by the bots ) to the chat with Bot Father. The third step is to provide the newly created Bot with a display name and a username. After all the above steps have been completed successfully, Bot Father will display general information about the newly created bot.

The most important piece of information regarding your bot is the TOKEN. Only through the token can one access the capabilities of the bot and program specialized software for bot management. The token usually is a string with the following format: <bot_id>:<bot_access_key>

The important parameters (as listed in the original documentation) for any Telegram Bot are shown below :

  • The name of your bot is displayed in contact details and elsewhere.
  • The Username is a short name, to be used in mentions and t.me links. Usernames are 5–32 characters long and are case insensitive, but may only include Latin characters, numbers, and underscores. Your bot’s username must end in ‘bot’, e.g. ‘tetris_bot’ or ‘TetrisBot’.
  • The token is a string along the lines of 110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw that is required to authorize the bot and send requests to the Bot API. Keep your token secure and store it safely, it can be used by anyone to control your bot.

System Architecture

Main Goal

The main goal of the program that I will be showing here is to send messages to a particular char in Telegram. The contents of these messages shall be acquired from files within a specific directory. This can be very useful, especially in system administration. In my particular case, I have important information like CPU usage, RAM usage, CPU temperature, etc. which in some extreme situations, needs to be managed, in some sense, directly by me. In order to be notified immediately of a particular circumstance, I need something to act immediately and send that information directly to me. I designed this simple program to make use of the Telegram API and send me information directly to my Telegram account.

Architecture

The architecture of the system is quite simple. I will divide each feature of this system into a specific module. In order to get the needed information from the system, like CPU, RAM etc. I have written other programs/scripts that fetch that particular information, format it and store it in files on the filesystem. This is the information gathering module. The communication module is the program that we will discuss today in this article — the Telegram Bot; It checks the files for new information and sends the new information directly to the chat that I have opened with this Bot. The system manger module here is represented by systemd. I have created a simple service that is responsible for the Telegram Bot and its child processes. Simply said, the design of this system goes something along the lines of:

There are some scripts that are execute and gather information about the system; They write that information into files; The Telegram Bot program will create N processes for each file that needs to be watched. Each process is responsible for one file only; If a file gets modified, a message will be sent to the recipient using the Telegram Bot API with the modified file contents. All of this will be managed by a systemd service.

In order to make things clear, I would like to conceptually divide the content information from the actual perpetrator which will send messages through the Telegram Bot API. The program responsible for the Telegram Bot will not deal with or manage any files on the filesystem, it will only be allowed to read a particular file and nothing more. This will increases the security of the system overall. The main reason being the low coupling of the module responsible for file management and the module responsible for sending the messages. Another reason I believe increases the level of security is the fact that even if, one day, a particular bug is found in the Telegram API that grants access to the remote executing program, the program itself will not have many features/options that give the attacker any type of advantage over the system.

Figure 1 provides a simple example of how the system architecture will look. In this example there are 5 resources that need to be managed by the system — CPU usage, RAM usage, Network traffic, system temperature and some other resource. There are 5 jobs belonging to the information gathering module which write information to their respective files on the filesystem. The main Telegram Bot process creates 5 child processes to manage each resource file. Each child process is responsible for one file only and it checks its file descriptor every M milliseconds for modifications. If the file has been modified, the contents are sent to the Telegram Bot object shared by all child processes and then sent to a specific chat. If the file has not been modified, the child process does not execute any additional code.

1. Information gathering module

This paragraph is mainly informative and therefore does not dive deep in specifics on how to implement such modules.

This module consists mainly of bash scripts, that are executed at a given interval. the output of these scripts is then piped >> to a file, which later on the Telegram Bot process reads.

You can implement your own information gathering module by again using bash scripts, compiling a program, overwriting files through the network by another machine etc.

2. Communication module

This paragraph describes the design of the communication module, responsible for reading the file contents and sending messages to the appointed chat id.

The main Telegram Bot process will be responsible for the creation of N child processes, which will constantly be checking if their designated file has been modified. On Figure 1 the main Telegram Bot process is represented as a blue square, each child process is a line inside the square which gets information from a specific file on the filesystem. For example, the CPU process reads the cpu.file.txt every M milliseconds and keeps track of the last modified timestamp.

In order to optimize this service a bit, we can implement an environment variable specific for each child process. This environment variable will contain the value of the last_modified_timestamp of the respective file [in Unix time]. In this way, each child process is self-sufficient and does not rely on anything else for its execution. The environment variable names are shown on Figure 2 in each child process box in green.

[ Note ] In GNU/Linux when a process creates a child process, the child process is “granted access” to the parent processes’ resources i.e. environment variables. However, the child does not share its environment with its parent.

Once this environment variable has been set, it is then compared to the real-time last_modified_timestamp every M milliseconds.

Figure 3 shows the process of sending the file contents from the cpu.file.txt. After the cpu get info job has written the new content to the file, the modified flag has changed. As this happens, the child process responsible for the cpu file has waited M milliseconds and therefore can go and compare the last_modified_timestamp value, stored in CPU_ENV_VAR with the current modified flag of the file. Because the file was modified within the M millisecond “sleep” time period of the child process, the two modified values do not match. Therefore, the contents of the file have to be sent to the Telegram Bot object, which is shared among all child processes. After that the Telegram Bot object can call send_message() function and send the new file content to a specific chat [chat_id].

The process of sending the modified file contents with the help of the Telegram Bot object is the same amongst all child processes.

3. System Manager module

This paragraph describes the design of the system manager module, responsible for the creation and termination of any Telegram Bot service here.

The system manager module will be able to create and manage any given Telegram Bot service. This module consists of a give number of telegram bot services — systemd service files located in the /etc/systemd/system/ directory. Each service will have its main process [ExecStart=] set to the already compiled Telegram Bot executable. The executable will take 2 arguments; the first argument will be the configuration directory that stores the resource files needed to be watched; the second argument will be process verbosity.

Termination of the service and all its subsequent child processes will also be managed through systemd. Because the main parent process will create N number of child processes and then exit [return 0] this leaves these N child processes in the CGroup of the service. In order to stop the service these child processes need to be stopped/terminated.

[ Note ] If you are not familiar with systemd unit file syntax or need a reminder of how some simple services are created, I encourage you to go read my article [Systemd] simple service examples.

[Code] Communication module

The code repository for this project is located here[GitHub]. You are free to use and modify it [✌️��] . If you find any errors or have any suggestions, please let me know be contacting me here or on other platforms.

The communication module is separated into 3 files: main.cpp, config.h and config.cpp. As you are familiar with C/C++ the main.cpp file contains the main function; the config.h is the header file and config.cpp is the implementation of the config header. I have decided to use this simple structure in order to contain most of the program within a small number of files, as well as having a clear logical distinction between them.

The basic program logic contains the following functions:

  • A function responsible for the creation of environment variables inside a given process;
  • A function responsible for

The config.h Header

This header file contains include directives for the required libraries, definitions for length and size of different buffers and variables, and also function declarations.

  • ENV_CHAR_VARIABLE_LENGTH — defines the length of the environment variable name for each child process [default: 16 bytes]
  • SIZE_ENV_CHAR_VARIABLE — defines the size of the environment variable for each child process [default: 16 bytes]
  • SIZE_FILE_NAME — defines the size of the file name buffer to be read from the filesystem [default 256 characters i.e. 256 bytes]
  • CONTENT_BUFFER_SIZE — the size of the buffer that will store the contents of the file of each child process [default 4 MB]

Inside config.h there is also a structure called directory_files, which includes two variables; _p which is the pointer to an allocated space where the file names of a particular directory are stored; _count which returns the number of files in that particular directory. This structure is used in the return type of the function list_files_in_directory().

Function declarations include the following functions:

  • create_environment_variable() — creates environment variable with name _name and value _val inside the invoking process.
  • send_message_to_char() — sends a message to _chat_id after comparing env_var_name with its previous value; this is the environment variable name for the variable that stores the last_modified_timestamp. _flag is a flag for verbosity. _file_path is the path to the file from which to read its contents. TgBot::Bot * b is a pointer to the common Telegram Bot object from TgBot-cpp library that is shared amongst all child processes.
  • list_files_in_directory() — indexes files inside the _dir_path directory and returns a directory_files structure.
  • get_file_last_modified_time() — returns the last_modified_timestamp of a file with path _file_path [default format: Unix time]
  • get_file_name() — returns the name of the file without the .xxx extension/format
  • get_folder_name() — returns the converted long long integer value of a numerical folder name i.e. when a folders name is the chad_id it gets converted from an array of characters to a long long integer.

The config.cpp Implementation

The config.cpp file contains implementations of the function definitions from the config.h header file.

  • int create_environment_variable(char * _name, char * _val) — This function takes two parameters _name and _val and creates an environment variable in the current process using the setenv() function. We add fflush(stdout) because when a child process is called and executes this function inside systemd service, the journal program that keeps logs of each service in systemd will not get the output of printf() unless flushed. [ Important ] If not flushed, this buffer (stdout) can grow a lot and consume a vast amount of memory resource.
  • void send_message_to_chat(unsigned long long int _chat_id, char * env_var_name, TgBot::Bot *b, char * _file_path, int _flag) — This function is basically one big infinite while loop. This function is called once a new child process has been successfully created. Therefore keeping each child process inside its own infinite loop.

Firstly, this functions tries to get the environment variable env_var_name and its value. If this process is not successful, the loop is broken and there is nothing else to do. Therefore the programmer must investigate this issue.

Once the environment variable with the last_modified_timestamp has been gotten, then the function executes get_last_modified_time() onto the file with path _file_path. Then this value gets stored inside a string _last_modified_char. Afterwards the environment variable value and the current last modified time stamp are to be compared. If they differ this means that the file has been modified within the sleep period, therefore a message must be send to chat_id. If they are the same nothing is to be done.

Secondly, the file contents must be acquired. We allocate CONTENT_BUFFER_SIZE amount of space for the contents of the file. Afterwards while the content of the file is being looped over a temporary character stores the current character of the file content in the content buffer. Once the End Of the File has been reached, we append 0x00 to indicate the end of the content buffer. After this procedure has been done, we can close the file.

Thirdly, after the information from the file has been copied to the content buffer, it must be appended inside a message variable of type string. This message variable is later passed to the sendMessage() function by the Telegram Bot object. Sending a message using the Telegram Bot object must be enclosed inside a try..catch.. block because of error prevention. For example, if for some reason the machine that is running this service is not connected to the internet and does not have the possibility to contact the Telegram API, then sending a message will result in an error. We catch 2 types of errors inside this block: 1) a system error and 2) TgException error.

Finally, we clean up all the allocated space for the buffers and flush all the printf statements to stdout and we sleep for 5 seconds. This is the final statement that gets executed before running the loop again from the beginning.

[ Note ] When _flag is set to 1, the print statements get executed, when _flag is set to 0 the print statements are not executed. This is a simple implementation of verbosity management.

  • directory_files * list_files_in_directory(char * _dir_path ) — This function takes one parameter, namely _dir_path and allocates a piece of memory to store the names of the files listed in that particular directory. Afterwards, this allocated memory block is being pointed to by pointer _p of the structure directory_files and also the number of files present inside the directory is saved inside the variable _count inside that same structure. Here we have already predefined SIZE_FILE_NAME, therefore we allocate that much memory for the name of the first file listed inside the directory. We want to exclude the “.” and “..” paths, that being the reason why we have a conditional statement inside the while loop. On each iteration of the loop a new file from the directory is listed, then it is compared if it matches the excluded paths. If not, we reallocate i.e. expand the currently allocated memory block with filenames to have place for one more file name. We also increment the number of currently listed files. Finally, the function returns a pointer to a structure holding a pointer pointing to the beginning of the already expanded memory block with file names and a _count variable holding the number of listed files.

[ Note ] The increment for the file names here is SIZE_FILE_NAME, not 1. This is the reason for having the line _current_file = _return_val + ( n * SIZE_FILE_NAME ) . Basically, for each new file name that must be stored in the per-allocated memory space there must be SIZE_FILE_NAME bytes, no matter if the file name is long enough to fill the whole SIZE_FILE_NAME space.

  • long long int get_file_last_modified_time(char *_file_path) —This function acquires the last modified timestamp for a particular file using the stat structure and stat() function. On success the result is returned in Unix time, otherwise -1 is the return value.
  • char * get_file_name(char * _file_name_w_extension) — This function has a parameter that is the file name with extension. This parameter is run through a for loop starting from the first character in the file name and looping through the whole name until the pointer has reached the ‘.’ character. Then the newly created file_name_no_extension is appended an end of string character “\0” indicating the termination of the loop and end of the file name. This new file name is then returned by the function.
  • unsigned long long int get_folder_name( char * _path, int _size) — This function has two parameters _path, indicating the path to the folder and _size, indicating the length of the path string. For example /home/user/.config/telegram_bot/123456789/ will be the _path parameter and 42 will be its length. The function starts from the end of the string skipping the last 2 characters. Then we loop the string until we have encountered a ”/” character indicating that the directory name has been fully looped through. On each iteration we reduce the current character value by 48 [the ASCII number for the ‘0’ character] producing an integer value corresponding to its character. On each iteration we also multiply the base by 10 and add the sum to the result, namely getting the 10th place 100th place 1000th place .. number and summing them all together.

The main.cpp Program

The main.cpp file contains the execution sequence of the designed architecture. The sequence of function execution is broken up into several parts.

Firstly, we pass 2 arguments to the main program: the path to the directory containing the files that are going to be watched by each child process and a verbosity parameter. The directory that is being passed as the 1st argument must be named after the desired chat id to which the Telegram Bot will send the messages. For example /home/user/.config/telegram_bot/123456789/ is a valid path and /home/user/.config/telegram_bot/chatBot100/ is NOT a valid path.

Secondly, before compiling the program, please make sure that the token variable is set to the the desired Telegram Bots’ token. Otherwise, there will be no communication with the Telegram API.

Afterwards the program continues its execution by converting the chat id folder name to a long long integer and storing its value inside the _chat_id variable. Then the files under that specific directory are listed inside the _files directory_files structure.

Consequently, the program enters a for loop looping over the number of files inside the directory. We pass each filename through the function that reduces the passed string value to only a file name without any extensions. Then we get the last_modified_timestamp flag of the current file and create an environment variable with this value.

Finally, a new process is forked for the current file name and assigned the recently created environment variable. From this point on the child process enters the while loop inside the send_message_to_chat() function and the parent process continues looping through the files and spawning child processes.

[ Note ] When looping through the files in the directory_files structure, the increment is not 1, rather than the predefined SIZE_FILE_NAME.

[ Note ] In order to compile the program correctly, you need to have the TgBot, Boost system, SSL, Cryptography and Threading libraries installed on your system and point the library files to the compiler.

[Code] System Manager module

In the System Manager module we create a simple systemd service that is going to execute our already compiled Telegram Bot executable. The executable has 2 parameters, as we already discussed, these parameters are the directory which stores the resource files and a verbosity flag.

[ Note ] Make sure to have KillMode= set to process. This is not recommended in regular process management, but here this is the simplest solution to stopping the service with just one command.

If set to process , only the main process itself is killed (not recommended!)

For more information please visit this link.

In order to stop/kill the service and all its CGroup processes use systemctl kill <telegram-bot.service>

Final Results

The final product can be seen on the image below. Here I am showing how to start the Telegram Bot systemd service. This is also a demonstration of the response time of the Telegram Bot system when a particular file get modified.

We can conclude that this resource management system is quite reliable and robust. I hope

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *