@hollanditkzn

Как реализовать на yii2 сохранение chat_id telegram bot?

Немного я изменил подход, посмотрел пример docs.mirocow.com/doku.php?id=php:telegram и где-то мне подсказали что нужно контроллере все это прописывать, так как я реализовывал все неправильно и понял зачем в этом примере контроллер, как бы не понятно было вначале данный пример. Использую сейчас виджет https://github.com/SonkoDmitry/yii2-telegram-bot-apiю Почему-то ни один виджет который я установил, по документации как написано обращаться через Yii::$app->bot-?sendMwssage то так не получается обратиться. Не знаю в чем причина такой ситуации.
Немного преписав код, у меня получилось следующее
В конфиге я указал
frontend/config/main.php
'components' => [
'bot' => [
            'class' => 'frontend\components\TelegramComponent',
            'apiToken' => '414134665:AAHfOIdeikQD04NdKckL8wadhqzggvmSqw0',
        ],
]

В frontend/components/TelegramComponent.php
<?php

namespace frontend\components;

use SonkoDmitry\Yii\TelegramBot\Component;


class TelegramComponent extends Component
{
    public function sendMessage(
        $chatId,
        $text,
        $parseMode = null,
        $disablePreview = false,
        $replyToMessageId = null,
        $replyMarkup = null,
        $disableNotification = false
    )
    {
        return parent::sendMessage(
            $chatId,
            $text,
            $parseMode,
            $disablePreview,
            $replyToMessageId,
            $replyMarkup,
            $disableNotification
        );
    }
}

И в контроллере frontend/controllers/TelegramController.php
<?php

namespace frontend\controllers;

use app\models\User;
use frontend\components\TelegramComponent;
use yii\db\Exception;
use yii\web\Controller;

class TelegramController extends Controller
{
    public function actionWebhook()
    {
        try{
            $bot = new TelegramComponent();
            echo $bot->setWebhook(['url' => ['web-hook']]);
        } catch (Exception $e){
            $e->getMessage();
        }
    }

    public function actionIndex()
    {
        try{
            $content = file_get_contents('php://input');
            $chatId = $content['message']['chat']['id'];

            $user = User::findOne(\Yii::$app->user->id);
            $user->telegram_chat_id = $chatId;
            $user->save();
        } catch (Exception $e){
            $e->getMessage();
        }
    }
}

И в адресной строке браузера я указал https://api.telegram.org/bot414134665:AAHfOIdeikQD...
Но вопрос, она все равно не работат, не записывает chat_id
  • Вопрос задан
  • 4128 просмотров
Решения вопроса 1
@hollanditkzn Автор вопроса
Решение данного вопроса, в контроллере TelegramController.php
use app\models\User;
use frontend\components\TelegramComponent;
use yii\db\Exception;
use yii\filters\AccessControl;
use yii\web\Controller;
use frontend\models\Telegram;

class TelegramController extends Controller
{
    public function beforeAction($action)//Обязательно нужно отключить Csr валидацию, так не будет работать
    {
        $this->enableCsrfValidation = ($action->id !== "webhook");
        return parent::beforeAction($action);
    }

       public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'only' => ['webhook'],
                'rules' => [
                    [
                        'allow' => true,
                        'roles' => ['?'],
                    ],
                ],
            ],
        ];
    }
    
    public function actionWebhook()
    {
        $data = json_decode(file_get_contents('php://input'), true);//Обязательно json формат
       if(isset($data['message']['chat']['id']))
        {
            $chatId = $data['message']['chat']['id'];//Получаем chat_id
            $message = isset($data['message']['text']) ? $data['message']['text'] : false;

            $send = false;

            if (strpos($message, '/start') !== false) {//Возвращает позицию
                $explode = explode(' ', $message);//Разбивает строку на подстроки
                $token = isset($explode[1]) ? $explode[1] : false;//Получаем токен
                $data = [
                    'raw' => $token,
                    'chat_id' => $chatId,
                ];
                $send = Telegram::start($data);//Сравниваем токен и если имеется схожесть то сохраняем telegram_chat_id в бд
            } else {
                $send = 'Комманда не найдена. Если Вы уверены в том, что ошибка, обратитесь в тех поддержку';
            }
            $send = $send ? '' : 'Что-то пошло не по плану. Обратитесь в тех.поддержку';
        }
    }
}

В моделе Telegram.php
<?php 
namespace frontend\models;

use common\models\User;

class Telegram
{
    public static function start($data){
    	return self::login($data);
    }
    public static function login($data)
    {
    	$token = $data['raw'];//берем токен который отправляем
    	if ($token && $user = User::findOne(['token' => $token])) {//сравниваем
    		if ($user->telegram_chat_id) {
                return "Уважаемый $user->name, Вы уже авторизованы в системе. ";
            }
            $user->telegram_chat_id = $data['chat_id'];//сохраняем chat_id в бд
            $user->save();
            return "Добро пожаловать, $user->name. Вы успешно авторизовались!";   
    	} else {
    		return "Извините, не удалось найти данный токен!";
    	}
    }
}

И да токен который мы сами создаем, надо записать в бд. Отдельный пользовательский токен, которая система будет проверять у данного пользователя и если он совпадает то сохраняет данному пользователю
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
usdglander
@usdglander
Yipee-ki-yay
Буквально вчера столкнулся
$message = $content['message'];
$chatId = $message['chat']['id'];

Не верно. Правильно будет:
$message = $content['callback_query']['message'];
$chatId = $message['chat']['id'];
Ответ написан
ExileeD
@ExileeD
PHP/Python developer
Вы указываете боту на
frontend/web/telegram/webhook
А сами ждете от него ответ на
frontend/web/telegram/index
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы