From bba20f16b191dc8e3e8d4ddb2dbecc547c87ccb7 Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Mon, 3 Apr 2017 17:28:14 +0200 Subject: [PATCH] initial commit --- .gitignore | 5 + .styleci.yml | 6 + README.md | 49 +++++++++ composer.json | 34 ++++++ src/BotManTinkerServiceProvider.php | 17 +++ src/Commands/BotManTinker.php | 71 ++++++++++++ src/Drivers/ConsoleDriver.php | 165 ++++++++++++++++++++++++++++ 7 files changed, 347 insertions(+) create mode 100644 .gitignore create mode 100644 .styleci.yml create mode 100644 README.md create mode 100644 composer.json create mode 100644 src/BotManTinkerServiceProvider.php create mode 100644 src/Commands/BotManTinker.php create mode 100644 src/Drivers/ConsoleDriver.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fb0edf3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.idea/ +.DS_Store +composer.lock +.php_cs.cache +/vendor/ \ No newline at end of file diff --git a/.styleci.yml b/.styleci.yml new file mode 100644 index 0000000..a2f2088 --- /dev/null +++ b/.styleci.yml @@ -0,0 +1,6 @@ +preset: laravel + +enabled: + - unalign_double_arrow + +linting: true \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..72f5ce3 --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# BotMan Tinker + +Gives your Laravel chatbot the ability to try your chatbot in your local terminal. + +## Installation + +Run `composer require mpociot/botman-tinker` to install the composer dependencies. + +Then in your `config/app.php` add + +```php +Mpociot\BotManTinker\BotManTinkerServiceProvider::class, +``` + +to the `providers` array. + +## Usage + +You now have a new Artisan command that helps you to test and develop your chatbot locally: + +```php +php artisan botman:tinker +``` + +## About BotMan + +BotMan is a framework agnostic PHP library that is designed to simplify the task of developing innovative bots for multiple messaging platforms, including [Slack](http://slack.com), [Telegram](http://telegram.me), [Microsoft Bot Framework](https://dev.botframework.com/), [Nexmo](https://nexmo.com), [HipChat](http://hipchat.com), [Facebook Messenger](http://messenger.com) and [WeChat](http://web.wechat.com). + +```php +$botman->hears('I want cross-platform bots with PHP!', function (BotMan $bot) { + $bot->reply('Look no further!'); +}); +``` + +## Documentation + +You can find the BotMan documentation at [http://botman.io](http://botman.io). + +## Contributing + +Please see [CONTRIBUTING](CONTRIBUTING.md) for details. + +## Security Vulnerabilities + +If you discover a security vulnerability within BotMan, please send an e-mail to Marcel Pociot at m.pociot@gmail.com. All security vulnerabilities will be promptly addressed. + +## License + +BotMan Tinker is free software distributed under the terms of the MIT license. diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..cb2efd8 --- /dev/null +++ b/composer.json @@ -0,0 +1,34 @@ +{ + "name": "mpociot/botman-tinker", + "license": "MIT", + "description": "BotMan tinker command for your Laravel BotMan project", + "keywords": [ + "Bot", + "BotMan", + "Laravel", + "Tinker" + ], + "homepage": "http://github.com/mpociot/botman-tinker", + "authors": [ + { + "name": "Marcel Pociot", + "email": "m.pociot@gmail.com" + } + ], + "require": { + "php": ">=5.6.0", + "mpociot/botman": "dev-master", + "clue/stdio-react": "^1.0", + "mpociot/slack-client": "^0.2.6", + "illuminate/support": "~5.0" + }, + "require-dev": { + "orchestra/testbench": "~3.0", + "phpunit/phpunit": "~5.0" + }, + "autoload": { + "psr-4": { + "Mpociot\\BotManTinker\\": "src/" + } + } +} diff --git a/src/BotManTinkerServiceProvider.php b/src/BotManTinkerServiceProvider.php new file mode 100644 index 0000000..9e2053f --- /dev/null +++ b/src/BotManTinkerServiceProvider.php @@ -0,0 +1,17 @@ +commands([ + BotManTinker::class + ]); + } + +} \ No newline at end of file diff --git a/src/Commands/BotManTinker.php b/src/Commands/BotManTinker.php new file mode 100644 index 0000000..7475b15 --- /dev/null +++ b/src/Commands/BotManTinker.php @@ -0,0 +1,71 @@ +singleton('botman', function ($app) use ($loop) { + $config = config('services.botman', []); + $botman = BotManFactory::create($config, new ArrayCache()); + + $stdio = new Stdio($loop); + $stdio->getReadline()->setPrompt('You: '); + + $botman->setDriver(new ConsoleDriver($config, $stdio)); + + $stdio->on('line', function ($line) use ($botman) { + $botman->listen(); + }); + + return $botman; + }); + + if (file_exists('routes/botman.php')) { + require base_path('routes/botman.php'); + } + + $loop->run(); + } +} \ No newline at end of file diff --git a/src/Drivers/ConsoleDriver.php b/src/Drivers/ConsoleDriver.php new file mode 100644 index 0000000..1e80d38 --- /dev/null +++ b/src/Drivers/ConsoleDriver.php @@ -0,0 +1,165 @@ +event = Collection::make(); + $this->config = Collection::make($config); + $this->client = $client; + + $this->client->on('line', function ($line) { + $this->message = $line; + }); + } + + /** + * Return the driver name. + * + * @return string + */ + public function getName() + { + return self::DRIVER_NAME; + } + + /** + * Determine if the request is for this driver. + * + * @return bool + */ + public function matchesRequest() + { + return false; + } + + /** + * @param Message $message + * @return Answer + */ + public function getConversationAnswer(Message $message) + { + $index = (int)$message->getMessage() - 1; + + if ($this->hasQuestion && isset($this->lastQuestions[$index])) { + $question = $this->lastQuestions[$index]; + return Answer::create($question['name']) + ->setInteractiveReply(true) + ->setValue($question['value']) + ->setMessage($message); + } + return Answer::create($this->message)->setMessage($message); + } + + /** + * Retrieve the chat message. + * + * @return array + */ + public function getMessages() + { + return [new Message($this->message, 999, '#channel', $this->message)]; + } + + /** + * @return bool + */ + public function isBot() + { + return strpos($this->message, 'BotMan: ') === 0; + } + + /** + * @param string|Question|IncomingMessage $message + * @param Message $matchingMessage + * @param array $additionalParameters + * @return $this + */ + public function reply($message, $matchingMessage, $additionalParameters = []) + { + $questionData = null; + if ($message instanceof IncomingMessage) { + $text = $message->getMessage(); + } elseif ($message instanceof Question) { + $text = $message->getText(); + $questionData = $message->toArray(); + } else { + $text = $message; + } + + $this->client->writeln(self::BOT_NAME.': '.$text); + + if (!is_null($questionData)) { + foreach ($questionData['actions'] as $key => $action) { + $this->client->writeln(($key+1).') '.$action['text']); + } + $this->hasQuestion = true; + $this->lastQuestions = $questionData['actions']; + } + + return $this; + } + + /** + * Send a typing indicator. + * @param Message $matchingMessage + * @return mixed + */ + public function types(Message $matchingMessage) + { + $this->client->writeln(self::BOT_NAME.': ...'); + } + + /** + * Retrieve User information. + * @param Message $matchingMessage + * @return User + */ + public function getUser(Message $matchingMessage) + { + return new User($matchingMessage->getUser()); + } + + /** + * @return bool + */ + public function isConfigured() + { + return false; + } +} \ No newline at end of file