diff --git a/.fernignore b/.fernignore
index 41e2e16..57fb11d 100644
--- a/.fernignore
+++ b/.fernignore
@@ -3,4 +3,5 @@
.github/PULL_REQUEST_TEMPLATE.md
.gitattributes
LICENSE
-REPO_OWNER
\ No newline at end of file
+REPO_OWNER
+tests/integration
\ No newline at end of file
diff --git a/tests/integration/admins.test.ts b/tests/integration/admins.test.ts
new file mode 100644
index 0000000..8302bf1
--- /dev/null
+++ b/tests/integration/admins.test.ts
@@ -0,0 +1,61 @@
+import { createClient } from "./utils/createClient";
+
+describe("Admins", () => {
+ let adminId: string;
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const adminList = await client.admins.list();
+ adminId = adminList.admins[0].id;
+ });
+
+ it("list", async () => {
+ // act
+ const response = await client.admins.list();
+
+ // assert
+ expect(response).toBeDefined();
+ });
+ it("find", async () => {
+ // act
+ const response = await client.admins.find({ admin_id: adminId });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("listAllActivityLogs", async () => {
+ // act
+ const response = await client.admins.listAllActivityLogs({
+ created_at_after: new Date("2021-12-12").toISOString(),
+ created_at_before: new Date("2022-01-01").toISOString(),
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("away - ON", async () => {
+ // act
+ const response = await client.admins.away({
+ admin_id: adminId,
+ away_mode_enabled: true,
+ away_mode_reassign: true,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+ it("away - OFF", async () => {
+ // act
+ const response = await client.admins.away({
+ admin_id: adminId,
+ away_mode_enabled: false,
+ away_mode_reassign: false,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/articles.test.ts b/tests/integration/articles.test.ts
new file mode 100644
index 0000000..1966891
--- /dev/null
+++ b/tests/integration/articles.test.ts
@@ -0,0 +1,116 @@
+import { IntercomClient as Client } from "../../src";
+import { randomString } from "./utils/random";
+import { createClient } from "./utils/createClient";
+
+async function createArticle(client: Client, parentId: number, adminId: number) {
+ return await client.articles.create({
+ title: randomString(),
+ description: randomString(),
+ body: "Eins Zwei",
+ author_id: adminId,
+ state: "draft",
+ parent_id: parentId,
+ parent_type: "collection",
+ translated_content: {
+ fr: {
+ type: "article_content",
+ title: "Allez les verts",
+ description: "French description",
+ body: "
French body in html
",
+ author_id: adminId,
+ state: "draft",
+ },
+ },
+ });
+}
+
+async function tryDeleteArticle(client: Client, articleId: string) {
+ try {
+ await client.articles.delete({ article_id: articleId });
+ } catch (error) {
+ console.error("Failed to delete article:", error);
+ }
+}
+
+describe("Articles", () => {
+ let articleId: string;
+ let parentId: number;
+ let adminId: number;
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const randomCollections = await client.helpCenters.collections.list({
+ per_page: 1,
+ });
+ const randomAdmins = await client.admins.list();
+
+ parentId = parseInt(randomCollections.data[0].id, 10);
+ adminId = parseInt(randomAdmins.admins[0].id, 10);
+
+ const article = await createArticle(client, parentId, adminId);
+ articleId = article.id;
+ });
+
+ afterAll(async () => {
+ // cleanup
+ await tryDeleteArticle(client, articleId);
+ });
+
+ it("create", async () => {
+ // act
+ const article = await createArticle(client, parentId, adminId);
+
+ // assert
+ expect(article).toBeDefined();
+
+ // cleanup
+ await tryDeleteArticle(client, article.id);
+ });
+
+ it("find", async () => {
+ // act
+ const response = await client.articles.find({ article_id: articleId });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("update", async () => {
+ // arrange
+ const article = await createArticle(client, parentId, adminId);
+
+ // act
+ const response = await client.articles.update({
+ article_id: article.id,
+ body: {
+ title: "Biba & Boba",
+ },
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteArticle(client, article.id);
+ });
+
+ it("list", async () => {
+ // act
+ const response = await client.articles.list({ page: 1, per_page: 12 });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("delete", async () => {
+ // arrange
+ const article = await createArticle(client, parentId, adminId);
+
+ // act
+ const response = await client.articles.delete({ article_id: article.id });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/companies.test.ts b/tests/integration/companies.test.ts
new file mode 100644
index 0000000..078d81e
--- /dev/null
+++ b/tests/integration/companies.test.ts
@@ -0,0 +1,148 @@
+import { Intercom } from "../../src";
+import { dateToUnixTimestamp } from "./utils/date";
+import { createCompany, tryDeleteCompany } from "./helpers";
+import { createClient } from "./utils/createClient";
+
+describe("Companies", () => {
+ let contactId: string;
+ let company: Intercom.Company;
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const randomContacts = await client.contacts.list({
+ per_page: 1,
+ });
+
+ contactId = randomContacts.data[0].id;
+ company = await createCompany(client);
+ });
+
+ afterAll(async () => {
+ // cleanup
+ await tryDeleteCompany(client, company.id);
+ });
+
+ it("create", async () => {
+ // act
+ const company = await createCompany(client);
+
+ // assert
+ expect(company).toBeDefined();
+
+ // cleanup
+ await tryDeleteCompany(client, company.id);
+ });
+
+ it("update", async () => {
+ // arrange
+ const company = await createCompany(client);
+
+ // act
+ const response = await client.companies.createOrUpdate({
+ company_id: company.company_id,
+ remote_created_at: dateToUnixTimestamp(new Date()),
+ name: "BestCompanyInc",
+ monthly_spend: 9001,
+ plan: "1. Get pizzaid",
+ size: 62049,
+ website: "http://the-best.one",
+ industry: "The Best One",
+ custom_attributes: {},
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteCompany(client, company.id);
+ });
+
+ it("find - by id", async () => {
+ // act
+ const response = await client.companies.find({
+ company_id: company.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("list", async () => {
+ // act
+ const response = await client.companies.list({
+ page: 1,
+ per_page: 35,
+ order: "desc",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("delete", async () => {
+ // arrange
+ const company = await createCompany(client);
+
+ // act
+ const response = await client.companies.delete({
+ company_id: company.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it.skip("scroll - infinite one", async () => {
+ // act
+ const response = await client.companies.scroll();
+
+ // assert
+ expect(response.data).toBeDefined();
+ });
+
+ it("attachContact", async () => {
+ // act
+ const response = await client.companies.attachContact({
+ contact_id: contactId,
+ id: company.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("detachContact", async () => {
+ // act
+ const response = await client.companies.detachContact({
+ contact_id: contactId,
+ company_id: company.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("listAttachedContacts", async () => {
+ // act
+ const response = await client.companies.listAttachedContacts({
+ company_id: company.id,
+ page: 1,
+ per_page: 25,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("listAttachedSegments", async () => {
+ // act
+ const response = await client.companies.listAttachedSegments({
+ company_id: company.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/contacts.test.ts b/tests/integration/contacts.test.ts
new file mode 100644
index 0000000..633714d
--- /dev/null
+++ b/tests/integration/contacts.test.ts
@@ -0,0 +1,243 @@
+import { Intercom } from "../../src";
+import { dateToUnixTimestamp } from "./utils/date";
+import { randomString } from "./utils/random";
+import { createContact, tryDeleteCompany, tryDeleteContact, tryUntagContact } from "./helpers";
+import { createClient } from "./utils/createClient";
+
+describe("Contacts", () => {
+ let subscriptionId: string;
+ let tag: Intercom.Tag;
+ let contact: Intercom.Contact;
+ let company: Intercom.Company;
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ contact = await createContact(client);
+
+ company = await client.companies.createOrUpdate({
+ remote_created_at: dateToUnixTimestamp(new Date()),
+ company_id: randomString(),
+ name: randomString(),
+ monthly_spend: 9001,
+ plan: "1. Get pizzaid",
+ size: 62049,
+ website: "http://the-best.one",
+ industry: "The Best One",
+ custom_attributes: {},
+ });
+
+ await client.companies.attachContact({
+ id: company.id,
+ contact_id: contact.id,
+ });
+
+ const subscriptionTypes = await client.subscriptionTypes.list();
+ subscriptionId = subscriptionTypes.data[0].id;
+ await client.contacts.attachSubscription({
+ contact_id: contact.id,
+ id: subscriptionId,
+ consent_type: "opt_in",
+ });
+
+ tag = await client.tags.create({
+ name: randomString(),
+ });
+ await client.tags.tagContact({
+ contact_id: contact.id,
+ id: tag.id,
+ });
+ });
+
+ afterAll(async () => {
+ // cleanup
+ try {
+ await client.contacts.detachSubscription({
+ contact_id: contact.id,
+ subscription_id: subscriptionId,
+ });
+ } catch (error) {
+ console.error("Failed to detach subscription:", error);
+ }
+ await tryUntagContact(client, contact.id, tag.id);
+ await tryDeleteCompany(client, company.id);
+ await tryDeleteContact(client, contact.id);
+ });
+
+ it("list", async () => {
+ // act
+ const response = await client.contacts.list({
+ per_page: 5,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("createUser", async () => {
+ // act
+ const response = await client.contacts.create({
+ external_id: randomString(),
+ phone: "+353871234567",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteContact(client, response.id);
+ });
+
+ it("createLead", async () => {
+ // act
+ const response = await client.contacts.create({
+ name: "Roman Bowling",
+ role: "lead",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteContact(client, response.id);
+ });
+
+ it("find - by id", async () => {
+ // act
+ const response = await client.contacts.find({
+ contact_id: contact.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("update", async () => {
+ // arrange
+ const contact = await createContact(client);
+
+ // act
+ const response = await client.contacts.update({
+ contact_id: contact.id,
+ name: "Nico Bellic",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteContact(client, contact.id);
+ });
+
+ it("archive", async () => {
+ // arrange
+ const contact = await createContact(client);
+
+ // act
+ const response = await client.contacts.archive({
+ contact_id: contact.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteContact(client, contact.id);
+ });
+
+ it("unarchive", async () => {
+ // arrange
+ const contact = await createContact(client);
+
+ // act
+ const response = await client.contacts.unarchive({
+ contact_id: contact.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteContact(client, contact.id);
+ });
+
+ it("delete", async () => {
+ // arrange
+ const contact = await client.contacts.create({
+ external_id: randomString(),
+ phone: "+353871234567",
+ });
+
+ // act
+ const response = await client.contacts.delete({
+ contact_id: contact.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("mergeLeadInUser", async () => {
+ // arrange
+ const createdUser = await client.contacts.create({
+ external_id: randomString(),
+ phone: "+353871234567",
+ });
+ const createdLead = await client.contacts.create({
+ name: "Roman Bowling",
+ role: "lead",
+ });
+ const response = await client.contacts.mergeLeadInUser({
+ from: createdLead.id,
+ into: createdUser.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteContact(client, createdUser.id);
+ await tryDeleteContact(client, createdLead.id);
+ });
+
+ it("listAttachedCompanies", async () => {
+ // act
+ const response = await client.contacts.listAttachedCompanies({
+ contact_id: contact.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("listAttachedEmailSubscriptions", async () => {
+ // act
+ const response = await client.contacts.listAttachedSubscriptions({
+ contact_id: contact.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("listAttachedSegments", async () => {
+ // act
+ const response = await client.contacts.listAttachedSegments({
+ contact_id: contact.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("listAttachedTags", async () => {
+ // act
+ const response = await client.contacts.listAttachedTags({
+ contact_id: contact.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/conversations.test.ts b/tests/integration/conversations.test.ts
new file mode 100644
index 0000000..c24b396
--- /dev/null
+++ b/tests/integration/conversations.test.ts
@@ -0,0 +1,286 @@
+import { Intercom } from "../../src";
+import { randomString } from "./utils/random";
+import { createConversation, tryDeleteContact } from "./helpers";
+import { wait } from "./utils/wait";
+import { createClient } from "./utils/createClient";
+
+describe("Conversations", () => {
+ let user: Intercom.Contact;
+ let secondUser: Intercom.Contact;
+ let lead: Intercom.Contact;
+
+ let adminId: string;
+ let secondAdminId: string;
+ let conversationId: string;
+ let conversation: Intercom.Conversation;
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const admins = await client.admins.list();
+
+ const adminList = admins.admins.filter((admin) => admin.has_inbox_seat);
+ // Only admins with inbox seat can interact with conversations.
+ adminId = adminList[0].id;
+ secondAdminId = adminList[1].id;
+ user = await client.contacts.create({
+ external_id: randomString(),
+ name: "Baba Booey",
+ });
+ secondUser = await client.contacts.create({
+ external_id: randomString(),
+ name: "Babushka Boy",
+ email: "babushka_boy@bababooey.com",
+ });
+ lead = await client.contacts.create({
+ name: "Babushka Lead",
+ email: "babushka_lead@bababooey.com",
+ role: "lead",
+ });
+
+ const conversationMessage = await client.conversations.create({
+ from: { id: user.id, type: "user" },
+ body: "Raz-dwa-try kalyna, czorniawaja diwczyna",
+ });
+ conversationId = conversationMessage.conversation_id;
+
+ // Give Intercom a few seconds to index conversation
+ await wait(5000);
+
+ conversation = await client.conversations.find({
+ conversation_id: conversationId,
+ });
+ }, 20_000);
+
+ afterAll(async () => {
+ // cleanup
+ await tryDeleteContact(client, user.id);
+ await tryDeleteContact(client, secondUser.id);
+ await tryDeleteContact(client, lead.id);
+ });
+
+ it("create conversation with user as default", async () => {
+ // act
+ const response = await client.conversations.create({
+ from: { id: user.id, type: "user" },
+ body: "Raz-dwa-try kalyna, czorniawaja diwczyna",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("create conversation with user", async () => {
+ // act
+ const response = await client.conversations.create({
+ from: { id: user.id, type: "user" },
+ body: "Raz-dwa-try kalyna, czorniawaja diwczyna",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("create conversation with lead", async () => {
+ // act
+ const response = await client.conversations.create({
+ from: { id: lead.id, type: "lead" },
+ body: "Raz-dwa-try kalyna, czorniawaja diwczyna",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("find - by id", async () => {
+ // act
+ const response = await client.conversations.find({
+ conversation_id: conversationId,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("update", async () => {
+ // act
+ const response = await client.conversations.update({
+ conversation_id: conversationId,
+ read: false,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("replyByIdAsAdmin", async () => {
+ // act
+ const response = await client.conversations.reply({
+ conversation_id: conversationId,
+ body: {
+ message_type: "comment",
+ type: "admin",
+ body: "test",
+ admin_id: adminId,
+ },
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("replyByIdAsUser", async () => {
+ // act
+ const response = await client.conversations.reply({
+ conversation_id: conversationId,
+ body: {
+ message_type: "comment",
+ type: "user",
+ body: "*click* Nice!",
+ intercom_user_id: user.id,
+ },
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("assign", async () => {
+ // arrange
+ const message = await createConversation(client, user.id);
+
+ // act
+ const response = await client.conversations.manage({
+ conversation_id: message.conversation_id,
+ body: {
+ message_type: "assignment",
+ type: "admin",
+ admin_id: adminId,
+ assignee_id: secondAdminId,
+ body: "Goodbye :)",
+ },
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("run assignment rules", async () => {
+ // arrange
+ const message = await createConversation(client, user.id);
+
+ // act
+ const response = await client.conversations.runAssignmentRules({
+ conversation_id: message.conversation_id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("snooze", async () => {
+ // act
+ const response = await client.conversations.manage({
+ conversation_id: conversationId,
+ body: {
+ message_type: "snoozed",
+ admin_id: adminId,
+ snoozed_until: new Date("2040.06.19").getTime() / 1000,
+ },
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("open", async () => {
+ // act
+ const response = await client.conversations.manage({
+ conversation_id: conversationId,
+ body: {
+ message_type: "open",
+ admin_id: adminId,
+ },
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("attachContactAsAdmin", async () => {
+ // act
+ const response = await client.conversations.attachContactAsAdmin({
+ conversation_id: conversationId,
+ customer: { intercom_user_id: secondUser.id },
+ admin_id: adminId,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("detachContactAsAdmin", async () => {
+ // act
+ const response = await client.conversations.detachContactAsAdmin({
+ admin_id: adminId,
+ contact_id: secondUser.id,
+ conversation_id: conversationId,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("redactConversationPart", async () => {
+ // arrange
+ const conversation = await client.conversations.find({
+ conversation_id: conversationId,
+ });
+
+ // act
+ const response = await client.conversations.redactConversationPart({
+ type: "conversation_part",
+ conversation_id: conversationId,
+ conversation_part_id: conversation.conversation_parts?.conversation_parts[2].id ?? "",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("close", async () => {
+ // act
+ const response = await client.conversations.manage({
+ conversation_id: conversationId,
+ body: {
+ type: "admin",
+ message_type: "close",
+ admin_id: adminId,
+ body: "Hasta la vista, baby",
+ },
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("search", async () => {
+ // act
+ const response = await client.conversations.search({
+ query: {
+ operator: "AND",
+ value: [
+ {
+ field: "id",
+ operator: "!=",
+ value: "123",
+ },
+ ],
+ },
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/dataAttributes.test.ts b/tests/integration/dataAttributes.test.ts
new file mode 100644
index 0000000..22c3ca1
--- /dev/null
+++ b/tests/integration/dataAttributes.test.ts
@@ -0,0 +1,67 @@
+import { Intercom } from "../../src";
+import { randomString } from "./utils/random";
+import { createClient } from "./utils/createClient";
+
+describe("Data Attributes", () => {
+ let randomDataAttribute: Intercom.DataAttribute | undefined;
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const attributes = await client.dataAttributes.list();
+ randomDataAttribute = attributes.data.find((attribute) => attribute.id !== undefined);
+ });
+
+ xit("create", async () => {
+ //act
+
+ // The workspace we test on has hit the CDA limit, so we can't create any more
+ // for now. We should reenable this test once we have a new workspace.
+ const response = await client.dataAttributes.create({
+ name: `Bebech${randomString()}`,
+ model: "contact",
+ data_type: "string",
+ description: "Dummy description",
+ options: ["yey", "yoy"],
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+ it("update", async () => {
+ // arrange
+ if (!randomDataAttribute?.id) {
+ console.log("randomDataAttribute", randomDataAttribute);
+ throw new Error("random_data_attribute.id is required to update");
+ }
+
+ // act
+ const response = await client.dataAttributes.update({
+ data_attribute_id: randomDataAttribute.id.toString(),
+ archived: false,
+ description: "Woo-aaa",
+ options: [
+ {
+ value: "1-10",
+ },
+ {
+ value: "11-20",
+ },
+ ],
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+ it("list", async () => {
+ // act
+ const response = await client.dataAttributes.list({
+ include_archived: true,
+ model: "conversation",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/dataExport.test.ts b/tests/integration/dataExport.test.ts
new file mode 100644
index 0000000..a26d014
--- /dev/null
+++ b/tests/integration/dataExport.test.ts
@@ -0,0 +1,57 @@
+import { Intercom, IntercomClient } from "../../src";
+import { createClient } from "./utils/createClient";
+
+async function createDataExport(client: IntercomClient): Promise {
+ const dataExport = await client.dataExport.create({
+ created_at_after: 1670000000,
+ created_at_before: 1670940528,
+ });
+ return dataExport;
+}
+
+async function tryCancelDataExport(client: IntercomClient, jobIdentifier: string): Promise {
+ try {
+ await client.dataExport.cancel({ job_identifier: jobIdentifier });
+ } catch (error: unknown) {
+ console.log(error);
+ }
+}
+
+describe("dataExport", () => {
+ const client = createClient();
+ it("create", async () => {
+ // act
+ const response = await createDataExport(client);
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryCancelDataExport(client, response.job_identifier);
+ });
+
+ it("find", async () => {
+ // arrange
+ const dataExport = await createDataExport(client);
+
+ // act
+ const response = await client.dataExport.find({ job_identifier: dataExport.job_identifier });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryCancelDataExport(client, dataExport.job_identifier);
+ });
+
+ it("cancel", async () => {
+ // arrange
+ const dataExport = await createDataExport(client);
+
+ // act
+ const response = await client.dataExport.cancel({ job_identifier: dataExport.job_identifier });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/events.test.ts b/tests/integration/events.test.ts
new file mode 100644
index 0000000..d86c25c
--- /dev/null
+++ b/tests/integration/events.test.ts
@@ -0,0 +1,69 @@
+import { IntercomClient as Client } from "../../src";
+import { dateToUnixTimestamp } from "./utils/date";
+import { randomString } from "./utils/random";
+import { createClient } from "./utils/createClient";
+
+describe("Events", () => {
+ let userId: string;
+ let eventId = randomString();
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const randomUsers = await client.contacts.search({
+ query: {
+ operator: "AND",
+ value: [
+ {
+ field: "role",
+ operator: "=",
+ value: "user",
+ },
+ {
+ field: "external_id",
+ operator: "!=",
+ value: undefined,
+ },
+ ],
+ },
+ pagination: {
+ per_page: 1,
+ },
+ });
+ userId = randomUsers.data[0].external_id || "";
+ if (!userId) {
+ console.warn("user_id is required to run tests");
+ }
+ });
+
+ it("create", async () => {
+ // act
+ expect(
+ async () =>
+ await client.events.create({
+ id: eventId,
+ user_id: userId,
+ event_name: "opinion-rejected",
+ created_at: dateToUnixTimestamp(new Date()),
+ metadata: {
+ guidance: "provided",
+ wereall: "gonna make it",
+ price: "9001",
+ },
+ })
+ ).not.toThrowError();
+ });
+
+ // expected to fail for now
+ it("listBy", async () => {
+ const response = await client.events.list({
+ type: "user",
+ user_id: userId,
+ per_page: 2,
+ summary: true,
+ });
+
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/helpCenter/collections.test.ts b/tests/integration/helpCenter/collections.test.ts
new file mode 100644
index 0000000..6dcfd78
--- /dev/null
+++ b/tests/integration/helpCenter/collections.test.ts
@@ -0,0 +1,105 @@
+import { IntercomClient as Client } from "../../../src";
+import { Collection } from "../../../src/api/resources/helpCenter/types";
+import { createClient } from "../utils/createClient";
+
+async function createCollection(client: Client): Promise {
+ return await client.helpCenters.collections.create({
+ name: "The Bruh Moment",
+ description: "Bruuuuuh",
+ translated_content: {
+ type: "group_translated_content",
+ fr: {
+ type: "group_content",
+ name: "Le Moment Frère",
+ description: "Frèèèèère",
+ },
+ },
+ });
+}
+
+async function tryDeleteCollection(client: Client, collectionId: string) {
+ try {
+ await client.helpCenters.collections.delete({ collection_id: collectionId });
+ } catch (error) {
+ console.log(error);
+ }
+}
+
+describe("Collections", () => {
+ let collectionId: string;
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const collection = await createCollection(client);
+ collectionId = collection.id;
+ });
+
+ afterAll(async () => {
+ // cleanup
+ await tryDeleteCollection(client, collectionId);
+ });
+
+ it("create", async () => {
+ // act
+ const collection = await createCollection(client);
+
+ // assert
+ expect(collection).toBeDefined();
+
+ // cleanup
+ await tryDeleteCollection(client, collection.id);
+ });
+
+ it("find", async () => {
+ // act
+ const response = await client.helpCenters.collections.find({
+ collection_id: collectionId,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("update", async () => {
+ // arrange
+ const collection = await createCollection(client);
+
+ // act
+ const response = await client.helpCenters.collections.update({
+ collection_id: collection.id,
+ name: "People of future, tell us if NFTs make sense in 2026",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteCollection(client, collection.id);
+ });
+
+ it("list", async () => {
+ // act
+ const response = await client.helpCenters.collections.list({
+ per_page: 25,
+ page: 1,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("delete", async () => {
+ // arrange
+ const collection = await createCollection(client);
+
+ // act
+ const response = await client.helpCenters.collections.delete({
+ collection_id: collection.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/helpers.ts b/tests/integration/helpers.ts
new file mode 100644
index 0000000..0d35844
--- /dev/null
+++ b/tests/integration/helpers.ts
@@ -0,0 +1,87 @@
+import { Intercom, IntercomClient } from "../../src";
+import { dateToUnixTimestamp } from "./utils/date";
+import { randomString } from "./utils/random";
+
+export async function createCompany(client: IntercomClient) {
+ return await client.companies.createOrUpdate({
+ remote_created_at: dateToUnixTimestamp(new Date()),
+ company_id: randomString(),
+ name: randomString(),
+ monthly_spend: 9001,
+ plan: "1. Get pizzaid",
+ size: 62049,
+ website: "http://the-best.one",
+ industry: "The Best One",
+ custom_attributes: {},
+ });
+}
+
+export async function tryDeleteCompany(client: IntercomClient, companyId: string) {
+ try {
+ await client.companies.delete({ company_id: companyId });
+ } catch (error) {
+ console.error("Failed to delete company:", error);
+ }
+}
+
+export async function createContact(client: IntercomClient) {
+ return await client.contacts.create({
+ external_id: randomString(),
+ phone: "+353871234567",
+ });
+}
+
+export async function tryDeleteContact(client: IntercomClient, contactId: string) {
+ try {
+ await client.contacts.delete({ contact_id: contactId });
+ } catch (error) {
+ console.error("Failed to delete contact:", error);
+ }
+}
+
+export async function tryDeleteTag(client: IntercomClient, tagId: string) {
+ try {
+ await client.tags.delete({ tag_id: tagId });
+ } catch (error) {
+ console.error(error);
+ }
+}
+
+export async function createConversation(client: IntercomClient, contactId: string) {
+ return await client.conversations.create({
+ from: { id: contactId, type: "user" },
+ body: randomString(),
+ });
+}
+
+export async function tryUntagContact(client: IntercomClient, contactId: string, tagId: string) {
+ try {
+ await client.tags.untagContact({ contact_id: contactId, tag_id: tagId });
+ } catch (error) {
+ console.error(error);
+ }
+}
+
+export async function tryUntagConversation(
+ client: IntercomClient,
+ conversationId: string,
+ tagId: string,
+ adminId: string
+) {
+ try {
+ await client.tags.untagConversation({ conversation_id: conversationId, tag_id: tagId, admin_id: adminId });
+ } catch (error) {
+ console.error(error);
+ }
+}
+
+export async function tryUntagCompany(client: IntercomClient, tagName: string, company: Intercom.Company) {
+ try {
+ await client.tags.create({
+ name: tagName,
+ companies: [{ id: company.id, company_id: company.company_id, untag: true }],
+ });
+ } catch (error) {
+ console.error(error);
+ }
+}
diff --git a/tests/integration/integration.test.ts b/tests/integration/integration.test.ts
new file mode 100644
index 0000000..321552f
--- /dev/null
+++ b/tests/integration/integration.test.ts
@@ -0,0 +1,86 @@
+import { Intercom } from "../../src";
+import { randomString } from "./utils/random";
+import { createCompany, tryDeleteCompany, tryDeleteContact, tryDeleteTag } from "./helpers";
+import { createClient } from "./utils/createClient";
+
+describe("Integration between Contact, Conversation, Company and Tag APIs", () => {
+ let adminId: string;
+ let company: Intercom.Company;
+ let user: Intercom.Contact;
+ let lead: Intercom.Contact;
+ let tag: Intercom.Tag;
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const admins = await client.admins.list();
+ adminId = admins.admins[0].id;
+
+ company = await createCompany(client);
+ user = await client.contacts.create({
+ external_id: randomString(),
+ });
+ lead = await client.contacts.create({
+ name: "Marek Barek",
+ role: "lead",
+ });
+ tag = await client.tags.create({
+ name: randomString(),
+ });
+ });
+
+ afterAll(async () => {
+ // cleanup
+ await tryDeleteContact(client, lead.id);
+ await tryDeleteContact(client, user.id);
+ await tryDeleteCompany(client, company.id);
+ await tryDeleteTag(client, tag.id);
+ });
+
+ it("Add Contact to Company", async () => {
+ // act
+ const response = await client.companies.attachContact({
+ contact_id: user.id,
+ id: company.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("Create Conversation with Contact", async () => {
+ // act
+ const response = await client.conversations.create({
+ from: {
+ type: "user",
+ id: user.id,
+ },
+ body: "Welcome to the club, buddy!",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("Tag the Conversation", async () => {
+ // arrange
+ const conversation = await client.conversations.create({
+ from: {
+ type: "user",
+ id: user.id,
+ },
+ body: "Welcome to the club, buddy!",
+ });
+
+ // act
+ const response = await client.tags.tagConversation({
+ conversation_id: conversation.conversation_id,
+ id: tag.id,
+ admin_id: adminId,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/messages.test.ts b/tests/integration/messages.test.ts
new file mode 100644
index 0000000..4b7df87
--- /dev/null
+++ b/tests/integration/messages.test.ts
@@ -0,0 +1,81 @@
+import { Intercom } from "../../src";
+import { tryDeleteContact } from "./helpers";
+import { randomString } from "./utils/random";
+import { wait } from "./utils/wait";
+import { createClient } from "./utils/createClient";
+
+describe("Messages", () => {
+ let adminId: string;
+ let user: Intercom.Contact;
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const admins = await client.admins.list();
+ const adminList = admins.admins.filter((admin) => admin.has_inbox_seat);
+
+ adminId = adminList[0].id;
+ user = await client.contacts.create({
+ external_id: randomString(),
+ name: "Message Test User",
+ });
+ });
+
+ afterAll(async () => {
+ // cleanup
+ await tryDeleteContact(client, user.id);
+ });
+
+ it("Message that creates a converation", async () => {
+ // act
+ const response = await client.messages.create({
+ message_type: "inapp",
+ body: "Hey, look at me! I am the conversations creator now!",
+ from: {
+ type: "admin",
+ id: Number(adminId),
+ },
+ to: {
+ type: "user",
+ id: user.id,
+ },
+ create_conversation_without_contact_reply: true,
+ });
+
+ const messageId = response.id;
+
+ // Give Intercom a few seconds to index conversation
+ await wait(5000);
+
+ const searchResults = await client.conversations.search({
+ query: {
+ field: "source.id",
+ operator: "=",
+ value: messageId,
+ },
+ });
+
+ // assert
+ expect(searchResults.data.length).toBeGreaterThan(0);
+ }, 10_000);
+
+ it("Create message, no conversation", async () => {
+ // act
+ const response = await client.messages.create({
+ message_type: "inapp",
+ body: "Message without creating conversation",
+ from: {
+ type: "admin",
+ id: Number(adminId),
+ },
+ to: {
+ type: "user",
+ id: user.id,
+ },
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/notes.test.ts b/tests/integration/notes.test.ts
new file mode 100644
index 0000000..b38c17f
--- /dev/null
+++ b/tests/integration/notes.test.ts
@@ -0,0 +1,65 @@
+import { Intercom } from "../../src";
+import { tryDeleteContact } from "./helpers";
+import { randomString } from "./utils/random";
+import { createClient } from "./utils/createClient";
+
+describe("Notes", () => {
+ let adminId: string;
+ let contact: Intercom.Contact;
+ let note: Intercom.Note;
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const admins = await client.admins.list();
+ adminId = admins.admins[0].id;
+
+ contact = await client.contacts.create({
+ external_id: randomString(),
+ });
+
+ note = await client.notes.create({
+ admin_id: adminId,
+ body: randomString(),
+ contact_id: contact.id,
+ });
+ });
+
+ afterAll(async () => {
+ // cleanup
+ await tryDeleteContact(client, contact.id);
+ });
+
+ it("create", async () => {
+ // act
+ const response = await client.notes.create({
+ admin_id: adminId,
+ body: randomString(),
+ contact_id: contact.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("find", async () => {
+ // act
+ const response = await client.notes.find({ note_id: note.id });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("list", async () => {
+ // act
+ const response = await client.notes.list({
+ contact_id: contact.id,
+ per_page: 25,
+ page: 1,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/pagination.test.ts b/tests/integration/pagination.test.ts
new file mode 100644
index 0000000..bfe4b2b
--- /dev/null
+++ b/tests/integration/pagination.test.ts
@@ -0,0 +1,148 @@
+import { Companies } from "../../src/api/resources/companies/client/Client";
+import { Contacts } from "../../src/api/resources/contacts/client/Client";
+import { Conversations } from "../../src/api/resources/conversations/client/Client";
+import { Collections } from "../../src/api/resources/helpCenters/resources/collections/client/Client";
+import { Notes } from "../../src/api/resources/notes/client/Client";
+import { createClient } from "./utils/createClient";
+import { randomString } from "./utils/random";
+
+type TestClient = Collections | Companies | Contacts | Conversations | Notes;
+
+describe("Pagination", () => {
+ const client = createClient();
+
+ interface TestCase {
+ name: string;
+ client: TestClient;
+ limit: number;
+ perPage: number;
+ greaterThan: number;
+ setup?: () => Promise;
+ additionalParams?: Record;
+ }
+
+ const testCases: TestCase[] = [
+ {
+ name: "helpCenters collections",
+ client: client.helpCenters.collections,
+ limit: 2,
+ perPage: 1,
+ greaterThan: 1,
+ },
+ {
+ name: "companies",
+ client: client.companies,
+ limit: 10,
+ perPage: 1,
+ greaterThan: 0,
+ },
+ {
+ name: "contacts",
+ client: client.contacts,
+ limit: 100,
+ perPage: 50,
+ greaterThan: 0,
+ },
+ {
+ name: "conversations",
+ client: client.conversations,
+ limit: 2,
+ perPage: 1,
+ greaterThan: 1,
+ },
+ {
+ name: "notes",
+ client: client.notes,
+ limit: 2,
+ perPage: 1,
+ greaterThan: 1,
+ async setup() {
+ const contact = await client.contacts.create({
+ email: `${randomString()}@test.com`,
+ });
+
+ await client.notes.create({
+ contact_id: contact.id,
+ body: "one",
+ });
+
+ await client.notes.create({
+ contact_id: contact.id,
+ body: "two",
+ });
+
+ return { contact_id: contact.id };
+ },
+ },
+ ];
+
+ async function testIterator({
+ client,
+ limit,
+ params,
+ }: {
+ client: TestClient;
+ limit: number;
+ params: Record;
+ }) {
+ const iterator = await client.list(params as any);
+ expect(iterator).toBeDefined();
+
+ let count = 0;
+ for await (const item of iterator) {
+ expect(item).toBeDefined();
+ expect(item.id).toBeDefined();
+ count++;
+
+ if (count >= limit) {
+ break;
+ }
+ }
+ return count;
+ }
+
+ async function testPager({
+ client,
+ limit,
+ params,
+ }: {
+ client: TestClient;
+ limit: number;
+ params: Record;
+ }) {
+ const pager = await client.list(params as any);
+ expect(pager).toBeDefined();
+
+ let count = pager.data.length;
+ while (pager.hasNextPage()) {
+ await pager.getNextPage();
+ count += pager.data.length;
+
+ if (count >= limit) {
+ break;
+ }
+ }
+ return count;
+ }
+
+ testCases.forEach(({ name, client, limit, perPage, greaterThan, setup, additionalParams }) => {
+ it(name, async () => {
+ let params: Record = { per_page: perPage };
+ if (setup) {
+ const setupParams = await setup();
+ params = { ...params, ...setupParams };
+ }
+ if (additionalParams) {
+ params = { ...params, ...additionalParams };
+ }
+
+ const iteratorCount = await testIterator({ client, limit, params: { ...params } });
+ const pagerCount = await testPager({ client, limit, params: { ...params } });
+ expect(iteratorCount).toBeGreaterThan(greaterThan);
+ expect(pagerCount).toBeGreaterThan(greaterThan);
+
+ // Confirm iterator and pager return same count.
+ expect(pagerCount).toEqual(iteratorCount);
+ });
+ });
+});
diff --git a/tests/integration/phoneCallRedirect.test.ts b/tests/integration/phoneCallRedirect.test.ts
new file mode 100644
index 0000000..3fc363d
--- /dev/null
+++ b/tests/integration/phoneCallRedirect.test.ts
@@ -0,0 +1,20 @@
+import { createClient } from "./utils/createClient";
+
+describe("phoneCallRedirect", () => {
+ const client = createClient();
+
+ // TODO: Configure Twilio to enable phone call redirect tests.
+ it.skip("create", async () => {
+ // act
+ const response = await client.phoneCallRedirects.create({
+ phone: "+353832345678",
+ custom_attributes: {
+ issue_type: "Billing",
+ priority: "High",
+ },
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/segments.test.ts b/tests/integration/segments.test.ts
new file mode 100644
index 0000000..902c4c7
--- /dev/null
+++ b/tests/integration/segments.test.ts
@@ -0,0 +1,31 @@
+import { createClient } from "./utils/createClient";
+
+describe("Segments", () => {
+ let segmentId: string;
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const response = await client.segments.list();
+ segmentId = response.segments[0].id;
+ });
+
+ it("list", async () => {
+ // act
+ const response = await client.segments.list({
+ include_count: true,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("find", async () => {
+ // act
+ const response = await client.segments.find({ segment_id: segmentId });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/subscriptions.test.ts b/tests/integration/subscriptions.test.ts
new file mode 100644
index 0000000..73b9dcb
--- /dev/null
+++ b/tests/integration/subscriptions.test.ts
@@ -0,0 +1,13 @@
+import { createClient } from "./utils/createClient";
+
+describe("Subscriptions", () => {
+ const client = createClient();
+
+ it("listTypes", async () => {
+ // act
+ const response = await client.subscriptionTypes.list();
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/tags.test.ts b/tests/integration/tags.test.ts
new file mode 100644
index 0000000..f4fa85c
--- /dev/null
+++ b/tests/integration/tags.test.ts
@@ -0,0 +1,217 @@
+import { Intercom } from "../../src";
+import {
+ tryDeleteTag,
+ createContact,
+ tryDeleteContact,
+ createConversation,
+ tryDeleteCompany,
+ createCompany,
+ tryUntagContact,
+ tryUntagConversation,
+ tryUntagCompany,
+} from "./helpers";
+import { createClient } from "./utils/createClient";
+import { randomString } from "./utils/random";
+import { wait } from "./utils/wait";
+
+describe("Tags", () => {
+ let adminId: string;
+ let tag: Intercom.Tag;
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const randomAdmins = await client.admins.list();
+ adminId = randomAdmins.admins[0].id;
+ tag = await client.tags.create({
+ name: randomString(),
+ });
+ });
+
+ afterAll(async () => {
+ // cleanup
+ await tryDeleteTag(client, tag.id);
+ });
+
+ it("create", async () => {
+ // act
+ const response = await client.tags.create({
+ name: "Bellic and Partners",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteTag(client, response.id);
+ });
+
+ it("update", async () => {
+ // arrange
+ const tag = await client.tags.create({
+ name: randomString(),
+ });
+
+ // act
+ const response = await client.tags.create({ id: tag.id, name: "Poor" });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteTag(client, response.id);
+ });
+
+ it("find", async () => {
+ // act
+ const response = await client.tags.find({ tag_id: tag.id });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("list", async () => {
+ // act
+ const response = await client.tags.list();
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("delete", async () => {
+ // arrange
+ const tag = await client.tags.create({
+ name: randomString(),
+ });
+
+ // act & assert
+ expect(async () => await client.tags.delete({ tag_id: tag.id })).not.toThrow();
+
+ // cleanup
+ await tryDeleteTag(client, tag.id);
+ });
+
+ it("tagContact", async () => {
+ // arrange
+ const contact = await createContact(client);
+
+ // act
+ const response = await client.tags.tagContact({
+ contact_id: contact.id,
+ id: tag.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryUntagContact(client, contact.id, tag.id);
+ await tryDeleteContact(client, contact.id);
+ });
+
+ it("tagConversation", async () => {
+ // arrange
+ const contact = await createContact(client);
+ const message = await createConversation(client, contact.id);
+
+ // act
+ const response = await client.tags.tagConversation({
+ conversation_id: message.conversation_id,
+ id: tag.id,
+ admin_id: adminId,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryUntagConversation(client, message.conversation_id, tag.id, adminId);
+ await tryDeleteContact(client, contact.id);
+ }, 10_000);
+
+ it("tagCompany", async () => {
+ // arrange
+ const company = await createCompany(client);
+
+ // act
+ const response = await client.tags.create({
+ name: "Poor",
+ companies: [{ company_id: company.company_id }],
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryUntagCompany(client, "Poor", company);
+ await tryDeleteCompany(client, company.id);
+ });
+
+ it("untagContact", async () => {
+ // arrange
+ const contact = await createContact(client);
+ await client.tags.tagContact({
+ contact_id: contact.id,
+ id: tag.id,
+ });
+
+ // act
+ const response = await client.tags.untagContact({
+ contact_id: contact.id,
+ tag_id: tag.id,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteContact(client, contact.id);
+ });
+
+ it("untagConversation", async () => {
+ // arrange
+ const contact = await createContact(client);
+ const message = await createConversation(client, contact.id);
+
+ await client.tags.tagConversation({
+ conversation_id: message.conversation_id,
+ id: tag.id,
+ admin_id: adminId,
+ });
+
+ // act
+ const response = await client.tags.untagConversation({
+ conversation_id: message.conversation_id,
+ tag_id: tag.id,
+ admin_id: adminId,
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteContact(client, contact.id);
+ }, 10_000);
+
+ it("untagCompany", async () => {
+ // arrange
+ const company = await createCompany(client);
+ await client.tags.create({
+ name: "Poor",
+ companies: [{ id: company.id, company_id: company.company_id }],
+ });
+
+ // act
+ const response = await client.tags.create({
+ name: "Poor",
+ companies: [{ id: company.id, company_id: company.company_id, untag: true }],
+ });
+
+ // assert
+ expect(response).toBeDefined();
+
+ // cleanup
+ await tryDeleteCompany(client, company.id);
+ });
+});
diff --git a/tests/integration/teams.test.ts b/tests/integration/teams.test.ts
new file mode 100644
index 0000000..5916546
--- /dev/null
+++ b/tests/integration/teams.test.ts
@@ -0,0 +1,29 @@
+import { createClient } from "./utils/createClient";
+
+describe("Teams", () => {
+ let teamId: string;
+
+ const client = createClient();
+
+ beforeAll(async () => {
+ // arrange
+ const response = await client.teams.list();
+ teamId = response.teams[0].id;
+ });
+
+ it("list", async () => {
+ // act
+ const response = await client.teams.list();
+
+ // assert
+ expect(response).toBeDefined();
+ });
+
+ it("find", async () => {
+ // act
+ const response = await client.teams.find({ team_id: teamId });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});
diff --git a/tests/integration/utils/createClient.ts b/tests/integration/utils/createClient.ts
new file mode 100644
index 0000000..4b2c547
--- /dev/null
+++ b/tests/integration/utils/createClient.ts
@@ -0,0 +1,5 @@
+import { IntercomClient } from "../../../src";
+
+export function createClient(): IntercomClient {
+ return new IntercomClient({ token: process.env.API_TOKEN as string });
+}
diff --git a/tests/integration/utils/date.ts b/tests/integration/utils/date.ts
new file mode 100644
index 0000000..4ec8b32
--- /dev/null
+++ b/tests/integration/utils/date.ts
@@ -0,0 +1 @@
+export const dateToUnixTimestamp = (date: Date): number => Math.floor(date.getTime() / 1000);
diff --git a/tests/integration/utils/random.ts b/tests/integration/utils/random.ts
new file mode 100644
index 0000000..496df28
--- /dev/null
+++ b/tests/integration/utils/random.ts
@@ -0,0 +1,6 @@
+import crypto from "crypto";
+
+export const randomString = (): string => crypto.randomBytes(16).toString("hex");
+
+export const randomInt = (min = 0, max = 999): number =>
+ Math.floor(Math.random() * (Math.floor(max) - Math.ceil(min) + 1)) + Math.ceil(min);
diff --git a/tests/integration/utils/wait.ts b/tests/integration/utils/wait.ts
new file mode 100644
index 0000000..685944a
--- /dev/null
+++ b/tests/integration/utils/wait.ts
@@ -0,0 +1,3 @@
+export async function wait(ms: number) {
+ return new Promise((resolve) => setTimeout(resolve, ms));
+}
diff --git a/tests/integration/visitors.test.ts b/tests/integration/visitors.test.ts
new file mode 100644
index 0000000..10e2a46
--- /dev/null
+++ b/tests/integration/visitors.test.ts
@@ -0,0 +1,53 @@
+import { createClient } from "./utils/createClient";
+
+// Skip by default, because there is no automation yet
+describe.skip("Visitors", () => {
+ // Info: should be set manually. Find a way to automate it.
+ // Tip: headless browser to visit test application and get visitorId from ping request.
+ const visitorId = "0";
+ const userId = "0";
+
+ const client = createClient();
+
+ it("find by id", async () => {
+ // act
+ const response = await client.visitors.find({ user_id: visitorId });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+ it("find by user id", async () => {
+ // act
+ const response = await client.visitors.find({ user_id: userId });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+ it("update", async () => {
+ // act
+ const response = await client.visitors.update({
+ user_id: userId,
+ name: "Winston Smith",
+ });
+
+ // assert
+
+ expect(response).toBeDefined();
+ });
+
+ it("mergeToContact", async () => {
+ // act
+ const response = await client.visitors.mergeToContact({
+ visitor: {
+ id: visitorId,
+ },
+ user: {
+ email: "mcboxford@intercom-test.com",
+ } as any,
+ type: "user",
+ });
+
+ // assert
+ expect(response).toBeDefined();
+ });
+});