129 lines
4.3 KiB
Plaintext
129 lines
4.3 KiB
Plaintext
---
|
|
title: Creating the client
|
|
description: "Each integration has a client that performs the actual HTTP requests. Usually this is a wrapper around an official SDK provided by the service."
|
|
---
|
|
|
|
### `src/index.ts`
|
|
|
|
This is where the client should live.
|
|
|
|
<Tip>
|
|
We're adopting the naming convention of naming the class after the service, without a suffix or
|
|
prefix. We prefer the exported name be `Slack` instead of something like `SlackIntegration` or
|
|
`SlackConnector`
|
|
</Tip>
|
|
|
|
## Example: GitHub
|
|
|
|
Comments are for instructional purposes only and should be removed in your implementation.
|
|
|
|
```ts
|
|
import { ConnectionAuth, IO, TriggerIntegration } from "@trigger.dev/sdk";
|
|
//the official GitHub SDK
|
|
import { Octokit } from "octokit";
|
|
|
|
//define the options that will be passed to the constructor
|
|
export type GithubIntegrationOptions = {
|
|
//this is required
|
|
id: string;
|
|
//GitHub can use OAuth or Personal Access Tokens, so this is optional
|
|
token?: string;
|
|
};
|
|
|
|
export class Github implements TriggerIntegration {
|
|
private _options: GithubIntegrationOptions;
|
|
private _client?: Octokit;
|
|
private _io?: IO;
|
|
private _connectionKey?: string;
|
|
|
|
constructor(private options: GithubIntegrationOptions) {
|
|
//if the token key is present but undefined, throw an error
|
|
//this is NOT the same as just: if (!options.token)
|
|
//it's a common user bug where an env var is used for the token but hasn't been set
|
|
if (Object.keys(options).includes("token") && !options.token) {
|
|
throw `Can't create GitHub integration (${options.id}) as token was undefined`;
|
|
}
|
|
|
|
this._options = options;
|
|
}
|
|
|
|
//this is used internally to identify the integration
|
|
get id() {
|
|
return this.options.id;
|
|
}
|
|
|
|
//this is used internally to identify the integration, and display nicely in the dashboard
|
|
get metadata() {
|
|
return { name: "GitHub", id: "github" };
|
|
}
|
|
|
|
//the two possible options are "LOCAL" or "HOSTED"
|
|
//LOCAL means that the client is using local auth (like a token)
|
|
//HOSTED means that the client is using hosted auth (like OAuth)
|
|
//GitHub supports both, and we use the presence of the token to determine which one to use
|
|
get authSource() {
|
|
return this._options.token ? ("LOCAL" as const) : ("HOSTED" as const);
|
|
}
|
|
|
|
//before the `run()` method is called on a Job, this function gets invoked
|
|
//this is important because the authentication data is dynamic, and can change (like OAuth credentials refreshing)
|
|
cloneForRun(io: IO, connectionKey: string, auth?: ConnectionAuth) {
|
|
const github = new Github(this._options);
|
|
github._io = io;
|
|
github._connectionKey = connectionKey;
|
|
|
|
if (this._options.token) {
|
|
github._client = new Octokit({
|
|
auth: this._options.token,
|
|
retry: {
|
|
enabled: false,
|
|
},
|
|
});
|
|
} else {
|
|
if (!auth) {
|
|
throw new Error("No auth");
|
|
}
|
|
|
|
github._client = new Octokit({
|
|
auth: auth.accessToken,
|
|
retry: {
|
|
enabled: false,
|
|
},
|
|
});
|
|
}
|
|
|
|
return github;
|
|
}
|
|
}
|
|
```
|
|
|
|
The `TriggerIntegration` interface requires three properties and one method to be implemented:
|
|
|
|
<ParamField body="id" type="string" required>
|
|
The `id` that uniquely identifies the Integration. This should always be passed through the
|
|
constructor options.
|
|
</ParamField>
|
|
|
|
<ParamField body="metadata" type="object" required>
|
|
<Expandable title="properties">
|
|
<ParamField body="id" type="string" required>
|
|
A unique identifier for the Integration. For example, the OpenAI Integration has an id of
|
|
`"openai"`.
|
|
</ParamField>
|
|
<ParamField body="name" type="string" required>
|
|
The name of the Integration. For example, the OpenAI Integration has a name of `"OpenAI"`.
|
|
</ParamField>
|
|
</Expandable>
|
|
</ParamField>
|
|
|
|
<ParamField body="authSource" type="LOCAL | HOSTED" required>
|
|
"LOCAL" should be returned for API keys. "HOSTED" should be returned for OAuth.
|
|
</ParamField>
|
|
|
|
<ParamField body="cloneForRun" type="function" required>
|
|
This method is called before the `run()` method is called on a Job. This is important because the
|
|
authentication data is dynamic, and can change (like OAuth credentials refreshing). This method
|
|
should return a new instance of the Integration, with the new authentication data, io, and
|
|
connectionKey set so they can be used by runTask and any Triggers.
|
|
</ParamField>
|