Telegram Bot API. Часть 2

stickerВ продолжении статьи Telegram Bot API. Часть 1 продолжим разбираться с API Telegram. Как я и говорил, в этой статье я покажу вам как отсылать и принимать сообщения из нашей программы.

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

Запрос выглядит следующим образом:

https://api.telegram.org/botВашТокен/sendmessage?chat_id=IDЧата&text=Текст сообщения;

Где брать Токен, мы уже узнали в первой статье. ID Чата мы получаем из принятого сообщения, чуть ниже разберем подробнее.

При выполнении запроса на отправку сообщения, в случае удачной отправки, в ответ мы должны получить отправленное нам сообщение в формате JSON:

{"ok":true,"result":{"message_id":103,"from":{"id":....,"first_name":"Lazarus_Bot","username":"devlaz_bot"},"chat":{"id":.....,"first_name":"\u041e\u043b\u0435\u0433","username":"EOleg","type":"private"},"date":1460455425,"text":"devlaz.ru","entities":[{"type":"url","offset":0,"length":9}]}}

После отправки сообщения, в программе я проверяю статус «ok»=True

Хочу обратить внимание что обмен данными с Telegram происходит в кодировке UTF8, наш Lazarus как раз по умолчанию работает именно в этой кодировке, поэтому проблем возникнуть не должно.

Итак для того чтобы отправить сообщение из программы я создал процедуру:

procedure TFormMain.SendMessage(IDUser,Text: String);
var
  JsObject: ISuperObject;
  zapros:String;
begin
   zapros:='/sendmessage?'+'chat_id='+IDUser+'&'+'text='+Text;
   try
     JsObject:=SO(THTTP.Get(BaseUrl+API+Zapros));
     if JsObject.B['ok']=True then
     begin
       FormMain.MemoLog.Lines.add(TimeToStr(now)+' Бот написал '+JsObject.s['result.chat.username']+' : '+JsObject.s['result.text']);
     end;
   except 
       ShowMessage('Ошибка отправки сообщения!');
   end;
end;

Теперь для отправки сообщения в программе я просто вызываю данную процедура:

SendMessage("ID Чата","Наше сообщение");

Обратите внимание что я не стал описывать процесс создания THttp, SSL, а так же переменные BaseUrl и API которые мы в прошлой статье добавили в Const. В принципе вопросов не должно возникнуть, с отправкой все просто.

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

Для начала давайте посмотрим как выглядит сам запрос:

https://api.telegram.org/botВашТокен/getUpdates?offset=ID_последнего_сообщения&timeout=30

Offset задает последнее обработанное сообщение + 1, его мы узнаем после выполнения запроса.

Timeout задает сколько мы будем ждать ответа от сервера. Я поставил оптимальное значение 30 сек. Вы можете использовать любое удобное для вас.

В ответ на данный запрос мы должны получить примерно следующий ответ:

{"ok":true,"result":[]}

Если сообщений нет или:

{"ok":true,"result":[{"update_id":158553581,
"message":{"message_id":104,"from":{"id":1281487,"first_name":"\u041e\u043b\u0435\u0433","username":"EOleg"},"chat":{"id":1281487,"first_name":"\u041e\u043b\u0435\u0433","username":"EOleg","type":"private"},"date":1460470734,"text":"Hello"}}]}

Здесь нас интересуют следующие данные:

update_id: к данному значению мы прибавляем единицу и забиваем при следующим запросе в Offset иначе мы будем постоянно получать данное сообщение (Оно будет не прочитанным)

«chat»:{«id»:1281487: Это и есть тот самый «ID чата» который требуется указывать при отправке сообщения.

«text» : Это текст присланного сообщения.

Выполнять данный запрос советую в отдельном потоке, чтобы избежать зависания программы из-за Timeout

Сам код выглядит так:

procedure TGetUpdate.Execute;
var
  RHttp:TIdHTTP;
  RSSL:TIdSSLIOHandlerSocketOpenSSL;
  Offset:integer=0;
  JsObject1, JsObject2: ISuperObject;
begin
  RHttp:=TIdHTTP.Create;
  RSSL:=TIdSSLIOHandlerSocketOpenSSL.Create;
  RHttp.IOHandler:=RSSL;
  while True do
  begin
    JsObject1:=SO(RHTTP.Get(BaseUrl+API+'/getUpdates?offset='+IntToStr(Offset)+'&timeout=30'));
    JsObject2:= JsObject1.A['result'].N[0];
    Offset:=JsObject2.i['update_id'] + 1; //В случае если сообщений не было, Offset станет равным 1.

   if Offset<>1 then
     begin
      if JsObject2.s['message.text']<>'' then
        Memo1.lines.add(JsObject2.s['message.from.username']+' '+  //Это имя написавшего боту
                        JsObject2.s['message.from.id']+' : '+  //Его ИД по которому можем ему написать
                        JsObject2.s['message.text']);   //Текст сообщения
     end;
   if GetUpdate.Terminated then break;
  end;
 RHttp.Free;
 RSSL.Free;
end;

И так мы разобрались как отсылать и принимать сообщения, в следующей статье я покажу как принимать файлы.

Telegram Bot API. Часть 2 обновлено: 20 апреля, 2016 автором: Oleg E.
Share

5 комментариев “Telegram Bot API. Часть 2

  1. Ведется разработка библиотеки для работы с Telegram API https://github.com/Al-Muhandis/fp-telegram , также как плагин к brookframework https://github.com/Al-Muhandis/brook-telegram
    Акцент пока сделан на получении обновлений через webhook. Используются только родные инструменты fpc. Если есть желание можете присоединиться

  2. Пока не написали статью об отправке картинок, подскажите, пож., как же их отправлять? Все просто, если картинка есть где-то в интернете (отправляем BaseUrl+API+’/sendphoto?chat_id=’+ID+’&photo=’+URL), но что делать, если картинка лежит в файле (сгенерирована самим ПО только что)?

    неужели класть на любой сервер, чтобы потом отправлять с помощью URL ?
    спасибо…

    И спасибо за отличный блог и статьи.

    • Если использовать библиотеку fp-telegram, то можно отправить фото потоком TFileStream, предварительно загрузив поток из файла. После чего передать поток в параметре APhotoStream
      TStream function sendPhotoStream(chat_id: Int64; const AFileName: String; APhotoStream: TStream;
      const ACaption: String; ReplyMarkup: TReplyMarkup = nil): Boolean;

  3. У Вас не продлен сертификат Let’s Encrypt. Рекомендую CDN Cloudflare. ТАм автоматом включается защищенный режим. Никаких доп. действий по продлению или регистрации

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

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