diff --git a/README.md b/README.md index 7acab69..abc4884 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,12 @@ $client->contacts->nextSearch($query, $response->pages); /** List all contacts */ $client->contacts->getContacts([]); + +/** Tag a Contact */ +$client->contacts->addTag("570680a8a1bcbca8a90001b9", "2084335"); + +/** Remove a Tag from a Contact */ +$client->contacts->removeTag("570680a8a1bcbca8a90001b9", "2084335"); ``` ## Users @@ -489,6 +495,25 @@ $client->teams->getTeams(); $client->teams->getTeam("1188"); ``` +## Articles + +```php +/** Create an Article */ +$client->articles->create(["title" => "How To Use the Intercom API", "description" => "A quick guide to the universe of the Intercom API", "body" => "
This is the body in html
", "author_id" => 1]); + +/** Retrieve an Article */ +$client->articles->getArticle("123456"); + +/** Update an Article */ +$client->articles->update("123456", ["title" => "How To Use the Intercom API", "description" => "A quick guide to the universe of the Intercom API", "body" => "This is the body in html
"); + +/** Delete an Article */ +$client->articles->deleteArticle("123456"); + +/** List Articles */ +$client->articles->getArticles(); +``` + ## Rate Limits diff --git a/src/IntercomArticles.php b/src/IntercomArticles.php new file mode 100644 index 0000000..9b8027c --- /dev/null +++ b/src/IntercomArticles.php @@ -0,0 +1,88 @@ +client->post("articles", $options); + } + + /** + * Gets a single Article based on the Article ID. + * + * @see https://developers.intercom.com/intercom-api-reference/v0/reference#retrieve-an-article + * @param string $id + * @param array $options + * @return stdClass + * @throws Exception + */ + public function getArticle(string $id, array $options = []) + { + $path = $this->articlePath($id); + return $this->client->get($path, $options); + } + + /** + * Updates an existing Article + * + * @see https://developers.intercom.com/intercom-api-reference/v0/reference#update-an-article + * @param string $id + * @param array $options + * @return stdClass + */ + public function update(string $id, array $options = []) + { + $path = $this->articlePath($id); + return $this->client->put($path, $options); + } + + /** + * Deletes a single article based on the Article ID. + * + * @see https://developers.intercom.com/intercom-api-reference/v0/reference#delete-an-article + * @param string $id + * @param array $options + * @return stdClass + * @throws Exception + */ + public function deleteArticle(string $id, array $options = []) + { + $path = $this->articlePath($id); + return $this->client->delete($path, $options); + } + + /** + * Lists Articles. + * + * @see https://developers.intercom.com/intercom-api-reference/v0/reference#list-all-articles + * @param array $options + * @return stdClass + * @throws Exception + */ + public function getArticles(array $options = []) + { + return $this->client->get('articles', $options); + } + + /** + * @param string $id + * @return string + */ + public function articlePath(string $id) + { + return 'articles/' . $id; + } +} diff --git a/src/IntercomClient.php b/src/IntercomClient.php index f9532e8..3470ecb 100644 --- a/src/IntercomClient.php +++ b/src/IntercomClient.php @@ -58,6 +58,11 @@ class IntercomClient */ public $users; + /** + * @var IntercomContacts $contacts + */ + public $contacts; + /** * @var IntercomEvents $events */ @@ -69,9 +74,9 @@ class IntercomClient public $companies; /** - * @var IntercomContacts $contacts + * @var IntercomDataAttributes $dataAttributes */ - public $contacts; + public $dataAttributes; /** * @var IntercomMessages $messages @@ -144,13 +149,16 @@ public function __construct(string $appIdOrToken, string $password = null, array { $this->users = new IntercomUsers($this); $this->contacts = new IntercomContacts($this); + //$this->customers = new IntercomCustomers($this); $this->events = new IntercomEvents($this); $this->companies = new IntercomCompanies($this); + $this->dataAttributes = new IntercomDataAttributes($this); $this->messages = new IntercomMessages($this); $this->conversations = new IntercomConversations($this); $this->leads = new IntercomLeads($this); $this->visitors = new IntercomVisitors($this); $this->admins = new IntercomAdmins($this); + $this->articles = new IntercomArticles($this); $this->tags = new IntercomTags($this); $this->segments = new IntercomSegments($this); $this->counts = new IntercomCounts($this); diff --git a/src/IntercomCompanies.php b/src/IntercomCompanies.php index e3256ad..c6404e4 100644 --- a/src/IntercomCompanies.php +++ b/src/IntercomCompanies.php @@ -74,7 +74,7 @@ public function detachContact(string $contactId, string $companyId, array $optio * @return stdClass * @throws Exception */ - public function getCompanies($options) + public function getCompanies($options = []) { return $this->client->get("companies", $options); } diff --git a/src/IntercomContacts.php b/src/IntercomContacts.php index 7cfc073..2f3f4a2 100644 --- a/src/IntercomContacts.php +++ b/src/IntercomContacts.php @@ -1,5 +1,4 @@ contactPath($id); + return $this->client->put($path, $options); } @@ -43,6 +43,7 @@ public function update(string $id, array $options) * @return stdClass * @throws Exception */ + public function getContacts(array $options = []) { return $this->client->get('contacts', $options); @@ -57,6 +58,7 @@ public function getContacts(array $options = []) * @return stdClass * @throws Exception */ + public function getContact(string $id, array $options = []) { $path = $this->contactPath($id); @@ -78,6 +80,83 @@ public function deleteContact(string $id, array $options = []) return $this->client->delete($path, $options); } + /** + * List attached tags + * + * @see https://developers.intercom.com/intercom-api-reference/reference#list-tags-of-contact + * @param string $id + * @return stdClass + * @throws Exception + */ + public function tags(string $id) + { + $path = $this->contactTagsPath($id); + + return $this->client->get($path); + } + + /** + * Applys a tag to a Contact based on the provided Tag ID + * + * @see https://developers.intercom.com/intercom-api-reference/reference#tag-contact + * @param string $id + * @param string $tagId + * @return stdClass + * @throws Exception + */ + public function addTag(string $id, string $tagId) + { + $path = $this->contactTagsPath($id); + + return $this->client->post($path, ['id' => $tagId]); + } + + /** + * Removes a tag from a Contact based on the provided Tag ID + * + * @see https://developers.intercom.com/intercom-api-reference/reference#untag-contact + * @param string $id + * @param string $tagId + * @return stdClass + * @throws Exception + */ + public function removeTag(string $id, string $tagId) + { + $path = $this->contactTagsPath($id); + + return $this->client->delete($path, ['id' => $tagId]); + } + + /** + * List attached segments + * + * @see https://developers.intercom.com/intercom-api-reference/reference#list-attached-segments + * @param string $id + * @return stdClass + * @throws Exception + */ + public function segments(string $id) + { + $path = $this->contactSegmentsPath($id); + + return $this->client->get($path); + } + + /** + * List attached companies + * + * @see https://developers.intercom.com/intercom-api-reference/reference#list-companies-of-contact + * @param string $id + * @return stdClass + * @throws Exception + */ + public function companies(string $id) + { + $path = $this->contactCompaniesPath($id); + + return $this->client->get($path); + } + /** * Returns list of Contacts that match search query. * @@ -92,6 +171,21 @@ public function search(array $options) return $this->client->post($path, $options); } + /** + * Gets all data attributes for the Contact model + * + * @see https://developers.intercom.com/intercom-api-reference/reference#list-data-attributes + * @param array $options + * @return stdClass + * @throws Exception + */ + public function getAttributes($options = []) + { + $options = array_merge($options, ["model" => "contact"]); + + return $this->client->get('data_attributes', $options); + } + /** * Returns next page of Contacts that match search query. * @@ -130,4 +224,39 @@ public function contactPath(string $id) { return 'contacts/' . $id; } + + /** + * Returns the path for viewing/adding/removing a tag for a given contact + * + * @param string $id Contact ID + * @return string + */ + public function contactTagsPath(string $id) + { + return 'contacts/' . $id . '/tags'; + } + + /** + * Returns the path for viewing segments for a given contact + * + * @param string $id Contact ID + * @return string + */ + public function contactSegmentsPath(string $id) + { + return 'contacts/' . $id . '/segments'; + } + + /** + * Returns the path for viewing companies for a given contact + * + * @param string $id Contact ID + * @return string + */ + public function contactCompaniesPath(string $id) + { + return 'contacts/' . $id . '/companies'; + } + + } diff --git a/src/IntercomConversations.php b/src/IntercomConversations.php index 801cb37..2a70be6 100644 --- a/src/IntercomConversations.php +++ b/src/IntercomConversations.php @@ -108,6 +108,40 @@ public function markConversationAsRead($id) return $this->client->put($path, $data); } + /** + * Adds a tag to a Conversation based on the provided Tag and Admin ID + * + * @see https://developers.intercom.com/intercom-api-reference/reference#attach-a-tag-to-a-conversation + * @param string $id + * @param string $tagId + * @param string $adminId + * @return stdClass + */ + + public function addTag($id, $tagId, $adminId) { + + $path = $this->conversationPath($id); + + return $this->client->post($path.'/tags', ['id' => $tagId, 'admin' => $adminId]); + } + + /** + * Removes a tag to a Conversation based on the provided Tag and Admin ID + * + * @see https://developers.intercom.com/intercom-api-reference/reference#attach-a-tag-to-a-conversation + * @param string $id + * @param string $tagId + * @param string $adminId + * @return stdClass + */ + + public function removeTag($id, $tagId) { + + $path = $this->conversationPath($id); + + return $this->client->delete($path.'/tags', ['id' => $tagId]); + } + /** * Returns endpoint path to Conversation with given ID. * diff --git a/src/IntercomDataAttributes.php b/src/IntercomDataAttributes.php new file mode 100644 index 0000000..28177ad --- /dev/null +++ b/src/IntercomDataAttributes.php @@ -0,0 +1,63 @@ +client->post($this->dataAttributePath(), $options); + } + + /** + * Updates a Data Attribute + * + * @see https://developers.intercom.com/intercom-api-reference/reference#update-data-attributes + * @param array $options + * @return stdClass + * @throws Exception + */ + public function update(array $options) + { + return $this->client->put($this->dataAttributePath(), $options); + } + + /** + * List all data attributes + * + * @see https://developers.intercom.com/intercom-api-reference/reference#list-data-attributes + * @param string $model + * @param bool $include_archived + * @return stdClass + */ + public function list(string $model = 'contact', bool $include_archived = false ) + { + $options = [ + 'model' => $model, + 'include_archived' => $include_archived + ]; + + return $this->client->get($this->dataAttributePath(), $options); + } + + /** + * @param string $id + * @return string + */ + public function dataAttributePath() + { + return 'data_attributes'; + } + +} diff --git a/src/IntercomMessages.php b/src/IntercomMessages.php index d4d9665..fd028e5 100644 --- a/src/IntercomMessages.php +++ b/src/IntercomMessages.php @@ -19,4 +19,45 @@ public function create($options) { return $this->client->post("messages", $options); } + + /** + * Creates Message Export Job + * + * @see https://developers.intercom.com/intercom-api-reference/reference#creating-an-export-job + * @param array $options + * @return stdClass + * @throws Exception + */ + public function createExport($options) + { + return $this->client->post("export/messages/data", $options); + } + + /** + * Retrieves Export Job Status + * + * @see https://developers.intercom.com/intercom-api-reference/reference#checking-the-status-of-the-job + * @param string $job_identifier + * @return stdClass + * @throws Exception + */ + public function retrieveExportStatus($job_identifier) + { + return $this->client->get("export/messages/data/" . $job_identifier, []); + } + + /** + * Retrieves Export Job Data + * + * Important: The Intercom Client Accept Header must be application/octet-stream + * + * @see https://developers.intercom.com/intercom-api-reference/reference#downloading-the-data + * @param string $job_identifier + * @return stdClass + * @throws Exception + */ + public function retrieveExportData($job_identifier) + { + return $this->client->get("download/messages/data/" . $job_identifier, []); + } } diff --git a/test/IntercomArticlesTest.php b/test/IntercomArticlesTest.php new file mode 100644 index 0000000..c82e607 --- /dev/null +++ b/test/IntercomArticlesTest.php @@ -0,0 +1,55 @@ +client->method('post')->willReturn('foo'); + + $articles = new IntercomArticles($this->client); + $this->assertSame('foo', $articles->create([ + 'title' => 'Test Article', + 'description' => 'Test Description', + 'body' => 'Test Body
', + 'author_id' => '123' + ])); + } + + public function testGetArticle() + { + $this->client->method('get')->willReturn('foo'); + + $articles = new IntercomArticles($this->client); + $this->assertSame('foo', $articles->getArticle('123')); + } + + public function testUpdateArticle() + { + $this->client->method('put')->willReturn('foo'); + + $articles = new IntercomArticles($this->client); + $this->assertSame('foo', $articles->update('123', [ + 'title' => 'Updated Title' + ])); + } + + public function testDeleteArticle() + { + $this->client->method('delete')->willReturn('foo'); + + $articles = new IntercomArticles($this->client); + $this->assertSame('foo', $articles->deleteArticle('123')); + } + + public function testListArticles() + { + $this->client->method('get')->willReturn('foo'); + + $articles = new IntercomArticles($this->client); + $this->assertSame('foo', $articles->getArticles()); + } +} \ No newline at end of file diff --git a/test/IntercomContactsTest.php b/test/IntercomContactsTest.php index 9d1578d..996a21f 100644 --- a/test/IntercomContactsTest.php +++ b/test/IntercomContactsTest.php @@ -79,4 +79,28 @@ public function testConversationNextCursor() $contacts = new IntercomContacts($this->client); $this->assertSame('foo', $contacts->nextCursor($pages)); } + + public function testContactRemoveTag() + { + $this->client->method('delete')->willReturn('foo'); + + $contacts = new IntercomContacts($this->client); + $this->assertSame('foo', $contacts->removeTag('contact123', 'tag456')); + } + + public function testContactTags() + { + $this->client->method('get')->willReturn('foo'); + + $contacts = new IntercomContacts($this->client); + $this->assertSame('foo', $contacts->tags('contact123')); + } + + public function testContactAddTag() + { + $this->client->method('post')->willReturn('foo'); + + $contacts = new IntercomContacts($this->client); + $this->assertSame('foo', $contacts->addTag('contact123', 'tag456')); + } } diff --git a/test/IntercomConversationsTest.php b/test/IntercomConversationsTest.php index 686e48f..4e32e03 100644 --- a/test/IntercomConversationsTest.php +++ b/test/IntercomConversationsTest.php @@ -63,4 +63,20 @@ public function testReplyToConversation() $users = new IntercomConversations($this->client); $this->assertSame('foo', $users->replyToConversation("bar", [])); } + + public function testConversationRemoveTag() + { + $this->client->method('delete')->willReturn('foo'); + + $conversations = new IntercomConversations($this->client); + $this->assertSame('foo', $conversations->removeTag('conv123', 'tag456')); + } + + public function testConversationAddTag() + { + $this->client->method('post')->willReturn('foo'); + + $conversations = new IntercomConversations($this->client); + $this->assertSame('foo', $conversations->addTag('conv123', 'tag456', 'admin789')); + } } diff --git a/test/IntercomMessagesTest.php b/test/IntercomMessagesTest.php index 2e92fdf..cb8d192 100644 --- a/test/IntercomMessagesTest.php +++ b/test/IntercomMessagesTest.php @@ -13,4 +13,31 @@ public function testMessageCreate() $messages = new IntercomMessages($this->client); $this->assertSame('foo', $messages->create([])); } + + public function testCreateExport() + { + $this->client->method('post')->willReturn('foo'); + + $messages = new IntercomMessages($this->client); + $this->assertSame('foo', $messages->createExport([ + 'created_at_after' => 1234567890, + 'created_at_before' => 1234567891 + ])); + } + + public function testRetrieveExportStatus() + { + $this->client->method('get')->willReturn('foo'); + + $messages = new IntercomMessages($this->client); + $this->assertSame('foo', $messages->retrieveExportStatus('job123')); + } + + public function testRetrieveExportData() + { + $this->client->method('get')->willReturn('foo'); + + $messages = new IntercomMessages($this->client); + $this->assertSame('foo', $messages->retrieveExportData('job123')); + } } diff --git a/test/IntercomTagsTest.php b/test/IntercomTagsTest.php index bc79bf3..8329d50 100644 --- a/test/IntercomTagsTest.php +++ b/test/IntercomTagsTest.php @@ -6,19 +6,29 @@ class IntercomTagsTest extends TestCase { - public function testTagUsers() + public function testCreateTag() { $this->client->method('post')->willReturn('foo'); - $tags = new IntercomTags($this->client); - $this->assertSame('foo', $tags->tag([])); + + $options = [ + 'name' => 'TestTag', + 'contacts' => [['id' => 'abc123']] + ]; + + $this->assertSame('foo', $tags->tag($options)); } - public function testTagsList() + public function testListTags() { $this->client->method('get')->willReturn('foo'); - $tags = new IntercomTags($this->client); + + // Test without options $this->assertSame('foo', $tags->getTags()); + + // Test with options + $options = ['type' => 'contact']; + $this->assertSame('foo', $tags->getTags($options)); } } diff --git a/test/TestCase.php b/test/TestCase.php index c999ec4..9976b8b 100644 --- a/test/TestCase.php +++ b/test/TestCase.php @@ -12,10 +12,11 @@ abstract class TestCase extends BaseTestCase */ protected $client; - protected function setUp() + protected function setUp(): void { parent::setUp(); - - $this->client = $this->getMockBuilder(IntercomClient::class)->disableOriginalConstructor()->getMock(); + $this->client = $this->getMockBuilder(IntercomClient::class) + ->disableOriginalConstructor() + ->getMock(); } }