Last active
August 29, 2015 14:26
-
-
Save believer-ufa/c1189dfbedb63a90ebfd to your computer and use it in GitHub Desktop.
Telegram bot example on Laravel
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php namespace QuranOnline\Http\Controllers; | |
use Curl\Curl; | |
use DB; | |
use Log; | |
use QuranOnline\Models\Telegram\User; | |
use QuranOnline\Services\TelegramQuranBot; | |
class Telegram extends Controller { | |
private $quran_bot; /* @var $this->quran_bot QuranOnline\Services\TelegramQuranBot */ | |
private $request; | |
function __construct(TelegramQuranBot $bot_service) | |
{ | |
parent::__construct(); | |
$this->quran_bot = $bot_service; | |
} | |
/** | |
* Функция используется для отладки, позволяет скинуть текущий объект запроса в лог-файл | |
*/ | |
function dumpRequest() | |
{ | |
ob_start(); | |
var_dump($this->request); | |
$debug_out = ob_get_contents(); | |
ob_end_clean(); | |
Log::debug($debug_out); | |
} | |
function QuranOnlineBot() | |
{ | |
$this->request = json_decode(file_get_contents('php://input')); | |
$this->user = User::where('telegram_id',$this->request->message->from->id)->first(); | |
if (is_null($this->user)) | |
{ | |
$this->user = new User([ | |
'telegram_id' => $this->request->message->from->id, | |
'name' => property_exists($this->request->message->from, 'first_name') ? $this->request->message->from->first_name : null, | |
'family' => property_exists($this->request->message->from, 'last_name') ? $this->request->message->from->last_name : null, | |
'nick' => property_exists($this->request->message->from, 'username') ? $this->request->message->from->username : null, | |
]); | |
$this->user->save(); | |
} | |
//$this->dumpRequest(); | |
$this->processMessage( | |
$this->quran_bot->processCommand($this->request, $this->user) | |
); | |
return 'thanks!'; | |
} | |
private function processMessage($answer) | |
{ | |
if ($answer) | |
{ | |
$curl = new Curl(); | |
$params = [ | |
'chat_id' => $this->request->message->chat->id, | |
'disable_web_page_preview' => true, | |
]; | |
if (is_array($answer)) { | |
$params = array_merge($params, $answer); | |
} else { | |
$params['text'] = $answer; | |
} | |
if (property_exists($this->request->message, 'text') AND $params['text']) | |
{ | |
DB::table('telegram_messaging_history')->insert([ | |
'user_id' => $this->user->id, | |
'question' => $this->request->message->text, | |
'answer' => $params['text'], | |
]); | |
} | |
$curl->get('https://api.telegram.org/bot123928604:AAFy6JsOgnjPGp615TnQhbJenz4f82r2UCY/sendMessage', $params); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace QuranOnline\Services; | |
use QuranOnline\Helpers\Text; | |
use QuranOnline\Models\Quran\Ayat; | |
use QuranOnline\Models\Quran\Sura; | |
/** | |
* Класс работы бота для программы "Телеграмм" | |
*/ | |
class TelegramQuranBot { | |
private $request; | |
private $user; /* @var $this->user \QuranOnline\Models\Telegram\User */ | |
function processCommand($request, $user) | |
{ | |
$this->request = $request; | |
$this->user = $user; | |
if (! property_exists($this->request->message, 'text')) { | |
return ''; | |
} | |
$first_word = explode(' ',$this->request->message->text)[0]; | |
switch ($first_word) | |
{ | |
case '/start': | |
case (preg_match('/^(привет|здорова|хай|здравствуй).*$/iu', $first_word) ? true : false): | |
return $this->commandHelloJahil(); | |
case '/start': | |
case (preg_match('/^.*(салям|салам).*$/iu', $first_word) ? true : false): | |
return $this->commandHelloMuslim(); | |
case '/help': | |
return $this->commandHelp(); | |
case '/search': | |
case 'искать': | |
case 'Искать': | |
case 'найти': | |
case 'Найти': | |
case 'поиск': | |
case 'Поиск': | |
return $this->commandSearch(); | |
// case '/settings': | |
// case 'настройки': | |
// return $this->commandSettings(); | |
case '/ayat': | |
case 'аят': | |
case 'Аят': | |
return $this->commandAyat(); | |
case '/sura': | |
case 'сура': | |
case 'Сура': | |
return $this->commandSura(); | |
case 'Завершить': | |
case 'завершить': | |
case 'Отмена': | |
case 'отмена': | |
case '/cancel': | |
return $this->cancelOperations(); | |
case 'далее': | |
case 'Далее': | |
case '/next': | |
case '>': | |
return $this->nextOperation(); | |
case 'назад': | |
case 'Назад': | |
case '/previous': | |
case '<': | |
return $this->previousOperation(); | |
default: | |
return 'Прошу прощения, но я не понял, что вам от меня нужно. Пожалуйста, постарайтесь уточнить ваш запрос.'; | |
} | |
} | |
private function commandHelloJahil() | |
{ | |
return "Добрый день, {$this->user->name}!\n\nНа данный момент, с моей помощью вы можете искать аяты в Священном Коране, а также получать текст нужного аята." | |
. "\n\nЧтобы что-то найти, просто напишите мне что-нибудь вроде \"найти Мухаммад\", и я найду все аяты в Священном Коране, в которых упоминается слово \"Мухаммад\"." | |
. "\n\nЧтобы прочитать текст нужного аята, напишите мне \"аят 1 2\" (или \"/ayat 1 2\", если бот в группе), и я найду текст второго аята первой суры." | |
. "\n\nВот так всё просто :) Всего хорошего вам, и пусть Аллах покроет вас Своей милостью :)"; | |
} | |
private function commandHelloMuslim() | |
{ | |
return "Уа алейкум ассаламу уа рахматуллахи уа баракятух, {$this->user->name}!\n\nНа данный момент, с моей помощью вы можете искать аяты в Священном Коране, а также получать текст нужного аята." | |
. "\n\nЧтобы что-то найти, просто напишите мне что-нибудь вроде \"найти Мухаммад\", и я найду все аяты в Священном Коране, в которых упоминается слово \"Мухаммад\"." | |
. "\n\nЧтобы прочитать текст нужного аята, напишите мне \"аят 1 2\" (или \"/ayat 1 2\", если бот в группе), и я найду текст второго аята первой суры." | |
. "\n\nВот так всё просто :) Всего хорошего вам, и пусть Аллах покроет вас Своей милостью :)"; | |
} | |
private function commandHelp() | |
{ | |
return 'Ас-саляму алейкум! Данный бот может помочь вам изучить Священный Коран.'; | |
} | |
private function commandSearch() | |
{ | |
$search_query = explode(' ', $this->request->message->text); | |
if (count($search_query) > 1) | |
{ | |
unset($search_query[0]); | |
$search = implode(' ', $search_query); | |
$ayats = $this->searchInQuran($search); | |
if ($ayats->count()) | |
{ | |
$this->user->state = 'search'; | |
$this->user->search = $search; | |
$this->user->search_num = 0; | |
$this->user->save(); | |
return $this->navigationReply( | |
'Мне удалось найти ' . Text::chislitelnie($ayats->count(), [ 'вхождение', 'вхождения', 'вхождений' ]) . ' по данному запросу.' | |
. "\n\nПосмотреть результаты поиска в более удобном виде вы всегда можете по данному адресу: quran-online.ru/search?search=".urlencode($search) | |
. ", а сейчас - первый результат в поиске: " . $this->showFindedAyat($ayats->first(), $search) | |
//. "\n\n Переключайтесь между результатами поиска: /next, /previous, /cancel" | |
. "\n\nПереключайтесь между результатами поиска: \n/next - следующий\n/previous - предыдущий\n/cancel - завершить поиск" | |
); | |
} else { | |
return 'Прошу прощения, но по данному запросу я ничего не нашел в Священном Коране, ни в одном из переводов :('; | |
} | |
} | |
else | |
{ | |
return 'Вы можете воспользоваться функцией поиска по Священному Корану. ' | |
. 'Чтобы сделать это, введите команду: "найти [слово или словосочетание]" (или "/search слово", если бот в группе), ' | |
. 'и я найду для вас аяты, содержащие указанное слово.'; | |
} | |
} | |
private function commandSura() | |
{ | |
$search_query = explode(' ', $this->request->message->text); | |
if (count($search_query) > 1) | |
{ | |
unset($search_query[0]); | |
$search = implode(' ', $search_query); | |
if (is_numeric($search)) | |
{ | |
$sura = Sura::findOrNew($search); | |
} | |
else | |
{ | |
$sura = Sura::where('name','like',"%{$search}%")->orWhere('translit','like',"%{$search}%")->first(); | |
} | |
if ($sura AND $sura->exists) | |
{ | |
$ayat_texts = $this->showAyatTexts($sura->id, 1); | |
$ayat_texts .= "\n\nНавигация по аятам суры: \n/next - следующий\n/previous - предыдущий\n/cancel - завершить чтение"; | |
$this->user->state = 'quran'; | |
$this->user->sura = $sura->id; | |
$this->user->ayat = 1; | |
$this->user->save(); | |
return $this->navigationReply($ayat_texts); | |
} | |
else | |
{ | |
return 'К сожалению, я не нашел указанную вами суру в Священном Коране.'; | |
} | |
} | |
else | |
{ | |
return 'Вы можете попросить меня показать вам текст первого аята нужной суры.' | |
. ' Чтобы сделать это, просто введите фразу "сура бакара" (или "/sura бакара", если бот в группе), и я верну вам текст первого аята данной суры.'; | |
} | |
} | |
private function commandAyat() | |
{ | |
$search_query = explode(' ', $this->request->message->text); | |
if (count($search_query) === 3) | |
{ | |
if (!is_numeric($search_query[1]) OR !is_numeric($search_query[2])) | |
{ | |
return 'Пожалуйста, при указании аята, используйте числовые значения для номера суры и номера аята.'; | |
} | |
if ($search_query[1] < 1 OR $search_query[1] > 114) | |
{ | |
return 'Номер суры должен быть в промежутке от 1 до 114.'; | |
} | |
if ($search_query[2] > Sura::maxAyat($search_query[1])) | |
{ | |
return 'Указанная вами сура не имеет такого аята'; | |
} | |
$ayat_texts = $this->showAyatTexts($search_query[1], $search_query[2]); | |
$ayat_texts .= "\n\nНавигация по аятам суры: \n/next - следующий\n/previous - предыдущий\n/cancel - завершить чтение"; | |
$this->user->state = 'quran'; | |
$this->user->sura = $search_query[1]; | |
$this->user->ayat = $search_query[2]; | |
$this->user->save(); | |
return $this->navigationReply($ayat_texts); | |
} | |
else | |
{ | |
return 'Вы можете попросить меня показать вам текст нужного аята.' | |
. ' Чтобы сделать это, просто введите фразу "аят 14 10" (или "/ayat 14 10", если бот в группе), и я верну вам текст десятого аята четырнадцатой суры.'; | |
} | |
} | |
private function cancelOperations() | |
{ | |
switch ($this->user->state) | |
{ | |
case 'search': | |
$this->user->state = null; | |
$this->user->search = null; | |
$this->user->search_num = null; | |
$this->user->save(); | |
return 'Режим поиска по аятам был отключён.'; | |
case 'quran': | |
$this->user->state = null; | |
$this->user->sura = null; | |
$this->user->ayat = null; | |
$this->user->save(); | |
return 'Режим чтения Корана был отключён.'; | |
default: | |
return 'В данный момент у вас нет активных операций, поэтому и завершать вам нечего :)'; | |
} | |
} | |
private function nextOperation() | |
{ | |
switch ($this->user->state) | |
{ | |
case 'search': | |
$search_results = $this->searchInQuran($this->user->search); | |
$search_results_count = $search_results->count(); | |
if ($this->user->search_num < ($search_results_count-1)) | |
{ | |
$this->user->search_num = $this->user->search_num + 1; | |
$this->user->save(); | |
$human_num = $this->user->search_num + 1; | |
$ayat = $search_results->skip($this->user->search_num)->take(1)->first(); | |
$text = "Результат поиска №{$human_num} из {$search_results_count}:"; | |
$text .= $this->showFindedAyat($ayat, $this->user->search); | |
$text .= "\n\nНавигация: /next /previous /cancel"; | |
return $this->navigationReply($text); | |
} else { | |
return 'Данный аят - последний в списке найденных аятов по данному запросу.'; | |
} | |
case 'quran': | |
if ($this->user->ayat < (Sura::maxAyat($this->user->sura))) | |
{ | |
$this->user->ayat = $this->user->ayat + 1; | |
$this->user->save(); | |
$ayat_texts = $this->showAyatTexts($this->user->sura, $this->user->ayat); | |
$ayat_texts .= "\n\nНавигация: /next /previous /cancel"; | |
return $this->navigationReply($ayat_texts); | |
} else { | |
return 'Данный аят последний в этой суре.'; | |
} | |
default: | |
return 'В данный момент у вас нет активных операций, поэтому операция "далее" бессмысленна.'; | |
} | |
} | |
private function previousOperation() | |
{ | |
switch ($this->user->state) | |
{ | |
case 'search': | |
$search_results = $this->searchInQuran($this->user->search); | |
$search_results_count = $search_results->count(); | |
if ($this->user->search_num > 0) | |
{ | |
$this->user->search_num = $this->user->search_num - 1; | |
$this->user->save(); | |
$human_num = $this->user->search_num + 1; | |
$ayat = $search_results->skip($this->user->search_num)->take(1)->first(); | |
$text = "Результат поиска №{$human_num} из {$search_results_count}:"; | |
$text .= $this->showFindedAyat($ayat, $this->user->search); | |
$text .= "\n\nНавигация: /next /previous /cancel"; | |
return $this->navigationReply($text); | |
} else { | |
return 'Данный аят - первый в списке найденных аятов по данному запросу.'; | |
} | |
case 'quran': | |
if ($this->user->ayat > 1) | |
{ | |
$this->user->ayat = $this->user->ayat - 1; | |
$this->user->save(); | |
$ayat_texts = $this->showAyatTexts($this->user->sura, $this->user->ayat); | |
$ayat_texts .= "\n\nНавигация: /next /previous /cancel"; | |
return $this->navigationReply($ayat_texts); | |
} else { | |
return 'Это первый аят данной суры.'; | |
} | |
default: | |
return 'В данный момент у вас нет активных операций, поэтому операция "назад" бессмысленна.'; | |
} | |
} | |
private function commandSettings() | |
{ | |
switch ($this->user->state) | |
{ | |
case 'search': | |
return 'В данный момент модуль поиска не имеет настроек.'; | |
case 'quran': | |
if ($this->user->ayat > 1) | |
{ | |
$this->user->ayat = $this->user->ayat - 1; | |
$this->user->save(); | |
$ayat_texts = $this->showAyatTexts($this->user->sura, $this->user->ayat); | |
$ayat_texts .= "\n\nНавигация: /next /previous /cancel"; | |
return $this->navigationReply($ayat_texts); | |
} else { | |
return [ | |
'text' => 'Настройте режимы отображения текстов аятов. Какой перевод вам следует отключить или включить?', | |
]; | |
} | |
default: | |
return 'Чтобы настроить какой-либо из режимов работы бота, сначала войдите в него.'; | |
} | |
} | |
private function searchInQuran($search) | |
{ | |
$ayats = Ayat | |
::where('text','LIKE',"%{$search}%") | |
->where('translate.enabled',1) | |
->where('translate.big_translate',0) | |
->join('quran_translates as translate','translate.id','=','quran_ayats.translate_id') | |
->orderBy('quran_ayats.translate_id') | |
->orderBy('quran_ayats.sura') | |
->orderBy('quran_ayats.ayat'); | |
return $ayats; | |
} | |
private function showFindedAyat($ayat, $search) | |
{ | |
$text = "\n\nАят quran-online.ru/{$ayat->sura}:{$ayat->ayat} ({$ayat->translate->name}):\n\n"; | |
$text .= preg_replace("/({$search})/ius", "*$1*", strip_tags($ayat->text)); | |
return $text; | |
} | |
private function showAyatTexts($sura, $ayat) | |
{ | |
$ayats = Ayat::where('sura', $sura) | |
->where('ayat', $ayat) | |
->join('quran_translates','quran_ayats.translate_id','=','quran_translates.id') | |
->where('quran_translates.enabled','=',true) | |
//->where('quran_translates.id','!=',2) | |
->orderBy('quran_translates.id') | |
->get(); | |
$text = ''; | |
if ($ayats->count() > 0) { | |
$text = "Сура {$ayats[0]->ssura->name}, аят quran-online.ru/{$ayats[0]->sura}:{$ayats[0]->ayat}\n\n"; | |
foreach($ayats as $ayat) { | |
$text .= "{$ayat->translate->name}: "; | |
$text .= str_limit(trim(html_entity_decode(strip_tags($ayat->text))),800, '... (текст обрезан из-за большой длины, полная версия доступна на сайте)'); | |
$text .= "\n\n"; | |
} | |
} | |
return $text; | |
} | |
private function navigationReply($answer) | |
{ | |
return [ | |
'text' => $answer, | |
'reply_markup' => json_encode([ | |
'keyboard' => | |
false, | |
//[ [ '<', '>', 'Отмена' ] ], | |
//'one_time_keyboard' => true, | |
//'hide_keyboard' => true, | |
'selective' => true, | |
]) | |
]; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Данный роут принимает обновления от бота в Телеграме | |
Route::post('telegram-updates/[secret-code]', 'Telegram@QuranOnlineBot'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment