技能 编程开发 Intercom SDK 生产级模式

Intercom SDK 生产级模式

v20260423
intercom-sdk-patterns
本指南提供了Intercom TypeScript SDK的生产级最佳实践。它详细介绍了如何实现类型安全的客户端封装、处理基于游标的翻页逻辑、管理复杂的错误状态码(如限速和认证失败),以及如何使用指数退避算法构建健壮的重试机制,确保API调用稳定可靠。
获取技能
407 次下载
概览

Intercom SDK Patterns

Overview

Production-ready patterns for the intercom-client TypeScript SDK covering client initialization, pagination, error handling, and type safety.

Prerequisites

  • intercom-client package installed
  • TypeScript 5.0+ project
  • Familiarity with async/await and generators

Instructions

Step 1: Type-Safe Client Wrapper

// src/intercom/client.ts
import { IntercomClient } from "intercom-client";
import { Intercom } from "intercom-client";

let instance: IntercomClient | null = null;

export function getClient(): IntercomClient {
  if (!instance) {
    instance = new IntercomClient({
      token: process.env.INTERCOM_ACCESS_TOKEN!,
    });
  }
  return instance;
}

// Type-safe contact creation helper
export async function createContact(
  params: Intercom.CreateContactRequest
): Promise<Intercom.Contact> {
  return getClient().contacts.create(params);
}

// Type-safe search helper
export async function searchContacts(
  query: Intercom.SearchRequest
): Promise<Intercom.ContactList> {
  return getClient().contacts.search(query);
}

Step 2: Cursor-Based Pagination

Intercom uses cursor-based pagination. The starting_after parameter points to the next page.

// Generic paginator for any list endpoint
async function* paginateContacts(
  client: IntercomClient,
  perPage = 50
): AsyncGenerator<Intercom.Contact> {
  let startingAfter: string | undefined;

  do {
    const page = await client.contacts.list({
      perPage,
      startingAfter,
    });

    for (const contact of page.data) {
      yield contact;
    }

    // Cursor for next page
    startingAfter = page.pages?.next?.startingAfter ?? undefined;
  } while (startingAfter);
}

// Usage
const client = getClient();
for await (const contact of paginateContacts(client)) {
  console.log(contact.email);
}

The SDK also supports built-in iteration:

// SDK auto-pagination (articles, contacts, etc.)
const response = await client.articles.list();
for await (const article of response) {
  console.log(article.title);
}

Step 3: Error Handling with IntercomError

import { IntercomError } from "intercom-client";

async function safeIntercomCall<T>(
  operation: () => Promise<T>,
  context: string
): Promise<{ data: T | null; error: IntercomError | null }> {
  try {
    const data = await operation();
    return { data, error: null };
  } catch (err) {
    if (err instanceof IntercomError) {
      console.error(`[Intercom:${context}] ${err.statusCode}: ${err.message}`, {
        requestId: err.body?.request_id,
        errors: err.body?.errors,
      });

      // Specific error handling
      switch (err.statusCode) {
        case 401:
          console.error("Token invalid or expired. Regenerate access token.");
          break;
        case 404:
          console.error("Resource not found. Verify the ID.");
          break;
        case 409:
          console.error("Conflict: resource already exists.");
          break;
        case 422:
          console.error("Validation failed:", err.body?.errors);
          break;
        case 429:
          console.error("Rate limited. Back off and retry.");
          break;
      }

      return { data: null, error: err };
    }
    throw err; // Re-throw non-Intercom errors
  }
}

// Usage
const { data: contact, error } = await safeIntercomCall(
  () => client.contacts.find({ contactId: "abc123" }),
  "findContact"
);

Step 4: Retry with Exponential Backoff

async function withRetry<T>(
  operation: () => Promise<T>,
  config = { maxRetries: 3, baseDelayMs: 1000 }
): Promise<T> {
  for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
    try {
      return await operation();
    } catch (err) {
      if (err instanceof IntercomError) {
        // Only retry on rate limits and server errors
        if (err.statusCode !== 429 && (err.statusCode ?? 0) < 500) {
          throw err;
        }

        if (attempt === config.maxRetries) throw err;

        // Use Retry-After header if available, otherwise exponential backoff
        const retryAfter = err.headers?.["retry-after"];
        const delay = retryAfter
          ? parseInt(retryAfter) * 1000
          : config.baseDelayMs * Math.pow(2, attempt) + Math.random() * 500;

        console.log(`Retry ${attempt + 1}/${config.maxRetries} in ${delay}ms`);
        await new Promise((r) => setTimeout(r, delay));
      } else {
        throw err;
      }
    }
  }
  throw new Error("Unreachable");
}

Step 5: Contact Search with Compound Queries

// Search with multiple conditions (AND/OR)
const results = await client.contacts.search({
  query: {
    operator: "AND",
    value: [
      { field: "role", operator: "=", value: "user" },
      { field: "custom_attributes.plan", operator: "=", value: "pro" },
      {
        operator: "OR",
        value: [
          { field: "email", operator: "~", value: "@acme.com" },
          { field: "email", operator: "~", value: "@bigcorp.com" },
        ],
      },
    ],
  },
  pagination: { per_page: 25 },
  sort: { field: "created_at", order: "descending" },
});

Step 6: Multi-Tenant Client Factory

const clientCache = new Map<string, IntercomClient>();

export function getClientForWorkspace(
  workspaceToken: string
): IntercomClient {
  if (!clientCache.has(workspaceToken)) {
    clientCache.set(
      workspaceToken,
      new IntercomClient({ token: workspaceToken })
    );
  }
  return clientCache.get(workspaceToken)!;
}

Intercom Search Operators

Operator Meaning Example
= Equals email = "test@example.com"
!= Not equals role != "lead"
~ Contains email ~ "@acme.com"
!~ Not contains name !~ "test"
> Greater than created_at > 1700000000
< Less than last_seen_at < 1700000000
IN In list tag_id IN ["tag1", "tag2"]
NIN Not in list segment_id NIN ["seg1"]

Error Handling

Pattern Use Case Benefit
safeIntercomCall wrapper All API calls Prevents uncaught exceptions
withRetry Transient failures (429, 5xx) Automatic recovery
Cursor pagination generator Large data sets Memory-efficient streaming
Client factory Multi-tenant apps Workspace isolation

Resources

Next Steps

Apply patterns in intercom-core-workflow-a for contact management workflows.

信息
Category 编程开发
Name intercom-sdk-patterns
版本 v20260423
大小 7.27KB
更新时间 2026-04-28
语言