Информер USD/EUR и криптовалют BTC/ETH в Телеграм бот PHP

09.01.2023     👁 4203


Расширяем возможности бота на PHP

В продолжении предыдущих статей:

Внимание!

Прежде чем продолжить, давайте поясню: вы пишите, что в преудущих статьях бот не работает, но не забывайте, что вы правильно проделали все действия последовательно: начните с 1й статьи — Как создать простого бота для Телеграм на PHP — и заставьте его работать, а далее последовательно добавляйте меню и информеры. Возможно, на каком-то этапе закралась ошибка.

Данный бот должен работать, я его взял из https://t.me/novelsite_bot, заменив все персональные данные и ключи API.
Не забывайте их заменить на свои!
Не забывайте про работающий https!
Не забывайте правильно прописать webhook вашего бота и сообщить его Телеграм!
Не забывайте дать права на запись в папке бота!
На сервере PHP должен работать модуль CURL

Информер курсов USD/EUR и криптовалют BTC/ETH в Телеграм бот на PHP

Готовый код бота можно скачать по ссылке: bot_usd_btc.zip

1. ПОлучим курсы USD/EUR к рублю с сайта центробанка

  1. Курсы валют будем получать отсюда https://www.cbr.ru/scripts/XML_daily.asp
  2. Напишем функцию простого парсинга cbr_get_currency для полученгия данных по USD и EUR используя библиотеку simplexml_load_file
  3. Для снижения количества обращений к cbr (вдруг забанят), сделаем кэширование в файле и будем заменять кэш, например раз в час (3600 секунд)
  4. Дайте папке где будет сохранятся кэш-файл права на создание и запись файлов
function cbr_get_currency($currency_code) 
{
    $format = 4;
    $currency_code = (isset($currency_code) && $currency_code != '') ? strtoupper($currency_code) : 'USD';
	$date = date('d/m/Y'); // Текущая дата
	$cache_time_out = '3600'; // Время жизни кэша в секундах
	$file_currency_cache = __DIR__.'/XML_daily.xml';
	if(!is_file($file_currency_cache) || filemtime($file_currency_cache) < (time() - $cache_time_out)) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, 'https://www.cbr.ru/scripts/XML_daily.asp?date_req='.$date);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
		curl_setopt($ch, CURLOPT_HEADER, 0);
		$out = curl_exec($ch);
		curl_close($ch);
		file_put_contents($file_currency_cache, $out);
	}

	$content_currency = simplexml_load_file($file_currency_cache);
	$kurs = $content_currency->xpath('Valute[CharCode="'.$currency_code.'"]')[0]->Value;
	$nominal = $content_currency->xpath('Valute[CharCode="'.$currency_code.'"]')[0]->Nominal;
	return number_format(str_replace(',', '.', $kurs), $format).' ₽ за '.$nominal.' '.$currency_code;
}

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

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

  1. Добавим меню USD - пусть будет команда /cbr или /usd или /eur
  2. Добавим кусок кода в обработку бота
		elseif (substr($text, 0, 4) == '/cbr' || substr($text, 0, 4) == '/usd' || substr($text, 0, 4) == '/eur') {
            $text_return = cbr_get_currency('USD')."\n".cbr_get_currency('EUR')."\n";
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '/cbr');
        }

2. Получим курсы криптовалют BTC/ETH

  1. Курсы валют будим получать отсюда https://coincap.io
  2. Напишем функцию простого парсинга bitcoin_get_currency для полученгия данных по BTC и ETH используя json_decode и простой перебор массива
  3. Кэширование данных добавлять не стал, можете также как в USD примере сделать, если хотите
function bitcoin_get_currency()
{
	$text_return = '';
	$currency_code = '';
	if ($currency_code == '') {
		$curl = curl_init();
		curl_setopt_array($curl, array(
		  CURLOPT_URL => 'api.coincap.io/v2/assets',
		  CURLOPT_RETURNTRANSFER => true,
		  CURLOPT_ENCODING => '',
		  CURLOPT_MAXREDIRS => 10,
		  CURLOPT_TIMEOUT => 0,
		  CURLOPT_FOLLOWLOCATION => true,
		  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
		  CURLOPT_CUSTOMREQUEST => 'GET',
		));

		$response = curl_exec($curl);
		curl_close($curl);
		$data = json_decode($response, true);
		foreach($data['data'] as $p) {
			if ($p['id'] == 'bitcoin' || $p['id'] == 'ethereum') {
				$text_return .= $p['symbol'].": ".round($p['priceUsd'])." USD\n";
			}
		}
	}
	return $text_return;
}

Сервер возвращает результаты в виде json данных, которые и обработаем найдя bitcoin и etherium.

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

  1. Добавим меню BTC - пусть будет команда /bitcoin или /btc или /eth
  2. Добавим кусок кода в обработку бота
		elseif (substr($text, 0, 8) == '/bitcoin' || substr($text, 0, 4) == '/btc' || substr($text, 0, 4) == '/eth') {
            $text_return = bitcoin_get_currency();
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '/bitcoin');
        }

И в итоге получим весь код бота:

header('Content-Type: text/html; charset=utf-8');
/**
*   Simple chat bot Novelsite.ru
*
*   + usd + bitcoin + eth informers
*   
*   Webhook:
*   https://api.telegram.org/botXXXXXXXXXX:YYYYYYYYYYYYYYYYYYYYYYYYYYYYYY/setWebhook?url=https://www.yoursite.ru/your_bot.php
*
*/

error_reporting(0);

$site_dir = dirname(dirname(__FILE__)).'/';
$bot_token = 'XXXXXXXXXX:YYYYYYYYYYYYYYYYYYYYYYYYYYYYYY';
$data = file_get_contents('php://input');
$data = json_decode($data, true);

$order_chat_id = 'MMMMMMMMM'; //manager for orders
$bot_state = '';

// last message to file
file_put_contents(__DIR__ . '/message.txt', print_r($data, true));
file_put_contents(__DIR__ . '/message_ip.txt', $_SERVER['REMOTE_ADDR']);

// buttons hack from callback_query
if (!empty($data['callback_query']['data'])) {
    $data['message']['from']['id'] = $data['callback_query']['from']['id'];
    $data['message']['from']['first_name'] = $data['callback_query']['from']['first_name'];
    $data['message']['from']['last_name'] = $data['callback_query']['from']['last_name'];
    $data['message']['text'] = $data['callback_query']['data'];
}

// message parsing
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);
    
    // send text order if need
    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' || mb_strstr($text, 'Помощь')) {
            $text_return = "$first_name $last_name, вы можете нажимать кнопки снизу или вводить команды: 
/help - список команд
/srv - список услуг
/about - о нас
/contact - контакты
/order - оставить заявку
/cbr - курсы валют
/btc - курсы криптовалют bitcoin, ethereum
/pogoda 1 - погода за 1 день

";
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '/help');
        }
        
        elseif (substr($text, 0, 4) == '/srv' || mb_strstr($text, 'Что')) {
            $ret = [];
            $num = (int)$text_array[array_key_last($text_array)];
            if ($num == 1) {
                $text_return = 
"1. Услуга 1:
--------------------------------------------------------
Описание услуги 1
";      
                $ret = [
                    ["text"=>"⬅️ Вернуться в Услуги", "callback_data"=>'/srv'],
                ];
            }
            elseif ($num == 2) {
                $text_return = 
"2. Услуга 2:
--------------------------------------------------------
Описание услуги 2
";      
                $ret = [
                    ["text"=>"⬅️ Вернуться в Услуги", "callback_data"=>'/srv'],
                ];
            }
        
            else {
                $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, 6) == '/about' || mb_strstr($text, 'Кто')) {
            $text_return = 
"О компании:
--------------------------------------------------------
О компании: ООО \"Компания\";
Адрес: Город, улица, офис;
Описание проезда
";          
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '/about');
        }
        elseif (substr($text, 0, 8) == '/contact' || mb_strstr($text, 'Контакты')) {
            $text_return = 
"Контакты компании:
--------------------------------------------------------
Телефон: +77777777777
E-mail: info@mydomain.ru
Сайт: www.mydomain.ru
Адрес: Город, улица, офис;
";          
            message_to_telegram($bot_token, $chat_id, $text_return);
        }
 
		elseif (substr($text, 0, 4) == '/cbr' || substr($text, 0, 4) == '/usd' || substr($text, 0, 4) == '/eur') {
            $text_return = cbr_get_currency('USD')."\n".cbr_get_currency('EUR')."\n";
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '/cbr');
        }
		
		elseif (substr($text, 0, 8) == '/bitcoin' || substr($text, 0, 4) == '/btc' || substr($text, 0, 4) == '/eth') {
            $text_return = bitcoin_get_currency();
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '/bitcoin');
        }

        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 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; // ваш API погоды!
            $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);
        }

        
        elseif (substr($text, 0, 6) == '/order' || mb_strstr($text, "Заявка")) {
            $ret = [];
            $num = (int)$text_array[array_key_last($text_array)];
            $text_return = 
    "$first_name $last_name, для подтверждения Заявки введите текст вашей заявки и нажмите отправьте его боту. 
    Наши специалисты свяжутся с вами в ближайшее время!
    ";
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '/order '.$num);
        }
        elseif (!mb_strstr($text, 'Заявка от')) {
            $text_return = "Привет, $first_name $last_name!
Я бот компании. 
С помощью меня вы можете узнать о нас, услугах
/help - список команд
";
            message_to_telegram($bot_token, $chat_id, $text_return);
            set_bot_state ($chat_id, '');
        }
        
    }

}

// return answer to callback_query
if (!empty($data['callback_query']['data'])) {
   $callback_query_id = $data['callback_query']['id'];
   file_get_contents("https://api.telegram.org/bot".$bot_token."/answerCallbackQuery?callback_query_id=".$callback_query_id."&text=");
}


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'];
        $btn[] = ["text"=>"USD", "callback_data"=>'/cbr'];
		$btn[] = ["text"=>"BTC", "callback_data"=>'/bitcoin'];
        $btn[] = ["text"=>"Погода", "callback_data"=>'/pogoda'];
        $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 photo_to_telegram($bot_token, $chat_id, $text, $photo_url)
{
    $ch = curl_init();
    $ch_post = [
        CURLOPT_URL => 'https://api.telegram.org/bot' . $bot_token . '/sendPhoto',
        CURLOPT_POST => TRUE,
        CURLOPT_RETURNTRANSFER => TRUE,
        CURLOPT_TIMEOUT => 10,
        CURLOPT_HTTPHEADER => ["Content-Type:multipart/form-data"],
        CURLOPT_POSTFIELDS => [
            'chat_id' => $chat_id,
            'photo' => new CURLFile(realpath($photo_url)),
            'caption' => $text,
        ]
    ];

    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 '';
    }
}



if (! function_exists("array_key_last")) {
    function array_key_last($array) {
        if (!is_array($array) || empty($array)) {
            return NULL;
        }
         
        return array_keys($array)[count($array)-1];
    }
}

function cbr_get_currency($currency_code) 
{
    $format = 4;
    $currency_code = (isset($currency_code) && $currency_code != '') ? strtoupper($currency_code) : 'USD';
	$date = date('d/m/Y'); // Текущая дата
	$cache_time_out = '3600'; // Время жизни кэша в секундах
	$file_currency_cache = __DIR__.'/XML_daily.xml';
	if(!is_file($file_currency_cache) || filemtime($file_currency_cache) < (time() - $cache_time_out)) {
		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL, 'https://www.cbr.ru/scripts/XML_daily.asp?date_req='.$date);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
		curl_setopt($ch, CURLOPT_HEADER, 0);
		$out = curl_exec($ch);
		curl_close($ch);
		file_put_contents($file_currency_cache, $out);
	}

	$content_currency = simplexml_load_file($file_currency_cache);
	$kurs = $content_currency->xpath('Valute[CharCode="'.$currency_code.'"]')[0]->Value;
	$nominal = $content_currency->xpath('Valute[CharCode="'.$currency_code.'"]')[0]->Nominal;
	
	return number_format(str_replace(',', '.', $kurs), $format).' ₽ за '.$nominal.' '.$currency_code;
}


function bitcoin_get_currency()
{
	$text_return = '';
	$currency_code = '';
	
	if ($currency_code == '') {
		$curl = curl_init();
		curl_setopt_array($curl, array(
		  CURLOPT_URL => 'api.coincap.io/v2/assets',
		  CURLOPT_RETURNTRANSFER => true,
		  CURLOPT_ENCODING => '',
		  CURLOPT_MAXREDIRS => 10,
		  CURLOPT_TIMEOUT => 0,
		  CURLOPT_FOLLOWLOCATION => true,
		  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
		  CURLOPT_CUSTOMREQUEST => 'GET',
		));

		$response = curl_exec($curl);
		curl_close($curl);
		
		$data = json_decode($response, true);
		
		foreach($data['data'] as $p) {
			if ($p['id'] == 'bitcoin' || $p['id'] == 'ethereum') {
				$text_return .= $p['symbol'].": ".round($p['priceUsd'])." USD\n";
			}
		}	
	}
	return $text_return;
}

P.S. Данный пример содержит работающий код бота на PHP, который может выдавать меню, показывать информацию по меню, есть подменю в разделе услуги, есть возможность отослать заявку менеджеру, и информеры: погода, валюты, криптовалюты. Для текста в кнопках меню бота и в выводах результатов можно использовать Эмодзи.

 


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


Смотрите также: Кейсы интернет-рекламы


620026, Россия, Свердловская область, Екатеринубрг, ул. Энгельса 36, оф. 640
Телефон: +7 (343) 221-00-40
Почта: info@novelsite.ru
Продолжая использовать наш сайт, вы даете согласие на обработку файлов cookie и пользовательских персональных данных.

Я принимаю

Заполните Бриф на расчет интернет-рекламы

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

ОТПРАВИТЬ ЗАПРОС НА РАССЧЕТ — Нажимая на кнопку "ОТПРАВИТЬ ЗАПРОС", я даю согласие на обработку персональных данных

Заявка успешно отправлена!

Спасибо, что обратилиcь в нашу компанию!

Наши специалисты обработают заявку в течении нескольких рабочих дней. Скорее всего, нам потребуется с вами пообщаться по телефону для уточнения деталей рекламной кампании для вас, поэтому постарайтесь быть на связи.

Закрыть

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

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