В начале пару новостей:
Репозиторий клонируется также на ГитХаб.
Можно устанавливать с помощью Delphinus'a
Бот калькулятор для Telegram.
А сейчас мы напишем своего бота, который сможет решать арифметические выражения(и не только).
Что для этого нужно:
Telega π - Библиотека для работы с Telegram Bot API в Delphi
TeeBI
После установки библиотек свыше - создаем новое консольное приложение. Далее создаем новый модуль(unit) и называем его, например, Telegram.Plugin.Calculator
В этом модуле мы будем писать логику калькулятора, а точнее взаимодействие команд от пользователя и модуля выражений BI.Expression(TeeBI).
Для наглядности, сразу код модуля:
unit Telegram.Plugin.Calculator;
interface
uses
TelegAPI.Bot,
TelegAPI.Types,
TelegAPI.Utils,
TelegAPI.Module;
Type
TTgCalculatorBot = Class(TTgModule)
private
FIsCommandWait: Boolean;
protected
procedure OnUpdate(Sender: TObject; Const Update: TtgUpdate); override;
End;
implementation
uses
BI.Expression, System.SysUtils;
{ TTgWelcomeBot }
procedure TTgCalculatorBot.OnUpdate(Sender: TObject; const Update: TtgUpdate);
var
Cmd: TCommandHelper;
Procedure Calculation;
var
TextExpr: String;
Begin
FIsCommandWait := False;
if Cmd.ParamCount = 0 then
TextExpr := Update.Message.Text
else
TextExpr := Cmd.ParamsToString;
try
(Sender as TTelegramBot).sendTextMessage(Update.Message.Chat.ID,
TExpression.FromString(TextExpr).Value);
except
on E: Exception do
(Sender as TTelegramBot).sendTextMessage(Update.Message.Chat.ID,
'упс, ошибочка вышла: ' + E.ClassName + ' ' + E.Message);
end;
End;
begin
Cmd := TCommandHelper.Create(Update.Message.Text);
try
if Cmd.Command = '/calc' then
Begin
if Cmd.ParamCount = 0 then
Begin
FIsCommandWait := true;
(Sender as TTelegramBot).sendTextMessage(Update.Message.Chat.ID,
'ожидаю выражение:');
End
else
Begin
Calculation;
End;
End
else if FIsCommandWait then
Begin
Calculation;
End;
finally
Cmd.Free;
end;
end;
end.
Первое на что обращаем внимание - наш класс TTgCalculatorBot будет наследоваться от TTgModule, в котором заложен базовый функционал для расширения функционала бота(на данный момент только получение обновлений от сервера).
В метод OnUpdate будут поставляться обновления, которые приходят от сервера, в нем мы и будем работать.
Насчет поля FIsCommandWait. Уж так сложилось - что, как правило, пользователь сразу отправляет боту команду - а потом параметры. Поэтому, если придет поддерживаемая модулем команда - мы устанавливаем это поле в True. Если это поле - правда - значит нужно обработать текст.
Теперь вернемся к нашему консольному приложению:
program CalculatorBot;
{$APPTYPE CONSOLE}
{$R *.res}
uses
TelegaPi.Bot,
TelegaPi.Types,
System.SysUtils,
Telegram.Plugin.Calculator in 'Telegram.Plugin.Calculator.pas';
Const
C_PAUSE_UPDATE = 1000; { 1sec. }
Var
TelegramBot: TTelegramBot;
TelegramCalc: TTgCalculatorBot;
Procedure InitRecesive;
var
Offset: Integer;
Updates: TArray<TtgUpdate>;
Update: TtgUpdate;
Begin
Offset := 0;
while True do
begin
Sleep(C_PAUSE_UPDATE); // Update pause
Updates := TelegramBot.getUpdates(Offset); // Get updates
if Length(Updates) = 0 then
Continue;
Offset := Updates[High(Updates)].ID + 1;
end;
End;
begin
WriteLn('Telegram Calculator Sample');
{ Here you Api key }
TelegramBot := TTelegramBot.Create({$I ..\telegaToken.inc} );
TelegramCalc := TTgCalculatorBot.Create(TelegramBot);
try
WriteLn('Bot token: ', TelegramBot.getMe.ID <> -1);
InitRecesive;
except
on E: Exception do
WriteLn(E.ClassName, ': ', E.Message);
end;
TelegramBot.Free;
TelegramCalc.Free;
end.
TelegramCalc := TTgCalculatorBot.Create(TelegramBot); - во время создания модуля - происходит подписка на сообщения от сервера. Никаких данных программисту передавать не нужно.
Далее, что бы консоль сразу же не закрылась - нужно зациклить прием данных от сервера. Пример - в процедуре InitRecesive.
Что получаем в итоге:
Так же можете сами протестировать бота(если он конечно будет запущен): @test_delphi_api_bot
Готовый пример: https://bitbucket.org/uasoft/telegapi/src//examples/PluginCalculator/?at=master