Skip to content

Commit

Permalink
feat: Add doc for send tweets and reply/tweetThread helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
alkihis committed Nov 23, 2021
1 parent 31c9252 commit cf28bdf
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 1 deletion.
100 changes: 100 additions & 0 deletions doc/v2.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ For streaming API, see [Streaming part](./streaming.md).
* [User timeline](#Usertimeline)
* [User mention timeline](#Usermentiontimeline)
* [Tweets](#Tweets)
* [Create a tweet](#Createatweet)
* [Reply to a tweet](#Replytoatweet)
* [Post a thread of tweets](#Postathreadoftweets)
* [Delete a tweet](#Deleteatweet)
* [Single tweet](#Singletweet)
* [Lookup for tweets](#Lookupfortweets)
* [Get users that liked a specific tweet](#Getusersthatlikedaspecifictweet)
Expand Down Expand Up @@ -177,6 +181,102 @@ const tweetsOfJack = await client.v2.userMentionTimeline('12', { end_time: '2020

## <a name='Tweets'></a>Tweets

### <a name='Createatweet'></a>Create a tweet

Post a new tweet.

**Method**: `.tweet()`

**Endpoint**: `tweets`

**Right level**: `Read-write`

**Arguments**:
- `statusOrPayload: string | SendTweetV2Params`
- `payload?: SendTweetV2Params`

**Returns**: `TweetV2PostTweetResult`

**Example**
```ts
const { data: createdTweet } = await client.v2.tweet('twitter-api-v2 is awesome!', {
poll: { duration_minutes: 120, options: ['Absolutely', 'For sure!'] },
});
console.log('Tweet', createdTweet.id, ':', createdTweet.text);
```

### <a name='Replytoatweet'></a>Reply to a tweet

Alias to a `.tweet` with `in_reply_to_tweet_id` already set.

**Method**: `.reply()`

**Endpoint**: `tweets`

**Right level**: `Read-write`

**Arguments**:
- `status: string`
- `in_reply_to_status_id: string`
- `payload?: SendTweetV2Params`

**Returns**: `TweetV2PostTweetResult`

**Example**
```ts
await client.v2.reply(
'reply to previously created tweet.',
createdTweet.id,
);
```

### <a name='Postathreadoftweets'></a>Post a thread of tweets

Post multiple tweets at one time.

**Method**: `.tweetThread()`

**Endpoint**: `tweets`

**Right level**: `Read-write`

**Arguments**:
- `tweets: (SendTweetV2Params | string)[]`

**Returns**: `TweetV2PostTweetResult[]`: Created tweets results (in the right order), first sent first position

**Example**
```ts
// You can use media IDs generated by v1 API to send medias!
const mediaId = await client.v1.uploadMedia('./image.png');

await client.v2.tweetThread([
'Hello, lets talk about Twitter!',
{ text: 'Twitter is a fantastic social network. Look at this:', media: { media_ids: [mediaId] } },
'This thread is automatically made with twitter-api-v2 :D',
]);
```

### <a name='Deleteatweet'></a>Delete a tweet

Delete a tweet that belongs to you.

**Method**: `.deleteTweet()`

**Endpoint**: `tweets/:id`

**Right level**: `Read-write`

**Arguments**:
- `tweetId: string`

**Returns**: `TweetV2DeleteTweetResult`

**Example**
```ts
await client.v1.deleteTweet('20');
```

### <a name='Singletweet'></a>Single tweet

**Method**: `.singleTweet()`
Expand Down
2 changes: 1 addition & 1 deletion src/types/v2/tweet.definition.v2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export interface SendTweetV2Params {
quote_tweet_id?: string;
reply?: {
exclude_reply_user_ids?: string[];
in_reply_to_tweet_id: string[];
in_reply_to_tweet_id: string;
};
reply_settings?: TTweetReplySettingsV2 | string;
text?: string;
Expand Down
36 changes: 36 additions & 0 deletions src/v2/client.v2.write.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,42 @@ export default class TwitterApiv2ReadWrite extends TwitterApiv2ReadOnly {
return this.post<TweetV2PostTweetResult>('tweets', payload);
}

/**
* Reply to a Tweet on behalf of an authenticated user.
* https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets
*/
public reply(status: string, toTweetId: string, payload: Partial<SendTweetV2Params> = {}) {
const reply = { in_reply_to_tweet_id: toTweetId, ...payload.reply ?? {} };

return this.post<TweetV2PostTweetResult>('tweets', { text: status, ...payload, reply });
}

/**
* Post a series of tweets.
* https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/post-tweets
*/
public async tweetThread(tweets: (SendTweetV2Params | string)[]) {
const postedTweets: TweetV2PostTweetResult[] = [];

for (const tweet of tweets) {
// Retrieve the last sent tweet
const lastTweet = postedTweets.length ? postedTweets[postedTweets.length - 1] : null;
// Build the tweet query params
const queryParams: SendTweetV2Params = { ...(typeof tweet === 'string' ? ({ text: tweet }) : tweet) };
// Reply to an existing tweet if needed
const inReplyToId = lastTweet ? lastTweet.data.id : queryParams.reply?.in_reply_to_tweet_id;
const status = queryParams.text ?? '';

if (inReplyToId) {
postedTweets.push(await this.reply(status, inReplyToId, queryParams));
} else {
postedTweets.push(await this.tweet(status, queryParams));
}
}

return postedTweets;
}

/**
* Allows a user or authenticated user ID to delete a Tweet
* https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/delete-tweets-id
Expand Down

0 comments on commit cf28bdf

Please sign in to comment.