--- title: Plain description: Plain is customer support for developer tools --- ## Installation ```bash npm npm install @trigger.dev/plain@latest ``` ```bash pnpm pnpm install @trigger.dev/plain@latest ``` ```bash yarn yarn add @trigger.dev/plain@latest ``` ## Authentication Plain supports API Keys, to create yours read the [Plain authentication guide](https://www.plain.com/docs/graphql-api/authentication). ```ts import { Plain } from "@trigger.dev/plain"; export const plain = new Plain({ id: "plain", apiKey: process.env.PLAIN_API_KEY!, }); ``` ## Create customers and timeline entries The Plain Integration allows you to create/update customers and add timeline entries. ```ts import { client } from "@/trigger"; import { Job } from "@trigger.dev/sdk"; import { Plain } from "@trigger.dev/plain"; export const plain = new Plain({ id: "plain", apiKey: process.env.PLAIN_API_KEY!, }); client.defineJob({ id: "plain-playground", name: "Plain Playground", version: "0.1.1", integrations: { plain, }, trigger: eventTrigger({ name: "plain.playground", }), run: async (payload, io, ctx) => { const { customer } = await io.plain.upsertCustomer("upsert-customer", { identifier: { emailAddress: "rick.astley@gmail.com", }, onCreate: { email: { email: "rick.astley@gmail.com", isVerified: true, }, fullName: "Rick Astley", externalId: "u_123", }, onUpdate: { fullName: { value: "Rick Astley", }, externalId: { value: "u_123", }, }, }); const foundCustomer = await io.plain.getCustomerById("get-customer", { customerId: customer.id, }); const timelineEntry = await io.plain.upsertCustomTimelineEntry("upsert-timeline-entry", { customerId: customer.id, title: "My timeline entry", components: [ { componentText: { text: `This is a nice title`, }, }, { componentDivider: { dividerSpacingSize: ComponentDividerSpacingSize.M, }, }, { componentText: { textSize: ComponentTextSize.S, textColor: ComponentTextColor.Muted, text: "External id", }, }, { componentText: { text: foundCustomer?.externalId ?? "", }, }, ], }); }, }); ``` ## Tasks ## All tasks | Function Name | Description | | --------------------------- | ----------------------------------- | | `getCustomerById` | Gets a customer using their id | | `upsertCustomer` | Creates or updates a customer | | `upsertCustomTimelineEntry` | Creates or updates a timeline entry | ## Using the underlying client You can use the underlying client to do anything [@team-plain/typescript-sdk](https://github.com/team-plain/typescript-sdk) supports by using runTask: ```ts import { Plain } from "@trigger.dev/plain"; //create client export const plain = new Plain({ id: "plain", apiKey: process.env.PLAIN_API_KEY!, }); client.defineJob({ id: "plain-client", name: "Plain Client", version: "0.1.0", integrations: { plain }, trigger: eventTrigger({ name: "plain.client", }), run: async (payload, io, ctx) => { const result = await io.plain.runTask( "create-issue", async (client) => client.createIssue({ customerId: "abcdefghij", issueTypeId: "123456", }), { name: "Create issue" } ); }, }); ```