diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b45d248
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+/nbproject/private
\ No newline at end of file
diff --git a/MessengerPlatform.php b/MessengerPlatform.php
new file mode 100644
index 0000000..f00e168
--- /dev/null
+++ b/MessengerPlatform.php
@@ -0,0 +1,161 @@
+loadConfig($config);
+ $this->gate = new Gate($this->config);
+ $this->request = new \fritak\MessengerPlatform\ParseRequest($request);
+ }
+
+ /**
+ * You can load another config later on.
+ *
+ * @param array $config
+ */
+ public function loadConfig($config)
+ {
+ $this->config = new Config($config);
+ }
+
+ /**
+ * In order for your webhook to receive events for a specific page, you must subscribe your app to the page.
+ *
+ * @return fritak\MessengerPlatform\Response Response.
+ * @see https://developers.facebook.com/docs/messenger-platform/implementation#subscribe_app_pages
+ */
+ public function subscribe()
+ {
+ return $this->gate->request(Gate::SUBSCRIBED_APPS);
+ }
+
+ /**
+ * Send a simple text message.
+ *
+ * @param int $recipientId This must be an id that was retrieved through the Messenger entry points or through the Messenger callbacks.
+ * @param string $textMessage Text.
+ * @param string $notificationType One of 3 types of notification, use constants (eg. NOTIFICATION_TYPE_REGULAR)
+ * @return fritak\MessengerPlatform\Response
+ * @see https://developers.facebook.com/docs/messenger-platform/send-api-reference#guidelines
+ */
+ public function sendMessage($recipientId, $textMessage, $notificationType = MessageSend::NOTIFICATION_TYPE_REGULAR)
+ {
+ $message = new MessageSend($recipientId, $textMessage, $notificationType);
+
+ return $this->gate->request(Gate::URL_MESSAGES, $message->getDataForCall());
+ }
+
+ /**
+ * Send an image (file).
+ *
+ * @param int $recipientId This must be an id that was retrieved through the Messenger entry points or through the Messenger callbacks.
+ * @param string $url Image URL.
+ * @param string $notificationType One of 3 types of notification, use constants (eg. NOTIFICATION_TYPE_REGULAR)
+ * @return fritak\MessengerPlatform\Response
+ * @see https://developers.facebook.com/docs/messenger-platform/send-api-reference#guidelines
+ */
+ public function sendImage($recipientId, $url, $notificationType = MessageSend::NOTIFICATION_TYPE_REGULAR)
+ {
+ $structuredMessage = new StructuredMessage($recipientId, ['url' => $url], $notificationType, StructuredMessage::ATTACHMENT_TYPE_IMAGE);
+
+ return $this->gate->request(Gate::URL_MESSAGES, $structuredMessage->getDataForCall());
+ }
+
+ /**
+ * Send a structured Message - button template.
+ *
+ * @param int $recipientId This must be an id that was retrieved through the Messenger entry points or through the Messenger callbacks.
+ * @param string $text Text.
+ * @param array $buttons Array of fritak\MessengerPlatform\Button.
+ * @param string $notificationType One of 3 types of notification, use constants (eg. NOTIFICATION_TYPE_REGULAR)
+ * @return fritak\MessengerPlatform\Response
+ * @see https://developers.facebook.com/docs/messenger-platform/send-api-reference#guidelines
+ */
+ public function sendButton($recipientId, $text, $buttons, $notificationType = MessageSend::NOTIFICATION_TYPE_REGULAR)
+ {
+ $structuredMessage = new StructuredMessage($recipientId,
+ ['text' => $text, 'buttons' => $buttons],
+ $notificationType,
+ StructuredMessage::ATTACHMENT_TYPE_TEMPLATE,
+ StructuredMessage::TEMPLATE_PAYLOAD_TYPE_BUTTON);
+
+ return $this->gate->request(Gate::URL_MESSAGES, $structuredMessage->getDataForCall());
+ }
+
+ /**
+ * Send a structured Message - receipt template.
+ *
+ * @param int $recipientId This must be an id that was retrieved through the Messenger entry points or through the Messenger callbacks.
+ * @param Receipt $receipt
+ * @param string $notificationType One of 3 types of notification, use constants (eg. NOTIFICATION_TYPE_REGULAR)
+ * @return fritak\MessengerPlatform\Response
+ * @see https://developers.facebook.com/docs/messenger-platform/send-api-reference#guidelines
+ */
+ public function sendReceipt($recipientId, Receipt $receipt, $notificationType = MessageSend::NOTIFICATION_TYPE_REGULAR)
+ {
+ $structuredMessage = new StructuredMessage($recipientId,
+ $receipt,
+ $notificationType,
+ StructuredMessage::ATTACHMENT_TYPE_TEMPLATE,
+ StructuredMessage::TEMPLATE_PAYLOAD_TYPE_RECEIPT);
+
+ return $this->gate->request(Gate::URL_MESSAGES, $structuredMessage->getDataForCall());
+ }
+
+ /**
+ * Send a complex message.
+ *
+ * @param fritak\MessengerPlatform\MessageSend|fritak\MessengerPlatform\StructuredMessage $message
+ * @return fritak\MessengerPlatform\Response
+ */
+ public function sendComplexMeesage($message)
+ {
+ return $this->gate->request(Gate::URL_MESSAGES, $message->getDataForCall());
+ }
+
+ /**
+ * Get messages received. Returns FALSE if request don`t have messages.
+ *
+ * @return boolean|array Array of \fritak\MessengerPlatform\MessageReceived.
+ */
+ public function getMessagesReceived()
+ {
+ return $this->request->getMessagesReceived();
+ }
+
+ /**
+ * Check if request is subscribe.
+ *
+ * @return boolean Is request subscribe?
+ */
+ public function checkSubscribe()
+ {
+ return $this->request->checkSubscribe($this->config->webhookToken);
+ }
+
+}
\ No newline at end of file
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..2a8e573
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,22 @@
+{
+ "name": "fritak/MessengerPlatform",
+ "description": "Facebook Messenger Platform PHP API for bots.",
+ "homepage": "https://github.com/fritak/messengerPlatform",
+ "license": "MIT",
+ "authors": [
+ {
+ "name": "Marek Sušický",
+ "email": "contact@fritak.eu",
+ "homepage": "http://www.fritak.eu",
+ "role": "Developer"
+ }
+ ],
+ "require": {
+ "php": ">=5.4.0"
+ },
+ "autoload": {
+ "psr-4": {
+ "fritak\\": ""
+ }
+ }
+}
\ No newline at end of file
diff --git a/example.php b/example.php
new file mode 100644
index 0000000..588e0a3
--- /dev/null
+++ b/example.php
@@ -0,0 +1,83 @@
+ 'CAAWiukRglNoBAJN4D0pUwKZCe3ZBOmwZA6ACwuDs4YkZAOsFyc5lVZBxcU2trTlNVteRy3T2ZANlyZAUn5znRwHKqFv0dmp8KOvs8mdOZCSH0cvH1dOXSR8xl9gZCU2GWwOQzBsnZCBJEhQaaaTvwHEIsUZAdOZCwXoPkrZCQSmzBkPyj5RWjLEQA8ZCZCuEPUpMgrbYcfP4wYyZCPR3XgZDZD',
+ 'webhookToken' => 'my_secret_token',
+ 'facebookApiUrl' => 'https://graph.facebook.com/v2.6/me/'
+ ], $request);
+
+// Check if request is subscribe and then return challenge (see https://developers.facebook.com/docs/messenger-platform/implementation#setup_webhook)
+if($bot->checkSubscribe())
+{
+ print $bot->request->getChallenge();
+ exit;
+}
+
+// Subscribe the App to a Page. Messenger documentation: In order for your webhook to receive events for a specific page, you must subscribe your app to the page.
+$bot->subscribe();
+
+
+// Messenger is calling your URL, someone is sending a message...
+$bot->getMessagesReceived();
+
+// Simple sending messages:
+
+// Send a simple text message.
+$bot->sendMessage($userToSendMessage, 'Example!');
+
+// Send an image (file).
+$bot->sendImage($userToSendMessage, 'http://placehold.it/150x150');
+
+// Send a structured Message - button template.
+$buttons = [new Button('Click', Button::TYPE_WEB, 'example.com'), new Button('Click2', Button::TYPE_POSTBACK, 'example.com')];
+$bot->sendButton($userToSendMessage, 'Example text... Not too long, hehe.', $buttons);
+
+
+// Send a structured Message - receipt template.
+$elements = [new ReceiptElement(['title' => 'Panda', 'price' => 9.99]), new ReceiptElement(['title' => 'Bunny', 'price' => 9.99])];
+$summary = new Summary(['total_cost' => 17.98]);
+$address = new Address(['street_1' => 'Queens 1', 'city' => 'Example city', 'postal_code' => '10000', 'state' => 'DO', 'country' => 'CZ']);
+$receipt = new Receipt('User', Rand(1,9999), 'USD', 'card', $elements, $summary, $address, $adjustments, time(), 'example.com');
+$adjustments = [new Adjustment(['name' => 'Discount', 'amount' => 2])];
+
+$bot->sendReceipt($userToSendMessage, $receipt);
+
+// You can send it with StructuredMessage:
+
+$bot->sendComplexMessage(new StructuredMessage($userToSendMessage,
+ ['url' => 'http://placehold.it/150x150'],
+ MessageSend::NOTIFICATION_TYPE_SILENT_PUSH,
+ StructuredMessage::ATTACHMENT_TYPE_IMAGE));
+
+$bot->sendComplexMeesage(new StructuredMessage($userToSendMessage,
+ [new Element('Example.', 'Example...', 'http://placehold.it/150x150', 'http://placehold.it/150x150', [new Button('Click', Button::TYPE_WEB, 'example.com')])],
+ MessageSend::NOTIFICATION_TYPE_SILENT_PUSH,
+ StructuredMessage::ATTACHMENT_TYPE_TEMPLATE,
+ StructuredMessage::TEMPLATE_PAYLOAD_TYPE_GENERIC));
+
+$bot->sendComplexMeesage(new StructuredMessage($userToSendMessage,
+ ['text' => 'Example text... Not too long, hehe.',
+ 'buttons' => [new Button('Click', Button::TYPE_WEB, 'example.com'), new Button('Click2', Button::TYPE_POSTBACK, 'example.com')]],
+ MessageSend::NOTIFICATION_TYPE_SILENT_PUSH,
+ StructuredMessage::ATTACHMENT_TYPE_TEMPLATE,
+ StructuredMessage::TEMPLATE_PAYLOAD_TYPE_BUTTON));
+
diff --git a/nbproject/project.properties b/nbproject/project.properties
new file mode 100644
index 0000000..d37ef95
--- /dev/null
+++ b/nbproject/project.properties
@@ -0,0 +1,7 @@
+include.path=${php.global.include.path}
+php.version=PHP_54
+source.encoding=UTF-8
+src.dir=.
+tags.asp=false
+tags.short=false
+web.root=.
diff --git a/nbproject/project.xml b/nbproject/project.xml
new file mode 100644
index 0000000..eb83fc3
--- /dev/null
+++ b/nbproject/project.xml
@@ -0,0 +1,9 @@
+
+
+ org.netbeans.modules.php.project
+
+
+ messenger-platform
+
+
+
diff --git a/readme.md b/readme.md
new file mode 100644
index 0000000..a5a32ad
--- /dev/null
+++ b/readme.md
@@ -0,0 +1,94 @@
+Facebook Messenger Platform PHP API for bots.
+========================
+
+This code is an implementation of the Messenger Platform in a PHP.
+
+INSTALLATION
+------------
+
+```
+composer require "fritak/MessengerPlatform"
+```
+
+REQUIREMENTS
+------------
+The minimum requirement is PHP 5.4 on your Web Server.
+
+
+## SETUP
+```php
+$userToSendMessage = $userToSendMessage; // now just and ID, phone matching will come in the future
+
+// This is just an example, this method of getting request is not safe!
+$stream = file_get_contents("php://input");
+$request = empty($stream)? $_REQUEST : $stream;
+
+$bot = new \fritak\MessengerPlatform(
+ ['accessToken' => 'token_for_app',
+ 'webhookToken' => 'my_secret_token',
+ 'facebookApiUrl' => 'https://graph.facebook.com/v2.6/me/' //2.6 is minimum
+ ], $request);
+```
+
+## BASIC USAGE
+```php
+// Check if request is subscribe and then return challenge - [documentation](https://developers.facebook.com/docs/messenger-platform/implementation#setup_webhook)
+if($bot->checkSubscribe())
+{
+ print $bot->request->getChallenge();
+ exit;
+}
+
+// Subscribe the App to a Page. In order for your webhook to receive events for a specific page, you must subscribe your app to the page.
+$bot->subscribe();
+```
+
+## GETTING MESSAGES
+```php
+// Messenger is calling your URL, someone is sending a message...
+$messages = $bot->getMessagesReceived();
+```
+
+## SENDING MESSAGES
+```php
+// Send a simple text message.
+$bot->sendMessage($userToSendMessage, 'Example!');
+
+// Send an image (file).
+$bot->sendImage($userToSendMessage, 'http://placehold.it/150x150');
+
+// Send a structured Message - button template.
+$buttons = [new Button('Click', Button::TYPE_WEB, 'example.com'), new Button('Click2', Button::TYPE_POSTBACK, 'example.com')];
+$bot->sendButton($userToSendMessage, 'Example text... Not too long, hehe.', $buttons);
+
+
+// Send a structured Message - receipt template.
+$elements = [new ReceiptElement(['title' => 'Panda', 'price' => 9.99]), new ReceiptElement(['title' => 'Bunny', 'price' => 9.99])];
+$summary = new Summary(['total_cost' => 17.98]);
+$address = new Address(['street_1' => 'Queens 1', 'city' => 'Example city', 'postal_code' => '10000', 'state' => 'DO', 'country' => 'CZ']);
+$receipt = new Receipt('User', Rand(1,9999), 'USD', 'card', $elements, $summary, $address, $adjustments, time(), 'example.com');
+$adjustments = [new Adjustment(['name' => 'Discount', 'amount' => 2])];
+
+$bot->sendReceipt($userToSendMessage, $receipt);
+```
+
+## SENDING MESSAGES WITH StructuredMessage
+```php
+$bot->sendComplexMessage(new StructuredMessage($userToSendMessage,
+ ['url' => 'http://placehold.it/150x150'],
+ MessageSend::NOTIFICATION_TYPE_SILENT_PUSH,
+ StructuredMessage::ATTACHMENT_TYPE_IMAGE));
+
+$bot->sendComplexMeesage(new StructuredMessage($userToSendMessage,
+ [new Element('Example.', 'Example...', 'http://placehold.it/150x150', 'http://placehold.it/150x150', [new Button('Click', Button::TYPE_WEB, 'example.com')])],
+ MessageSend::NOTIFICATION_TYPE_SILENT_PUSH,
+ StructuredMessage::ATTACHMENT_TYPE_TEMPLATE,
+ StructuredMessage::TEMPLATE_PAYLOAD_TYPE_GENERIC));
+
+$bot->sendComplexMeesage(new StructuredMessage($userToSendMessage,
+ ['text' => 'Example text... Not too long, hehe.',
+ 'buttons' => [new Button('Click', Button::TYPE_WEB, 'example.com'), new Button('Click2', Button::TYPE_POSTBACK, 'example.com')]],
+ MessageSend::NOTIFICATION_TYPE_SILENT_PUSH,
+ StructuredMessage::ATTACHMENT_TYPE_TEMPLATE,
+ StructuredMessage::TEMPLATE_PAYLOAD_TYPE_BUTTON));
+```
\ No newline at end of file
diff --git a/source/BaseObject.php b/source/BaseObject.php
new file mode 100644
index 0000000..4d8393f
--- /dev/null
+++ b/source/BaseObject.php
@@ -0,0 +1,57 @@
+ $val)
+ {
+ $this->data[$key] = is_array($val)? new Config($val) : $val;
+ }
+ }
+
+ public function &__get($key)
+ {
+ if(empty($this->data[$key]))
+ {
+ throw new MessengerPlatformException('Key "' . $key . '" is missing in "' . (get_class($this)) . '".', 1);
+ }
+
+ return $this->data[$key];
+ }
+
+ public function __isset($name)
+ {
+ return isset($this->data[$name]);
+ }
+
+ public function getDataForCall()
+ {
+ $result = [];
+ foreach($this->data as $key => $item)
+ {
+ $result[$key] = $item;
+ }
+
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/source/Config.php b/source/Config.php
new file mode 100644
index 0000000..7ee2eb5
--- /dev/null
+++ b/source/Config.php
@@ -0,0 +1,17 @@
+title = $title;
+ $this->itemUrl = $itemUrl;
+ $this->imageUrl = $imageUrl;
+ $this->subtitle = $subtitle;
+ $this->buttons = $buttons;
+ }
+
+
+ public function getDataForCall()
+ {
+ $request = ['title' => $this->title,];
+
+ if (!empty($this->itemUrl))
+ {
+ $request['item_url'] = $this->itemUrl;
+ }
+
+ if (!empty($this->image_url))
+ {
+ $request['image_url'] = $this->imageUrl;
+ }
+
+ if (!empty($this->subtitle))
+ {
+ $request['subtitle'] = $this->subtitle;
+ }
+
+ if (!empty($this->buttons))
+ {
+ $request['buttons'] = [];
+
+ foreach ($this->buttons as $button)
+ {
+ $request['buttons'][] = $button->getDataForCall();
+ }
+ }
+
+ return $request;
+ }
+}
+
+/**
+ *
+ * @package fritak\MessengerPlatform
+ * @see https://developers.facebook.com/docs/messenger-platform/send-api-reference#request
+ */
+class Button
+{
+ const TYPE_WEB = "web_url";
+ const TYPE_POSTBACK = "postback";
+
+ /** @var string Value is web_url or postback, use constants. */
+ protected $type = NULL;
+
+ /** @var string Button title */
+ protected $title = NULL;
+
+ /** @var string For web_url buttons, this URL is opened in a mobile browser when the button is tapped. For postback buttons, this data will be sent back to you via webhook. */
+ protected $url = NULL;
+
+
+ public function __construct($title, $type, $url)
+ {
+ $this->type = $type;
+ $this->title = $title;
+ $this->url = $url;
+ }
+
+ public function getDataForCall()
+ {
+ $result =
+ [
+ 'type' => $this->type,
+ 'title' => $this->title,
+ ];
+
+ switch($this->type)
+ {
+ case self::TYPE_POSTBACK:
+ $result['payload'] = $this->url;
+ break;
+ case self::TYPE_WEB:
+ $result['url'] = $this->url;
+ break;
+ }
+
+ return $result;
+ }
+}
\ No newline at end of file
diff --git a/source/Gate.php b/source/Gate.php
new file mode 100644
index 0000000..baa2e9e
--- /dev/null
+++ b/source/Gate.php
@@ -0,0 +1,99 @@
+config = &$config;
+ }
+
+ /**
+ * Request to API
+ *
+ * @param string $requestUrl Url for request.
+ * @param array $data Data for send.
+ * @param string $type Type of request GET/POST
+ * @return fritak\MessengerPlatform\Response
+ */
+ public function request($requestUrl, $data = [], $type = self::TYPE_POST)
+ {
+ $callUrl = $this->config->facebookApiUrl . $requestUrl;
+
+ if($type === self::TYPE_GET)
+ {
+ $callUrl .= '?' . $this->prepareData($data);
+ }
+
+ $curl = curl_init($callUrl);
+
+ curl_setopt($curl, CURLOPT_TIMEOUT, 30);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curl, CURLOPT_HTTPHEADER, $this->getHeaders());
+ curl_setopt($curl, CURLOPT_HEADER, 0);
+
+ if($type === self::TYPE_POST)
+ {
+ curl_setopt($curl, CURLOPT_POST, 1);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $this->prepareData($data));
+ }
+
+ $response = new Response(curl_exec($curl));
+
+ $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
+
+ if($statusCode != 200)
+ {
+ throw new MessengerPlatformException('Gate exception #2: ' . $response->error->message, 2);
+ }
+
+ curl_close($curl);
+
+ return $response;
+ }
+
+ /**
+ * Prepare data for request.
+ *
+ * @param array $data
+ * @return string
+ */
+ protected function prepareData($data)
+ {
+ if(!is_array($data))
+ {
+ $data = [];
+ }
+
+ $data['access_token'] = $this->config->accessToken;
+
+ return http_build_query($data);
+ }
+
+ protected function getHeaders()
+ {
+ return ['Content-Type: application/json',];
+ }
+
+}
\ No newline at end of file
diff --git a/source/MessageReceived.php b/source/MessageReceived.php
new file mode 100644
index 0000000..0b4b8f5
--- /dev/null
+++ b/source/MessageReceived.php
@@ -0,0 +1,88 @@
+id = $data->id;
+ $this->time = $data->time;
+
+ foreach($data->messaging AS $messaging)
+ {
+ $this->messaging[] = new Messaging($messaging);
+ }
+
+ }
+}
+
+/**
+ * Object containing data related to messaging.
+ *
+ * @package fritak\MessengerPlatform
+ * @see https://developers.facebook.com/docs/messenger-platform/webhook-reference#received_message
+ */
+class Messaging
+{
+ /** @var fritak\MessengerPlatform\Recipient Recipient. */
+ public $recipient;
+
+ /** @var fritak\MessengerPlatform\Sender Sender. */
+ public $sender;
+
+ /** @var int Timestamp of message. */
+ public $timestamp;
+
+ /** @var fritak\MessengerPlatform\Message Message. */
+ public $message;
+
+ public function __construct($data)
+ {
+ $this->recipient = new Recipient(['id' => $data->recipient->id]);
+ $this->sender = new Sender(['id' => $data->sender->id]);
+ $this->timestamp = $data->timestamp;
+
+ $this->message = new Message([
+ 'mid' => $data->message->mid,
+ 'seq' => $data->message->seq,
+ 'text' => $data->message->text,
+ ]);
+ }
+}
+
+/**
+ * @property-read int $id Recipient user id.
+ * @package fritak\MessengerPlatform
+ */
+class Recipient extends BaseObject {}
+
+/**
+ * @property-read int $id Sender user id.
+ * @package fritak\MessengerPlatform
+ */
+class Sender extends BaseObject {}
+
+/**
+ * @property-read int $mid Message ID.
+ * @property-read int $seq Message sequence number.
+ * @property-read string $text Text of message.
+ * @package fritak\MessengerPlatform
+ */
+class Message extends BaseObject {}
\ No newline at end of file
diff --git a/source/MessageSend.php b/source/MessageSend.php
new file mode 100644
index 0000000..3890ccc
--- /dev/null
+++ b/source/MessageSend.php
@@ -0,0 +1,42 @@
+recipientId = $recipientId;
+ $this->textMessage = $textMessage;
+ $this->notificationType = $notificationType;
+ }
+
+ public function getDataForCall()
+ {
+ if(empty($this->messageTemplate))
+ {
+ $this->messageTemplate = ['text' => $this->textMessage];
+ }
+
+ return [
+ 'message' => $this->messageTemplate,
+ 'recipient' => ['id' => $this->recipientId],
+ 'notification_type' => $this->notificationType
+ ];
+ }
+}
\ No newline at end of file
diff --git a/source/MessengerPlatformException.php b/source/MessengerPlatformException.php
new file mode 100644
index 0000000..ee33dff
--- /dev/null
+++ b/source/MessengerPlatformException.php
@@ -0,0 +1,13 @@
+mode = isset($data['hub_mode'])? $data['hub_mode'] : NULL;
+ $this->challenge = isset($data['hub_challenge'])? $data['hub_challenge'] : NULL;
+ $this->verifyWebhookToken = isset($data['hub_verify_token'])? $data['hub_verify_token'] : NULL;
+
+ $this->response = is_string($data)? json_decode($data) : $data;
+
+ }
+
+ /**
+ * Verify request token is valid.
+ *
+ * @param string $webhookToken WebhookToken from our configuration.
+ * @return boolean Is token from request valid?
+ */
+ public function verifyWebhookToken($webhookToken)
+ {
+ return $this->verifyWebhookToken == $webhookToken;
+ }
+
+ public function isSubscribe()
+ {
+ return !empty($this->mode) && $this->mode == self::MODE_SUBSCRIBE;
+ }
+
+ public function isMessage()
+ {
+ try
+ {
+ $messaging = $this->response->entry['0']->messaging;
+ }
+ catch(MessengerPlatformException $e)
+ {
+ return FALSE;
+ }
+
+ return !empty($messaging);
+ }
+
+ /**
+ * Check if request is subscribe.
+ *
+ * @param string $webhookToken WebhookToken from our configuration.
+ * @return boolean Is request subscribe?
+ */
+ public function checkSubscribe($webhookToken)
+ {
+ return $this->verifyWebhookToken($webhookToken) && $this->isSubscribe();
+ }
+
+ public function getChallenge()
+ {
+ return $this->challenge;
+ }
+
+ /**
+ * Get messages received. Returns FALSE if request don`t have messages.
+ *
+ * @return boolean|array Array of \fritak\MessengerPlatform\MessageReceived.
+ */
+ public function getMessagesReceived()
+ {
+ if($this->isMessage())
+ {
+ $messages = [];
+ foreach($this->response->entry AS $entry)
+ {
+ $messages[] = new MessageReceived($entry);
+ }
+
+ return $messages;
+ }
+
+ return FALSE;
+ }
+}
\ No newline at end of file
diff --git a/source/Receipt.php b/source/Receipt.php
new file mode 100644
index 0000000..15adaab
--- /dev/null
+++ b/source/Receipt.php
@@ -0,0 +1,119 @@
+recipientName = $recipientName;
+ $this->orderNumber = $orderNumber;
+ $this->currency = $currency;
+ $this->paymentMethod = $payment_method;
+ $this->elements = $elements;
+ $this->summary = $summary;
+ $this->address = $address;
+ $this->adjustments = $adjustments;
+ $this->timestamp = $timestamp;
+ $this->orderUrl = $orderUrl;
+ }
+
+ public function getDataForCall()
+ {
+ $payload = [];
+ $payload['recipient_name'] = $this->recipientName;
+ $payload['order_number'] = $this->orderNumber;
+ $payload['currency'] = $this->currency;
+ $payload['payment_method'] = $this->paymentMethod;
+ $payload['order_url'] = $this->orderUrl;
+ $payload['timestamp'] = $this->timestamp;
+ $payload['elements'] = [];
+
+
+ if(!empty($this->address))
+ {
+ $payload['address'] = $this->address->getDataForCall();
+ }
+
+ if(!empty($this->summary))
+ {
+ $payload['summary'] = $this->summary->getDataForCall();
+ }
+
+ foreach ($this->elements as $element)
+ {
+ $payload['elements'][] = $element->getDataForCall();
+ }
+
+ if(!empty($this->adjustments))
+ {
+ $payload['adjustments'] = [];
+ foreach ($this->adjustments as $adjustments)
+ {
+ $payload['adjustments'][] = $adjustments->getDataForCall();
+ }
+ }
+
+ return $payload;
+ }
+}
+
+/**
+ * @property string $street_1 Street Address, line 1 required
+ * @property string $street_2 Street Address, line 2
+ * @property string $city City required
+ * @property string $postal_code US Postal Code required
+ * @property string $state Two-letter state abbrevation (US) required
+ * @property string $country Two-letter country abbreviation required
+ */
+class Address extends BaseObject {}
+
+/**
+ * @property string $name Name of adjustment
+ * @property float $amount Adjusted amount
+ */
+class Adjustment extends BaseObject {}
+
+/**
+ * @property string $title Title of item required
+ * @property string $subtitle Subtitle of item
+ * @property int $quantity Quantity of item
+ * @property float $price Item price required
+ * @property string $currency Currency of price
+ * @property string $image_url Image URL of item
+ */
+class ReceiptElement extends BaseObject {}
+
+/**
+ * @property type $subtotal Subtotal
+ * @property type $shippingCost Cost of shipping
+ * @property type $total_tax Total tax
+ * @property type $total_cost Total cost required
+ */
+class Summary extends BaseObject {}
\ No newline at end of file
diff --git a/source/Response.php b/source/Response.php
new file mode 100644
index 0000000..709e08d
--- /dev/null
+++ b/source/Response.php
@@ -0,0 +1,38 @@
+ $val)
+ {
+ $this->data[$key] = is_array($val)? new Response($val) : $val;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/source/StructuredMessage.php b/source/StructuredMessage.php
new file mode 100644
index 0000000..6923f05
--- /dev/null
+++ b/source/StructuredMessage.php
@@ -0,0 +1,92 @@
+recipientId = $recipientId;
+ $this->data = $data;
+ $this->notificationType = $notificationType;
+ $this->typeAttachment = $typeAttachment;
+ $this->typePayolad = $typePayolad;
+ }
+
+ public function getDataForCall()
+ {
+ $payload = [];
+
+ if($this->typeAttachment == self::ATTACHMENT_TYPE_IMAGE)
+ {
+ if(isset($this->data['url']))
+ {
+ $payload['url'] = $this->data['url'];
+ }
+ }
+ else
+ {
+ $payload['template_type'] = $this->typePayolad;
+ }
+
+ switch ($this->typePayolad)
+ {
+ case self::TEMPLATE_PAYLOAD_TYPE_BUTTON:
+ $payload['text'] = $this->data['text'];
+ $buttons = [];
+
+ foreach ($this->data['buttons'] as $button)
+ {
+ $buttons[] = $button->getDataForCall();
+ }
+ $payload['buttons'] = $buttons;
+ break;
+
+ case self::TEMPLATE_PAYLOAD_TYPE_GENERIC:
+ $elements = [];
+
+ foreach ($this->data as $element)
+ {
+ $elements[] = $element->getDataForCall();
+ }
+
+ $payload['elements'] = $elements;
+ break;
+
+ case self::TEMPLATE_PAYLOAD_TYPE_RECEIPT:
+ $payload = array_replace($payload, $this->data->getDataForCall());
+ break;
+ }
+
+ $this->messageTemplate =
+ [
+ 'attachment' =>
+ [
+ 'type' => $this->typeAttachment,
+ 'payload' => $payload,
+ ]
+ ];
+
+ return parent::getDataForCall();
+ }
+}
\ No newline at end of file