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