DotNetRu / Commune

DotNetRu Meetup Management App
MIT License
13 stars 12 forks source link

Интеграция с Telegram #4

Open kulakovt opened 6 years ago

kulakovt commented 6 years ago

Необходимо найти или разработать компонент, который предоставит возможность взаимодействовать с чат-сервисом Telegram.

Обязательные требования:

egorikas commented 6 years ago

Буду заниматься. Отписываюсь тут, т.к. повесит на себя не особо могу

kulakovt commented 6 years ago

Самое приоритетное это уметь логиниться и постить в канал (анонсы о митапах). Всё остальное обсуждаемо.

Sergey-Buyanov commented 6 years ago

@egorikas Назначил задачу, Как будет понятно, что и как возможно сделать. можно будет обсудить интерфейс компонента для реализации (если не найдется готовых). Если будут вопросы пиши )

egorikas commented 6 years ago

Исследовал что есть. 1) Есть клиентская либа - https://github.com/sochix/TLSharp По апи, она достаточно простая и посылать сообщения в канал можно будет в 50 строк (где-то) ссылка на авторизационный пример, придется авторизовываться, т.к. неавторизованные могут делать очень мало тык

2) Ручной поток авторизации - придется искать либу для работы с Mtp протоколом и делать что-то такое

  1. Зарегестрироваться как разработчики
  2. Указать хэши приложения
  3. Отправляем номер телеграмму
  4. Отправляем код, который пришел на этот номер
  5. Получаем авторизационную сессию, храним ее, пользуемся ей

3) Можно сделать бота (не факт, что нужно), я не особо представляю, как он может пригодиться

egorikas commented 6 years ago

Если нет возражений, я сделаю на готовой либе, а потом будем смотреть, если чего-то не хватает, допилим ручками. @AnatolyKulakov @Sergey-Buyanov есть возражения?

Sergey-Buyanov commented 6 years ago

По поводу кода и библиотек забыли указать, что нужна поддержка .NET Core TLSharp можно использовать в .NET Core? Если нет, возможно помогут библиотеки https://github.com/OpenTl/OpenTl.ClientApi https://github.com/egramtel/egram.tel

Также можешь указать, что нам надо хранить на стороне сервера для аутентификации пользователя? + что нужно для уникальной идентифицировать пользователя (userId, Phone?) в Telegram, чтобы можно было на этой основе выдавать права

egorikas commented 6 years ago

Нам не нужна вся функционально, можно куски выдрать из той TLSharp, потому что она под MIT. Либо взять https://github.com/OpenTl/OpenTl.ClientApi, чтобы не изобретать велосипед. egram.tel построен на Rx, поэтому что-то позаимствовать будет проблематично.

Поэтому я наверное настроен попробовать OpenTl.ClientApi, если нет, выдрать куски классов из TLSharp, потому что пул-реквесты в него не мержатся с мая и это очень странно.

Хранить надо:

  1. API_ID и API_HASH - эти штуки берутся из личного кабинета разработчика, на сайте телеграмма
  2. Объект, который вернется от телеграмма
    (auth.authorization
    expires:1403938438
    user:(userSelf
    id:603177
    first_name:"John"
    last_name:"Doe"
    phone:"79991234567"
    photo:(userProfilePhotoEmpty)
    status:(userStatusEmpty)
    inactive:(boolTrue)
    )
    )

    При реализации станет понятно, но скорее всего, можно будет хранить access hash

  3. Можно хранить телефон, через который будут проводиться аунтефикации, а можно не хранить. Суть в том, что токен иногда придется обновлять и для этого, нужно будет приложение и код доступа, которое в это приложение придет As a result of authorization, the client key, auth_key_id, becomes associated with the user, and each subsequent API call with this key will be executed with that user’s identity. The authorization method itself returns the relevant user and the association expiration time, expires. It is best to immediately store the User ID locally in a binding with the key. At some point in time (>= expires), the association will expire, and the authorization process will have to be repeated. (c)
Sergey-Buyanov commented 6 years ago

Да,давай, как ты говоришь попробуем использовать OpenTi.ClientApi. Ещё вопрос, для поста в группу достаточно использовать app id + hash. Или для этого нужно ещё аутентифицировать пользователя по коду. Т.е. возможны ли не интерактивные действия?

Т.е например, такой use case возможен? Например, пользователь логинится, через vk. Формируем информацию для публикации и отправляем её в telegram.

egorikas commented 6 years ago

Да, возможны, только переодически нужно будет перелогиниваться в систему, для этого, пользователь должен будет ввести код, который приедет ему на телефон, чтобы мы смогли его использовать в запросах Да, возможен, если пользователь зарегестрирован в телеграмме под тем же номером + ему нужно будет ввести код из приложения телеграмма

kulakovt commented 6 years ago

А нет ли возможности AutoRefreshToken? Кажется что обязательное переодическое перелогиневание - это довольно странная ситуация. Я не хочу внезапно потерять возможность писать анонсы в Канал, только потому что нашей библиотеке понадобилось снова ввести код подтверждения. У меня может с собой рядом не быть телефона, или не быть окна для ввода нового кода или вообще я буду в необитаемом отпуске. Процесс должен работать и без моего вмешательстава. Я хочу один раз дать ей "бесконечный токен", "админский доступ", "вечную жизнь" или "права на автоматическое обновление токена" и всё!

Sergey-Buyanov commented 6 years ago

Вроде возможно также постить новости в группу через бота

egorikas commented 6 years ago

@AnatolyKulakov авторефреш и прочее, только через бота. Тогда надо будет сделать бота, дать ему админские права к каналу и писать через него. Это конечно добавление уровень сложности, но тоже прекрасно решаемо

egorikas commented 6 years ago

P.s. мне тогда надо будет что-то такое сделать https://medium.com/@xabaras/sending-a-message-to-a-telegram-channel-the-easy-way-eb0a0b32968 А тебе его добавить админом на страничку и вуаля, все счастливы

kulakovt commented 6 years ago

Звучит, аки то что нам надо. У использования бота для этих целей есть минусы?

egorikas commented 6 years ago
Sergey-Buyanov commented 6 years ago

@egorikas а что с точки с зрения безопасности? Отсылать сообщение к боту (делать post) сможет любой? При request-е используется какой-то токен?

egorikas commented 6 years ago

При реквесте надо будет знать уникальный идентификатор бота и токен авторизации, при каждом запросе используется их связка @Sergey-Buyanov

Sergey-Buyanov commented 6 years ago

Давайте сделаем тогда какой-нибудь прототип на основе bot-a, чтобы он делал post в тестовую группу и посмотрим как-это будет работать.

egorikas commented 6 years ago

@AnatolyKulakov @Sergey-Buyanov Немножечко поэксмерементировал https://github.com/egorikas/AuditServer/tree/master/TelegramBotTheory https://t.me/dot_net_ru_test_channel

P.s. примеры всякого с ботом - https://github.com/TelegramBots/Telegram.Bot/tree/master/test/Telegram.Bot.Tests.Integ

kulakovt commented 6 years ago

Если рассмотреть вариант, что ключи от бота утекли. Можно ли как-то оперативно забрать у него доступ ко всему? Отозвать ключ?

egorikas commented 6 years ago

https://botsfortelegram.com/project/the-bot-father/ можно

Sergey-Buyanov commented 6 years ago

Пара вопросов 1 > https://github.com/egorikas/AuditServer/tree/master/TelegramBotTheory Где в примере используется/нужно использовать ключ?

  1. Можешь написать, какие действия нам нужно сделать для создания/регистрации bot-a?
  2. Можно ли как-то оперативно забрать у него доступ ко всему? Отозвать ключ? Это может делать любой?

egorikas commented 6 years ago

1) var botClient = new TelegramBotClient("здесь будет ключ", proxy); 2) в телеграмме есть бот @BotFather, создается через него. буквально в 3 команды image


3) Нужно вызвать /revoke – Revoke bot access token, вызвать это для бота, сможет только создатель бота

egorikas commented 6 years ago

image Пример генерации нового токена

kulakovt commented 6 years ago

@Sergey-Buyanov , думаю, во время интеграции снова встанет вопрос про Key Chain (который мы затрагивали при обсуждении VK интеграции). Нам нужно обеспечить общий механизм хранения, раздачи, создания и перевыпуска ключей для всех внешних сервисов.

Sergey-Buyanov commented 6 years ago

Да, согласен, и это отдельная тема. @egorikas вообще можно автоматизировать получение/обновление bot access token? Я так понимаю минимум для этого нам надо сделать аутентификацию пользователя в telegram, от которого будут делаться эти действия

Ещё, @AnatolyKulakov в рамках текущей задачи, хотим делать аутентификацию пользователя у нас на сервере через Telegram?

kulakovt commented 6 years ago

автоматизировать получение/обновление bot access token

Думаю на первом этапе можно просто описать в wiki как это сделать вручную. Всё-таки авторизация новых интеграций это не самая частая операция. А автоматизироваться подобные задачи могут сложно.

в рамках текущей задачи, хотим делать аутентификацию пользователя у нас на сервере через Telegram

В рамках этой точно не надо. Да и домен управления пользователями у нас ещё не придуман. Надо заняться этой задачей на ближайшем собрании.

egorikas commented 6 years ago

Я считаю, что токен в конфиге - это оптимальный выбор. Чтобы совсем это автоматизировать - это путь с вводом кода из приложения, как я уже говорил. + он бессрочный и если его особо не раскрывать, вероятность того, что он утечет не особо большая + бота можно ограничить только постингом сообщений в канал.

Sergey-Buyanov commented 6 years ago

Да, думаю сделаем пока в конфиге appsettings.json. Для тестовых целей выделим access token тестового бота и тестовый канал Потом в appveyour можно будет зашифровать и деплоить с рабочим ключом

@egorikas давая тогда сделаем интерфейс для компонента(фасада) работы с Telegram и позволяющего пока только постить сообщения в канал и который будем использовать в проекте положить думаю можно сюда src/Components/DotNetRu.Components.Telegram.Contract сделаю branch для этого

egorikas commented 6 years ago

Я вечером сегодня или завтра набросаю интерфейс и обсудим

kulakovt commented 6 years ago

Да, думаю сделаем пока в конфиге appsettings.json. Для тестовых целей выделим access token тестового бота и тестовый канал

Для тестов да. Но всё же хотелось бы начать пользоваться Сервером как только в нём появится минимальный функционал (Публикация). Поэтому предлагаю создать таску по написанию нормального «Секретного хранилища» и начать там его обсуждение.

И хотелось бы чтобы уже сейчас Телеграмная интеграция просто попросила зависимостью ISecretManager, который в тестовой реализации использует AppSettings. Чтобы при реализации таски можно было не менять все интеграции (VK, Twitter), а просто подменить реализацию провайдера с паролями.

Sergey-Buyanov commented 6 years ago

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

egorikas commented 6 years ago

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

Sergey-Buyanov commented 6 years ago

Для компонента должно быть без разницы, а так пока из appsettings.json сервиса

egorikas commented 6 years ago

Я скорее про то, если ли какой-то интерфейс для секретов. Или сделать по классике, через инекцию Options в компонент?

Sergey-Buyanov commented 6 years ago

Можно завести в компоненте нужный тебе интерфейс, также IOptions вполне подойдет В дальнейшем, мы сможем смаппить его на что угодно

Sergey-Buyanov commented 6 years ago

Если что, буду доступен только в понедельник

egorikas commented 6 years ago

Хорошо, я как раз думаю к нему сделаю.

egorikas commented 6 years ago

@AnatolyKulakov в каком формате обычно сообщения в канал? Просто текст? Достаточно будет только текста для первой итерации?

kulakovt commented 6 years ago

Обычно это просто текст и ссылка (на регистрацию или материалы). Вот тут примеры: https://t.me/spbdotnet