Closed trueSiberian closed 4 years ago
Авторизацию достаточно пройти 1 раз добавив в свой скрипт обработку событий авторизации (updateAuthorizationState), т.е. шаги "authorizationStateWaitTdlibParameters"->"authorizationStateWaitPhoneNumber"->"authorizationStateWaitCode"->"authorizationStateReady". Далее при запуске скрипта будет достаточно "скормить" параметры на событии "authorizationStateWaitTdlibParameters" и начать слушать события. И вы уверены, что вам нужно не что-то вроде https://github.com/evgeny-nadymov/telegram-react ?
Клиент в любом случае будет ждать параметры и авторизацию. Как верно заметил @radmirr , достаточно пройти один раз. Но нужно иметь ввиду, что авторизация рано или поздно может "слететь". По этому крайне желательно (я бы даже сказал - обязательно) проверять с помощью getAuthorizationState. Если вернёт authorizationStateReady:
The user has been successfully authorized. TDLib is now ready to answer queries.
Насчет паблик кей я ничего не подскажу, т.к. лично сам расширением не пользуюсь =) Возможно кто-то сможет подсказать. Но судя по Function Class Reference навряд ли.
на счет PUBLIC KEY понял и про проверку авторизации, но как по итогу авторизироваться. Так как брал функцию из примера.
Я же правильно понимаю, при первом выполнении скрипта, должен придти код на телефон $client->setAuthenticationPhoneNumber($phone_number, 3); // wait response 3 seconds. default - 1.
а после это, мы комментируем получение кода,а полученный код вставляем ниже. $result = $client->query(json_encode(['@type' => 'checkAuthenticationCode', 'code' => 'xxxxx', 'first_name' => 'dummy', 'last_name' => 'dummy']), 10);
Но код не приходит, вот в чем беда.
У тебя перед setAuthenticationPhoneNumber какой статус?
Должно быть так:
Начинаешь с этого: td_json_client_execute($client, json_encode(['@type' => 'getAuthorizationState']));
По идее, ответом приходит updateAuthorizationState. Смотришь @type.
На authorizationStateWaitTdlibParameters отвечаешь параметрами тдлиб.
Тебе опять прилетает updateAuthorizationState. Опять смотришь @type
Должен быть authorizationStateWaitEncryptionKey. Отвечаешь ему ключом.
Опять прилетает ответ с updateAuthorizationState и ты опять смотришь @type.
Если authorizationStateWaitPhoneNumber - то вот тогда-то и даешь ему setAuthenticationPhoneNumber
И вот если все сработало, то тебе телега отправит код (на другой тг) и прилетит запрос authorizationStateWaitCode
И вот на него уже отвечаешь кодом.
Я же правильно понимаю, при первом выполнении скрипта, должен придти код на телефон $client->setAuthenticationPhoneNumber($phone_number, 3); // wait response 3 seconds. default - 1
Да, всё правильно. Но код должен придти. Не приходит на указанный номер? Значит что-то не так. Нужен лог из консоли, тот что тдлиб. Для этого в строке из примера из документации нужно указать LVL_ALL
вместо LVL_ERROR
.
\TDApi\LogConfiguration::setLogVerbosityLevel(\TDApi\LogConfiguration::LVL_ALL);
В этом случае лог будет как примерно тут (в самом конце). Но не забудь удалить из лога айди и ключ апи и телефон =) И сам лог желательно скинуть используя это (так как там должно быть много чего, тут поедет).
А в целом, @DerAlSem описал действия, как оно должно работать с обычными td_json_client_...
функциями. То что в примере - просто "обёртка" на этими функциями.
td_json_client_execute($client, json_encode(['@type' => 'getAuthorizationState']));
@DerAlSem я не уверен на 100%, но разве getAuthorizationState не обычным td_json_clinet_send
вызывается?
Сейчас ошибок нет, но код все равно не приходит. [30]=> string(306) "{"@type":"updateAuthorizationState","authorization_state":{"@type":"authorizationStateWaitCode","code_info":{"@type":"authenticationCodeInfo","phone_number":"+7XXXXXXXXXX","type":{"@type":"authenticationCodeTypeSms","length":5},"next_type":{"@type":"authenticationCodeTypeCall","length":0},"timeout":120}}}" [31]=> string(34) "{"@type":"ok","@extra":1714636915}"
Вот лог https://pastebin.com/B9Squ4vx
и ввиду того, что я не имел опыта работы с подобными extension. направьте как это потом можно интегрировать в yii2 и laravel.
еще все развертуто локально и стоит telegram-desktop для Ubuntu. Я просто уже не знаю в чем проблема может быть.
Судя по всему, вы не сообщаете телеграму код - как только приходит событие "authorizationStateWaitCode" телеграм начинает ждать код подтверждения (он приходит в другой клиент телеграма или по СМС), как только это событие поступило, нужно с помощью функции "checkAuthenticationCode" передать этот код. Например,
$this->client->send(json_encode(['@type' => 'checkAuthenticationCode', 'code' => $code]));
, где $code это код из сообщения.
Так в том то и дело, что код никуда не приходит
после $client->setAuthenticationPhoneNumber($phone_number, 3); все без ошибок, и код не приходит
Выставьте в параметрах библиотеки параметр TDApi\TDLibParameters::USE_TEST_DC в значение false (у вас он в true), в тестовом инстансе код просто так не придет, там еще и регистрацию необходимо правильно пройти.
Пришло, я пару раз менял USE_TEST_DC, но смс не приходило, а сейчас пришло в телеграм на телефоне. Спасибо больное. МОжно еще пример попросить как отправлять сообщения То что попробвал я выдало ошибку {"@type":"error","code":5,"message":"Can't send message without content","@extra":1957747793}
$result = $client->query(json_encode(['@type' => 'sendMessage', 'chatid' => 'usernaem', 'input_messagecontent' => 'Если тебя это пришло, значит заработало']), 10);
и хотя направьте, как это интегрировать в Yii2 и Laravel
И еще раз большое спасибо
Что-то вроде
$this->client->send(json_encode(['@type'=>'openChat','chat_id'=>$chat_id]));
$this->client->send(json_encode([
'@type'=>'sendMessage',
'chat_id'=>$chat_id,
'reply_to_message_id'=>0,
'disable_notification'=>false,
'from_background'=>false,
'input_message_content'=>[
'@type'=>'inputMessageText',
'text'=>[
'@type'=>'formattedText',
'text'=>$message_text,
'entities'=>[]
],
'disable_web_page_preview'=>false,
'clear_draft'=>false
],
'@extra' => $extra
]));
$this->client->send(json_encode(['@type' => 'closeChat', 'chat_id' => $chat_id]));
где $chat_id - id чата в телеграме, $message_text - текстовое сообщение, $extra - поле для последующей идентификации ответа на запрос, можно не использовать. По вопросу интеграции с Yii2 и Laravel уже не смогу подсказать, т.к. использовал библиотеку для интеграции с совершенно другой системой.
как это интегрировать в Yii2 и Laravel
это можно использовать где угодно, хоть в чистом PHP коде без фреймворков. Это расширение PHP, по этому функции и классы доступны везде, если расширение включено. Дальше уже зависит от потребностей и правил каждого фреймворка. Как пример - это может быть сервис, который предоставляет доступ к уже инициализированному клиенту (что есть заботой сервиса).
sendMessage
Выше уже привели пример, но еще раз упомяну как узнать, что надо отправлять:
Ищем и смотрим в документации сам метод sendMessage. На этом этапе мы знаем @type
:
{"@type":"sendMessage"}
У каждого метода в документации есть публичные поля (Public Fields). И если они не пустые, тогда это и есть дополнительные аргументы в запросе. В данном конкретном случае:
type | key | description | |
---|---|---|---|
std::int64_t | chatid | Target chat. | |
std::int64_t | reply_to_messageid | Identifier of the message to reply to or 0. | |
object_ptr |
options_ | Options to be used to send the message. | |
object_ptr |
replymarkup | Markup for replying to the message; for bots only. | |
object_ptr |
input_messagecontent | The content of the message to be sent. |
Это и будут наши последующие ключи в массиве, который будет кодирован в результирующий json'е.
{"@type":"sendMessage","chat_id":123123123,"reply_to_message_id":0,"options":[],"reply_markup":[],"input_message_content":[]}
Так же замечу, что для ключей я удалил последний символ подчёркивания "_" Ну а тип подсказывает, чего ожидает тдлиб. Если это std::int64_t
- очевидно, что нужно целое число. object_ptr
- объекты определенного типа (как указано в дженерике, в данном случае sendMessageOptions, ReplyMarkup и InputMessageContent)
json_encode([
'@type' => 'sendMessage',
'chat_id' => 123123123,
'reply_to_message_id' => 0,
'options' => [/* смотрим sendMessageOptions Class Reference */],
'reply_markup' => [/* смотрим ReplyMarkup Class Reference */],
'input_message_content' => [/* смотрим InputMessageContent Class Reference */],
]);
Всё остальное в json api работает идентичным образом.
'@extra' => $extra , $extra - поле для последующей идентификации ответа на запрос, можно не использовать.
Кстати, '@extra' всегда добавляется в запрос, если этот ключ не указан напрямую и используется \TDLib\JsonClient::query
код. Собственно, именно таким способом отслеживается определенное сообщение, которое возвращается методом query
Спасибо, сейчас буду пробовать разбираться дальше)
@radmirr @DerAlSem @trueSiberian (и возможно еще кто-то прочитает и захочет =) ) так как вы уже прекрасно понимаете как работает tdlib json client, не могли бы вы помочь написать документацию, которая снизит количество подобных issue (которых множество, однотипны и в целом не очень-то и зависят от phptdlib
, а от понимания самого tdlib
)? Лучше на русском (потом уже и переведётся, улучшится.), т.к. основная масса пользователей - так или иначе понимающие русский. Я могу перевести то, что я писал тут. Но я не знаю как лучше объяснить правильно. Буду благодарен за помощь =) PRs welcome
Я попробую немного позже, несколько примеров описать которые использую, но мне кажется это будет топорно)))
Итого по интеграции все ок в laravel, просто с котроллере use \TDApi; use \TDLib;
а вот когда docker поднимаю, там класс не находит. разбираюсь
И как фото пользователя скачать, потому что возвращаются данные, типа скачено, а что и куда не понятно. [photo][ [remote]][is_uploading_completed] => 1
Фото в сторейдж дир в тдлиб параметрах.
"uploading_complete" это скорее всего отображение загружен файл на сервер или нет. Чтобы скачать файл себе наверно придется загружать его через https://core.telegram.org/tdlib/docs/classtd_1_1td__api_1_1download_file.html
а вот когда docker поднимаю, там класс не находит. разбираюсь
ну а в контейнере (где php) расширение собрано и включено? Его нужно включить и там. Что показывает php -m | grep tdlib
?
Inactive. Feel free to reopen
Доброго времени суток!
Если возможность авторизавать без кода подтверждения с помощью PUBLIC KEY.
Взял пример с https://yaroslavche.github.io/phptdlib/documentation.html (TDLib\JsonClient)
Запускаю php ../php_examples/test.php
Ответ: [32]=> string(266) "{"@type":"authorizationStateWaitCode","code_info":{"@type":"authenticationCodeInfo","phone_number":"7XXXXXXXXXX","type":{"@type":"authenticationCodeTypeSms","length":5},"next_type":{"@type":"authenticationCodeTypeCall","length":0},"timeout":120},"@extra":1957747793}" [33]=> string(72) "{"@type":"error","code":401,"message":"Unauthorized","@extra":424238335}"
Что с этим можно сделать?
Подскажите пожулуста)