diff --git a/spec/MessengerSpec.php b/spec/MessengerSpec.php index f065732..8d005d5 100644 --- a/spec/MessengerSpec.php +++ b/spec/MessengerSpec.php @@ -16,6 +16,7 @@ use Tgallice\FBMessenger\Model\MessageResponse; use Tgallice\FBMessenger\Model\ThreadSetting; use Tgallice\FBMessenger\Model\UserProfile; +use Tgallice\FBMessenger\Model\WhitelistedDomains; use Tgallice\FBMessenger\NotificationType; use Tgallice\FBMessenger\TypingIndicator; @@ -297,4 +298,52 @@ function it_should_set_typing_status($client) $this->setTypingStatus('USER_ID', TypingIndicator::TYPING_ON); } + + function it_should_define_domain_whitelisting($client) + { + $expectedBody = [ + 'setting_type' => 'domain_whitelisting', + 'whitelisted_domains' => ['https://www.google.com'], + 'domain_action_type' => 'add' + ]; + + $client->post('/me/thread_settings', Argument::that(function ($body) use ($expectedBody) { + return json_encode($body) === json_encode($expectedBody); + }))->shouldBeCalled(); + + $this->setDomainWhitelisting(['https://www.google.com']); + } + + function it_get_domain_whitelisting($client, ResponseInterface $response) + { + $response->getBody()->willReturn(' + { + "data" : [{ + "whitelisted_domains" : [ + "domain_1", + "domain_2" + ], + "id" : "123456" + }] + } + '); + + $query = [ + 'fields' => 'whitelisted_domains', + ]; + + $client->get('/me/thread_settings', $query)->willReturn($response); + + $whitelistedDomains = new WhitelistedDomains([ + 'data' => [[ + 'whitelisted_domains' => [ + 'domain_1', + 'domain_2' + ], + 'id' => '123456' + ]] + ]); + + $this->getDomainWhitelisting()->shouldBeLike($whitelistedDomains); + } } diff --git a/spec/Model/ThreadSetting/DomainWhitelistingSpec.php b/spec/Model/ThreadSetting/DomainWhitelistingSpec.php new file mode 100644 index 0000000..0c50a2d --- /dev/null +++ b/spec/Model/ThreadSetting/DomainWhitelistingSpec.php @@ -0,0 +1,79 @@ +beConstructedWith(['https://google.com']); + } + + function it_is_initializable() + { + $this->shouldHaveType('Tgallice\FBMessenger\Model\ThreadSetting\DomainWhitelisting'); + } + + function it_has_a_domains() + { + $this->getDomains()->shouldReturn(['https://google.com']); + } + + function it_has_a_add_action() + { + $this->getAction()->shouldReturn('add'); + } + + function it_has_a_remove_action() + { + $this->beConstructedWith(['https://google.com'], 'remove'); + + $this->getAction()->shouldReturn('remove'); + } + + function it_throws_exception_when_is_not_add_or_remove_action() + { + $this->beConstructedWith(['https://google.com'], 'update'); + + $this + ->shouldThrow(new \InvalidArgumentException('The action must be type: "add" or "remove".')) + ->duringInstantiation(); + } + + function it_throws_exception_when_domains_is_not_a_array() + { + $this->beConstructedWith('not array'); + + $this + ->shouldThrow(new \InvalidArgumentException('Domains must be a array.')) + ->duringInstantiation(); + } + + function it_throws_exception_when_one_domains_has_not_a_https_protocol() + { + $this->beConstructedWith([ + 'https://petersfancyapparel.com', + 'http://google.com', + 'https://www.google.com' + ], 'add'); + + $this + ->shouldThrow(new \InvalidArgumentException('Each domain must be a "https" protocol.')) + ->duringInstantiation(); + } + + function it_should_be_serializable() + { + $this->shouldImplement(\JsonSerializable::class); + + $expected = [ + 'whitelisted_domains' => ['https://google.com'], + 'domain_action_type' => 'add' + ]; + + $this->jsonSerialize()->shouldBeLike($expected); + } +} diff --git a/src/Messenger.php b/src/Messenger.php index 96c1a12..4ec2525 100644 --- a/src/Messenger.php +++ b/src/Messenger.php @@ -11,7 +11,9 @@ use Tgallice\FBMessenger\Model\ThreadSetting; use Tgallice\FBMessenger\Model\ThreadSetting\GreetingText; use Tgallice\FBMessenger\Model\ThreadSetting\StartedButton; +use Tgallice\FBMessenger\Model\ThreadSetting\DomainWhitelisting; use Tgallice\FBMessenger\Model\UserProfile; +use Tgallice\FBMessenger\Model\WhitelistedDomains; class Messenger { @@ -170,6 +172,33 @@ public function deleteGreetingText() $this->deleteThreadSettings($setting); } + /** + * @param array $domains + * @param string $action + */ + public function setDomainWhitelisting($domains, $action = DomainWhitelisting::TYPE_ADD) + { + $domainWhitelisting = new DomainWhitelisting($domains, $action); + $setting = $this->buildSetting(ThreadSetting::TYPE_DOMAIN_WHITELISTING, null, $domainWhitelisting, true); + + $this->postThreadSettings($setting); + } + + /** + * @return array + */ + public function getDomainWhitelisting() + { + $query = [ + 'fields' => DomainWhitelisting::WHITELISTED_DOMAINS + ]; + + $response = $this->client->get('/me/thread_settings', $query); + $data = $this->decodeResponse($response); + + return WhitelistedDomains::create($data); + } + /** * Messenger Factory * @@ -205,10 +234,11 @@ private function deleteThreadSettings(array $setting) * @param string $type * @param null|string $threadState * @param mixed $value + * @param bool $mergeValueWithSetting * * @return array */ - private function buildSetting($type, $threadState = null, $value = null) + private function buildSetting($type, $threadState = null, $value = null, $mergeValueWithSetting = false) { $setting = [ 'setting_type' => $type, @@ -217,8 +247,10 @@ private function buildSetting($type, $threadState = null, $value = null) if (!empty($threadState)) { $setting['thread_state'] = $threadState; } - - if (!empty($value)) { + + if($mergeValueWithSetting === true) { + $setting = array_merge($setting, $value->jsonSerialize()); + } else if(!empty($value)) { $setting[$type] = $value; } diff --git a/src/Model/ThreadSetting.php b/src/Model/ThreadSetting.php index 67d83b7..7b7afdd 100644 --- a/src/Model/ThreadSetting.php +++ b/src/Model/ThreadSetting.php @@ -7,6 +7,7 @@ interface ThreadSetting // Setting type const TYPE_GREETING = 'greeting'; const TYPE_CALL_TO_ACTIONS = 'call_to_actions'; + const TYPE_DOMAIN_WHITELISTING = 'domain_whitelisting'; // Thread state const NEW_THREAD = 'new_thread'; diff --git a/src/Model/ThreadSetting/DomainWhitelisting.php b/src/Model/ThreadSetting/DomainWhitelisting.php new file mode 100644 index 0000000..9b3f42e --- /dev/null +++ b/src/Model/ThreadSetting/DomainWhitelisting.php @@ -0,0 +1,102 @@ +action = $action; + $this->domains = $domains; + } + + /** + * + * @return array + */ + public function getDomains() + { + return $this->domains; + } + + /** + * + * @return string + */ + public function getAction() + { + return $this->action; + } + + /** + * + * @param string $action + * + * @throws \InvalidArgumentException + */ + public static function validateAction($action) + { + if(!in_array($action, [DomainWhitelisting::TYPE_ADD, DomainWhitelisting::TYPE_REMOVE])) { + throw new \InvalidArgumentException('The action must be type: "add" or "remove".'); + } + } + + /** + * + * @param array $domains + * + * @throws \InvalidArgumentException + */ + public static function validateDomains($domains) + { + if(!is_array($domains)) { + throw new \InvalidArgumentException('Domains must be a array.'); + } + + //https://developers.facebook.com/docs/messenger-platform/thread-settings/domain-whitelisting + foreach($domains as $domain) { + if(!preg_match('#^https:\/\/#', $domain)) { + throw new \InvalidArgumentException('Each domain must be a "https" protocol.'); + } + } + } + + /** + * @inheritdoc + */ + public function jsonSerialize() + { + return [ + DomainWhitelisting::WHITELISTED_DOMAINS => $this->domains, + DomainWhitelisting::DOMAIN_ACTION_TYPE => $this->action + ]; + } +} diff --git a/src/Model/WhitelistedDomains.php b/src/Model/WhitelistedDomains.php new file mode 100644 index 0000000..672d2ef --- /dev/null +++ b/src/Model/WhitelistedDomains.php @@ -0,0 +1,41 @@ +data = $data; + } + + /** + * @return array|null + */ + public function getDomains() + { + return isset($this->data['data'][0][DomainWhitelisting::WHITELISTED_DOMAINS]) ? + $this->data['data'][0][DomainWhitelisting::WHITELISTED_DOMAINS] : + null; + } + + /** + * @param array $data + * + * @return WhitelistedDomains + */ + public static function create(array $data) + { + return new self($data); + } +} \ No newline at end of file