Легенда о 386 строчках PHP

24.11.2017

Для создания своего бота для инвестиций необходимо следующее:

  1. Сервер с SSL (для работы бота)
  2. Аккаунт на block.io
  3. Прямые руки

А теперь обо всем по порядку.

Бот в Telegram

Необходимо получить токен для работы с ботом — для этого идем за помощью к https://t.me/BotFather и получаем заветный токен.  Дальше установим WebHook для обработки сообщений боте с помощью команды
https://api.telegram.org/bot<токен>/setWebhook?url=<путь к файлу bot.php>

А дальше необходимо писать код на php

block.io

Сервис https://block.io дает доступ к API для работы с сетью Bitcoin — создание новых адресов, проверка баланса на кошельке и перевод между кошельками. Большим плюсом данного сервиса можно отнести возможно работать в тестовой сети Bitcoin — то есть без какого либо опасения можно использовать биткоины в экспериментальных целях!

При регистрации мы получаем API KEY к различным сетям, а так же секретный пин для выполнения некоторых операция.

block.io

Получить биткоины для тестовой сети можно по этой ссылке — просто указываем адрес и получаем!

Для функционирования бота нам необходимо три процедуры из API block.io

В зависимости от указанного API KEY будет работать с разными сетями — тестовой или нет, биткоин или лайткоин и так далее.

bot.php

Файл bot.php будет взаимодействовать с Telegram — анализировать входящую команду и отвечать пользователю.

    $botToken = "BOT TOKEN";
    $website = "https://api.telegram.org/bot".$botToken;
 
    $content = file_get_contents("php://input");
    $update = json_decode($content, TRUE);

в строчке 3 происходит получение данных от бота, а следующая строка преобразует полученные данные в формат JSON.

	$text = getTextFromMessage($update);
	$chatId = getChatIDFromMessage($update);
 
	$pos = strpos($text, "_");
	if($pos == 0){
		$command = $text;
		$parametrs = "";			
	} else {
		$command = substr($text, 0, $pos);
		$parametrs = substr($text, $pos + 1, strlen($text)-$pos);			
	}

в переменную $text и из входящего JSON получим текст сообщения, а в $chatId — идентификатор чата, он необходимо для отправки сообщения от бота. Далее $text разбивается на две переменные $commad и $parametrs — это необходимо для работы с командой set (/set_2N7ahJZx81we7PAwxdk8tb3apTruXdgsvGT).

И теперь необходимо добавить клавиатуру на экран с командами Баланс, Пополнить и Вывести:

	$button1 = array("text"=&gt;"Баланс", "callback_data"=&gt;"/balance");
	$button2 = array("text"=&gt;"Пополнить", "callback_data"=&gt;"/invest");
	$button4 = array("text"=&gt;"Вывести", "callback_data"=&gt;"/withdraw");
 
	$keyboard = array(array($button1, $button2, $button4));
	$resp = array("keyboard" =&gt; $keyboard,"resize_keyboard" =&gt; true,"one_time_keyboard" =&gt; true);
	$reply = json_encode($resp);

переменная $reply будет содержать JSON с кнопками клавиатуры.

Теперь разберемся я командами бота — они будут следующми
/start — приветственное сообщение и старт работа
/set — установка адреса кошелька для вывода средств
Баланс — вывод сообщения с балансом пользователя
Пополнить — вывод сообщения с адрес, куда необходимо перечислить BTC для начала работы (После этого будет две команда Сделано (проверит были ли переведены средства) и Отмена (если мы не хотим пополнять наш счет/депозит)
Вывести — просто выводим то, что «заработали».

telegram.php

Содержит в себе процедуры для взаимодействия с ботом — выделение текста сообщения, идентификатора чата, а так же отправка сообщения.

	function getTextFromMessage($update) {
 
		$text = "";
		if(isset($update["callback_query"])){
			//$text = $update["callback_query"]["data"];
			$text = $update["callback_query"]["message"]["text"];
		}else{
			$text = $update["message"]["text"];
		}		
		return $text;
	}
 
	function getChatIDFromMessage($update) {
 
		$chatId = "";
		if(isset($update["callback_query"])){
			$chatId = $update["callback_query"]["message"]["chat"]["id"];
		}else {
			$chatId = $update["message"]["chat"]["id"];
		}		
		return $chatId;		
 
	}
 
	function sendMessage($website, $chatID, $message) {
 
		file_get_contents($website."/sendmessage?chat_id=".$chatID."&amp;text=".urlencode($message));		
 
	}
 
	function sendMessageWithKeyboard($website, $chatID, $message, $reply) {
 
		file_get_contents($website."/sendmessage?chat_id=".$chatID."&amp;text=".urlencode($message)."&amp;reply_markup=".$reply);
 
	}

getTextFromMessage и getChatIDFromMessage — выделяют нужные объекты для работы
sendMessage — просто отравляет сообщение пользователю
sendMessageWithKeyboard — отправляет сообщение пользователя и выводит кнопки клавиатуры (см. вышел переменная $reply)

btc.php

Основной файл с логикой работы всего бота.

В начале файла добавлена процедура с параметрами подключения к базе MySQL

	function getConnect() {
 
		$link = mysqli_connect( 
			'localhost', 	 				/* Хост, к которому мы подключаемся */ 
			'USER',     	  				/* Имя пользователя */ 
			'PASSWORD', 		  	        /* Используемый пароль */ 
			'SQLDB');       				/* База данных для запросов по умолчанию */ 
 
		return $link;
 
	}

Так же стоит забывать, что мы будем использовать базу MySQL всего лишь с одной таблицей

CREATE TABLE IF NOT EXISTS `users` (
  `id` INT(11) NOT NULL,
  `gramid` VARCHAR(32) NOT NULL,
  `btc` VARCHAR(64) NOT NULL,
  `deposit` DOUBLE NOT NULL,
  `amount` DOUBLE NOT NULL,
  `outbtc` VARCHAR(64) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

id — порядковый номер в таблице
gramid — идентификатор чата с пользователем
btc — адрес, который будет создан для пользователя. Отдельный адрес кошелька для каждого пользователя позволит проще отслеживать поступление средств на кошелек
deposit — сумма депозита
amount — сумма «заработанных» средств
outbtc — адрес, на который мы будем выводить средства.

Добавление нового пользователя

	function addUser($userID) {
 
		$apikey = "APIKEY";
 
		$link = getConnect();
 
		if (!$link) { 
		   return "Ошибка при работе с БД";
		}			
 
		$QUERY = "SELECT id FROM users WHERE gramid='$userID'";
		$result = mysqli_query($link, $QUERY);
		$num = mysqli_num_rows($result);		
		mysqli_free_result($result); 
 
		if($num == 0) {
 
			$url = "https://block.io/api/v2/get_new_address/?api_key=".$apikey;
			$resultData = http_request(0, $url, 0, 0);
			$address = $resultData['data']['address'];
 
			// user not found - add in DB 
			$QUERY = "INSERT INTO users(gramid, btc, deposit, amount, outbtc) VALUES('$userID', '$address', 0, 0, '')";
			mysqli_query($link, $QUERY);
 
		}
		mysqli_close($link);
 
		return "Привет! Я твой инвестиционный бот в Telegram и готов начислять тебе по 0.5% в день от твоего депозита! \xF0\x9F\x92\xB0\nНе забудь указать адрес своего кошелька для вывода с помощью команды /set_адрес";
	}

Функция на входе получает идентификатор чата и проверяет если ли уже идентификатор чата в базе. Если он отсутствует, то генерируем новый адрес и добавляем в базу.

Добавление адреса пользователя

	function addAddress($userID, $outbtc) {
 
		$link = getConnect();
 
		if (!$link) { 
		   return "Ошибка при работе с БД";
		}			
 
		$QUERY = "UPDATE users SET outbtc = '$outbtc' WHERE gramid='$userID'";
		mysqli_query($link, $QUERY);
 
		mysqli_close($link);
 
		return "Адрес кошелька BTC успешно добавлен!";
	}

При отправке боту команду /set — просто добавляем адрес в базу.

Сообщение с балансом пользователя

	function getBalance($userID) {
 
		$link = getConnect();
 
		if (!$link) { 
		   return "Ошибка при работе с БД";
		}			
 
		$QUERY = "SELECT deposit, amount FROM users WHERE gramid='$userID'";
		$result = mysqli_query($link, $QUERY);
 
		$row = mysqli_fetch_row($result);
		$deposit = $row[0];
		$amount = $row[1];	
 
		$message = "Баланс\xF0\x9F\x92\xB0\nДепозит: ".$deposit." BTC\nВаш баланс: ".$amount." BTC";
 
		mysqli_query($link, $QUERY);
		mysqli_close($link);
 
		return $message;
	}

Получаем из базы сумму депозита и баланс пользователя.

Вывод сообщения с адресом, куда необходимо направить средства

	function getInvest($userID) {
 
		$link = getConnect();
 
		if (!$link) { 
		   return "Ошибка при работе с БД";
		}			
 
		$QUERY = "SELECT btc FROM users WHERE gramid='$userID'";
		$result = mysqli_query($link, $QUERY);
 
		$row = mysqli_fetch_row($result);
		$btc = $row[0];			
 
		$message = "Данные для инвестиции\nАдрес:\n".$btc."\nКоличество 0.001 BTC";
 
		mysqli_query($link, $QUERY);
		mysqli_close($link);		
 
		return $message;
	}

Функция показывает пользователю тот самый сгенерированный адрес для отправки средств.

Вывод средств

	function withdraw($userID) {
 
		$apikey = "APIKEY";
		$secretpin = "SECREPIN";
		$from = "ADDR_FROM";		
 
		$link = getConnect();
 
		if (!$link) { 
		   return "Ошибка при работе с БД";
		}			
 
		$QUERY = "SELECT amount, outbtc FROM users WHERE gramid='$userID'";
		$result = mysqli_query($link, $QUERY);
 
		$row = mysqli_fetch_row($result);
		$amount = $row[0];
		$to = $row[1];
 
		if($amount &lt; 0.001) {
 
			$message = "Минимальная сумма для вывода 0.001 BTC!\nУ вас на балансе ".$amount." BTC";
 
		} else {
			$url = "https://block.io/api/v2/withdraw_from_addresses/?api_key=".$apikey."&amp;from_addresses=".$from."&amp;to_addresses=".$to."&amp;amounts=".$amount."&amp;pin=".$secretpin;
			$resultData = http_request(0, $url, 0, 0);
 
			$message = "Вывод ".$amount." BTC выполнен!";
 
			$QUERY = "UPDATE users SET amount = 0 WHERE gramid='$userID'";
			mysqli_query($link, $QUERY);
 
		}
 
		mysqli_close($link);
 
		return $message;
 
	}

Функция проверяет баланс пользователя и если он соответствует минимальным требованиям, тогда выполняется перевод средств.

Проверка перевода средств

	function checkInvest($userID) {
 
		$apikey = "APIKEY";
 
		$link = getConnect();
 
		if (!$link) { 
		   return "Ошибка при работе с БД";
		}
 
		$QUERY = "SELECT btc, deposit FROM users WHERE gramid='$userID'";
		$result = mysqli_query($link, $QUERY);
 
		$row = mysqli_fetch_row($result);
		$btc = $row[0];
		$deposit = $row[1];		
 
		$url = "https://block.io/api/v2/get_address_balance/?api_key=".$apikey."&amp;addresses=".$btc;
		$resultData = http_request(0, $url, 0, 0);
 
		$data = $resultData['data']['balances'][0];
 
		$btc_address = ($data['pending_received_balance'] + $data['available_balance']) - $deposit;
 
		if ($btc_address &gt;= 0.001) {
			$message = "200";
 
			$deposit_new = $deposit + 0.001;
			$QUERY = "UPDATE users SET deposit = $deposit_new WHERE gramid='$userID'";
			mysqli_query($link, $QUERY);			
 
		} else {
			$message = "404";
		}
 
		return $message;
	}

Данная функция отрабатывает после перевода средств. Если возвращается код 200 — значит перевод средств был выполнен, а если 404 — перевод не найден.

Начисление «процентов»

	function growAmount() {
 
		$link = getConnect();
 
		if (!$link) { 
		   return "Ошибка при работе с БД";
		}
 
		$QUERY = "SELECT gramid, deposit, amount FROM users WHERE deposit &gt; 0";
		$result = mysqli_query($link, $QUERY);
 
		while($row = mysqli_fetch_row($result)){
 
			$userID = $row[0];
			$deposit = $row[1];
			$amount = $row[2];
 
			$new_amount = $deposit * 0.005 + $amount;
 
			$QUERY = "UPDATE users SET amount = $new_amount WHERE gramid='$userID'";
			mysqli_query($link, $QUERY);
 
			$new = number_format($deposit * 0.005, 8, '.', '');
			$message = "Вы получили ".$new." BTC! Спасибо вам \xF0\x9F\x92\x9E";
			$botToken = "BOT TOKEN";
			$website = "https://api.telegram.org/bot".$botToken;
			$button1 = array("text"=&gt;"Баланс", "callback_data"=&gt;"/balance");
			$button2 = array("text"=&gt;"Пополнить", "callback_data"=&gt;"/invest");
			$button4 = array("text"=&gt;"Вывести", "callback_data"=&gt;"/withdraw");			
			$keyboard = array(array($button1, $button2, $button4));
			$resp = array("keyboard" =&gt; $keyboard,"resize_keyboard" =&gt; true,"one_time_keyboard" =&gt; true);
			$reply = json_encode($resp);				
			sendMessageWithKeyboard($website, $userID, $message, $reply);
		}
 
	}

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

Хочу такого же бота!!!

Исходники бота можно купить по частям — bot.php и telegram.php и btc.php.

НО!

Внимание! Информация представлена исключительно с целью ознакомления! Автор за твои действия ответственности не несет!

Tittygram