Creating the client
src/index.ts
This is where the client should live.
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
Example: GitHub
Comments are for instructional purposes only and should be removed in your implementation.
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:
The id
that uniquely identifies the Integration. This should always be passed through the
constructor options.
“LOCAL” should be returned for API keys. “HOSTED” should be returned for OAuth.
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.