Created
February 15, 2017 13:16
-
-
Save christophrumpel/ebfad7af0d470614491c4669f507064d to your computer and use it in GitHub Desktop.
BotMan ApiDriver Draft
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 App\Chatbot\Conversations; | |
| use Illuminate\Support\Arr; | |
| use Illuminate\Support\Facades\Cache; | |
| use Mpociot\BotMan\Answer; | |
| use Mpociot\BotMan\Drivers\Driver; | |
| use Mpociot\BotMan\Facebook\ButtonTemplate; | |
| use Mpociot\BotMan\Facebook\GenericTemplate; | |
| use Mpociot\BotMan\Facebook\ListTemplate; | |
| use Mpociot\BotMan\Facebook\ReceiptTemplate; | |
| use Mpociot\BotMan\Interfaces\UserInterface; | |
| use Mpociot\BotMan\Message; | |
| use Mpociot\BotMan\Question; | |
| use Illuminate\Support\Collection; | |
| use Mpociot\BotMan\User; | |
| use Symfony\Component\HttpFoundation\Request; | |
| use Symfony\Component\HttpFoundation\Response; | |
| use Symfony\Component\HttpFoundation\ParameterBag; | |
| use Mpociot\BotMan\Messages\Message as IncomingMessage; | |
| class ApiDriver extends Driver | |
| { | |
| /** @var Collection|ParameterBag */ | |
| protected $payload; | |
| /** @var Collection */ | |
| protected $event; | |
| /** @var array */ | |
| protected $templates = [ | |
| ButtonTemplate::class, | |
| GenericTemplate::class, | |
| ListTemplate::class, | |
| ReceiptTemplate::class, | |
| ]; | |
| const DRIVER_NAME = 'Api'; | |
| /** | |
| * @param Request $request | |
| */ | |
| public function buildPayload(Request $request) | |
| { | |
| $this->payload = $request->request->all(); | |
| $this->event = Collection::make($this->payload); | |
| } | |
| /** | |
| * 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 $this->event->get('driver') === 'api'; | |
| } | |
| /** | |
| * @param Message $message | |
| * @return Answer | |
| */ | |
| public function getConversationAnswer(Message $message) | |
| { | |
| return Answer::create($message->getMessage()); | |
| } | |
| /** | |
| * Retrieve the chat message. | |
| * @return array | |
| */ | |
| public function getMessages() | |
| { | |
| $message = $this->event->get('message'); | |
| $userId = $this->event->get('userId'); | |
| return [new Message($message, $userId, $userId, $this->payload)]; | |
| } | |
| /** | |
| * @return bool | |
| */ | |
| public function isBot() | |
| { | |
| return false; | |
| } | |
| /** | |
| * @param string|Question|IncomingMessage $message | |
| * @param Message $matchingMessage | |
| * @param array $additionalParameters | |
| * @return $this|void | |
| */ | |
| public function reply($message, $matchingMessage, $additionalParameters = []) | |
| { | |
| $cachedReplies = $this->getCachedMessages($message); | |
| if ($this->isLastReply($message)) { | |
| Cache::forget($this->event->get('userId')); | |
| $messages = $this->buildReply($cachedReplies); | |
| $replyData = [ | |
| 'status' => 200, | |
| 'messages' => $messages | |
| ]; | |
| Response::create(json_encode($replyData), 200, [ | |
| 'Content-Type' => 'application/json', | |
| 'Access-Control-Allow-Credentials' => true, | |
| 'Access-Control-Allow-Origin' => '*' | |
| ])->send(); | |
| } | |
| } | |
| /** | |
| * @return bool | |
| */ | |
| public function isConfigured() | |
| { | |
| return true; | |
| } | |
| /** | |
| * Retrieve User information. | |
| * @param Message $matchingMessage | |
| * @return UserInterface | |
| */ | |
| public function getUser(Message $matchingMessage) | |
| { | |
| return new User($matchingMessage->getChannel()); | |
| } | |
| /** | |
| * Build API reply | |
| * @param $messages | |
| * @return array | |
| */ | |
| private function buildReply($messages) | |
| { | |
| $replyData = collect($messages)->transform(function ($message) { | |
| if ($message instanceof Question) { | |
| $reply = $this->buildQuestionPayload($message); | |
| } elseif (is_object($message) && in_array(get_class($message), $this->templates)) { | |
| $reply = $this->buildTemplatePayload($message); | |
| } else { | |
| $reply = [ | |
| 'type' => 'text', | |
| 'text' => str_replace('##end##', '', $message) | |
| ]; | |
| } | |
| return $reply; | |
| })->toArray(); | |
| return $replyData; | |
| } | |
| /** | |
| * Check if this is the last reply of multiple ones | |
| * @param $message | |
| * @return bool|mixed | |
| */ | |
| public function isLastReply($message) | |
| { | |
| if ($message instanceof Question) { | |
| $message = $message->toArray()['text']; | |
| } elseif (is_object($message) && in_array(get_class($message), $this->templates)) { | |
| $message = Arr::get($message->toArray(), 'attachment.payload.text'); | |
| } | |
| return strpos($message, '##end##') !== false; | |
| } | |
| /** | |
| * Pull cached replies | |
| * @param $message | |
| * @return array | |
| */ | |
| private function getCachedMessages($message) | |
| { | |
| $userId = $this->event->get('userId'); | |
| $cachedReplies = Cache::pull($userId); | |
| $cachedReplies[] = $message; | |
| Cache::put($userId, $cachedReplies, 100); | |
| return $cachedReplies; | |
| } | |
| /** | |
| * Build reply payload for a Question object | |
| * @param Question $message | |
| * @return array | |
| */ | |
| private function buildQuestionPayload(Question $message) | |
| { | |
| $questionsData = $message->toArray(); | |
| $reply = [ | |
| 'type' => 'text', | |
| 'text' => str_replace('##end##', '', $questionsData['text']) | |
| ]; | |
| if ( ! empty($message->getButtons())) { | |
| $reply['type'] = 'buttons'; | |
| $reply['buttons'] = Collection::make($message->getButtons())->map(function ($button) { | |
| return [ | |
| 'text' => $button['text'], | |
| 'keyword' => $button['value'], | |
| 'imageUrl' => $button['image_url'] | |
| ]; | |
| })->toArray(); | |
| } | |
| return $reply; | |
| } | |
| private function buildTemplatePayload($message) | |
| { | |
| $reply = []; | |
| if ($message instanceof ButtonTemplate) { | |
| $reply['type'] = 'buttonlist'; | |
| $reply['text'] = str_replace('##end##', '', Arr::get($message->toArray(), 'attachment.payload.text')); | |
| $reply['buttons'] = Collection::make(Arr::get($message->toArray(), | |
| 'attachment.payload.buttons'))->map(function ($button) { | |
| $returnArray = [ | |
| 'type' => $button['type'] === 'web_url' ? 'url' : 'postback', | |
| 'text' => $button['title'], | |
| 'keyword' => $button['payload'] ?? null | |
| ]; | |
| if (isset($button['url'])) { | |
| $returnArray['url'] = $button['url']; | |
| } | |
| return $returnArray; | |
| }); | |
| } else { | |
| $reply = [ | |
| 'status' => 500, | |
| 'message' => 'unknown tempalte' | |
| ]; | |
| } | |
| return $reply; | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment