Тут показані розбіжності між вибраною ревізією та поточною версією сторінки.
Порівняння попередніх версій Попередня ревізія | Попередня ревізія | ||
wolfdispatcher [2020/06/27 02:40] |
wolfdispatcher [2023/11/16 13:08] (поточний) nightfly |
||
---|---|---|---|
Рядок 1: | Рядок 1: | ||
+ | ====== WolfDispatcher ====== | ||
+ | WolfDispatcher - це неймовірно простий, | ||
+ | |||
+ | ====== Як це працює? | ||
+ | |||
+ | Отак: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | |||
+ | ====== З чого почати? | ||
+ | |||
+ | У випадку, | ||
+ | |||
+ | Поїхали. Розгортаємо фреймворк, | ||
+ | < | ||
+ | $ mkdir ourbot | ||
+ | $ cd ourbot | ||
+ | $ fetch http:// | ||
+ | $ tar zxvf yalf_current.tgz && rm -fr yalf_current.tgz | ||
+ | $ chmod -R 777 exports content config | ||
+ | </ | ||
+ | |||
+ | Вмикаємо потрібні для функціонування нашого боту " | ||
+ | |||
+ | <file ini yalf.ini> | ||
+ | LAYER_TELEBOT=" | ||
+ | </ | ||
+ | |||
+ | Ось власне і все приготування оточення, | ||
+ | < | ||
+ | $ mkdir modules/ | ||
+ | $ touch modules/ | ||
+ | $ touch modules/ | ||
+ | </ | ||
+ | |||
+ | Та редагуємо їх відповідним чином | ||
+ | <file php module.php> | ||
+ | <?php | ||
+ | |||
+ | $this-> | ||
+ | </ | ||
+ | |||
+ | |||
+ | <file php index.php> | ||
+ | <? | ||
+ | |||
+ | // Імплементація бота OurBot котра повинна наслідувати WolfDispatcher | ||
+ | class OurBot extends WolfDispatcher { } | ||
+ | |||
+ | // Створюємо інстанс бота з токеном бота Telegram | ||
+ | $bot = new OurBot(' | ||
+ | // Вмикаємо автоматичну інсталляцю web-хуку для взаємодії з Telegram | ||
+ | $bot-> | ||
+ | // Слухаємо що нам кажуть | ||
+ | $bot-> | ||
+ | |||
+ | </ | ||
+ | |||
+ | Все, цих чотирьох рядків коду достатньо, | ||
+ | |||
+ | < | ||
+ | https:// | ||
+ | </ | ||
+ | |||
+ | та бачимо наступне: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | що означає, | ||
+ | |||
+ | |||
+ | Окей, а як переконатись, | ||
+ | |||
+ | <code php> | ||
+ | $bot-> | ||
+ | </ | ||
+ | |||
+ | Всі необхідні вам сповіщення почнуть сипатись в **exports/ | ||
+ | |||
+ | < | ||
+ | $ tail -F exports/ | ||
+ | </ | ||
+ | |||
+ | і як реакцію на щось таке | ||
+ | |||
+ | {{: | ||
+ | |||
+ | ми отримаємо такий результат | ||
+ | |||
+ | <file txt ourbot_debug.log> | ||
+ | OurBot: 2022-08-12 16:49:36 | ||
+ | Array | ||
+ | ( | ||
+ | [message_id] => 1295 | ||
+ | [from] => Array | ||
+ | ( | ||
+ | [id] => 777777777 | ||
+ | [first_name] => Nightfly | ||
+ | [username] => MyxaBkyco4kax | ||
+ | [language_code] => uk | ||
+ | ) | ||
+ | |||
+ | [chat] => Array | ||
+ | ( | ||
+ | [id] => 777777777 | ||
+ | [type] => private | ||
+ | ) | ||
+ | |||
+ | [date] => 1660312176 | ||
+ | [text] => привіт бот! | ||
+ | [photo] => | ||
+ | [document] => | ||
+ | [voice] => | ||
+ | [audio] => | ||
+ | [video_note] => | ||
+ | [location] => | ||
+ | [sticker] => | ||
+ | [new_chat_member] => | ||
+ | [left_chat_member] => | ||
+ | [reply_to_message] => | ||
+ | ) | ||
+ | |||
+ | GT: 0.0038 QC: 0 | ||
+ | |||
+ | Called actions: NONE | ||
+ | ================== | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ====== Хеллоуворлди ====== | ||
+ | |||
+ | Окей, вже результат. Але ж ми тут інтерактивності хочемо? | ||
+ | |||
+ | <file php api.ourbot.php> | ||
+ | <?php | ||
+ | |||
+ | class OurBot extends WolfDispatcher { | ||
+ | |||
+ | protected function actionHello() { | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | </ | ||
+ | |||
+ | запихуємо всі конфігурабельні штуки нашого бота в **config/ | ||
+ | |||
+ | <file ini alter.ini> | ||
+ | OURBOT_TOKEN=" | ||
+ | OURBOT_DEBUG=1 | ||
+ | OURBOT_AUTOSETUP=1 | ||
+ | </ | ||
+ | |||
+ | а контроллер приводимо до якогось такого вигляду | ||
+ | |||
+ | <file php index.php> | ||
+ | <?php | ||
+ | |||
+ | $bot = new OurBot($ubillingConfig-> | ||
+ | $bot-> | ||
+ | $bot-> | ||
+ | |||
+ | // Це масив екшонів. Формат рядок=> | ||
+ | // Дією може бути як метод класу імплементації боту (як приватний так і публічний) так і ім`я просто функції. | ||
+ | // У випадку, | ||
+ | $commands = array( | ||
+ | ' | ||
+ | ); | ||
+ | |||
+ | // Передаємо набір екшенів в діспатчер. Він сам розбереться, | ||
+ | $bot-> | ||
+ | |||
+ | // Слухаємо | ||
+ | $bot-> | ||
+ | </ | ||
+ | |||
+ | отримуючи повністю закономірний результат | ||
+ | |||
+ | {{: | ||
+ | |||
+ | власне, | ||
+ | |||
+ | <file txt ourbot_debug.log> | ||
+ | .......... | ||
+ | [date] => 1660313508 | ||
+ | [text] => привіт | ||
+ | [photo] => | ||
+ | [document] => | ||
+ | [voice] => | ||
+ | [audio] => | ||
+ | [video_note] => | ||
+ | [location] => | ||
+ | [sticker] => | ||
+ | [new_chat_member] => | ||
+ | [left_chat_member] => | ||
+ | [reply_to_message] => | ||
+ | ) | ||
+ | |||
+ | GT: 0.0164 QC: 0 | ||
+ | |||
+ | Called actions: Array | ||
+ | ( | ||
+ | [0] => METHOD: actionHello | ||
+ | ) | ||
+ | |||
+ | ================== | ||
+ | |||
+ | </ | ||
+ | |||
+ | Що власне свідчить, | ||
+ | |||
+ | < | ||
+ | Called actions: Array | ||
+ | ( | ||
+ | [0] => FUNC: actionHello | ||
+ | ) | ||
+ | </ | ||
+ | |||
+ | у випадку, | ||
+ | |||
+ | {{: | ||
+ | |||
+ | що в лозі буде виглядати приблизно так | ||
+ | |||
+ | < | ||
+ | Called actions: Array | ||
+ | ( | ||
+ | [0] => FAILED: actionHello2 | ||
+ | ) | ||
+ | </ | ||
+ | |||
+ | Також є пачка " | ||
+ | |||
+ | <code php> | ||
+ | // виконується у випадку, | ||
+ | | ||
+ | |||
+ | // виконується у випадку якщо надійшло повідомлення з порожнім текстом | ||
+ | | ||
+ | |||
+ | // виконується у випадку якщо отримано фотокартку | ||
+ | | ||
+ | |||
+ | // виконується як реакція на будь-яке повідомлення взагалі завжди | ||
+ | | ||
+ | </ | ||
+ | |||
+ | усі ці методи виконуються у випадку, | ||
+ | |||
+ | Давайте розширимо функціонал нашого хеллоуворлдного боту чимось осмисленішим, | ||
+ | |||
+ | |||
+ | <file php api.ourbot.php> | ||
+ | class OurBot extends WolfDispatcher { | ||
+ | |||
+ | const CHATS_LOG_PATH = ' | ||
+ | |||
+ | /** | ||
+ | * Just reacts for user greeting personally | ||
+ | | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function actionHelloName() { | ||
+ | $hisName = $this-> | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Replies on photo posted in chat | ||
+ | | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function actionPhotoWow() { | ||
+ | if ($this-> | ||
+ | $message = $this-> | ||
+ | if ($message[' | ||
+ | $replyText = ' | ||
+ | } else { | ||
+ | $replyText = ' | ||
+ | } | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Just logs all chats non empty text messages to some log file | ||
+ | | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function handleAnyWay() { | ||
+ | if (!empty($this-> | ||
+ | $logData = date(" | ||
+ | $logData .= $this-> | ||
+ | file_put_contents(self:: | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | <file php index.php> | ||
+ | $bot = new OurBot($ubillingConfig-> | ||
+ | $bot-> | ||
+ | $bot-> | ||
+ | |||
+ | $commands = array( | ||
+ | ' | ||
+ | ); | ||
+ | |||
+ | $bot-> | ||
+ | $bot-> | ||
+ | $bot-> | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====== Інтерфейс та всіляке таке інше ====== | ||
+ | |||
+ | Реакція на текстові команди, | ||
+ | |||
+ | Відкриваємо таємницю - в більшості випадків, | ||
+ | |||
+ | < | ||
+ | $ mkdir modules/ | ||
+ | $ touch modules/ | ||
+ | $ touch modules/ | ||
+ | $ touch api/ | ||
+ | </ | ||
+ | |||
+ | |||
+ | малюємо його конфіг в **config/ | ||
+ | |||
+ | <file ini alter.ini> | ||
+ | PORADNYK_TOKEN=" | ||
+ | PORADNYK_DEBUG=1 | ||
+ | PORADNYK_AUTOSETUP=1 | ||
+ | </ | ||
+ | |||
+ | заповнюємо опис модуля в **modules/ | ||
+ | |||
+ | <file php module.php> | ||
+ | <?php | ||
+ | |||
+ | $this-> | ||
+ | </ | ||
+ | |||
+ | збираємо імплементацію в **api/ | ||
+ | <file php api.poradnyk.php> | ||
+ | <?php | ||
+ | |||
+ | class Poradnyk extends WolfDispatcher { | ||
+ | |||
+ | /** | ||
+ | * Some predefined text-routes aka actions | ||
+ | */ | ||
+ | const ROUTE_INIT = '/ | ||
+ | const ROUTE_ADVICE_UA = ' | ||
+ | const ROUTE_ADVICE_RU = ' | ||
+ | const GROUTE_ADVICE_UA = ' | ||
+ | const GROUTE_ADVICE_RU = ' | ||
+ | |||
+ | /** | ||
+ | * Renders custom keyboard | ||
+ | | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function actionKeyboard() { | ||
+ | $buttons[] = array(self:: | ||
+ | $keyboard = $this-> | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Gets awesome advice and sends message with it to current chat | ||
+ | | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function actionAdvice() { | ||
+ | $fga = new OmaeUrl(' | ||
+ | $advice = $fga-> | ||
+ | $advice = json_decode($advice, | ||
+ | $advice = $advice[' | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Gets awasome advice in russian | ||
+ | | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function actionNahuy() { | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | } | ||
+ | </ | ||
+ | |||
+ | Та контроллер цього всього в **modules/ | ||
+ | |||
+ | <file php index.php> | ||
+ | |||
+ | <?php | ||
+ | |||
+ | // Bot instance creation | ||
+ | $bot = new Poradnyk($ubillingConfig-> | ||
+ | $bot-> | ||
+ | $bot-> | ||
+ | |||
+ | // Commands/ | ||
+ | $commands = array( | ||
+ | $bot:: | ||
+ | $bot:: | ||
+ | $bot:: | ||
+ | ); | ||
+ | |||
+ | // Group-chat commands is text-only and starts with " | ||
+ | // Using custom keyboards in group chats isn`t best practice. | ||
+ | $groupCommands = array( | ||
+ | $bot:: | ||
+ | $bot:: | ||
+ | ); | ||
+ | |||
+ | |||
+ | $bot-> | ||
+ | $bot-> | ||
+ | $bot-> | ||
+ | |||
+ | </ | ||
+ | |||
+ | Йдемо за URL нашого контроллера задля встановлення веб-хука. Можемо до речі браузером, | ||
+ | |||
+ | {{: | ||
+ | |||
+ | |||
+ | Все, тестуємо: | ||
+ | |||
+ | {{: | ||
+ | |||
+ | Як бачимо, | ||
+ | |||
+ | Не складно помітити, | ||
+ | |||
+ | <code php> | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | {{: | ||
+ | |||
+ | або якось так: | ||
+ | |||
+ | <code php> | ||
+ | $buttons[] = array(' | ||
+ | $buttons[] = array(__(' | ||
+ | $buttons[] = array(' | ||
+ | </ | ||
+ | |||
+ | з отаким от результатом | ||
+ | |||
+ | {{: | ||
+ | |||
+ | Чому на кнопочках стараємось використовувати емоджі? | ||
+ | - Стараємось уникати випадкових реакцій бота, на рандомні повідомлення в чаті | ||
+ | - Красівоє | ||
+ | |||
+ | Також, насправді, | ||
+ | |||
+ | <code php> | ||
+ | $buttons[] =array(' | ||
+ | $buttons[] =array(' | ||
+ | | ||
+ | $this-> | ||
+ | </ | ||
+ | ====== Про складне ====== | ||
+ | |||
+ | Так, а зараз видихніть, | ||
+ | |||
+ | {{wolfprey.webm? | ||
+ | |||
+ | та зосередьтесь. | ||
+ | |||
+ | Будемо говорити про не самі очевидні речі. Про такі як " | ||
+ | |||
+ | Отож, розпочнемо з параметризації ваших обробників. Якщо у випадку, | ||
+ | |||
+ | <code php> | ||
+ | function doSomething($argument) { | ||
+ | //тут далі робимо щось з цими даними, | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | То методи викликаються в лоб взагалі без параметрів. Зроблено це так, задля економії пам`яті. Звісно, | ||
+ | |||
+ | <code php> | ||
+ | protected function handleEmptyAction() { | ||
+ | if (!empty($this-> | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | Власне все що отримує бот в даних хука, ми рахуємо " | ||
+ | |||
+ | |||
+ | Ось трохи детальніше, | ||
+ | |||
+ | <code php> | ||
+ | Array | ||
+ | ( | ||
+ | [message_id] => (int) 666 - ідентифікатор повідомлення. Воно ж зберігається в проперті this-> | ||
+ | та на нього за замовчуванням відповідає this-> | ||
+ | [from] => Array | ||
+ | ( | ||
+ | [id] => (int) 7777777777 - chatId користувача від якого надійшло повідомлення. | ||
+ | [first_name] => (string) Микола Петренко - iм`я користувача | ||
+ | [username] => (string) l33tmykola - юзернейм користувача | ||
+ | [language_code] => (string) uk - мова клієнту користувача, | ||
+ | ) | ||
+ | |||
+ | [chat] => Array | ||
+ | ( | ||
+ | [id] => (int) 7777777777 - chatId чату з яким ведеться діалог. У випадку приватного чату він співпадає з [from][id]. | ||
+ | У випадку, | ||
+ | | ||
+ | | ||
+ | [type] => (string) private | ||
+ | ) | ||
+ | |||
+ | [date] => (int) 1660393421 - дата отримання повідомлення у вигляді unixtimestamp | ||
+ | [text] => (string) test message - не повірите, | ||
+ | [photo] => array() - структура, | ||
+ | [document] => array() - виглядає приблизно як і photo тільки містить файлики з якимось mime_type. стосується також voice, audio, video_note | ||
+ | [voice] => array() - звукові повідомлення, | ||
+ | [audio] => array() - аудіо файлики. | ||
+ | [video_note] => array() - коротки відео, типу сторізів. | ||
+ | [location] => array() - дані про геолокацію, | ||
+ | [sticker] => array() - стікери, | ||
+ | [new_chat_member] => array() - структура котра заповнюється при появі користувача в груповому чаті. | ||
+ | | ||
+ | | ||
+ | id, is_bot, first_name, username - інші боти | ||
+ | [left_chat_member] => array() - структура, | ||
+ | [reply_to_message] => array() - у випадку, | ||
+ | як і ось ця, поточна, | ||
+ | ) | ||
+ | |||
+ | </ | ||
+ | |||
+ | У випадку, | ||
+ | |||
+ | <code php> | ||
+ | | ||
+ | [photo] => Array | ||
+ | ( | ||
+ | [0] => Array | ||
+ | ( | ||
+ | [file_id] => AgACAgIAAxkBAAIFkWL3nxfnsM4SlGHiXNi4qDPdX2bmAAKsvjEbdRC4S58-T_p7q3ZCAQADAgADcwADKQQ | ||
+ | [file_unique_id] => AQADrL4xG3UQuEt4 | ||
+ | [file_size] => 1982 | ||
+ | [width] => 90 | ||
+ | [height] => 89 | ||
+ | ) | ||
+ | |||
+ | [1] => Array | ||
+ | ( | ||
+ | [file_id] => AgACAgIAAxkBAAIFkWL3nxfnsM4SlGHiXNi4qDPdX2bmAAKsvjEbdRC4S58-T_p7q3ZCAQADAgADbQADKQQ | ||
+ | [file_unique_id] => AQADrL4xG3UQuEty | ||
+ | [file_size] => 19215 | ||
+ | [width] => 320 | ||
+ | [height] => 315 | ||
+ | ) | ||
+ | |||
+ | [2] => Array | ||
+ | ( | ||
+ | [file_id] => AgACAgIAAxkBAAIFkWL3nxfnsM4SlGHiXNi4qDPdX2bmAAKsvjEbdRC4S58-T_p7q3ZCAQADAgADeAADKQQ | ||
+ | [file_unique_id] => AQADrL4xG3UQuEt9 | ||
+ | [file_size] => 19267 | ||
+ | [width] => 324 | ||
+ | [height] => 319 | ||
+ | ) | ||
+ | |||
+ | ) | ||
+ | </ | ||
+ | |||
+ | З самого вигляду цього всього, | ||
+ | |||
+ | ====== Робота з зображеннями ====== | ||
+ | |||
+ | Перш за все, необхідно пам' | ||
+ | |||
+ | - Завантажувати це зображення собі | ||
+ | - Якось його модифікувати | ||
+ | - Відсилати в чатік назад уже спохабленим | ||
+ | |||
+ | От якось так | ||
+ | |||
+ | <code php> | ||
+ | class DemoBot extends WolfDispatcher { | ||
+ | |||
+ | /** | ||
+ | * Для відсилання зображень, | ||
+ | */ | ||
+ | const IMG_SAVE_PATH = ' | ||
+ | const IMG_URL = ' | ||
+ | |||
+ | /** | ||
+ | * Catches and returns processed image to user | ||
+ | | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function actionProcessImage() { | ||
+ | // Якусь фоточку зловлено? | ||
+ | // так, що ця перевірка надлишкова тут. Просто як ілюстрація. | ||
+ | if ($this-> | ||
+ | // Зберігаємо зображення до тимчасової директорії. Також ми могли б використати getPhoto() | ||
+ | // задля того, щоб просто отримати в змінну вміст самого зображеня, | ||
+ | // але навіщо, | ||
+ | $photoSaveResult = $this-> | ||
+ | // перевіряємо чи воно взагалі збереглось? | ||
+ | if ($photoSaveResult) { | ||
+ | // | ||
+ | $image = imagecreatefromjpeg($photoSaveResult); | ||
+ | // | ||
+ | imagefilter($image, | ||
+ | imagefilter($image, | ||
+ | imagefilter($image, | ||
+ | imagefilter($image, | ||
+ | imagefilter($image, | ||
+ | |||
+ | // | ||
+ | $newImageName = $photoSaveResult . ' | ||
+ | imagejpeg($image, | ||
+ | $fullImageUrl = self:: | ||
+ | // | ||
+ | $message = ' | ||
+ | // | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | $bot = new DemoBot($ubillingConfig-> | ||
+ | $bot-> | ||
+ | $bot-> | ||
+ | </ | ||
+ | |||
+ | З повністю очікуваним результатом | ||
+ | |||
+ | {{:: | ||
+ | |||
+ | Окей, а якщо ми не хочемо робити тільки " | ||
+ | |||
+ | <code php> | ||
+ | class ImgFiltersBot extends WolfDispatcher { | ||
+ | |||
+ | /** | ||
+ | * Contains per-user image file path | ||
+ | * | ||
+ | * @var string | ||
+ | */ | ||
+ | protected $userImageFilePath = ''; | ||
+ | |||
+ | /** | ||
+ | * Contains GD image resource to apply some filters | ||
+ | * | ||
+ | * @var mixed | ||
+ | */ | ||
+ | protected $image = ''; | ||
+ | |||
+ | /** | ||
+ | * Some predefined data here | ||
+ | */ | ||
+ | const IMG_SAVE_PATH = ' | ||
+ | const IMG_URL = ' | ||
+ | const FILTER_MARK = '🔥 '; | ||
+ | |||
+ | /** | ||
+ | * Sets user image path on any input action | ||
+ | | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function setImagePath() { | ||
+ | $this-> | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Catches and saves one image per user | ||
+ | | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function actionCatchImage() { | ||
+ | $this-> | ||
+ | $photoSaveResult = $this-> | ||
+ | if ($photoSaveResult) { | ||
+ | $this-> | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Renders available filters keyboard if image loaded | ||
+ | | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function actionKeyboard() { | ||
+ | $this-> | ||
+ | //user loaded any image? | ||
+ | if (file_exists($this-> | ||
+ | |||
+ | $availableFilters = array( | ||
+ | ' | ||
+ | ' | ||
+ | ); | ||
+ | |||
+ | $buttonsInRow = 3; | ||
+ | $i = 1; | ||
+ | $buttons = array(); | ||
+ | $buttonsRow = array(); | ||
+ | foreach ($availableFilters as $io => $each) { | ||
+ | | ||
+ | if ($i <= $buttonsInRow) { | ||
+ | $buttonsRow[] = self:: | ||
+ | } else { | ||
+ | $buttons[] = $buttonsRow; | ||
+ | $buttonsRow = array(); | ||
+ | $i = 0; | ||
+ | } | ||
+ | $i++; | ||
+ | } | ||
+ | $this-> | ||
+ | } else { | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Returns processed image to user | ||
+ | | ||
+ | * @return void | ||
+ | */ | ||
+ | protected function returnProcessedImage() { | ||
+ | $this-> | ||
+ | //is image loaded? | ||
+ | if (!empty($this-> | ||
+ | $newImageName = $this-> | ||
+ | //re-save new image if not exists | ||
+ | if (!file_exists($newImageName)) { | ||
+ | imagejpeg($this-> | ||
+ | } | ||
+ | $fullImageUrl = self:: | ||
+ | $message = ' | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Runs selected filter and returns image to user | ||
+ | */ | ||
+ | protected function applyFilter() { | ||
+ | $this-> | ||
+ | if (file_exists($this-> | ||
+ | if (!empty($this-> | ||
+ | $filterName = str_replace(self:: | ||
+ | $filterName = trim($filterName); | ||
+ | if (!empty($filterName)) { | ||
+ | if (method_exists($this, | ||
+ | //load image from filesystem | ||
+ | $this-> | ||
+ | $this-> | ||
+ | $this-> | ||
+ | $this-> | ||
+ | } else { | ||
+ | $this-> | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /** | ||
+ | * Some image instagram-like filters here. | ||
+ | */ | ||
+ | protected function tender() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function dream() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function frozen() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function forest() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function rain() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function orangepeel() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagegammacorrect($this-> | ||
+ | } | ||
+ | |||
+ | protected function darken() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function summer() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function retro() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function country() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagegammacorrect($this-> | ||
+ | } | ||
+ | |||
+ | protected function washed() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagegammacorrect($this-> | ||
+ | } | ||
+ | |||
+ | protected function freshblue() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function everglow() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function hermajesty() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function concentrate() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function vintage() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function blur() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function blackwhite() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function antique() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function gray() { | ||
+ | |||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function boost() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function fuzzy() { | ||
+ | $gaussian = array( | ||
+ | array(1.0, 1.0, 1.0), | ||
+ | array(1.0, 1.0, 1.0), | ||
+ | array(1.0, 1.0, 1.0) | ||
+ | ); | ||
+ | |||
+ | imageconvolution($this-> | ||
+ | } | ||
+ | |||
+ | protected function aqua() { | ||
+ | |||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | protected function sepia() { | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | imagefilter($this-> | ||
+ | } | ||
+ | |||
+ | } | ||
+ | |||
+ | $bot = new ImgFiltersBot($ubillingConfig-> | ||
+ | |||
+ | $commands = array( | ||
+ | '/ | ||
+ | $bot:: | ||
+ | ); | ||
+ | |||
+ | $bot-> | ||
+ | $bot-> | ||
+ | $bot-> | ||
+ | |||
+ | $bot-> | ||
+ | </ | ||
+ | |||
+ | а ось, як це все працює на практиці: | ||
+ | |||
+ | {{instafiltersdemo.webm? | ||
+ | |||
+ | |||
+ | ====== Використання поза фреймворком ====== | ||
+ | |||
+ | Також ви можете використовувати WolfDispatcher просто інклудячи тільки дві бібліотеки: | ||
+ | |||
+ | < | ||
+ | $ mkdir ourbot | ||
+ | $ cd ourbot/ | ||
+ | $ mkdir exports | ||
+ | $ echo "deny from all" > exports/ | ||
+ | $ chmod 777 exports | ||
+ | $ wget https:// | ||
+ | $ wget https:// | ||
+ | $ touch index.php | ||
+ | </ | ||
+ | |||
+ | і все працює: | ||
+ | |||
+ | <file php index.php> | ||
+ | <?php | ||
+ | |||
+ | // low-level Telegram API implementation | ||
+ | require_once(' | ||
+ | // WolfDispatcher lib | ||
+ | require_once(' | ||
+ | |||
+ | class OurBot extends WolfDispatcher { } | ||
+ | |||
+ | $bot = new OurBot(' | ||
+ | $bot-> | ||
+ | $bot-> | ||
+ | |||
+ | </ | ||
+ | |||
+ | Власне тут [[https:// |