Информер USD/EUR и криптовалют BTC/ETH в Телеграм бот PHP
09.01.2023 👁 2309
В продолжении предыдущих статей:
- Информер погоды в Телеграм-боте на PHP
- Добавляем пункты меню в Телеграм бота на PHP
- Как создать простого бота для Телеграм на 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 к рублю с сайта центробанка
- Курсы валют будем получать отсюда https://www.cbr.ru/scripts/XML_daily.asp
- Напишем функцию простого парсинга cbr_get_currency для полученгия данных по USD и EUR используя библиотеку simplexml_load_file
- Для снижения количества обращений к cbr (вдруг забанят), сделаем кэширование в файле и будем заменять кэш, например раз в час (3600 секунд)
- Дайте папке где будет сохранятся кэш-файл права на создание и запись файлов
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-данных.
Теперь перепишем бота
- Добавим меню USD - пусть будет команда /cbr или /usd или /eur
- Добавим кусок кода в обработку бота
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
- Курсы валют будим получать отсюда https://coincap.io
- Напишем функцию простого парсинга bitcoin_get_currency для полученгия данных по BTC и ETH используя json_decode и простой перебор массива
- Кэширование данных добавлять не стал, можете также как в 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.
Теперь перепишем бота
- Добавим меню BTC - пусть будет команда /bitcoin или /btc или /eth
- Добавим кусок кода в обработку бота
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;
}
-
Скачать данный пример: bot_usd_btc.zip (3.8 kb)
P.S. Данный пример содержит работающий код бота на PHP, который может выдавать меню, показывать информацию по меню, есть подменю в разделе услуги, есть возможность отослать заявку менеджеру, и информеры: погода, валюты, криптовалюты. Для текста в кнопках меню бота и в выводах результатов можно использовать Эмодзи.
Николай Комарков