Skip to content

Instantly share code, notes, and snippets.

@koistya
Last active July 20, 2023 17:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save koistya/19efbe9698e55681c57305990e5dd5cc to your computer and use it in GitHub Desktop.
Save koistya/19efbe9698e55681c57305990e5dd5cc to your computer and use it in GitHub Desktop.
Twitter API v2 usage example using Got and OAuth-1.0a

Twitter API v2 Usage Example

Install got and oauth-1.0a NPM dependencies.

import { TwitterClient } from "./twitter";

// Initializes a new Twitter client using OAuth 1.0a credentials
const twitter = new TwitterClient({
  // Twitter App credentials (API key and secret)
  // https://developer.twitter.com/en/portal/projects
  apiKey: env.TWITTER_API_KEY,
  apiSecret: env.TWITTER_API_SECRET,
  // User credentials (avaialble upon sign in)
  userToken: "xxxxx",
  userSecret: "xxxxx",
});

// Posts a new tweet to the user's timeline
const tweet = await twitter.post({
  text: "Hello"
});
/* SPDX-FileCopyrightText: 2023-present Konstantin Tarkus */
/* SPDX-License-Identifier: MIT */
import { got, RequestError } from "got";
import crypto from "node:crypto";
import OAuth, { HashFunction, RequestOptions } from "oauth-1.0a";
/**
* Initializes a Twitter client.
*
* @example
* const twitter = new TwitterClient({
* apiKey: env.TWITTER_API_KEY,
* apiSecret: env.TWITTER_API_SECRET,
* userToken: "xxxxx",
* userSecret: "xxxxx"
* });
*
* const tweet = await twitter.post({
* text: "hello"
* });
*/
export class TwitterClient {
readonly oauth: OAuth;
readonly userToken: string;
readonly userSecret: string;
constructor(options: {
apiKey: string;
apiSecret: string;
userToken: string;
userSecret: string;
}) {
this.oauth = new OAuth({
consumer: {
key: options.apiKey,
secret: options.apiSecret,
},
signature_method: "HMAC-SHA1",
hash_function: hashFn,
});
this.userToken = options.userToken;
this.userSecret = options.userSecret;
}
/**
* Posts a new tweet on the user's timeline.
*/
post(data: { text: string }): Promise<Tweet> {
const options: RequestOptions = {
url: "https://api.twitter.com/2/tweets",
includeBodyHash: true,
method: "POST",
data,
};
const request = this.oauth.authorize(options, {
key: this.userToken,
secret: this.userSecret,
});
return got
.post(options.url, {
headers: { ...this.oauth.toHeader(request) },
json: options.data,
})
.json<{ data: Tweet }>()
.then((res) => res.data)
.catch((err) => {
if (err instanceof RequestError && err.response) {
const res = JSON.parse(err.response.body as string);
const message = res.errors?.[0]?.message;
if (message) {
throw new Error(message, { cause: res });
}
}
throw err;
});
}
}
const hashFn: HashFunction = (value, key) => {
return crypto.createHmac("sha1", key).update(value).digest("base64");
};
export type Tweet = {
id: string;
text: string;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment