Telegram Native API

Взаимодействие с Telegram без Bot API. Только C++ компоненты. Только хардкор.

Сразу хочу отметить — заметка в большей степени не про telegram, а про правильную, по мнению автора, разработку native внешних компонент.

Сама технологии создания внешних компонент с native API существует уже много лет, но несмотря на это, найти достойный пример open source реализации внешней компоненты крайне сложно. Вполне вероятно, что все компоненты с открытыми исходными кодами можно пересчитать по пальцам одной руки. Буду рад увидеть ссылки в комментариях, чтобы понять, что не прав.

В конечном счете я решил исправить эту несправедливость и опубликовать не слишком сложный пример компоненты "по фэн-шую". И первой проблемой, которую предстояло решить, был функционал компоненты. В итоге выбор пал на интеграцию с telegram.

Сегодня тема взаимодействия с telegram уже не так популярна, как ранее. С одной стороны на это повлияли действия РКН, с другой — библиотека инфостарта уже изрядно наполнена примерами взаимодействия с Bot API. Но что делать, если функционала bot API недостаточно? Допустим, мы хотим сами писать пользователю, или хотим использовать секретные чаты с end-to-end шифрованием, или, о боже, хотим написать полноценный telegram клиент на 1С? Выход — TDLib.

Telegram database library — это официальная библиотека для создания Telegram клиентов, предоставляющая доступ ко всему функционалу MTProto. Один из вариантов работы с библиотекой — JSON. Все методы описаны в документации.

Внешняя компонента доступна на Github. Она предоставляет доступ к следующим методам TDLib: Отправить / Send, Получить Receive, Выполнить / Execute, а так же реализует метод УстановитьАсинхронныйРежим / SetAsyncMode для получения ответов компоненты через внешние события (естественно работает только на клиенте).

CI сборки реализованы для Windows x86/x64 и Linux x64. 

Для желающий просто оценить компоненту в работе, мною был сделан примитивный пример, реализующий следующий тестовый сценарий: авторизация в telegram и отправка сообщения абоненту с указанным номером телефона (даже если его еще нет у вас в контактах). Пример проверен на Windows 10 + 8.3.11 и на Ubuntu 18.04 + 8.3.12.

На данный момент демо-обработка содержит множество допущений. В частности:

  • Авторизация выполняется только для существующих учетных записей
  • Ввод некорректного кода подтверждения никак не обрабатывается
  • Не реализована двухфакторная аутентификация
  • Не указывается куда отправлен код подтверждения (Telegram / SMS)
  • Не задаются настройки TDLib. База всегда хранится в каталоге временных файлов. Токены app_id и api_hash совпадает с тестовыми для TDLib.

В общем, самый, самый минимум.

22 Comments

  1. baton_pk
    заметка в большей степени … про правильную, по мнению автора, разработку native внешних компонент

    вот этот момент совсем не раскрыт в статье, стоило уделить этому внимание. В остальном — плюс за проделанную работу.

    Reply
  2. Synoecium

    Жаль что вашей статьи не было, когда писал свою компоненту по рисованию графов, теперь её даже стыдно выкладывать на GiHub 🙂

    Reply
  3. azubar

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

    Вопрос: сейчас отправить можно только тестовое сообщение, файлы/изображения?

    Reply
  4. Infactum

    (5) Отправить можно все, что поддерживается протоколом. Виды контента описаны тут.

    Reply
  5. oyti

    Windows 7 x64,

    1С:Предприятие 8.3 (8.3.12.1412),

    Бухгалтерия предприятия, редакция 3.0 (3.0.61.47)

    Reply
  6. oyti

    (8) 1С:Предприятие 8.3 (8.3.11.2867) — ошибка та же

    Reply
  7. Infactum

    (8) Разрядность клиента 1С какая?

    Если попробовать подключить напрямую dll, а не через бандл, что скажет?

    ПодключитьВнешнююКомпоненту(«<Путь_к_DLL>», «Telegram», ТипВнешнейКомпоненты.Native)
    Reply
  8. oyti

    x86

    Если явно задать путь к dll на диске, вроде работает

    Reply
  9. Anton64

    У меня Win 7, появляется окно с вводом номера телефона, после нажатия Далее ничего не происходит…

    Попробовал так: ПодключитьВнешнююКомпоненту(«D:Telegram.dll», «Telegram», ТипВнешнейКомпоненты.Native) — пишет, что либо не предназначен для выполнения под управлением Виндоус или содержит ошибку и т.д.

    Reply
  10. Infactum

    (12)

    Если появилось окно ввода телефона, значит компонента успешно подключилась — лучше конечно проверить отладчиком.

    После ввода телефона может ничего не происходить, потому что нет подключения к ДЦ телеграма (спасибо РКН).

    Если есть желание разобраться в проблеме, то рекомендую скачать на гитхабе последнюю сборку. В ней есть возможность включения журнала tdlib — метод УстановитьКаталогЖурнала(<Путь>).

    Reply
  11. Anton64

    (13) Про блокировку понял, думаю что в ней дело.

    Тогда возникает вопрос, можно ли как-то указать прокси сервер для работы компоненты?

    Reply
  12. Infactum

    (14) Можно через setProxy. Текущая версия TDLib только Socks5 умеет.

    Reply
  13. Mopo3

    Круто! Помучался, но научился получать сообщения от пользователей, из секретных групп, что и требовалось для задачи.

    Замечательная библиотека и пример, спасибо!

    Reply
  14. Mopo3

    (0), подскажите пожалуйста. Я правильно понимаю, что если я хочу получить/отправить сообщения от пользователей БЕЗ использования бота, то это можно сделать ТОЛЬКО через TDLib и более никак?

    То есть использовать для этого

    Соединение = Новый HTTPСоединение(«api.telegram.org»,443,,,Прокси,,Новый ЗащищенноеСоединениеOpenSSL());

    ПараметрыЗапроса = «?chat_id=[chat_id]»;

    ТекстЗапросаHTTP = «getChatHistory» + ПараметрыЗапроса;

    Запрос = Новый HTTPЗапрос(ТекстЗапросаHTTP);

    Запрос.УстановитьТелоИзСтроки(ПараметрыЗапроса);

    Ответ = Соединение.ОтправитьДляОбработки(Запрос);

    не получится при всем желании, т.к. он предназначен ТОЛЬКО для ботов?

    Reply
  15. Infactum

    (17) С использованием REST вы можете работать только с BOT API. Для использования всех возможностей (например чтобы стать инициатором сообщения или использовать секретный чат) нужен Telegram API. Так вот TDLib — это лишь одна из реализаций (правда официальная). Можете воспользоваться любой другой (на GitHub полно), но к ним биндингов на 1С нету.

    Reply
  16. dtybr

    Добрый день.

    Подскажите пожалуйста как можно настроить опции TDLib (https://core.telegram.org/tdlib/options)

    Мне нужно чтоб библиотека отправляла запросы через мое собственное DNS имя. Или так нельзя. Только прокси (setProxy)

    С ним не смог разобраться.

    Делаю вот так после соединения:

    ФорматированныйТекст = Новый Соответствие;
    ФорматированныйТекст.Вставить(«@type», «proxySocks5»);
    ФорматированныйТекст.Вставить(«server», «176.94.2.84»);
    ФорматированныйТекст.Вставить(«port», «1080»);
    ФорматированныйТекст.Вставить(«username», «»);
    ФорматированныйТекст.Вставить(«password», «»);
    
    ЗапросКомпоненты = Новый Соответствие;
    ЗапросКомпоненты.Вставить(«@type», «setProxy»);
    ЗапросКомпоненты.Вставить(«proxy», ФорматированныйТекст);
    
    ОтправитьЗапрос(ЗапросКомпоненты);
    

    Показать

    Но не работает не приходит СМС

    Reply
  17. Infactum

    (19) Не понимаю, что значит «отправлять запросы через DNS имя».

    Для разбора проблемы прокси рекомендую включить лог и заглянуть туда. Так же надо выяснить, на какой версии TDLib ваша компонента, т.к. в последней (той, что на TDLib 1.3) метода setProxy больше нету.

    New methods addProxy, editProxy, enableProxy, disableProxy, removeProxy and getProxies were added instead of setProxy and getProxy.
    Reply
  18. dtybr

    У меня есть transparent Proxy по адресу telegram.mysite.com если TDLib будет запросы отправлять через него то оно не будет заблокировано РКН.

    И это не SOCKS5 поэтому его прописать в список прокси нельзя. ( И поэтому я обратил внимание на опцию http://prntscr.com/l4icxi

    TDLib у меня скорей 1.3 так как библиотеку качал с GITHub сегодня.

    Так что видимо придется использовать новые методы.

    Скажите я вам можно поручить задачу по разработке подсистемы с 4 методами которые будут через TDLib 1.3 работать:

    — НайтиКонтактТелеграмм()

    — СоздатьКОнтактТелеграмм()

    — ОтправитьСообщениеТелеграмм()

    — ПринятьСообщенияТелеграмм()

    Методы должны быть в серверном модуле и выполняться на сервере WINx64

    Могу сформулировать более точные требования.

    Reply
  19. Crush

    АдресTDLib = «D:TDlib elegram_native_x86.dll»;

    Если ПодключитьВнешнююКомпоненту(АдресTDLib,»Telegram», AddInType.Native) Тогда

    тлг = Новый(«AddIn.Telegram.TelegramNative»);

    … чет вот тут ни один метод запустить не получается. Пробовал:

    //тлг.УстановитьКаталогЖурнала(«D:TDliblogs»);

    //тлг.setProxy(«###:80»);

    //тлг.addProxy(«###:80»);

    //тлг.set_file_path(«D:TDliblogs»);

    //тлг.TdSetLogFilePath(«D:TDliblogs»);

    //Сообщить(тлг.GetInfo());

    КонецЕсли;

    Номер телефона не спрашивает, на методы ругается, что нет таких.

    Что я делаю не так?

    Reply
  20. Infactum

    (22) Из всех методов более-менее в цель попал только УстановитьКаталогЖурнала — только в какой-то из версий он был переименован в УстановитьФайлЖурнала.

    Методы TDLib так вызвать нельзя. В статье же написано, что компонента является оберткой над JSON методами.

    Если на других языках не работали с TDLib, то лучше скачать обработку-пример из публикации.

    Reply
  21. neo980

    Подскажите, какой командой происходит создание нового клиента?

    Reply
  22. Infactum

    (24) Не совсем понял вопрос. Подключаете компоненту и создаете новый экземпляр

    AddIn.Telegram.TelegramNative

    Рекомендую просто скачать обработку из публикации и ознакомиться с полноценным примером кода. Создать экземпляр клиента это же самое начало. Даже подключение к серверу выполнить задача нетривиальная.

    Reply

Leave a Comment

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