Информер погоды в Телеграм-боте на PHP

29.06.2022     👁 3059


В продолжении предыдущей статьи "Добавляем пункты меню в Телеграм бота на PHP", представляем вам продолжение данной темы: "Информер погоды в Телеграм-боте на PHP".

Информер погоды в Телеграм-боте на PHP

Телеграм-бота с меню мы уже сделали вы уже сделали, благодаря этой статье. Будем использовать код из этой статьи, который вы можете скачать тут: verysimple_bot_menu.zip (2.7 Kb).

Для этого нам нужно найти сервис получения погоды по API И выдать данные телеграм-боту

  1. Зарегистрируемся на сервере https://openweathermap.org/api
  2. Получим API-ключ - там есть бесплатный пакет "Free plan" с до 60 запросов в минуту, до 1 млн. запросов в месяц - я думаю нам хватит для небольшого не сильно посещаемого бота :)
  3. В разделе API keys скопируем Api-ключ
  4. Далее напишем кусочек PHP-кода с запросом к серверу и получение погоды по нашему Api-ключу
  5. Впишем латиницей нужный нам город, страну, язык получения результатов
  6. Получим данные в json, декодируем в массив и обработаем нужные нам данные погоды (смотрите ниже массив результатов, чтобы вывести что-то еще)

$city = "Yekaterinburg"; // город, где узнаем погоду
$country = "RU"; // страна
$mode = "json"; // формат получения ответа сервера
$units = "metric"; // в какой системе выдавать результаты 
$lang = "ru";  // нужный язык вывода результатов
$countDay = ($num > 0) ? $num : 1; // количество дней для вывода информации по погоде
$appID = "1234567890absdef0123456789abcde"; // сюда вставьте свой ключ
$url = "http://api.openweathermap.org/data/2.5/forecast?q=$city,$country&cnt=$countDay&lang=$lang&units=$units&appid=$appID"; // собственно ссылка запроса к серверу
$data = @file_get_contents($url); // получение массива данных

// Далее обработаем массив $data и выведем в html-текст в переменную $text_return
// Выведем данные в виде 
$text_return = '';
if ($data) {
	$clima = json_decode($data, true);
	foreach($clima['list'] as $p) {
		$text_return .= date("d.m.Y", $p['dt']).": ".$p['weather'][0]['description']."\n";
		$text_return .= "Температура: ".round($p['main']['temp_min'])."°C ... ".round($p['main']['temp_max'])."°C\n";
		$text_return .= "Влажность: ".$p['main']['humidity']."%\n";
		$text_return .= "Ветер: ".$p['wind']['speed']."км/ч\n\n";
	}
}
else {
	$text_return = 'Тишина...';
}


Сервер возвращает результаты в виде массива данных:


$data = {
	"cod":"200",
	"message":0,
	"cnt":1,
	"list":[{
		"dt":1656082800,
		"main":	{
			"temp":20.19,
			"feels_like":19.67,
			"temp_min":17.04,
			"temp_max":20.19,
			"pressure":1009,
			"sea_level":1009,
			"grnd_level":977,
			"humidity":54,
			"temp_kf":3.15
		},
		"weather":[{
			"id":802,
			"main":"Clouds",
			"description":"переменная облачность",
			"icon":"03d"
		}],
		"clouds":{"all":33},
		"wind":{
			"speed":2,
			"deg":293,
			"gust":5.1
		},
		"visibility":10000,
		"pop":0.25,
		"sys":{"pod":"d"},
		"dt_txt":"2022-06-24 15:00:00"
	}],
	"city":{
		"id":1486209,
		"name":"Екатеринбург",
		"coord":{
			"lat":56.8575,
			"lon":60.6125
		},
		"country":"RU",
		"population":1287573,
		"timezone":18000,
		"sunrise":1656025479,
		"sunset":1656089703
	}
}

Теперь перепишем бота

  1. Добавим меню Погода - пусть будет команда /pogoda, а если за несколько дней (например, 3) то: /pogoda 3 или просто "погода" и "погода 3"
  2. Добавим обработку раздела Погода: строки 114 - 142
/**
*   Very simple chat bot @verysimple_bot_menu_pogoda by Novelsite.ru
*   + menu
*   29.06.2022
*/
header('Content-Type: text/html; charset=utf-8'); // на всякий случай досообщим PHP, что все в кодировке UTF-8

$site_dir = dirname(dirname(__FILE__)).'/'; // корень сайта
$bot_token = '1234567899:AAKJhkkjhkjhKhKhjkhkhk_kJhgkjhJhgjghjhG'; // токен вашего бота
$data = file_get_contents('php://input'); // весь ввод перенаправляем в $data
$data = json_decode($data, true); // декодируем json-закодированные-текстовые данные в PHP-массив

$order_chat_id = '123456789';  //chat_id менеджера компании для заявок
$bot_state = ''; // состояние бота, по-умолчанию пустое

// Для отладки, добавим запись полученных декодированных данных в файл message.txt, 
// который можно смотреть и понимать, что происходит при запросе к боту
// Позже, когда все будет работать закомментируйте эту строку:
file_put_contents(__DIR__ . '/message.txt', print_r($data, true));

// Основной код: получаем сообщение, что юзер отправил боту и 
// заполняем переменные для дальнейшего использования
if (!empty($data['message']['text'])) {
    $chat_id = $data['message']['from']['id'];
    $user_name = $data['message']['from']['username'];
    $first_name = $data['message']['from']['first_name'];
    $last_name = $data['message']['from']['last_name'];
    $text = trim($data['message']['text']);
    $text_array = explode(" ", $text);

	// получим текущее состояние бота, если оно есть
	$bot_state = get_bot_state ($chat_id);

    // если текущее состояние бота отправка заявки, то отправим заявку менеджеру компании на $order_chat_id
    if (substr($bot_state, 0, 6) == '/order') {
        $text_return = "
Заявка от @$user_name:
Имя: $first_name $last_name 
$text
";
        message_to_telegram($bot_token, $order_chat_id, $text_return);
        set_bot_state ($chat_id, ''); // не забудем почистить состояние на пустоту, после отправки заявки
    }
    // если состояние бота пустое -- то обычные запросы
    else {
    
    	// вывод информации Помощь
        if ($text == '/help') {
            $text_return = "Привет, $first_name $last_name, вот команды, что я понимаю: 
    /help - список команд
    /about - о нас
    /order - оставить заявку
    ";
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '/help');
        }
        
        // вывод информации о нас
        elseif ($text == '/about') {
            $text_return = "verysimple_bot:
    Я пример самого простого бота для телеграм, написанного на PHP.
    Мой код можно скачивать, дополнять, исправлять. Код доступен в этой статье:
    https://www.novelsite.ru/kak-sozdat-prostogo-bota-dlya-telegram-na-php.html
	также есть дополнение статиь про добавление пунктов меню в бота: 
	https://www.novelsite.ru/dobavlyaem-punkty-menyu-telegram-bota-na-php.html
    ";
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '/about');
        }
		
        // вывод информации об услугах и подменю 
        elseif ($text == '/srv') {
            $num = (int)$text_array[array_key_last($text_array)];
            if ($num == 1) {
				$ret = ["text"=>"⬅️ Вернуться", "callback_data"=>'/srv'],;
                $text_return = 
"Услуга 1:
---------------------
Текст об услуга 1 услуга 1 услуга 1 услуга 1 услуга 1 услуга 1 услуга 1.
";
			}
            elseif ($num == 2) {
				$ret = ["text"=>"⬅️ Вернуться", "callback_data"=>'/srv'],;
                $text_return = 
"Услуга 2:
---------------------
Текст об услуга 2 услуга 2 услуга 2 услуга 2 услуга 2 услуга 2 услуга 2.
";
			}
			else {
				$ret = [];
                $text_return = 
"Услуги:
---------------------
 1. Услуга 1
 2. Услуга 2
";
            }

            $reply_markup = json_encode([
                "inline_keyboard" => [
                    [
                        ["text"=>"Услуга 1", "callback_data"=>'/srv 1'],
                        ["text"=>"Услуга 2", "callback_data"=>'/srv 2'],
                    ],
                    $ret,
                ]
            ]);
                
            message_to_telegram($bot_token, $chat_id, $text_return, $reply_markup);
            set_bot_state ($chat_id, '/srv');
        }
		
        // вывод информации Погода
        elseif (substr($text, 0, 7) == '/pogoda' || mb_strstr($text, "погода")) {
			$num = (int)$text_array[array_key_last($text_array)];
		    $city = "Yekaterinburg"; // город, где узнаем погоду
			$country = "RU"; // страна
			$mode = "json"; // формат получения ответа сервера
			$units = "metric"; // в какой системе выдавать результаты 
			$lang = "ru";  // нужный язык вывода результатов
			$countDay = ($num > 0) ? $num : 1; // количество дней для вывода информации по погоде
			$appID = "1234567890absdef0123456789abcde"; // сюда вставьте свой ключ
			$url = "http://api.openweathermap.org/data/2.5/forecast?q=$city,$country&cnt=$countDay&lang=$lang&units=$units&appid=$appID"; // собственно ссылка запроса к серверу
			$data = @file_get_contents($url); // получение массива данных
			$text_return = '';
			if ($data) {
				$clima = json_decode($data, true);
				foreach($clima['list'] as $p) {
					$text_return .= date("d.m.Y", $p['dt']).": ".$p['weather'][0]['description']."\n";
					$text_return .= "Температура: ".round($p['main']['temp_min'])."°C ... ".round($p['main']['temp_max'])."°C\n";
					$text_return .= "Влажность: ".$p['main']['humidity']."%\n";
					$text_return .= "Ветер: ".$p['wind']['speed']."км/ч\n\n";
				}
			}
			else {
				$text_return = 'Погода молчит...';
			}		   
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '/pogoda');
        }
		// конец вывода Погоды
        
        // переход в режим Заявки
        elseif ($text == '/order') {
            $text_return = "$first_name $last_name, для подтверждения Заявки введите текст вашей заявки и нажмите отправить. 
Наши специалисты свяжутся с вами в ближайшее время!
";
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '/order');
        }
	}
}

// функция отправки сообщения от бота в диалог с юзером
function message_to_telegram($bot_token, $chat_id, $text, $reply_markup = '')
{
    $ch = curl_init();
    if ($reply_markup == '') {
        $btn[] = ["text"=>"О нас", "callback_data"=>'/about'];
        $btn[] = ["text"=>"Услуги", "callback_data"=>'/srv'];
        $btn[] = ["text"=>"Контакты", "callback_data"=>'/contact'];
        $btn[] = ["text"=>"Заявка", "callback_data"=>'/order'];
        $reply_markup = json_encode(["keyboard" => [$btn],  "resize_keyboard" => true]);
    }
    $ch_post = [
        CURLOPT_URL => 'https://api.telegram.org/bot' . $bot_token . '/sendMessage',
        CURLOPT_POST => TRUE,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_POSTFIELDS => [
            'chat_id' => $chat_id,
            'parse_mode' => 'HTML',
            'text' => $text,
            'reply_markup' => $reply_markup,
        ]
    ];

    curl_setopt_array($ch, $ch_post);
    curl_exec($ch);
}

// сохранить состояние бота для пользователя
function set_bot_state ($chat_id, $data)
{
    file_put_contents(__DIR__ . '/users/'.$chat_id.'.txt', $data);
}

// получить текущее состояние бота для пользователя
function get_bot_state ($chat_id)
{
    if (file_exists(__DIR__ . '/users/'.$chat_id.'.txt')) {
        $data = file_get_contents(__DIR__ . '/users/'.$chat_id.'.txt');
        return $data;
    }
    else {
        return '';
    }
}

P.S. Для текста в кнопках меню бота и в выводах результатов можно использовать Эмодзи.

 


Николай Комарков



Подписывайся на наш Телеграм

Подписывайся на наш
Телеграм канал!
Контекст решает