Перейти к содержанию

HTTP-бот (смарт)

ℹ️ В данном разделе приведен пример использования HTTP-запроса для синхронизации "Первой Формы" с Telegram через чат-бот

С помощью смарт-действия "Отправить HTTP-запрос" можно автоматизировать общение через чат-бот Telegram. HTTP-запрос необходимо использовать в категории "Группы", когда в чате должно быть более одного пользователя, или "Сообщения", когда в чате должен быть только один пользователь и чат-бот. Действие срабатывает после написания комментария и отправляет запрос из "Первой Формы" в Telegram.

Порядок действий

1. Если вы еще не зарегистрированы в Telegram, пройдите регистрацию.

2. Создайте чат-бота. Для получения идентификатора нового бота (bot token) найдите в Telegram пользователя @BotFather, запустите с ним чат (команда /start при первом обращении) и введите команду создания нового бота: /newbot.

Введите публичное имя для вашего бота и имя пользователя для бота в Telegram. Обратите внимание: имя пользователя должно быть уникальным и должно заканчиваться на "bot" (например: Chat1FBot). Если пользователь с таким именем уже существует вы увидите ошибку: "Sorry, this username is invalid" — необходимо ввести уникальное имя. При успешном создании вы получите сообщение с ссылкой на свого бота в Telegram и токеном для доступа к HTTP API.

3. Получите идентификатор беседы с ботом \<chat_id>: В диалоге с созданным ботом и напишите ему произвольное сообщение, затем откройте в браузере ссылку: https://api.telegram.org/bot\<bot_token>/getUpdates

где \<bot_token> — идентификатор, полученный от @BotFather.

В полученном json-ответе найдите значение в параметре result->message->chat->id, это и есть \<chat_id>.

URL для отправки сообщения боту формируется по образцу:

https://api.telegram.org/bot\<bot_token>/sendMessage?chat_id=\<chat_id>&text=\<текст_отправляемого_сообщения>

URL для получения последнего сообщения от бота формируется по образцу:

https://api.telegram.org/bot\<bot_token>/getUpdates?offset=\<номер_последнего_полученного_сообщения+1>

Если возвращается одно сообщение, то json имеет вид:

{"ok":true,"result":[
{"update_id":<offset>,
"message":{"message_id":14,
   "from":{"id":<user_id>,"is_bot":false,"first_name":"<name>","last_name":"<surname>","username":"<nick>","language_code":"ru-RU"},
   "chat":{"id":<chat_id>,"first_name":"<name>","last_name":"<surname>","username":"<nick>","type":"private"},
   "date":1519205140,
   "text":"текст_сообщения"}
}
]}

Чат-бот может вернуть сразу несколько последних ответов — json вида:

{"ok":true,"result":[
{"update_id":<offset1>,
"message":{"message_id":14,
   "from":{"id":<user_id>,"is_bot":false,"first_name":"<name>","last_name":"<surname>","username":"<nick>","language_code":"ru-RU"},
   "chat":{"id":<chat_id>,"first_name":"<name>","last_name":"<surname>","username":"<nick>","type":"private"},
   "date":1519205140,
   "text":"текст_сообщения1"}
},
{"update_id":<offset2>,
"message":{"message_id":15,
   "from":{"id":<user_id>,"is_bot":false,"first_name":"<name>","last_name":"<surname>","username":"<nick>","language_code":"ru-RU"},
   "chat":{"id":<chat_id>,"first_name":"<name>","last_name":"<surname>","username":"<nick>","type":"private"},
   "date":1519205140,
   "text":"текст_сообщения2"}
}
]}

Первое непрочитанное ответное сообщение доступно как значение атрибута result.message[0].text, а \<chat-id> доступен как значение атрибута result.message[0].chat.id (этот параметр важен, поскольку бот может вести несколько чатов одновременно).

Простейший пример обмена сообщениями с чат-ботом Telegram описан ниже.

Отправка сообщения Смарт-пакет для отправки сообщения боту

Вариант смарт-действия для отправки сообщения боту с использованием двух параметров:

ℹ️ Для данного кейса не поддерживаются зашифрованные задачи

Получение сообщения

Обратите внимание на необходимость очистки ответа веб-сервиса от лишних символов. Поэтому во втором смарт-действии для выделения текста сообщения используется выражение TSQL:

select top 1 JSON_VALUE ( @ActionResult8639, '$.HttpResponse.ResponseContent.result[0].message.text' )

Примеры настройки смарт-правил в категории

Удаление пользователя из чата Telegram после удаления подписчика из задачи:

Событие: После удаления подписчика Создано смарт-правило Smart фильтр: Задача чата входит в список синхронизации с телеграмм

select 1
from cm_vw_ChatToTask v
where v.TaskID = @ContextID

Смарт-действие: Отправить HTTP запрос Смарт-действие "Отправить HTTP запрос" Тип HTTP запроса: Get Url: токен, полученный от чат-бота Список параметров: -chat_id — определение ChatID группы Telegram

SELECT chatid
FROM   cm_vw_chattotask
WHERE  taskid = @ContextID

Определение ChatID группы Telegram -user_id — TelegramID пользователя, которого удалили из подписчиков

select ICQ
from Users with(nolock)
where UserID = @eventParam0

TelegramID пользователя, которого удалили из подписчиков Обновление сообщения в Telegram после редактирования комментария в системе:

Событие: После редактирования комментария Создано смарт-правило Smart фильтр: Задача чата входит в список синхронизации с Telegram и номер комментария есть в списке синхронизации

select 1
from cm_vw_ChatToTask v
join [custom].[cm_tlg_tasks] t
on v.chatid=t.tlg_chat_id
where v.TaskID =  @ContextID
and t.task_id = @eventparam0

Смарт-действие: Отправить HTTP запрос Смарт-действие "Отправить HTTP запрос" Тип HTTP запроса: Post Url: токен, полученный от чат-бота Список параметров: -chat_id — определение ChatID Telegram по номеру задачи

declare @ChatID varchar(max) = null

select @ChatID = ChatID
from cm_vw_ChatToTask
where TaskID = @ContextID

select isnull(@ChatID,'') ResTxt

Определение ChatID группы Telegram по номеру задачи -message_id — MessageID Telegram по номеру комментария

select tlg_id
from cm_vw_ChatToTask v
join [custom].[cm_tlg_tasks] t
on v.chatid=t.tlg_chat_id
where v.TaskID = @ContextID
and t.task_id = @eventparam0

MessageID Telegram по номеру комментария -text — Новый текст комментария после редактирования Новый текст комментария после редактирования -entities — Адресаты комментария после редактирования

declare @json nvarchar(max)
set @json = (
   SELECT sum([pre_offset])over(order by [name]) as [offset],[length],[type], JSON_QUERY([user]) as [user]
   FROM
   (
       select lag(len(isnull(u.TelegramUserName,u.FirstName)),1,-2)over(order by isnull(u.TelegramUserName,u.FirstName))+2 as [pre_offset]
             ,len(isnull(u.TelegramUserName,u.FirstName))+1 as [length]
             ,iif(u.TelegramUserName is null, N'text_mention', N'mention') as [type]
             ,isnull(u.TelegramUserName,u.FirstName) as [name]
             ,iif(u.TelegramUserName is null,JSON_QUERY(ca.v),null) as [user]
       from CommentRecipients cp
       join users u (nolock)
           on u.UserID = cp.UserID
       CROSS APPLY (SELECT ICQ as [id]
                          ,cast(0 as bit) as [is_bot]
                          ,FirstName as [first_name]
                          ,LastName as [last_name]
                    FROM Users with(nolock)
                    WHERE UserID= u.UserID
                    FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
       ) as ca(v)
       where CommentID = @eventParam0 and isnull(nullif(u.TelegramUserName,''),nullif(u.ICQ,'')) is not null
       and cp.IsRealRecipient = 1

   ) tab
   FOR JSON AUTO
)

select isnull(@json,'[]')

Адресаты комментария после редактирования Отправка ответа боту в Telegram после написания комментария в системе:

Событие: После написания комментария Создано смарт-правило Smart фильтр: Задача чата входит в список синхронизации с Telegram, комментарий не пустой, не является ответом, содержит адресатов и его написал не робот

declare
 @all int,        --все получатели
 @real int        --кому адресовано

select
 @all = count(iif(u.IsFired_2 = 0,cr.UserID,null)),
 @real = count(iif(IsRealRecipient = 1,cr.UserID,null))
from CommentRecipients cr
join Users u on u.UserID = cr.UserID
where commentid = @eventParam0

select 1
from Comments (nolock) c
where c.CommentID = @eventParam0
and c.TaskID = @ContextID
and c.RealUserID is null
and @CurrentSessionUserID not in (-1,3,8330)
and exists(
 select 1
   from cm_vw_ChatToTask v
   where v.TaskID = c.TaskID
)
and len(@eventParam1) != 0
and @real < (@all - 1)
and InReplyToCommentID is null

Два смарт-действия: 1. Отправить HTTP запрос Смарт-действие "Отправить HTTP запрос" Тип HTTP запроса: Post Url: токен, полученный от чат-бота Список параметров: -chat_id — ChatID Telegram по номеру задачи чата в системе

declare @ChatID varchar(max) = null

select @ChatID = ChatID
from cm_vw_ChatToTask
where TaskID = @ContextID

select isnull(@ChatID,'') ResTxt

ChatID Telegram по номеру задачи чата в системе -text — Текст комментария plaintext с адресатами

SELECT '[' + u.DisplayName + ': '
+ u_cr.TelegramUserName
+ ' ' +  @EventParam1
FROM Comments as c
join users u
on c.userid = u.userid
join (
SELECT  CommentID,
STUFF((SELECT ' ' +
case when left(u_cr.TelegramUserName,1) = '@'
then u_cr.TelegramUserName
else '@'+ u_cr.TelegramUserName
end
from CommentRecipients t2
join users u_cr
on t2.userid = u_cr.userid
WHERE t1.CommentID = t2.CommentID and IsRealRecipient = 1 FOR XML PATH('')),1,1,'') TelegramUserName
from CommentRecipients t1
where t1.CommentID = @EventParam0
GROUP BY CommentID
)u_cr
on  u_cr.CommentID  = c.CommentID
WHERE c.CommentID=@EventParam0

Текст комментария plaintext -entities — Номер комментария, на который ответ из Telegram

declare @json nvarchar(max)
set @json = (
   SELECT sum([pre_offset])over(order by [name]) as [offset],[length],[type], JSON_QUERY([user]) as [user]
   FROM
   (
       select lag(len(isnull(u.TelegramUserName,u.FirstName)),1,-2)over(order by isnull(u.TelegramUserName,u.FirstName))+2 as [pre_offset]
             ,len(isnull(u.TelegramUserName,u.FirstName))+1 as [length]
             ,iif(u.TelegramUserName is null, N'text_mention', N'mention') as [type]
             ,isnull(u.TelegramUserName,u.FirstName) as [name]
             ,iif(u.TelegramUserName is null,JSON_QUERY(ca.v),null) as [user]
       from CommentRecipients cp
       join users u (nolock)
           on u.UserID = cp.UserID
       CROSS APPLY (SELECT ICQ as [id]
                          ,cast(0 as bit) as [is_bot]
                          ,FirstName as [first_name]
                          ,LastName as [last_name]
                    FROM Users with(nolock)
                    WHERE UserID= u.UserID
                    FOR JSON PATH, WITHOUT_ARRAY_WRAPPER
       ) as ca(v)
       where CommentID = @eventParam0 and isnull(nullif(u.TelegramUserName,''),nullif(u.ICQ,'')) is not null
       and cp.IsRealRecipient = 1

   ) tab
   FOR JSON AUTO
)

select isnull(@json,'[]')

Адресаты комментария 2. Выполнить sql скрипт Смарт-действие "Выполнить sql скрипт" Sql скрипт — Запись результата в таблицу

insert into [custom].[cm_tlg_tasks] --таблица синхронизации сообщений ТГ и 1Ф
           select cast(JSON_VALUE(@ActionResult34071, '$.HttpResponse.ResponseContent.result.chat.id') as varchar(20)),
           cast(JSON_VALUE(@ActionResult34071, '$.HttpResponse.ResponseContent.result.message_id') as varchar(20)),
           cast(@eventParam0 as varchar(20))

Sql скрипт Отправка ответа в Telegram на всех после написания комментария в системе:

Событие: После написания комментария Создано смарт-правило Smart фильтр: Задача чата входит в список синхронизации с Telegram, комментарий не пустой, является ответом и его написал не робот

declare
 @all int,        --все получатели
 @real int        --кому адресовано

select
 @all = count(iif(u.IsFired_2 = 0,cr.UserID,null)),
 @real = count(iif(IsRealRecipient = 1,cr.UserID,null))
from CommentRecipients cr
join Users u on u.UserID = cr.UserID
where commentid = @eventParam0

select 1
from Comments (nolock) c
where c.CommentID = @eventParam0
and c.TaskID = @ContextID
and (@CurrentSessionUserID not in (-1,3,8330) or c.RealUserID is not null)
and exists(
 select 1
   from cm_vw_ChatToTask v
   where v.TaskID = c.TaskID
)
and len(@eventParam1) != 0
and @real = (@all - 1)
and InReplyToCommentID is not null

Два смарт-действия: 1. Отправить HTTP запрос Смарт-действие "Отправить HTTP запрос" Тип HTTP запроса: Post Url: токен, полученный от чат-бота Список параметров: -chat_id — определение ChatID Telegram по номеру задачи

declare @ChatID varchar(max) = null

select @ChatID = ChatID
from cm_vw_ChatToTask
where TaskID = @ContextID

select isnull(@ChatID,'') ResTxt

Определение ChatID группы Telegram по номеру задачи -text — Текст комментария plaintext Текст комментария plaintext -reply_to_message_id — Номер комментария, на который ответ из Telegram

select
case when tlg_id is not null then tlg_id else 0 end
from comments c
left join  [custom].[cm_tlg_tasks] t
on t.task_id = c.InReplyToCommentID
where c.commentid =  @EventParam0

Номер комментария, на который ответ из Telegram 2. Выполнить sql скрипт Смарт-действие "Выполнить sql скрипт" Sql скрипт — Запись результата в таблицу

insert into [custom].[cm_tlg_tasks]
           select cast(JSON_VALUE(@ActionResult74280, '$.HttpResponse.ResponseContent.result.chat.id') as varchar(20)),
           cast(JSON_VALUE(@ActionResult74280, '$.HttpResponse.ResponseContent.result.message_id') as varchar(20)),
           cast(@eventParam0 as varchar(20))

Sql скрипт Отправка сообщения в Telegram на всех после написания комментария в системе:

Событие: После написания комментария Создано смарт-правило Smart фильтр: Задача чата входит в список синхронизации с Telegram, комментарий не пустой, не является ответом и его написал не робот

declare
 @all int,        --все получатели
 @real int        --кому адресовано

select
 @all = count(iif(u.IsFired_2 = 0,cr.UserID,null)),
 @real = count(iif(IsRealRecipient = 1,cr.UserID,null))
from CommentRecipients cr
join Users u on u.UserID = cr.UserID
where commentid = @eventParam0

select 1
from Comments (nolock) c
where c.CommentID = @eventParam0
and c.TaskID = @ContextID
and (@CurrentSessionUserID not in (-1,3,8330) or c.RealUserID is not null)
and exists(
 select 1
   from cm_vw_ChatToTask v
   where v.TaskID = c.TaskID
)
and len(@eventParam1) != 0
and @real = (@all - 1)
and InReplyToCommentID is null

Два смарт-действия: 1. Отправить HTTP запрос Смарт-действие "Отправить HTTP запрос" Тип HTTP запроса: Post Url: токен, полученный от чат-бота Список параметров: -chat_id — определение ChatID Telegram по номеру задачи

declare @ChatID varchar(max) = null

select @ChatID = ChatID
from cm_vw_ChatToTask
where TaskID = @ContextID

select isnull(@ChatID,'') ResTxt

Определение ChatID группы Telegram по номеру задачи -text — Текст комментария plaintext Текст комментария plaintext 2. Выполнить sql скрипт Смарт-действие "Выполнить sql скрипт" Sql скрипт — Запись результата в таблицу

insert into [custom].[cm_tlg_tasks]
           select cast(JSON_VALUE(@ActionResult74280, '$.HttpResponse.ResponseContent.result.chat.id') as varchar(20)),
           cast(JSON_VALUE(@ActionResult74280, '$.HttpResponse.ResponseContent.result.message_id') as varchar(20)),
           cast(@eventParam0 as varchar(20))

Sql скрипт Удаление сообщения в чате Telegram перед удалением комментария в задаче:

Событие: Перед удалением комментария Создано смарт-правило Smart фильтр: Задача чата входит в список синхронизации с Telegram

select 1
from cm_vw_ChatToTask v
where v.TaskID = @ContextID

Смарт-действие: Отправить HTTP запрос Смарт-действие "Отправить HTTP запрос" Тип HTTP запроса: Post Url: токен, полученный от чат-бота Список параметров: -chat_id — определение ChatID Telegram по номеру задачи

declare @ChatID varchar(max) = null

select @ChatID = ChatID
from cm_vw_ChatToTask
where TaskID = @ContextID

select isnull(@ChatID,'') ResTxt

Определение ChatID группы Telegram по номеру задачи -message_id — Сообщение, которое удаляется

declare @ChatID varchar(max) = null

select tlg_id
from [custom].[cm_tlg_tasks]
where tlg_chat_id =
(
 select ChatID
 from cm_vw_ChatToTask
 where TaskID = @ContextID
)
and
task_id = @eventParam0

Сообщение, которое удаляется

Полезные ссылки

API Telegram

Возможные смарт-действия