diff --git a/Magento2/app/code/Werules/Chatbot/Api/Data/ChatbotAPIInterface.php b/Magento2/app/code/Werules/Chatbot/Api/Data/ChatbotAPIInterface.php index e7f5c8e..5b66509 100644 --- a/Magento2/app/code/Werules/Chatbot/Api/Data/ChatbotAPIInterface.php +++ b/Magento2/app/code/Werules/Chatbot/Api/Data/ChatbotAPIInterface.php @@ -25,6 +25,7 @@ interface ChatbotAPIInterface { const CHATBOTUSER_ID = 'chatbotuser_id'; + const LAST_COMMAND_DETAILS = 'last_command_details'; const FALLBACK_QTY = 'fallback_qty'; const CHATBOTAPI_ID = 'chatbotapi_id'; const CREATED_AT = 'created_at'; @@ -34,7 +35,6 @@ interface ChatbotAPIInterface const CHATBOT_TYPE = 'chatbot_type'; const UPDATED_AT = 'updated_at'; const ENABLED = 'enabled'; - const LAST_COMMAND_DETAILS = 'last_command_details'; const CHAT_ID = 'chat_id'; diff --git a/Magento2/app/code/Werules/Chatbot/Api/Data/MessageInterface.php b/Magento2/app/code/Werules/Chatbot/Api/Data/MessageInterface.php index c744815..d9b874b 100644 --- a/Magento2/app/code/Werules/Chatbot/Api/Data/MessageInterface.php +++ b/Magento2/app/code/Werules/Chatbot/Api/Data/MessageInterface.php @@ -24,10 +24,11 @@ interface MessageInterface { - const MESSAGE_ID = 'message_id'; - const CONTENT_TYPE = 'content_type'; const CONTENT = 'content'; + const CONTENT_TYPE = 'content_type'; + const SENT_AT = 'sent_at'; const STATUS = 'status'; + const MESSAGE_ID = 'message_id'; const CREATED_AT = 'created_at'; const SENDER_ID = 'sender_id'; const DIRECTION = 'direction'; @@ -35,6 +36,7 @@ interface MessageInterface const UPDATED_AT = 'updated_at'; const MESSAGE_PAYLOAD = 'message_payload'; const CHAT_MESSAGE_ID = 'chat_message_id'; + const CURRENT_COMMAND_DETAILS = 'current_command_details'; /** @@ -179,4 +181,30 @@ public function getMessagePayload(); * @return \Werules\Chatbot\Api\Data\MessageInterface */ public function setMessagePayload($message_payload); + + /** + * Get sent_at + * @return string|null + */ + public function getSentAt(); + + /** + * Set sent_at + * @param string $sent_at + * @return \Werules\Chatbot\Api\Data\MessageInterface + */ + public function setSentAt($sent_at); + + /** + * Get current_command_details + * @return string|null + */ + public function getCurrentCommandDetails(); + + /** + * Set current_command_details + * @param string $current_command_details + * @return \Werules\Chatbot\Api\Data\MessageInterface + */ + public function setCurrentCommandDetails($current_command_details); } diff --git a/Magento2/app/code/Werules/Chatbot/Block/Adminhtml/System/Config/Form/Field/MessageQueueModeList.php b/Magento2/app/code/Werules/Chatbot/Block/Adminhtml/System/Config/Form/Field/MessageQueueModeList.php new file mode 100644 index 0000000..7ca7b87 --- /dev/null +++ b/Magento2/app/code/Werules/Chatbot/Block/Adminhtml/System/Config/Form/Field/MessageQueueModeList.php @@ -0,0 +1,40 @@ +. + */ + +namespace Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field; + +class MessageQueueModeList implements \Magento\Framework\Option\ArrayInterface +{ + /** + * Provide available options as a value/label array + * + * @return array + */ + public function toOptionArray() + { + return array( + array('value' => 0, 'label' => __("None")), + array('value' => 1, 'label' => __("Simple Restrictive")), + array('value' => 2, 'label' => __("Restrictive")), + array('value' => 3, 'label' => __("Non-restrictive")) + ); + } +} \ No newline at end of file diff --git a/Magento2/app/code/Werules/Chatbot/Block/Adminhtml/System/Config/Form/Field/MessageQueueModeSelect.php b/Magento2/app/code/Werules/Chatbot/Block/Adminhtml/System/Config/Form/Field/MessageQueueModeSelect.php new file mode 100644 index 0000000..d2f7b70 --- /dev/null +++ b/Magento2/app/code/Werules/Chatbot/Block/Adminhtml/System/Config/Form/Field/MessageQueueModeSelect.php @@ -0,0 +1,53 @@ +. + */ + +namespace Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field; + +class MessageQueueModeSelect extends \Magento\Framework\View\Element\Html\Select +{ + /** + * @var \Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field\MessageQueueModeList + */ + protected $_messageQueueModeList; + + public function __construct( + \Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field\MessageQueueModeList $messageQueueModeList, + \Magento\Backend\Block\Template\Context $context, array $data = array()) + { + parent::__construct($context, $data); + $this->_messageQueueModeList = $messageQueueModeList; + } + + public function _toHtml() + { + if (!$this->getOptions()) { + foreach ($this->_messageQueueModeList->toOptionArray() as $option) { + $this->addOption($option['value'], $option['label']); + } + } + return parent::_toHtml(); + } + + public function getName() + { + return $this->getInputName(); + } +} \ No newline at end of file diff --git a/Magento2/app/code/Werules/Chatbot/Block/Webhook/Index.php b/Magento2/app/code/Werules/Chatbot/Block/Webhook/Index.php index d2ff50c..f56edd0 100644 --- a/Magento2/app/code/Werules/Chatbot/Block/Webhook/Index.php +++ b/Magento2/app/code/Werules/Chatbot/Block/Webhook/Index.php @@ -87,26 +87,46 @@ public function requestHandler() protected function messageHandler($messageObject) { - $messageModel = $this->_messageModel->create(); - $messageModel->setSenderId($messageObject->senderId); - $messageModel->setContent($messageObject->content); - $messageModel->setChatbotType($messageObject->chatType); - $messageModel->setContentType($messageObject->contentType); - $messageModel->setStatus($messageObject->status); - $messageModel->setDirection($messageObject->direction); - $messageModel->setMessagePayload($messageObject->messagePayload); - $messageModel->setChatMessageId($messageObject->chatMessageId); - $messageModel->setCreatedAt($messageObject->createdAt); - $messageModel->setUpdatedAt($messageObject->updatedAt); - - try { - $messageModel->save(); - } catch (\Magento\Framework\Exception\LocalizedException $e) { - return $this->_helper->getJsonErrorResponse(); +// $messageModel = $this->_messageModel->create(); +// $messageModel->setSenderId($messageObject->senderId); +// $messageModel->setContent($messageObject->content); +// $messageModel->setChatbotType($messageObject->chatType); +// $messageModel->setContentType($messageObject->contentType); +// $messageModel->setStatus($messageObject->status); +// $messageModel->setDirection($messageObject->direction); +// $messageModel->setMessagePayload($messageObject->messagePayload); +// $messageModel->setChatMessageId($messageObject->chatMessageId); +// $messageModel->setCreatedAt($messageObject->createdAt); +// $messageModel->setUpdatedAt($messageObject->updatedAt); + +// try { +// $messageModel->save(); +// } catch (\Magento\Framework\Exception\LocalizedException $e) { +// return $this->_helper->getJsonErrorResponse(); +// } + $messageModel = $this->_helper->createIncomingMessage($messageObject); + if ($messageModel->getMessageId()) + { + $messageQueueMode = $this->_helper->getQueueMessageMode(); + if (($messageQueueMode == $this->_define::QUEUE_NONE) || ($messageQueueMode == $this->_define::QUEUE_NON_RESTRICTIVE)) + { + $outgoingMessages = $this->_helper->processIncomingMessage($messageModel); + foreach ($outgoingMessages as $outgoingMessage) + { + $result = $this->_helper->processOutgoingMessage($outgoingMessage); + } + } + else if (($messageQueueMode == $this->_define::QUEUE_RESTRICTIVE) || ($messageQueueMode == $this->_define::QUEUE_SIMPLE_RESTRICTIVE)) + { + $result = $this->_helper->processIncomingMessageQueueBySenderId($messageModel->getSenderId()); + if ($result) + $result = $this->_helper->processOutgoingMessageQueueBySenderId($messageModel->getSenderId()); + } } - $result = $this->_helper->processMessage($messageModel->getMessageId()); + else + return $this->_helper->getJsonErrorResponse(); - return $this->_helper->getJsonSuccessResponse(); + return $this->getJsonSuccessResponse(); } public function getConfigValue($code) @@ -119,6 +139,18 @@ protected function getJsonErrorResponse() return $this->_helper->getJsonErrorResponse(); } + protected function getJsonSuccessResponse() + { + return $this->_helper->getJsonSuccessResponse(); + } + + protected function logPostData($data, $file = 'werules_chatbot.log') + { + $postLog = ($this->getConfigValue('werules_chatbot_general/general/enable_post_log') == $this->_define::ENABLED); + if ($postLog) + $this->_helper->logger($data, $file); + } + // public function getDefine() // { // return $this->_define; diff --git a/Magento2/app/code/Werules/Chatbot/Block/Webhook/Messenger.php b/Magento2/app/code/Werules/Chatbot/Block/Webhook/Messenger.php index 2a6411e..325ace7 100644 --- a/Magento2/app/code/Werules/Chatbot/Block/Webhook/Messenger.php +++ b/Magento2/app/code/Werules/Chatbot/Block/Webhook/Messenger.php @@ -85,11 +85,13 @@ protected function processRequest() else // process message { $messengerInstance = $this->getMessengerInstance(); - $postLog = ($this->getConfigValue('werules_chatbot_general/general/enable_post_log') == $this->_define::ENABLED); - if ($postLog) - $this->_helper->logger($messengerInstance->getPostData(), 'werules_chatbot_messenger.log'); + $this->logPostData($messengerInstance->getPostData(), 'werules_chatbot_messenger.log'); + $messageObject = $this->createMessageObject($messengerInstance); - $result = $this->messageHandler($messageObject); + if (isset($messageObject->content)) + $result = $this->messageHandler($messageObject); + else + $result = $this->getJsonSuccessResponse(); // return success to avoid receiving the same message again } // } // else @@ -108,18 +110,26 @@ protected function getMessengerInstance() protected function createMessageObject($messenger) { $messageObject = new \stdClass(); - $messageObject->senderId = $messenger->ChatID(); if ($messenger->Text()) $content = $messenger->Text(); else $content = $messenger->getPostbackTitle(); + if (!$content) + return $messageObject; + + $messageObject->senderId = $messenger->ChatID(); $messageObject->content = $content; $messageObject->status = $this->_define::PROCESSING; $messageObject->direction = $this->_define::INCOMING; $messageObject->chatType = $this->_define::MESSENGER_INT; // TODO $messageObject->contentType = $this->_define::CONTENT_TEXT; // TODO + $messageObject->currentCommandDetails = $this->_define::CURRENT_COMMAND_DETAILS_DEFAULT; // TODO $messageObject->messagePayload = $this->getMessengerPayload($messenger); // TODO $messageObject->chatMessageId = $messenger->MessageID(); + if ($messenger->getMessageTimestamp()) + $messageObject->sentAt = (int)$messenger->getMessageTimestamp(); + else + $messageObject->sentAt = time(); $datetime = date('Y-m-d H:i:s'); $messageObject->createdAt = $datetime; $messageObject->updatedAt = $datetime; diff --git a/Magento2/app/code/Werules/Chatbot/Cron/Worker.php b/Magento2/app/code/Werules/Chatbot/Cron/Worker.php index 0236a7d..59055a7 100644 --- a/Magento2/app/code/Werules/Chatbot/Cron/Worker.php +++ b/Magento2/app/code/Werules/Chatbot/Cron/Worker.php @@ -61,29 +61,68 @@ public function execute() // ->addFieldToFilter('status', array('eq' => '0')); // } // } - $processingLimit = $this->_define::SECONDS_IN_MINUTE * 3; - $messageCollection = $this->_messageModel->getCollection() - ->addFieldToFilter('status', array('neq' => $this->_define::PROCESSED)) - ; - foreach ($messageCollection as $message) { - $result = true; - $datetime = date('Y-m-d H:i:s'); - if ($message->getStatus() == $this->_define::NOT_PROCESSED) + if ($this->_helper->getConfigValue('werules_chatbot_danger/general/clear_message_pending') == $this->_define::CLEAR_MESSAGE_QUEUE) + { + $messageSenderId = $this->_helper->getConfigValue('werules_chatbot_danger/general/clear_message_sender_id'); + if ($messageSenderId) { - $message->updateMessageStatus($this->_define::PROCESSING); - $result = $this->_helper->processMessage($message->getMessageId()); + $messageCollection = $this->_messageModel->getCollection() + ->addFieldToFilter('sender_id', array('eq' => $messageSenderId)) + ; } - else if (($message->getStatus() == $this->_define::PROCESSING) && ((strtotime($datetime) - strtotime($message->getUpdatedAt())) > $processingLimit)) + else + $messageCollection = $this->_messageModel->getCollection(); + + foreach ($messageCollection as $message) { - // if a message is in 'processing' status for more than 3 minutes, try to reprocess it -// $message->updateMessageStatus($this->_define::PROCESSING); // already on 'processing' status - $result = $this->_helper->processMessage($message->getMessageId()); + $message->updateMessageStatus($this->_define::PROCESSED); } - if (!$result) - $message->updateMessageStatus($this->_define::NOT_PROCESSED); + $this->_helper->setConfigValue('werules_chatbot_danger/general/clear_message_pending', $this->_define::DONT_CLEAR_MESSAGE_QUEUE); + } + + $messageQueueMode = $this->_helper->getQueueMessageMode(); + if (($messageQueueMode == $this->_define::QUEUE_NONE) || ($messageQueueMode == $this->_define::QUEUE_NON_RESTRICTIVE)) + { + $processingLimit = $this->_define::QUEUE_PROCESSING_LIMIT; + $messageCollection = $this->_messageModel->getCollection() + ->addFieldToFilter('status', array('neq' => $this->_define::PROCESSED)) + ; + foreach ($messageCollection as $message) + { + $result = array(); + $datetime = date('Y-m-d H:i:s'); + if ( // if not processed neither in the processing queue limit + ($message->getStatus() == $this->_define::NOT_PROCESSED) || + (($message->getStatus() == $this->_define::PROCESSING) && ((strtotime($datetime) - strtotime($message->getUpdatedAt())) > $processingLimit)) + ) + { +// $message->updateMessageStatus($this->_define::PROCESSING); + if ($message->getDirection() == $this->_define::INCOMING) + $result = $this->_helper->processIncomingMessage($message); + else //if ($message->getDirection() == $this->_define::OUTGOING) + $result = $this->_helper->processOutgoingMessage($message); + } + + if (!$result) + $message->updateMessageStatus($this->_define::NOT_PROCESSED); // else // $this->_logger->addInfo('Result of MessageID ' . $message->getMessageId() . ':\n' . var_export($result, true)); + } + } + else if (($messageQueueMode == $this->_define::QUEUE_RESTRICTIVE) || ($messageQueueMode == $this->_define::QUEUE_SIMPLE_RESTRICTIVE)) + { + // get all messages with different sender_id values (aka list of all sender_id) + $uniqueMessageCollection = $this->_messageModel->getCollection()->distinct(true); + $uniqueMessageCollection->getSelect()->group('sender_id'); + + foreach ($uniqueMessageCollection as $message) + { + // foreach unique sender_id, process all their queue messages + $result = $this->_helper->processIncomingMessageQueueBySenderId($message->getSenderId()); + if ($result) + $result = $this->_helper->processOutgoingMessageQueueBySenderId($message->getSenderId()); + } } // $this->_logger->addInfo("Chatbot Cronjob was executed."); } diff --git a/Magento2/app/code/Werules/Chatbot/Helper/Data.php b/Magento2/app/code/Werules/Chatbot/Helper/Data.php index cd33dea..909d031 100644 --- a/Magento2/app/code/Werules/Chatbot/Helper/Data.php +++ b/Magento2/app/code/Werules/Chatbot/Helper/Data.php @@ -26,8 +26,9 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper { protected $storeManager; - protected $objectManager; +// protected $objectManager; protected $_messageModelFactory; + protected $_messageModel; protected $_chatbotAPIFactory; protected $_chatbotUserFactory; protected $_serializer; @@ -38,6 +39,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper protected $_productCollection; protected $_customerRepositoryInterface; protected $_quoteModel; + protected $_configWriter; protected $_imageHelper; protected $_stockRegistry; protected $_stockFilter; @@ -49,6 +51,7 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper // not from construct parameters protected $_define; + protected $_messageQueueMode; protected $_configPrefix; protected $_commandsList; protected $_completeCommandsList; @@ -58,11 +61,12 @@ class Data extends \Magento\Framework\App\Helper\AbstractHelper public function __construct( \Magento\Framework\App\Helper\Context $context, - \Magento\Framework\ObjectManagerInterface $objectManager, +// \Magento\Framework\ObjectManagerInterface $objectManager, \Magento\Framework\Serialize\Serializer\Json $serializer, \Werules\Chatbot\Model\ChatbotAPIFactory $chatbotAPI, \Werules\Chatbot\Model\ChatbotUserFactory $chatbotUser, - \Werules\Chatbot\Model\MessageFactory $message, + \Werules\Chatbot\Model\MessageFactory $messageFactory, + \Werules\Chatbot\Model\Message $message, \Magento\Catalog\Helper\Category $categoryHelper, \Magento\Catalog\Model\CategoryFactory $categoryFactory, \Magento\Catalog\Model\ResourceModel\Category\CollectionFactory $categoryCollectionFactory, @@ -74,6 +78,7 @@ public function __construct( // \Magento\Quote\Api\CartManagementInterface $cartManagementInterface, // \Magento\Quote\Api\CartRepositoryInterface $cartRepositoryInterface, // \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig, + \Magento\Framework\App\Config\Storage\WriterInterface $configWriter, \Magento\Catalog\Helper\Image $imageHelper, \Magento\CatalogInventory\Api\StockRegistryInterface $stockRegistry, \Magento\CatalogInventory\Helper\Stock $stockFilter, @@ -81,13 +86,12 @@ public function __construct( \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollection ) { - $this->objectManager = $objectManager; $this->_serializer = $serializer; $this->storeManager = $storeManager; - $this->_messageModelFactory = $message; + $this->_messageModel = $message; + $this->_messageModelFactory = $messageFactory; $this->_chatbotAPIFactory = $chatbotAPI; $this->_chatbotUserFactory = $chatbotUser; - $this->_define = new \Werules\Chatbot\Helper\Define; $this->_categoryHelper = $categoryHelper; $this->_categoryFactory = $categoryFactory; $this->_categoryCollectionFactory = $categoryCollectionFactory; @@ -96,13 +100,16 @@ public function __construct( $this->_quoteModel = $quoteModel; $this->_stockRegistry = $stockRegistry; $this->_stockFilter = $stockFilter; + $this->_configWriter = $configWriter; + $this->_imageHelper = $imageHelper; + $this->_priceHelper = $priceHelper; + $this->_productCollection = $productCollection; +// $this->objectManager = $objectManager; // $this->_cartModel = $cartModel; // $this->_cartManagementInterface = $cartManagementInterface; // $this->_cartRepositoryInterface = $cartRepositoryInterface; // $this->_storeConfig = $scopeConfig; - $this->_imageHelper = $imageHelper; - $this->_priceHelper = $priceHelper; - $this->_productCollection = $productCollection; + $this->_define = new \Werules\Chatbot\Helper\Define; parent::__construct($context); } @@ -133,46 +140,126 @@ private function generateRandomHashKey($len = 32) return substr(md5(openssl_random_pseudo_bytes(20)), -$len); } - public function processMessage($messageId) + public function processIncomingMessageQueueBySenderId($senderId) + { + $outgoingMessageList = array(); + $messageQueueMode = $this->getQueueMessageMode(); + $messageCollection = $this->getMessageCollectionBySenderIdAndDirection($senderId, $this->_define::INCOMING); + + foreach ($messageCollection as $message) + { + $datetime = date('Y-m-d H:i:s'); + $processingLimit = $this->_define::QUEUE_PROCESSING_LIMIT; + // if processed or not in the processing queue limit + if (($message->getStatus() == $this->_define::PROCESSED) || (($message->getStatus() == $this->_define::PROCESSING) && ((strtotime($datetime) - strtotime($message->getUpdatedAt())) > $processingLimit))) + continue; + + $outgoingMessageList = $this->processIncomingMessage($message); + if (!$outgoingMessageList) + { + if ($messageQueueMode != $this->_define::QUEUE_SIMPLE_RESTRICTIVE) + break; + } + } + + return $outgoingMessageList; + } + + public function processOutgoingMessageQueueBySenderId($senderId) { - $message = $this->getMessageModelById($messageId); $result = array(); + $messageQueueMode = $this->getQueueMessageMode(); + $messageCollection = $this->getMessageCollectionBySenderIdAndDirection($senderId, $this->_define::OUTGOING); - if ($message->getMessageId()) + foreach ($messageCollection as $message) { - if ($message->getDirection() == $this->_define::INCOMING) - $result = $this->processIncomingMessage($message); - else //if ($message->getDirection() == $this->_define::OUTGOING) - $result = $this->processOutgoingMessage($message); + $datetime = date('Y-m-d H:i:s'); + $processingLimit = $this->_define::QUEUE_PROCESSING_LIMIT; + // if processed or not in the processing queue limit + if (($message->getStatus() == $this->_define::PROCESSED) || (($message->getStatus() == $this->_define::PROCESSING) && ((strtotime($datetime) - strtotime($message->getUpdatedAt())) > $processingLimit))) + continue; + + $result = $this->processOutgoingMessage($message); + if (!$result) + { + if ($messageQueueMode == $this->_define::QUEUE_SIMPLE_RESTRICTIVE) + { + // only breaks the loop if it's a message that changes conversation state + if ($message->getCurrentCommandDetails()) + { + $currentCommandDetails = json_decode($message->getCurrentCommandDetails()); + if (isset($currentCommandDetails->conversation_state)) + break; + } + } + else + break; + } } return $result; } - private function processIncomingMessage($message) +// public function processMessage($messageId) +// { +// $message = $this->getMessageModelById($messageId); +// $result = false; +// +// if ($message->getMessageId()) +// { +// $message->updateMessageStatus($this->_define::PROCESSING); +// if ($message->getDirection() == $this->_define::INCOMING) +// $result = $this->processIncomingMessage($message); +// else //if ($message->getDirection() == $this->_define::OUTGOING) +// $result = $this->processOutgoingMessage($message); +// } +// +// return $result; +// } + + public function processIncomingMessage($message) { + $messageQueueMode = $this->getQueueMessageMode(); + if (($messageQueueMode == $this->_define::QUEUE_NONE) && ($message->getStatus() != $this->_define::PROCESSED)) + $message->updateIncomingMessageStatus($this->_define::PROCESSED); + else if ($message->getStatus() != $this->_define::PROCESSING) + $message->updateIncomingMessageStatus($this->_define::PROCESSING); + $this->setConfigPrefix($message->getChatbotType()); $chatbotAPI = $this->getChatbotAPIModelBySenderId($message->getSenderId()); - $result = true; + $result = array(); if (!($chatbotAPI->getChatbotapiId())) { $chatbotAPI = $this->createChatbotAPI($chatbotAPI, $message); - $this->sendWelcomeMessage($message); + $welcomeMessage = $this->getWelcomeMessage($message); + if ($welcomeMessage) + array_push($result, $welcomeMessage); } $enabled = $this->getConfigValue($this->_configPrefix . '/general/enable'); if ($enabled == $this->_define::DISABLED) - $this->sendDisabledMessage($message); + $outgoingMessages = $this->getDisabledMessage($message); else if ($chatbotAPI->getEnabled() == $this->_define::DISABLED) - $this->sendDisabledByCustomerMessage($message); + $outgoingMessages = $this->getDisabledByCustomerMessage($message); else { // all good, let's process the request $this->setChatbotAPIModel($chatbotAPI); - $result = $this->prepareOutgoingMessage($message); + $outgoingMessages = $this->prepareOutgoingMessage($message); + } + + if ($outgoingMessages) + { + foreach ($outgoingMessages as $outgoingMessage) + { + array_push($result, $outgoingMessage); + } } + if (($result) && ($message->getStatus() != $this->_define::PROCESSED)) + $message->updateIncomingMessageStatus($this->_define::PROCESSED); + // $this->logger("Message ID -> " . $message->getMessageId()); // $this->logger("Message Content -> " . $message->getContent()); // $this->logger("ChatbotAPI ID -> " . $chatbotAPI->getChatbotapiId()); @@ -183,13 +270,13 @@ private function processIncomingMessage($message) private function prepareOutgoingMessage($message) { $responseContents = $this->processMessageRequest($message); - $result = false; + $outgoingMessages = array(); if ($responseContents) { - $result = $message->updateIncomingMessageStatus($this->_define::PROCESSED); +// $result = $message->updateIncomingMessageStatus($this->_define::PROCESSED); +// if ($result) // TODO - $outgoingMessages = array(); foreach ($responseContents as $content) { // first guarantee outgoing message is saved @@ -197,21 +284,29 @@ private function prepareOutgoingMessage($message) array_push($outgoingMessages, $outgoingMessage); } - foreach ($outgoingMessages as $outMessage) - { - // then process outgoing message - $this->processOutgoingMessage($outMessage); // ignore output - } +// if (count($responseContents) != count($outgoingMessages)) // TODO + +// foreach ($outgoingMessages as $outMessage) +// { +// // then process outgoing message +// $this->processOutgoingMessage($outMessage); // ignore output +// } } - return $result; + return $outgoingMessages; } - private function processOutgoingMessage($outgoingMessage) + public function processOutgoingMessage($outgoingMessage) { + $result = true; + $messageQueueMode = $this->getQueueMessageMode(); + if ($messageQueueMode == $this->_define::QUEUE_NONE && ($outgoingMessage->getStatus() != $this->_define::PROCESSED)) + $outgoingMessage->updateOutgoingMessageStatus($this->_define::PROCESSED); + else if ($outgoingMessage->getStatus() != $this->_define::PROCESSING) + $outgoingMessage->updateOutgoingMessageStatus($this->_define::PROCESSING); + $chatbotAPI = $this->getChatbotAPIModelBySenderId($outgoingMessage->getSenderId()); - $result = array(); if ($outgoingMessage->getContentType() == $this->_define::CONTENT_TEXT) $result = $chatbotAPI->sendMessage($outgoingMessage); else if ($outgoingMessage->getContentType() == $this->_define::QUICK_REPLY) @@ -225,11 +320,43 @@ private function processOutgoingMessage($outgoingMessage) if ($result) { -// $outgoingMessage->setStatus($this->_define::PROCESSED); -// $datetime = date('Y-m-d H:i:s'); -// $outgoingMessage->setUpdatedAt($datetime); -// $outgoingMessage->save(); - $outgoingMessage->updateOutgoingMessageStatus($this->_define::PROCESSED); + if ($outgoingMessage->getCurrentCommandDetails()) + { + $currentCommandDetails = json_decode($outgoingMessage->getCurrentCommandDetails()); + + if (isset($currentCommandDetails->conversation_state)) + { + if ($chatbotAPI->getConversationState() != $currentCommandDetails->conversation_state) + $chatbotAPI->updateConversationState($currentCommandDetails->conversation_state); + } + + if (isset($currentCommandDetails->list_more_conversation_state)) + $lastConversationState = $currentCommandDetails->list_more_conversation_state; + else + $lastConversationState = null; + + if (isset($currentCommandDetails->listed_quantity)) + $lastListedQuantity = $currentCommandDetails->listed_quantity; + else + $lastListedQuantity = null; + + if (isset($currentCommandDetails->command_text)) + $lastCommandText = $currentCommandDetails->command_text; + else + $lastCommandText = null; + + if (isset($currentCommandDetails->command_parameter)) + $lastCommandParameter = $currentCommandDetails->command_parameter; + else + $lastCommandParameter = null; + + $chatbotAPI->setChatbotAPILastCommandDetails($lastCommandText, $lastListedQuantity, $lastConversationState, $lastCommandParameter); + } + + if ($outgoingMessage->getStatus() != $this->_define::PROCESSED) + $outgoingMessage->updateOutgoingMessageStatus($this->_define::PROCESSED); + + $outgoingMessage->updateSentAt(time()); } // $this->logger("Outgoing Message ID -> " . $outgoingMessage->getMessageId()); @@ -248,11 +375,14 @@ private function processMessageRequest($message) $payloadCommandResponses = array(); $NLPResponses = array(); $this->setHelperMessageAttributes($message); - $this->setLastCommandDetails($message); + +// $lastMessageDetails = $this->getLastCommandDetailsForMessage($message); // this message is only set to save current command details +// if ($lastMessageDetails) +// array_push($responseContent, $lastMessageDetails); // first of all must check if it's a cancel command $command = $this->getCurrentCommand($message->getContent()); - $cancelResponses = $this->checkCancelCommand($command, $message->getSenderId()); + $cancelResponses = $this->checkCancelCommand($command); if ($cancelResponses) { foreach ($cancelResponses as $cancelResponse) @@ -318,40 +448,6 @@ private function processMessageRequest($message) return $responseContent; } - private function sendWelcomeMessage($message) - { -// $this->setHelperMessageAttributes($message); - $text = $this->getConfigValue($this->_configPrefix . '/general/welcome_message'); - if ($text != '') - { - $contentObj = $this->getTextMessageArray($text); - $outgoingMessage = $this->createOutgoingMessage($message, reset($contentObj)); // TODO reset -> gets first item of array - $this->processOutgoingMessage($outgoingMessage); - } - } - - private function sendDisabledByCustomerMessage($message) - { - $text = __("To chat with me, please enable Messenger on your account chatbot settings."); - $contentObj = $this->getTextMessageArray($text); - $outgoingMessage = $this->createOutgoingMessage($message, reset($contentObj)); // TODO reset -> gets first item of array - $this->processOutgoingMessage($outgoingMessage); - } - - private function sendDisabledMessage($message) - { -// $this->setHelperMessageAttributes($message); - $text = $this->getConfigValue($this->_configPrefix . '/general/disabled_message'); - - if ($text != '') - $contentObj = $this->getTextMessageArray($text); - else - $contentObj = $this->getErrorMessage(); - - $outgoingMessage = $this->createOutgoingMessage($message, reset($contentObj)); // TODO reset -> gets first item of array - $this->processOutgoingMessage($outgoingMessage); - } - private function handleUnableToProcessRequest($message) { // $responseContent = array(); @@ -425,10 +521,10 @@ private function handleNaturalLanguageProcessor($message) if ($parameterValue) { if ($parameter['confidence'] >= $confidence) // check parameter confidence - $result = $this->handleCommandsWithParameters($message, $commandString, $parameterValue, $commandCode); + $result = $this->handleCommandsWithParameters($message, $parameterValue, $commandCode); } else - $result = $this->processCommands($commandString, $message->getSenderId(), false, $commandCode); + $result = $this->processCommands($commandString, $message->getSenderId(), $commandCode); if ($result) { @@ -446,7 +542,10 @@ private function handleNaturalLanguageProcessor($message) { $extraMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => $extraText + 'content' => $extraText, + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($commandCode) + )) ); array_unshift($result, $extraMessage); } @@ -462,7 +561,10 @@ private function handleNaturalLanguageProcessor($message) { $extraMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => $extraText + 'content' => $extraText, + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($commandCode) + )) ); array_unshift($result, $extraMessage); } @@ -501,25 +603,25 @@ private function handleConversationState($content, $senderId, $keyword = false) } else if ($chatbotAPI->getConversationState() == $this->_define::CONVERSATION_TRACK_ORDER) { - $result = $this->listOrderFromOrderId($messageContent, $senderId); + $result = $this->listOrderDetailsFromOrderId($messageContent, $senderId); } - if ($result) - { - $chatbotAPI->updateConversationState($this->_define::CONVERSATION_STARTED); - $this->setChatbotAPIModel($chatbotAPI); - } +// if ($result) +// { +// $chatbotAPI->updateConversationState($this->_define::CONVERSATION_STARTED); +// $this->setChatbotAPIModel($chatbotAPI); +// } return $result; } - private function listOrderFromOrderId($messageContent, $senderId) + private function listOrderDetailsFromOrderId($orderId, $senderId) { $result = array(); $orderList = array(); $chatbotUser = $this->getChatbotuserBySenderId($senderId); $ordersCollection = $this->getOrdersFromCustomerId($chatbotUser->getCustomerId()); - $ordersCollection->addFieldToFilter('increment_id', $messageContent); + $ordersCollection->addFieldToFilter('increment_id', $orderId); if (count($ordersCollection) > 0) { $orderObject = $this->getImageWithOptionsOrderObject($ordersCollection->getFirstItem()); @@ -539,22 +641,18 @@ private function listOrderFromOrderId($messageContent, $senderId) $responseMessage = array( 'content_type' => $contentType, - 'content' => $content + 'content' => $content, + 'current_command_details' => json_encode(array( + 'conversation_state' => $this->_define::CONVERSATION_STARTED, + 'command_text' => $this->getCommandText($this->_define::LIST_ORDERS_COMMAND_ID), + 'listed_quantity' => 1 + )) ); array_push($result, $responseMessage); return $result; } - private function getStockByProductId($productId) - { - $stockQty = $this->_stockRegistry->getStockItem($productId); - if ($stockQty) - return $stockQty; - - return 0; - } - private function listProductsFromSearch($messageContent, $senderId) { $result = array(); @@ -563,10 +661,16 @@ private function listProductsFromSearch($messageContent, $senderId) $productCollection = $this->getProductCollectionByName($messageContent); $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); $lastCommandObject = json_decode($chatbotAPI->getLastCommandDetails()); + $searchCommandText = $this->getCommandText($this->_define::SEARCH_COMMAND_ID); if (!isset($lastCommandObject->last_listed_quantity)) return $result; - if ($lastCommandObject->last_conversation_state == $this->_define::CONVERSATION_SEARCH) +// if ($lastCommandObject->last_conversation_state == $this->_define::CONVERSATION_SEARCH) +// $startAt = $lastCommandObject->last_listed_quantity; +// else +// $startAt = 0; + + if (strtolower($lastCommandObject->last_command_text) == strtolower($searchCommandText)) $startAt = $lastCommandObject->last_listed_quantity; else $startAt = 0; @@ -590,8 +694,10 @@ private function listProductsFromSearch($messageContent, $senderId) $totalListCount = $listCount + $startAt; if (count($productCollection) > $totalListCount) { - $chatbotAPI->setChatbotAPILastCommandDetails($messageContent, $totalListCount); - $this->setChatbotAPIModel($chatbotAPI); +// $chatbotAPI->setChatbotAPILastCommandDetails($messageContent, $totalListCount); +// $this->setChatbotAPIModel($chatbotAPI); + $conversationState = $chatbotAPI->getConversationState(); + $commandText = $searchCommandText; if ($listCount > 0) $extraListMessage = $this->getListMoreMessage(); } @@ -600,9 +706,13 @@ private function listProductsFromSearch($messageContent, $senderId) if (($listCount > 0) && ($startAt != 0)) $extraListMessage = $this->getLastListItemMessage(); - $chatbotAPI->updateConversationState($this->_define::CONVERSATION_STARTED); - $chatbotAPI->setChatbotAPILastCommandDetails($this->getCommandText($this->_define::LIST_MORE_COMMAND_ID), 0); - $this->setChatbotAPIModel($chatbotAPI); + // TODO make this cleaner +// $chatbotAPI->updateConversationState($this->_define::CONVERSATION_STARTED); +// $chatbotAPI->setChatbotAPILastCommandDetails($this->getCommandText($this->_define::LIST_MORE_COMMAND_ID), 0, $this->_define::CONVERSATION_STARTED); +// $this->setChatbotAPIModel($chatbotAPI); + $totalListCount = 0; + $commandText = $this->getCommandText($this->_define::LIST_MORE_COMMAND_ID); + $conversationState = $this->_define::CONVERSATION_STARTED; } if ($listCount > 0) @@ -621,7 +731,14 @@ private function listProductsFromSearch($messageContent, $senderId) // $responseMessage['content'] = $content; $responseMessage = array( 'content_type' => $contentType, - 'content' => $content + 'content' => $content, + 'current_command_details' => json_encode(array( + 'list_more_conversation_state' => $conversationState, + 'command_parameter' => $messageContent, + 'command_text' => $commandText, + 'listed_quantity' => $totalListCount, + 'conversation_state' => $this->_define::CONVERSATION_STARTED + )) ); array_push($result, $responseMessage); if ($extraListMessage) @@ -649,10 +766,16 @@ private function listProductsFromCategory($messageContent, $messagePayload, $sen $productCollection = $this->getProductsFromCategoryId($category->getId()); $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); $lastCommandObject = json_decode($chatbotAPI->getLastCommandDetails()); + $listCategoriesText = $this->getCommandText($this->_define::LIST_CATEGORIES_COMMAND_ID); if (!isset($lastCommandObject->last_listed_quantity)) return $result; - if ($lastCommandObject->last_conversation_state == $this->_define::CONVERSATION_LIST_CATEGORIES) +// if ($lastCommandObject->last_conversation_state == $this->_define::CONVERSATION_LIST_CATEGORIES) +// $startAt = $lastCommandObject->last_listed_quantity; +// else +// $startAt = 0; + + if (strtolower($lastCommandObject->last_command_text) == strtolower($listCategoriesText)) $startAt = $lastCommandObject->last_listed_quantity; else $startAt = 0; @@ -676,8 +799,10 @@ private function listProductsFromCategory($messageContent, $messagePayload, $sen $totalListCount = $listCount + $startAt; if (count($productCollection) > $totalListCount) { - $chatbotAPI->setChatbotAPILastCommandDetails($messageContent, $totalListCount); - $this->setChatbotAPIModel($chatbotAPI); +// $chatbotAPI->setChatbotAPILastCommandDetails($messageContent, $totalListCount); +// $this->setChatbotAPIModel($chatbotAPI); + $conversationState = $chatbotAPI->getConversationState(); + $commandText = $listCategoriesText; if ($listCount > 0) $extraListMessage = $this->getListMoreMessage(); } @@ -686,9 +811,13 @@ private function listProductsFromCategory($messageContent, $messagePayload, $sen if (($listCount > 0) && ($startAt != 0)) $extraListMessage = $this->getLastListItemMessage(); - $chatbotAPI->updateConversationState($this->_define::CONVERSATION_STARTED); - $chatbotAPI->setChatbotAPILastCommandDetails($this->getCommandText($this->_define::LIST_MORE_COMMAND_ID), 0); - $this->setChatbotAPIModel($chatbotAPI); + // TODO make this cleaner +// $chatbotAPI->updateConversationState($this->_define::CONVERSATION_STARTED); +// $chatbotAPI->setChatbotAPILastCommandDetails($this->getCommandText($this->_define::LIST_MORE_COMMAND_ID), 0, $this->_define::CONVERSATION_STARTED); +// $this->setChatbotAPIModel($chatbotAPI); + $totalListCount = 0; + $commandText = $this->getCommandText($this->_define::LIST_MORE_COMMAND_ID); + $conversationState = $this->_define::CONVERSATION_STARTED; } if ($listCount > 0) @@ -707,7 +836,14 @@ private function listProductsFromCategory($messageContent, $messagePayload, $sen // $responseMessage['content'] = $content; $responseMessage = array( 'content_type' => $contentType, - 'content' => $content + 'content' => $content, + 'current_command_details' => json_encode(array( + 'list_more_conversation_state' => $conversationState, + 'command_parameter' => $messageContent, + 'command_text' => $commandText, + 'listed_quantity' => $totalListCount, + 'conversation_state' => $this->_define::CONVERSATION_STARTED + )) ); array_push($result, $responseMessage); if ($extraListMessage) @@ -746,11 +882,11 @@ private function prepareCommandsList() return true; } - private function checkCancelCommand($command, $senderId) + private function checkCancelCommand($command) { $result = array(); if ($command == $this->_define::CANCEL_COMMAND_ID) - $result = $this->processCancelCommand($senderId); + $result = $this->processCancelCommand(); return $result; } @@ -775,195 +911,140 @@ private function processPayloadCommands($message) return $result; } - private function processCommands($messageContent, $senderId, $setStateOnly = false, $command = '', $payload = false) + private function processCommands($messageContent, $senderId, $commandCode = '', $payload = false) { // $messageContent = $message->getContent(); $result = array(); - $state = false; - if (!$command) - $command = $this->getCurrentCommand($messageContent); + if (!$commandCode) + $commandCode = $this->getCurrentCommand($messageContent); if (!$payload) $payload = $this->getCurrentMessagePayload(); - if ($command) + if ($commandCode) { - if ($command == $this->_define::START_COMMAND_ID) + if ($commandCode == $this->_define::START_COMMAND_ID) + $result = $this->processStartCommand(); + else if ($commandCode == $this->_define::LIST_CATEGORIES_COMMAND_ID) // changes conversation state + $result = $this->processListCategoriesCommand(); + else if ($commandCode == $this->_define::SEARCH_COMMAND_ID) // changes conversation state + $result = $this->processSearchCommand(); + else if ($commandCode == $this->_define::LOGIN_COMMAND_ID) { - if (!$setStateOnly) - $result = $this->processStartCommand(); - } - else if ($command == $this->_define::LIST_CATEGORIES_COMMAND_ID) - { - if (!$setStateOnly) - $result = $this->processListCategoriesCommand(); - $state = $this->_define::CONVERSATION_LIST_CATEGORIES; - } - else if ($command == $this->_define::SEARCH_COMMAND_ID) - { - if (!$setStateOnly) - $result = $this->processSearchCommand(); - $state = $this->_define::CONVERSATION_SEARCH; - } - else if ($command == $this->_define::LOGIN_COMMAND_ID) - { - if (!$setStateOnly) + $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); + if ($chatbotAPI->getLogged() == $this->_define::NOT_LOGGED) + $result = $this->processLoginCommand($senderId); + else { - $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); - if ($chatbotAPI->getLogged() == $this->_define::NOT_LOGGED) - $result = $this->processLoginCommand($senderId); - else - { - $text = __("You are already logged."); - $result = $this->getTextMessageArray($text); - } + $text = __("You are already logged."); + $result = $this->getTextMessageArray($text); } } - else if ($command == $this->_define::LIST_ORDERS_COMMAND_ID) + else if ($commandCode == $this->_define::LIST_ORDERS_COMMAND_ID) { $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); if ($chatbotAPI->getLogged() == $this->_define::LOGGED) - { - if (!$setStateOnly) - $result = $this->processListOrdersCommand($senderId); - } + $result = $this->processListOrdersCommand($senderId); else $result = $this->getNotLoggedMessage(); } -// else if ($command == $this->_define::REORDER_COMMAND_ID) +// else if ($commandCode == $this->_define::REORDER_COMMAND_ID) // { // $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); // if ($chatbotAPI->getLogged() == $this->_define::LOGGED) -// { -// if (!$setStateOnly) -// $result = $this->processReorderCommand(); -// } +// $result = $this->processReorderCommand($payload, $senderId); // else -// $result = $this->getNotLoggedMessage(); +// $result = $this->getNotLoggedMessage(); // } - else if ($command == $this->_define::ADD_TO_CART_COMMAND_ID) + else if ($commandCode == $this->_define::ADD_TO_CART_COMMAND_ID) { $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); if ($chatbotAPI->getLogged() == $this->_define::LOGGED) { - if (!$setStateOnly) - { - if ($payload) - $result = $this->processAddToCartCommand($senderId, $payload); - else - $result = $this->getErrorMessage(); - } + if ($payload) + $result = $this->processAddToCartCommand($senderId, $payload); + else + $result = $this->getErrorMessage(); } else $result = $this->getNotLoggedMessage(); } - else if ($command == $this->_define::CHECKOUT_COMMAND_ID) + else if ($commandCode == $this->_define::CHECKOUT_COMMAND_ID) { $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); if ($chatbotAPI->getLogged() == $this->_define::LOGGED) - { - if (!$setStateOnly) - $result = $this->processCheckoutCommand($senderId); - } + $result = $this->processCheckoutCommand($senderId); else $result = $this->getNotLoggedMessage(); } - else if ($command == $this->_define::CLEAR_CART_COMMAND_ID) - { - if (!$setStateOnly) - $result = $this->processClearCartCommand($senderId); - } - else if ($command == $this->_define::TRACK_ORDER_COMMAND_ID) + else if ($commandCode == $this->_define::CLEAR_CART_COMMAND_ID) + $result = $this->processClearCartCommand($senderId); + else if ($commandCode == $this->_define::TRACK_ORDER_COMMAND_ID) // changes conversation state { $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); if ($chatbotAPI->getLogged() == $this->_define::LOGGED) - { - if (!$setStateOnly) - $result = $this->processTrackOrderCommand(); - $state = $this->_define::CONVERSATION_TRACK_ORDER; - } + $result = $this->processTrackOrderCommand(); else $result = $this->getNotLoggedMessage(); } - else if ($command == $this->_define::SUPPORT_COMMAND_ID) - { - if (!$setStateOnly) - $result = $this->processSupportCommand(); - } - else if ($command == $this->_define::SEND_EMAIL_COMMAND_ID) - { - if (!$setStateOnly) - $result = $this->processSendEmailCommand(); - $state = $this->_define::CONVERSATION_EMAIL; - } - else if ($command == $this->_define::CANCEL_COMMAND_ID) - { - if (!$setStateOnly) - $result = $this->processCancelCommand($senderId); - } - else if ($command == $this->_define::HELP_COMMAND_ID) - { - if (!$setStateOnly) - $result = $this->processHelpCommand(); - } - else if ($command == $this->_define::ABOUT_COMMAND_ID) - { - if (!$setStateOnly) - $result = $this->processAboutCommand(); - } - else if ($command == $this->_define::LOGOUT_COMMAND_ID) + else if ($commandCode == $this->_define::SUPPORT_COMMAND_ID) + $result = $this->processSupportCommand(); + else if ($commandCode == $this->_define::SEND_EMAIL_COMMAND_ID) // changes conversation state + $result = $this->processSendEmailCommand(); + else if ($commandCode == $this->_define::CANCEL_COMMAND_ID) + $result = $this->processCancelCommand(); + else if ($commandCode == $this->_define::HELP_COMMAND_ID) + $result = $this->processHelpCommand(); + else if ($commandCode == $this->_define::ABOUT_COMMAND_ID) + $result = $this->processAboutCommand(); + else if ($commandCode == $this->_define::LOGOUT_COMMAND_ID) { $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); if ($chatbotAPI->getLogged() == $this->_define::LOGGED) { - if (!$setStateOnly) - $result = $this->processLogoutCommand($senderId); + $result = $this->processLogoutCommand($senderId); } else $result = $this->getNotLoggedMessage(); } - else if ($command == $this->_define::REGISTER_COMMAND_ID) + else if ($commandCode == $this->_define::REGISTER_COMMAND_ID) { $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); if ($chatbotAPI->getLogged() == $this->_define::NOT_LOGGED) - { - if (!$setStateOnly) - $result = $this->processRegisterCommand(); - } + $result = $this->processRegisterCommand(); else { $text = __("You are already registered."); $result = $this->getTextMessageArray($text); } } - else if ($command == $this->_define::LIST_MORE_COMMAND_ID) + else if ($commandCode == $this->_define::LIST_MORE_COMMAND_ID) { $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); $lastCommandObject = json_decode($chatbotAPI->getLastCommandDetails()); - - if (!$setStateOnly) - $result = $this->processListMore($lastCommandObject, $senderId); + $result = $this->processListMore($lastCommandObject, $senderId); } else // should never fall in here - { $result = $this->getConfusedMessage(); - } - } - if ($state && (($result) || $setStateOnly)) // TODO - { - $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); - $chatbotAPI->updateConversationState($state); - $this->setChatbotAPIModel($chatbotAPI); } +// $state = $this->getCommandConversationState($commandCode); +// if (($state !== null) && $result) // TODO +// { +// $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); +// $chatbotAPI->updateConversationState($state); +// $this->setChatbotAPIModel($chatbotAPI); +// } + return $result; } - private function handleCommandsWithParameters($message, $command, $keyword, $commandCode) + private function handleCommandsWithParameters($message, $keyword, $commandCode) { - $result = $this->processCommands($command, $message->getSenderId(), true, $commandCode); // should return empty array - if ($result) - return $result; // if this happens, means there's an error message + $chatbotAPI = $this->getChatbotAPIModelBySenderId($message->getSenderId()); + $state = $this->getCommandConversationState($commandCode); + if ($state) + $chatbotAPI->updateConversationState($state); $result = $this->handleConversationState($message->getContent(), $message->getSenderId(), $keyword); return $result; @@ -976,7 +1057,13 @@ private function handlePayloadCommands($message) private function handleCommands($message) { - $result = $this->processCommands($message->getContent(), $message->getSenderId()); + // TODO uncomment this to dirty accepet typed orders number +// $chatbotAPI = $this->getChatbotAPIModelBySenderId($message->getSenderId()); +// $lastCommandObject = json_decode($chatbotAPI->getLastCommandDetails()); +// if (strtolower($lastCommandObject->last_command_text) == strtolower($this->getCommandText($this->_define::LIST_ORDERS_COMMAND_ID))) +// $result = $this->processCommands('', $message->getSenderId(), $this->_define::REORDER_COMMAND_ID, $message->getContent()); +// else + $result = $this->processCommands($message->getContent(), $message->getSenderId()); return $result; } @@ -986,19 +1073,18 @@ private function sendEmailFromMessage($text) $result = array(); $response = $this->sendZendEmail($text); if ($response) - { - $responseMessage = array( - 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("Email sent.") - ); - } + $text = __("Email sent."); else - { - $responseMessage = array( - 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("Sorry, I wasn't able to send an email this time. Please try again later.") - ); - } + $text = __("Sorry, I wasn't able to send an email this time. Please try again later."); + + $responseMessage = array( + 'content_type' => $this->_define::CONTENT_TEXT, + 'content' => $text, + 'current_command_details' => json_encode(array( + 'conversation_state' => $this->_define::CONVERSATION_STARTED, + 'command_text' => $this->getCommandText($this->_define::SEND_EMAIL_COMMAND_ID) + )) + ); array_push($result, $responseMessage); return $result; @@ -1102,16 +1188,41 @@ public function createChatbotAPI($chatbotAPI, $message) return $chatbotAPI; } + public function createIncomingMessage($messageObject) + { + $incomingMessage = $this->_messageModelFactory->create(); + if (isset($messageObject->senderId)) + { + $incomingMessage->setSenderId($messageObject->senderId); + $incomingMessage->setContent($messageObject->content); + $incomingMessage->setChatbotType($messageObject->chatType); + $incomingMessage->setContentType($messageObject->contentType); + $incomingMessage->setCurrentCommandDetails($messageObject->currentCommandDetails); + $incomingMessage->setStatus($messageObject->status); + $incomingMessage->setDirection($messageObject->direction); + $incomingMessage->setMessagePayload($messageObject->messagePayload); + $incomingMessage->setChatMessageId($messageObject->chatMessageId); + $incomingMessage->setSentAt($messageObject->sentAt); + $incomingMessage->setCreatedAt($messageObject->createdAt); + $incomingMessage->setUpdatedAt($messageObject->updatedAt); + $incomingMessage->save(); + } + + return $incomingMessage; + } + public function createOutgoingMessage($message, $content) { $outgoingMessage = $this->_messageModelFactory->create(); $outgoingMessage->setSenderId($message->getSenderId()); $outgoingMessage->setContent($content['content']); $outgoingMessage->setContentType($content['content_type']); // TODO + $outgoingMessage->setCurrentCommandDetails($content['current_command_details']); // TODO $outgoingMessage->setStatus($this->_define::PROCESSING); $outgoingMessage->setDirection($this->_define::OUTGOING); $outgoingMessage->setChatMessageId($message->getChatMessageId()); $outgoingMessage->setChatbotType($message->getChatbotType()); +// $outgoingMessage->setSentAt(time()); $datetime = date('Y-m-d H:i:s'); $outgoingMessage->setCreatedAt($datetime); $outgoingMessage->setUpdatedAt($datetime); @@ -1121,27 +1232,9 @@ public function createOutgoingMessage($message, $content) } // SETS - - private function setLastCommandDetails($currentMessage) + public function setConfigValue($field, $value) { - $command = $this->getCurrentCommand($currentMessage->getContent()); - if ($command != $this->_define::LIST_MORE_COMMAND_ID) - { - $listingConversationStates = array( - $this->_define::CONVERSATION_LIST_CATEGORIES, - $this->_define::CONVERSATION_SEARCH - ); - $chatbotAPI = $this->getChatbotAPIModelBySenderId($currentMessage->getSenderId()); - $lastCommandObject = json_decode($chatbotAPI->getLastCommandDetails()); - if (isset($lastCommandObject->last_conversation_state)) - { - if ((!(in_array($lastCommandObject->last_conversation_state, $listingConversationStates))) || ($command == $this->_define::LIST_ORDERS_COMMAND_ID)) - { - $chatbotAPI->setChatbotAPILastCommandDetails($currentMessage->getContent()); - $this->setChatbotAPIModel($chatbotAPI); - } - } - } + $this->_configWriter->save($field, $value); } private function setCommandsList($commandsList) @@ -1208,6 +1301,111 @@ private function setCurrentCommand($messageContent) } // GETS + private function getWelcomeMessage($message) + { +// $this->setHelperMessageAttributes($message); + $outgoingMessage = array(); + $text = $this->getConfigValue($this->_configPrefix . '/general/welcome_message'); + if ($text != '') + { + $contentObj = $this->getTextMessageArray($text); + $outgoingMessage = $this->createOutgoingMessage($message, reset($contentObj)); // TODO reset -> gets first item of array +// $this->processOutgoingMessage($outgoingMessage); + } + + return $outgoingMessage; + } + + private function getDisabledByCustomerMessage($message) + { + $outgoingMessages = array(); + $text = __("To chat with me, please enable Messenger on your account chatbot settings."); + $contentObj = $this->getTextMessageArray($text); + $outgoingMessage = $this->createOutgoingMessage($message, reset($contentObj)); // TODO reset -> gets first item of array + if ($outgoingMessage) + array_push($outgoingMessages, $outgoingMessage); +// $this->processOutgoingMessage($outgoingMessage); + + return $outgoingMessages; + } + + private function getDisabledMessage($message) + { + $outgoingMessages = array(); +// $this->setHelperMessageAttributes($message); + $text = $this->getConfigValue($this->_configPrefix . '/general/disabled_message'); + + if ($text != '') + $contentObj = $this->getTextMessageArray($text); + else + $contentObj = $this->getErrorMessage(); + + $outgoingMessage = $this->createOutgoingMessage($message, reset($contentObj)); // TODO reset -> gets first item of array +// $this->processOutgoingMessage($outgoingMessage); + if ($outgoingMessage) + array_push($outgoingMessages, $outgoingMessage); + + return $outgoingMessages; + } + + private function getMessageCollectionBySenderIdAndDirection($senderId, $direction) + { + $messageCollection = $this->_messageModel->getCollection() + ->addFieldToFilter('status', array('neq' => $this->_define::PROCESSED)) + ->addFieldToFilter('direction', array('eq' => $direction)) + ->addFieldToFilter('sender_id', array('eq' => $senderId)) + ->setOrder('created_at', 'asc'); + + return $messageCollection; + } + + public function getQueueMessageMode() + { + if (isset($this->_messageQueueMode)) + return $this->_messageQueueMode; + + $this->_messageQueueMode = $this->getConfigValue('werules_chatbot_general/general/message_queue_mode'); + return $this->_messageQueueMode; + } + + private function getStockByProductId($productId) + { + $stockQty = $this->_stockRegistry->getStockItem($productId); + if ($stockQty) + return $stockQty; + + return 0; + } + + private function getCommandConversationState($command) + { + $result = null; + if ($command == $this->_define::START_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::LIST_CATEGORIES_COMMAND_ID) + $result = $this->_define::CONVERSATION_LIST_CATEGORIES; + else if ($command == $this->_define::SEARCH_COMMAND_ID) + $result = $this->_define::CONVERSATION_SEARCH; + else if ($command == $this->_define::LOGIN_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::LIST_ORDERS_COMMAND_ID){}// doesn't change conversation state +// else if ($command == $this->_define::REORDER_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::ADD_TO_CART_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::CHECKOUT_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::CLEAR_CART_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::TRACK_ORDER_COMMAND_ID) + $result = $this->_define::CONVERSATION_TRACK_ORDER; + else if ($command == $this->_define::SUPPORT_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::SEND_EMAIL_COMMAND_ID) + $result = $this->_define::CONVERSATION_EMAIL; + else if ($command == $this->_define::CANCEL_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::HELP_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::ABOUT_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::LOGOUT_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::REGISTER_COMMAND_ID){}// doesn't change conversation state + else if ($command == $this->_define::LIST_MORE_COMMAND_ID){}// doesn't change conversation state + + return $result; + } + private function getCurrentMessagePayload() { if (isset($this->_messagePayload)) @@ -1267,7 +1465,8 @@ private function getTextMessageArray($text) $result = array(); $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => $text + 'content' => $text, + 'current_command_details' => json_encode(array()) ); array_push($result, $responseMessage); return $result; @@ -1582,11 +1781,13 @@ private function getProductDetailsObject($product, $checkout = false) // used to } } + $subtitle = $this->excerpt($product->getShortDescription(), 60); + $price = $this->_priceHelper->currency($product->getPrice(), true, false); $element = array( 'title' => $productName, 'item_url' => $productUrl, 'image_url' => $productImage, - 'subtitle' => $this->excerpt($product->getShortDescription(), 60), + 'subtitle' => $subtitle . chr(10) . $price, 'buttons' => $options ); //array_push($result, $element); @@ -1743,13 +1944,13 @@ private function getChatbotuserBySenderId($senderId) return $chatbotUser; } - private function getMessageModelById($messageId) - { - $message = $this->_messageModelFactory->create(); - $message->load($messageId); - - return $message; - } +// private function getMessageModelById($messageId) +// { +// $message = $this->_messageModelFactory->create(); +// $message->load($messageId); +// +// return $message; +// } // COMMANDS FUNCTIONS private function processListCategoriesCommand() @@ -1790,7 +1991,13 @@ private function processListCategoriesCommand() // $responseMessage['content'] = json_encode($contentObject); $responseMessage = array( 'content_type' => $this->_define::QUICK_REPLY, - 'content' => json_encode($contentObject) + 'content' => json_encode($contentObject), + 'current_command_details' => json_encode(array( + 'conversation_state' => $this->_define::CONVERSATION_LIST_CATEGORIES, + 'command_text' => $this->getCommandText($this->_define::LIST_CATEGORIES_COMMAND_ID), + 'listed_quantity' => 0 +// 'listed_quantity' => count($quickReplies) // TODO only if we add feature to list more categories + )) ); array_push($result, $responseMessage); return $result; @@ -1801,7 +2008,10 @@ private function processStartCommand() $result = array(); $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => 'you just sent the START command!' // TODO + 'content' => 'you just sent the START command!', // TODO + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($this->_define::START_COMMAND_ID) + )) ); array_push($result, $responseMessage); return $result; @@ -1812,7 +2022,12 @@ private function processSearchCommand() $result = array(); $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("Sure, send me the name of the product you're looking for.") + 'content' => __("Sure, send me the name of the product you're looking for."), + 'current_command_details' => json_encode(array( + 'conversation_state' => $this->_define::CONVERSATION_SEARCH, + 'command_text' => $this->getCommandText($this->_define::SEARCH_COMMAND_ID), + 'listed_quantity' => 0 + )) ); array_push($result, $responseMessage); return $result; @@ -1826,7 +2041,10 @@ private function processLoginCommand($senderId) $loginUrl = $this->getStoreURL('chatbot/customer/login/hash/' . $chatbotAPI->getHashKey()); $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("To link your account to this Chatbot, access %1", $loginUrl) + 'content' => __("To link your account to this Chatbot, access %1", $loginUrl), + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($this->_define::LOGIN_COMMAND_ID) + )) ); array_push($result, $responseMessage); return $result; @@ -1842,7 +2060,10 @@ private function processLogoutCommand($senderId) { $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("Ok, you're logged out.") + 'content' => __("Ok, you're logged out."), + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($this->_define::LOGOUT_COMMAND_ID) + )) ); array_push($result, $responseMessage); } @@ -1858,7 +2079,10 @@ private function processRegisterCommand() $registerUrl = $this->getStoreURL('customer/account/create'); $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("Access %1 to register a new account on our shop.", $registerUrl) + 'content' => __("Access %1 to register a new account on our shop.", $registerUrl), + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($this->_define::REGISTER_COMMAND_ID) + )) ); array_push($result, $responseMessage); return $result; @@ -1878,7 +2102,7 @@ private function processListOrdersCommand($senderId) if (!isset($lastCommandObject->last_listed_quantity)) return $result; - if ($lastCommandObject->last_message_content == $listOrdersCommand) + if (strtolower($lastCommandObject->last_command_text) == strtolower($listOrdersCommand)) $startAt = $lastCommandObject->last_listed_quantity; else $startAt = 0; @@ -1915,8 +2139,10 @@ private function processListOrdersCommand($senderId) $totalListCount = $listCount + $startAt; if (count($ordersCollection) > $totalListCount) { - $chatbotAPI->setChatbotAPILastCommandDetails($listOrdersCommand, $totalListCount); - $this->setChatbotAPIModel($chatbotAPI); +// $chatbotAPI->setChatbotAPILastCommandDetails($listOrdersCommand, $totalListCount); +// $this->setChatbotAPIModel($chatbotAPI); + $conversationState = $chatbotAPI->getConversationState(); + $commandText = $listOrdersCommand; if ($listCount > 0) { $payload = array( @@ -1933,9 +2159,13 @@ private function processListOrdersCommand($senderId) } else { - $chatbotAPI->updateConversationState($this->_define::CONVERSATION_STARTED); - $chatbotAPI->setChatbotAPILastCommandDetails($listMoreCommand, 0); - $this->setChatbotAPIModel($chatbotAPI); + // TODO make this cleaner +// $chatbotAPI->updateConversationState($this->_define::CONVERSATION_STARTED); +// $chatbotAPI->setChatbotAPILastCommandDetails($listMoreCommand, 0, $this->_define::CONVERSATION_STARTED); +// $this->setChatbotAPIModel($chatbotAPI); + $totalListCount = 0; + $commandText = $listMoreCommand; + $conversationState = $this->_define::CONVERSATION_STARTED; } if ($listCount > 0) @@ -1951,7 +2181,13 @@ private function processListOrdersCommand($senderId) $responseMessage = array( 'content_type' => $contentType, - 'content' => $content + 'content' => $content, + 'current_command_details' => json_encode(array( + 'list_more_conversation_state' => $conversationState, + 'command_text' => $commandText, + 'listed_quantity' => $totalListCount +// 'conversation_state' => $this->_define::CONVERSATION_STARTED, + )) ); array_push($result, $responseMessage); @@ -1962,7 +2198,10 @@ private function processListOrdersCommand($senderId) $contentObject->quick_replies = $quickReplies; $responseMessage = array( 'content_type' => $this->_define::QUICK_REPLY, - 'content' => json_encode($contentObject) + 'content' => json_encode($contentObject), + 'current_command_details' => json_encode(array( + 'command_text' => $listOrdersCommand + )) ); array_push($result, $responseMessage); } @@ -1993,7 +2232,10 @@ private function processReorderCommand($orderId, $senderId) { $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("All products from order %1 that are in stock were added to your cart.", $order->getIncrementId()) + 'content' => __("All products from order %1 that are in stock were added to your cart.", $order->getIncrementId()), + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($this->_define::REORDER_COMMAND_ID) + )) ); array_push($result, $responseMessage); } @@ -2016,7 +2258,10 @@ private function processAddToCartCommand($senderId, $payload) { $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("Ok, I just add the product to your cart, to checkout send '%1'.", $this->getCommandText($this->_define::CHECKOUT_COMMAND_ID)) + 'content' => __("Ok, I just add the product to your cart, to checkout send '%1'.", $this->getCommandText($this->_define::CHECKOUT_COMMAND_ID)), + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($this->_define::ADD_TO_CART_COMMAND_ID) + )) ); array_push($result, $responseMessage); } @@ -2050,7 +2295,10 @@ private function processCheckoutCommand($senderId) $contentObject->buttons = $buttons; $responseMessage = array( 'content_type' => $this->_define::TEXT_WITH_OPTIONS, - 'content' => json_encode($contentObject) + 'content' => json_encode($contentObject), + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($this->_define::CHECKOUT_COMMAND_ID) + )) ); array_push($result, $responseMessage); } @@ -2066,63 +2314,6 @@ private function processCheckoutCommand($senderId) return $result; } -// private function processCheckoutCommand($senderId) -// { -// $chatbotUser = $this->getChatbotuserBySenderId($senderId); -// $quote = $this->getQuoteByCustomerId($chatbotUser->getCustomerId()); -// $orderItems = $quote->getItemsCollection(); -//// $orderItems = $this->getCartItemsByCustomerId($chatbotUser->getCustomerId()); -// $result = array(); -// $listObjectList = array(); -// if (count($orderItems) > 1) -// { -// foreach ($orderItems as $orderItem) -// { -// $listObject = $this->getItemListImageProductObject($orderItem->getProduct()); -// if ($listObject) -// array_push($listObjectList, $listObject); -// } -// $buttons = array( -// array( -// 'type' => 'web_url', -// 'title' => __("Checkout"), -// 'url' => $this->getStoreURL('checkout/cart') -// ) -// ); -// -// if ($listObjectList) -// { -// $contentObject = new \stdClass(); -// $contentObject->list = $listObjectList; -// $contentObject->buttons = $buttons; -// $responseMessage = array( -// 'content_type' => $this->_define::LIST_WITH_IMAGE, -// 'content' => json_encode($contentObject) -// ); -// array_push($result, $responseMessage); -// } -// } -// else if (count($orderItems) == 1) -// { -// $orderItem = $orderItems->getFirstItem(); -// $imageWithOptionsProdObj = $this->getUnitWithImageProductObject($orderItem->getProduct()); -// array_push($listObjectList, $imageWithOptionsProdObj); -// -// $responseMessage = array( -// 'content_type' => $this->_define::IMAGE_WITH_OPTIONS, -// 'content' => json_encode($listObjectList) -// ); -// array_push($result, $responseMessage); -// } -// else // if (count($orderItems) <= 0) -// { -// $text = __("Your cart is empty."); -// $result = $this->getTextMessageArray($text); -// } -// -// return $result; -// } - private function processClearCartCommand($senderId) { $chatbotUser = $this->getChatbotuserBySenderId($senderId); @@ -2132,7 +2323,10 @@ private function processClearCartCommand($senderId) { $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("Cart cleared.") + 'content' => __("Cart cleared."), + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($this->_define::CLEAR_CART_COMMAND_ID) + )) ); array_push($result, $responseMessage); } @@ -2147,7 +2341,11 @@ private function processTrackOrderCommand() $result = array(); $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("Ok, send me the order number you're looking for.") + 'content' => __("Ok, send me the order number you're looking for."), + 'current_command_details' => json_encode(array( + 'conversation_state' => $this->_define::CONVERSATION_TRACK_ORDER, + 'command_text' => $this->getCommandText($this->_define::TRACK_ORDER_COMMAND_ID) + )) ); array_push($result, $responseMessage); return $result; @@ -2158,7 +2356,10 @@ private function processSupportCommand() $result = array(); $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => 'The SUPPORT command is still under development' // TODO + 'content' => 'The SUPPORT command is still under development', // TODO + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($this->_define::SUPPORT_COMMAND_ID) + )) ); array_push($result, $responseMessage); return $result; @@ -2169,28 +2370,31 @@ private function processSendEmailCommand() $result = array(); $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("Sure, send me the email content.") + 'content' => __("Sure, send me the email content."), + 'current_command_details' => json_encode(array( + 'conversation_state' => $this->_define::CONVERSATION_EMAIL, + 'command_text' => $this->getCommandText($this->_define::SEND_EMAIL_COMMAND_ID) + )) ); array_push($result, $responseMessage); return $result; } - private function processCancelCommand($senderId) + private function processCancelCommand() { $result = array(); - $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); - $response = $chatbotAPI->updateConversationState($this->_define::CONVERSATION_STARTED); - $this->setChatbotAPIModel($chatbotAPI); - if ($response) - { - $responseMessage = array( - 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => __("Ok, canceled.") - ); - array_push($result, $responseMessage); - } - else - $result = $this->getErrorMessage(); +// $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); +// $response = $chatbotAPI->updateConversationState($this->_define::CONVERSATION_STARTED); +// $this->setChatbotAPIModel($chatbotAPI); + $responseMessage = array( + 'content_type' => $this->_define::CONTENT_TEXT, + 'content' => __("Ok, canceled."), + 'current_command_details' => json_encode(array( + 'conversation_state' => $this->_define::CONVERSATION_STARTED, + 'command_text' => $this->getCommandText($this->_define::CANCEL_COMMAND_ID) + )) + ); + array_push($result, $responseMessage); return $result; } @@ -2203,7 +2407,10 @@ private function processHelpCommand() { $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => $text + 'content' => $text, + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($this->_define::HELP_COMMAND_ID) + )) ); array_push($result, $responseMessage); } @@ -2221,7 +2428,10 @@ private function processAboutCommand() { $responseMessage = array( 'content_type' => $this->_define::CONTENT_TEXT, - 'content' => $text + 'content' => $text, + 'current_command_details' => json_encode(array( + 'command_text' => $this->getCommandText($this->_define::ABOUT_COMMAND_ID) + )) ); array_push($result, $responseMessage); } @@ -2234,10 +2444,10 @@ private function processAboutCommand() private function processListMore($lastCommandObject, $senderId) { $result = array(); - $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); if (!isset($lastCommandObject->last_listed_quantity)) return $result; + $chatbotAPI = $this->getChatbotAPIModelBySenderId($senderId); $listedQuantity = $lastCommandObject->last_listed_quantity; if ($listedQuantity > 0) @@ -2250,16 +2460,14 @@ private function processListMore($lastCommandObject, $senderId) if (in_array($conversationState, $listCommands)) { - $messageContent = $lastCommandObject->last_message_content; + // change conversation state to use handleConversationState flow $chatbotAPI->updateConversationState($conversationState); $this->setChatbotAPIModel($chatbotAPI); - $result = $this->handleConversationState($messageContent, $senderId); + $result = $this->handleConversationState($lastCommandObject->last_command_parameter, $senderId); } - else if ($lastCommandObject->last_message_content == $this->getCommandText($this->_define::LIST_ORDERS_COMMAND_ID)) - { + else if (strtolower($lastCommandObject->last_command_text) == strtolower($this->getCommandText($this->_define::LIST_ORDERS_COMMAND_ID))) $result = $this->processListOrdersCommand($senderId); - } } return $result; diff --git a/Magento2/app/code/Werules/Chatbot/Helper/Define.php b/Magento2/app/code/Werules/Chatbot/Helper/Define.php index 5444646..91ac394 100644 --- a/Magento2/app/code/Werules/Chatbot/Helper/Define.php +++ b/Magento2/app/code/Werules/Chatbot/Helper/Define.php @@ -40,6 +40,8 @@ class Define const SECONDS_IN_HOUR = 3600; const SECONDS_IN_MINUTE = 60; const DEFAULT_MIN_CONFIDENCE = 0.7; + const BREAK_LINE = '\n'; // chr(10) + const QUEUE_PROCESSING_LIMIT = self::SECONDS_IN_MINUTE * 3; // commands const START_COMMAND_ID = 0; @@ -60,12 +62,15 @@ class Define const LOGOUT_COMMAND_ID = 15; const REGISTER_COMMAND_ID = 16; const LIST_MORE_COMMAND_ID = 17; - const LAST_COMMAND_DETAILS_DEFAULT = '{"last_message_content":"","last_conversation_state":0,"last_listed_quantity":0}'; + const LAST_COMMAND_DETAILS_DEFAULT = '{"last_command_parameter":"","last_command_text":"","last_conversation_state":0,"last_listed_quantity":0}'; // array( -// 'last_message_content' => '', +// 'last_command_parameter' => '', +// 'last_command_text' => '', // 'last_conversation_state' => 0, // 'last_listed_quantity' => 0, // ); + const CURRENT_COMMAND_DETAILS_DEFAULT = '[]'; +// json_encode(array()) // message content types const CONTENT_TEXT = 0; @@ -85,4 +90,13 @@ class Define // API const MAX_MESSAGE_ELEMENTS = 7; + + // MESSAGE QUEUE MODES + const QUEUE_NONE = 0; + const QUEUE_SIMPLE_RESTRICTIVE = 1; + const QUEUE_RESTRICTIVE = 2; + const QUEUE_NON_RESTRICTIVE = 3; + + const DONT_CLEAR_MESSAGE_QUEUE = 0; + const CLEAR_MESSAGE_QUEUE = 1; } \ No newline at end of file diff --git a/Magento2/app/code/Werules/Chatbot/Model/ChatbotAPI.php b/Magento2/app/code/Werules/Chatbot/Model/ChatbotAPI.php index b1b3d46..d63ef37 100644 --- a/Magento2/app/code/Werules/Chatbot/Model/ChatbotAPI.php +++ b/Magento2/app/code/Werules/Chatbot/Model/ChatbotAPI.php @@ -310,6 +310,16 @@ public function updateConversationState($state) } public function updateLastCommandDetails($lastCommandObject) + { + $this->setLastCommandDetails($lastCommandObject); + $datetime = date('Y-m-d H:i:s'); + $this->setUpdatedAt($datetime); + $this->save(); + + return true; + } + + public function updateLastCommandDetailsObject($lastCommandObject) { $this->setLastCommandDetails(json_encode($lastCommandObject)); $datetime = date('Y-m-d H:i:s'); @@ -319,21 +329,32 @@ public function updateLastCommandDetails($lastCommandObject) return true; } - public function setChatbotAPILastCommandDetails($messageContent, $lastListQuantity = null) + public function setChatbotAPILastCommandDetails($messageContent = null, $lastListQuantity = null, $conversationState = null, $commandParameter = null) { // sets current command details for next call +// if (($lastListQuantity === null) || ($messageContent === null) || ($commandParameter === null) || ($conversationState === null)) +// { + $lastCommandObject = json_decode($this->getLastCommandDetails()); if ($lastListQuantity === null) - { - $lastCommandObject = json_decode($this->getLastCommandDetails()); $lastListQuantity = $lastCommandObject->last_listed_quantity; - } + if ($messageContent === null) + $messageContent = $lastCommandObject->last_command_text; + if ($commandParameter === null) + $commandParameter = $lastCommandObject->last_command_parameter; + if ($conversationState === null) + $conversationState = $lastCommandObject->last_conversation_state; +// } + +// if ($conversationState === null) +// $conversationState = $this->getConversationState(); $lastCommandNewObject = array( - 'last_message_content' => $messageContent, - 'last_conversation_state' => $this->getConversationState(), + 'last_command_text' => $messageContent, + 'last_conversation_state' => $conversationState, 'last_listed_quantity' => $lastListQuantity, + 'last_command_parameter' => $commandParameter ); - $this->updateLastCommandDetails($lastCommandNewObject); + $this->updateLastCommandDetailsObject($lastCommandNewObject); } // API RELATED @@ -359,10 +380,12 @@ public function setChatbotAPILastCommandDetails($messageContent, $lastListQuanti public function sendMessage($message) { - $result = array(); + $result = true; if ($this->getChatbotType() == $this->_define::MESSENGER_INT) { $result = $this->sendMessageToMessenger($message); + if (isset($result['error'])) + $result = false; } return $result; @@ -380,10 +403,12 @@ public function sendMessageToMessenger($message) public function sendQuickReply($message) { - $result = array(); + $result = true; if ($this->getChatbotType() == $this->_define::MESSENGER_INT) { $result = $this->sendQuickReplyToMessenger($message); + if (isset($result['error'])) + $result = false; } return $result; @@ -407,10 +432,12 @@ public function sendQuickReplyToMessenger($message) public function sendReceiptList($message) { - $result = array(); + $result = true; if ($this->getChatbotType() == $this->_define::MESSENGER_INT) { $result = $this->sendReceiptListToMessenger($message); + if (isset($result['error'])) + $result = false; } return $result; @@ -493,10 +520,12 @@ public function sendReceiptList($message) public function sendMessageWithOptions($message) { - $result = array(); + $result = true; if ($this->getChatbotType() == $this->_define::MESSENGER_INT) { $result = $this->sendMessageWithOptionsToMessenger($message); + if (isset($result['error'])) + $result = false; } return $result; @@ -504,10 +533,12 @@ public function sendMessageWithOptions($message) public function sendImageWithOptions($message) { - $result = array(); + $result = true; if ($this->getChatbotType() == $this->_define::MESSENGER_INT) { $result = $this->sendImageWithOptionsToMessenger($message); + if (isset($result['error'])) + $result = false; } return $result; diff --git a/Magento2/app/code/Werules/Chatbot/Model/Message.php b/Magento2/app/code/Werules/Chatbot/Model/Message.php index 053c807..86f14f8 100644 --- a/Magento2/app/code/Werules/Chatbot/Model/Message.php +++ b/Magento2/app/code/Werules/Chatbot/Model/Message.php @@ -244,6 +244,44 @@ public function setMessagePayload($message_payload) return $this->setData(self::MESSAGE_PAYLOAD, $message_payload); } + /** + * Get sent_at + * @return string + */ + public function getSentAt() + { + return $this->getData(self::SENT_AT); + } + + /** + * Set sent_at + * @param string $sent_at + * @return \Werules\Chatbot\Api\Data\MessageInterface + */ + public function setSentAt($sent_at) + { + return $this->setData(self::SENT_AT, $sent_at); + } + + /** + * Get current_command_details + * @return string + */ + public function getCurrentCommandDetails() + { + return $this->getData(self::CURRENT_COMMAND_DETAILS); + } + + /** + * Set current_command_details + * @param string $current_command_details + * @return \Werules\Chatbot\Api\Data\MessageInterface + */ + public function setCurrentCommandDetails($current_command_details) + { + return $this->setData(self::CURRENT_COMMAND_DETAILS, $current_command_details); + } + // CUSTOM METHODS public function updateIncomingMessageStatus($status) @@ -256,7 +294,7 @@ public function updateOutgoingMessageStatus($status) return $this->updateMessageStatus($status); } - private function updateMessageStatus($status) + public function updateMessageStatus($status) { $this->setStatus($status); $datetime = date('Y-m-d H:i:s'); @@ -265,4 +303,14 @@ private function updateMessageStatus($status) return true; } + + public function updateSentAt($timestamp) + { + $this->setSentAt($timestamp); + $datetime = date('Y-m-d H:i:s'); + $this->setUpdatedAt($datetime); + $this->save(); + + return true; + } } diff --git a/Magento2/app/code/Werules/Chatbot/Setup/InstallSchema.php b/Magento2/app/code/Werules/Chatbot/Setup/InstallSchema.php index e836065..725bf3a 100644 --- a/Magento2/app/code/Werules/Chatbot/Setup/InstallSchema.php +++ b/Magento2/app/code/Werules/Chatbot/Setup/InstallSchema.php @@ -374,9 +374,28 @@ public function install( \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, null, ['nullable' => True], - 'Listed Items Quantity' + 'Last Command Details' ); - + + + $table_werules_chatbot_message->addColumn( + 'sent_at', + \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, + null, + ['nullable' => True], + 'Sent At' + ); + + + + $table_werules_chatbot_message->addColumn( + 'current_command_details', + \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + null, + ['nullable' => False], + 'Current Command Details' + ); + // TODO uncomment this // $table_werules_chatbot_message->addForeignKey( diff --git a/Magento2/app/code/Werules/Chatbot/Setup/UpgradeData.php b/Magento2/app/code/Werules/Chatbot/Setup/UpgradeData.php index 8c0396c..f376e72 100644 --- a/Magento2/app/code/Werules/Chatbot/Setup/UpgradeData.php +++ b/Magento2/app/code/Werules/Chatbot/Setup/UpgradeData.php @@ -36,7 +36,7 @@ public function upgrade( ModuleContextInterface $context ) { $setup->startSetup(); - if (version_compare($context->getVersion(), "1.0.2", "<")) { + if (version_compare($context->getVersion(), "1.0.3", "<")) { //Your upgrade script } $setup->endSetup(); diff --git a/Magento2/app/code/Werules/Chatbot/Setup/UpgradeSchema.php b/Magento2/app/code/Werules/Chatbot/Setup/UpgradeSchema.php index 05c2de1..3381fca 100644 --- a/Magento2/app/code/Werules/Chatbot/Setup/UpgradeSchema.php +++ b/Magento2/app/code/Werules/Chatbot/Setup/UpgradeSchema.php @@ -21,9 +21,9 @@ namespace Werules\Chatbot\Setup; -use Magento\Framework\Setup\UpgradeSchemaInterface; use Magento\Framework\Setup\ModuleContextInterface; use Magento\Framework\Setup\SchemaSetupInterface; +use Magento\Framework\Setup\UpgradeSchemaInterface; class UpgradeSchema implements UpgradeSchemaInterface { @@ -42,8 +42,9 @@ public function upgrade( $tableName = $setup->getTable('werules_chatbot_chatbotapi'); $connection = $setup->getConnection(); - // Check if the table already exists - if ($connection->isTableExists($tableName) == true) { + // Check if the table werules_chatbot_chatbotapi already exists + if ($connection->isTableExists($tableName) == true) + { $connection->addColumn( $tableName, 'last_command_details', @@ -56,6 +57,41 @@ public function upgrade( ); } } +// $setup->endSetup(); + +// $setup->startSetup(); + if (version_compare($context->getVersion(), "1.0.3", "<")) { + + //Your upgrade script + // Get module table + $tableName = $setup->getTable('werules_chatbot_message'); + $connection = $setup->getConnection(); + + // Check if the table werules_chatbot_message already exists + if ($connection->isTableExists($tableName) == true) + { + $connection->addColumn( + $tableName, + 'sent_at', + array( + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TIMESTAMP, + 'length' => null, + 'comment' => 'Sent At', + 'nullable' => true + ) + ); + $connection->addColumn( + $tableName, + 'current_command_details', + array( + 'type' => \Magento\Framework\DB\Ddl\Table::TYPE_TEXT, + 'length' => null, + 'comment' => 'Current Command Details', + 'nullable' => false + ) + ); + } + } $setup->endSetup(); } } diff --git a/Magento2/app/code/Werules/Chatbot/etc/adminhtml/system.xml b/Magento2/app/code/Werules/Chatbot/etc/adminhtml/system.xml index efe0cbc..0c6955d 100644 --- a/Magento2/app/code/Werules/Chatbot/etc/adminhtml/system.xml +++ b/Magento2/app/code/Werules/Chatbot/etc/adminhtml/system.xml @@ -11,8 +11,8 @@ Magento Chatbot v1.0.2 -

To use this module you'll have to use SSL in your store.

+

Magento Chatbot v1.0.3

+

To use this module you'll have to use SSL in your store.

]]>
@@ -31,22 +31,27 @@ Enable listing of categories with no products or unallowed products (this module supports only simple products for now). Magento\Config\Model\Config\Source\Yesno - + + + Message Queue mode. + Werules\Chatbot\Block\Adminhtml\System\Config\Form\Field\MessageQueueModeList + + - + Log will be at root/var/log/. Magento\Config\Model\Config\Source\Yesno - + Enable wit.ai Natural Language Processor. Magento\Config\Model\Config\Source\Yesno - + 1 @@ -61,7 +66,10 @@ Werules_Chatbot::config_werules_chatbot - Magento Chatbot v1.0.2

To use this module you'll have to use SSL in your store.

]]>
+ Magento Chatbot v1.0.3 +

To use this module you'll have to use SSL in your store.

+ ]]>
Enable Messenger bot. @@ -212,5 +220,34 @@
+
+ + werules + Werules_Chatbot::config_werules_chatbot + + + Magento Chatbot v1.0.3 +

To use this module you'll have to use SSL in your store.

+

You should only change settings here if you know what you're doing.

+ + ]]>
+ + + Clear message pending list. After changing this value and saving, a process to clear message pending list will be schedule for the next minute. + Magento\Config\Model\Config\Source\Enabledisable + + + + 1 + + + If you like, you can specify a Sender Chat ID to filter the message clearing process. + +
+
diff --git a/Magento2/app/code/Werules/Chatbot/etc/config.xml b/Magento2/app/code/Werules/Chatbot/etc/config.xml index 7c9a22f..fc621b3 100644 --- a/Magento2/app/code/Werules/Chatbot/etc/config.xml +++ b/Magento2/app/code/Werules/Chatbot/etc/config.xml @@ -41,5 +41,11 @@ 1 + + + 0 + + + diff --git a/Magento2/app/code/Werules/Chatbot/etc/module.xml b/Magento2/app/code/Werules/Chatbot/etc/module.xml index c194e97..6786491 100644 --- a/Magento2/app/code/Werules/Chatbot/etc/module.xml +++ b/Magento2/app/code/Werules/Chatbot/etc/module.xml @@ -1,4 +1,4 @@ - + diff --git a/Magento2/app/code/Werules/Chatbot/view/adminhtml/templates/system/config/custom_js.phtml b/Magento2/app/code/Werules/Chatbot/view/adminhtml/templates/system/config/custom_js.phtml index 5c304ae..15537e8 100644 --- a/Magento2/app/code/Werules/Chatbot/view/adminhtml/templates/system/config/custom_js.phtml +++ b/Magento2/app/code/Werules/Chatbot/view/adminhtml/templates/system/config/custom_js.phtml @@ -28,6 +28,14 @@ if (custom_key) updateCustomKeyUrl(custom_key.value); + var scheduled_clear = document.getElementById('werules_chatbot_danger_general_clear_message_pending'); + if (scheduled_clear.value === '1') + { + var schedule_message = document.getElementById('werules_scheduled_clearing'); + if (schedule_message) + document.getElementById('werules_scheduled_clearing').style.display = 'block'; + } + function updateCustomKeyUrl(custom_key) { var messenger_url = document.getElementById('werules_messenger_url'); diff --git a/Magento2/app/code/Werules/Chatbot/view/adminhtml/ui_component/werules_chatbot_message_index.xml b/Magento2/app/code/Werules/Chatbot/view/adminhtml/ui_component/werules_chatbot_message_index.xml index 5a70a32..146f3e0 100644 --- a/Magento2/app/code/Werules/Chatbot/view/adminhtml/ui_component/werules_chatbot_message_index.xml +++ b/Magento2/app/code/Werules/Chatbot/view/adminhtml/ui_component/werules_chatbot_message_index.xml @@ -121,5 +121,13 @@ + + + + text + Sent At + + + diff --git a/README.md b/README.md index 09268a9..b1932e7 100644 --- a/README.md +++ b/README.md @@ -99,6 +99,14 @@ Go to **System > General Settings > Chatbot Settings** ## Release Notes ### Magento2 +- **v1.0.3:** + - Add Messages Queue Modes + - Add option to Clear Message Queue + - Add price to product list + - Add condition to only handle messages from Messenger + - Add new configuration tab + - Fix some bugs + - Add bugs to fix later - **v1.0.2:** - Add Messages Queue - Add List More command @@ -263,6 +271,8 @@ A: Thank you! You can help by codding more features, creating pull requests, or - Add Welcome Message Options - Add Command Listing on Help Command - Add Enable Default Replies + - Add more options to filter clearing message queue + - Add handler for other posts from Messenger ## License MIT License