@glagan/rettiwt-api 7.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.js +166 -0
- package/.gitattributes +3 -0
- package/.github/FUNDING.yml +4 -0
- package/.github/ISSUE_TEMPLATE/bug-report.yml +57 -0
- package/.github/ISSUE_TEMPLATE/feature-request.yml +20 -0
- package/.github/ISSUE_TEMPLATE/question.yml +15 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +32 -0
- package/.github/workflows/ci.yml +32 -0
- package/.github/workflows/publish.yml +23 -0
- package/.nvmrc +1 -0
- package/.prettierignore +3 -0
- package/.prettierrc +13 -0
- package/LICENSE +21 -0
- package/README.md +566 -0
- package/dist/cli.js +43 -0
- package/eslint.config.mjs +17 -0
- package/package.json +50 -0
- package/src/Rettiwt.ts +97 -0
- package/src/cli.ts +48 -0
- package/src/collections/Extractors.ts +155 -0
- package/src/collections/Groups.ts +81 -0
- package/src/collections/Requests.ts +89 -0
- package/src/collections/Tweet.ts +17 -0
- package/src/commands/DirectMessage.ts +62 -0
- package/src/commands/List.ts +90 -0
- package/src/commands/Tweet.ts +437 -0
- package/src/commands/User.ts +367 -0
- package/src/enums/Api.ts +10 -0
- package/src/enums/Authentication.ts +10 -0
- package/src/enums/Data.ts +13 -0
- package/src/enums/Logging.ts +14 -0
- package/src/enums/Media.ts +10 -0
- package/src/enums/Notification.ts +12 -0
- package/src/enums/Resource.ts +69 -0
- package/src/enums/Tweet.ts +8 -0
- package/src/enums/raw/Analytics.ts +32 -0
- package/src/enums/raw/Media.ts +10 -0
- package/src/enums/raw/Notification.ts +11 -0
- package/src/enums/raw/Tweet.ts +20 -0
- package/src/helper/CliUtils.ts +17 -0
- package/src/helper/JsonUtils.ts +70 -0
- package/src/index.ts +128 -0
- package/src/models/RettiwtConfig.ts +101 -0
- package/src/models/args/FetchArgs.ts +169 -0
- package/src/models/args/PostArgs.ts +93 -0
- package/src/models/args/ProfileArgs.ts +68 -0
- package/src/models/auth/AuthCookie.ts +58 -0
- package/src/models/auth/AuthCredential.ts +83 -0
- package/src/models/data/Analytics.ts +97 -0
- package/src/models/data/BookmarkFolder.ts +73 -0
- package/src/models/data/Conversation.ts +344 -0
- package/src/models/data/CursoredData.ts +64 -0
- package/src/models/data/DirectMessage.ts +335 -0
- package/src/models/data/Inbox.ts +124 -0
- package/src/models/data/List.ts +113 -0
- package/src/models/data/Notification.ts +84 -0
- package/src/models/data/Tweet.ts +388 -0
- package/src/models/data/User.ts +187 -0
- package/src/models/errors/TwitterError.ts +65 -0
- package/src/models/params/Variables.ts +62 -0
- package/src/requests/DirectMessage.ts +229 -0
- package/src/requests/List.ts +203 -0
- package/src/requests/Media.ts +67 -0
- package/src/requests/Tweet.ts +607 -0
- package/src/requests/User.ts +1191 -0
- package/src/services/internal/AuthService.ts +115 -0
- package/src/services/internal/ErrorService.ts +41 -0
- package/src/services/internal/LogService.ts +34 -0
- package/src/services/public/DirectMessageService.ts +159 -0
- package/src/services/public/FetcherService.ts +366 -0
- package/src/services/public/ListService.ts +241 -0
- package/src/services/public/TweetService.ts +886 -0
- package/src/services/public/UserService.ts +1154 -0
- package/src/types/ErrorHandler.ts +13 -0
- package/src/types/Fetch.ts +3 -0
- package/src/types/RettiwtConfig.ts +48 -0
- package/src/types/args/FetchArgs.ts +233 -0
- package/src/types/args/PostArgs.ts +142 -0
- package/src/types/args/ProfileArgs.ts +33 -0
- package/src/types/auth/AuthCookie.ts +22 -0
- package/src/types/auth/AuthCredential.ts +28 -0
- package/src/types/auth/TransactionHeader.ts +8 -0
- package/src/types/data/Analytics.ts +58 -0
- package/src/types/data/BookmarkFolder.ts +12 -0
- package/src/types/data/Conversation.ts +44 -0
- package/src/types/data/CursoredData.ts +24 -0
- package/src/types/data/DirectMessage.ts +33 -0
- package/src/types/data/Inbox.ts +23 -0
- package/src/types/data/List.ts +33 -0
- package/src/types/data/Notification.ts +26 -0
- package/src/types/data/Tweet.ts +99 -0
- package/src/types/data/User.ts +54 -0
- package/src/types/errors/TwitterError.ts +37 -0
- package/src/types/params/Variables.ts +41 -0
- package/src/types/raw/base/Analytic.ts +32 -0
- package/src/types/raw/base/BookmarkFolder.ts +12 -0
- package/src/types/raw/base/Cursor.ts +13 -0
- package/src/types/raw/base/Error.ts +38 -0
- package/src/types/raw/base/LimitedVisibilityTweet.ts +40 -0
- package/src/types/raw/base/List.ts +50 -0
- package/src/types/raw/base/Media.ts +53 -0
- package/src/types/raw/base/Message.ts +22 -0
- package/src/types/raw/base/Notification.ts +66 -0
- package/src/types/raw/base/Space.ts +35 -0
- package/src/types/raw/base/Tweet.ts +139 -0
- package/src/types/raw/base/User.ts +182 -0
- package/src/types/raw/composite/DataResult.ts +8 -0
- package/src/types/raw/composite/TimelineList.ts +10 -0
- package/src/types/raw/composite/TimelineTweet.ts +14 -0
- package/src/types/raw/composite/TimelineUser.ts +13 -0
- package/src/types/raw/dm/Conversation.ts +59 -0
- package/src/types/raw/dm/InboxInitial.ts +155 -0
- package/src/types/raw/dm/InboxTimeline.ts +301 -0
- package/src/types/raw/dm/UserUpdates.ts +46 -0
- package/src/types/raw/generic/Response.ts +10 -0
- package/src/types/raw/list/AddMember.ts +175 -0
- package/src/types/raw/list/Details.ts +176 -0
- package/src/types/raw/list/Members.ts +154 -0
- package/src/types/raw/list/RemoveMember.ts +174 -0
- package/src/types/raw/list/Tweets.ts +2296 -0
- package/src/types/raw/media/FinalizeUpload.ts +20 -0
- package/src/types/raw/media/InitalizeUpload.ts +12 -0
- package/src/types/raw/media/LiveVideoStream.ts +21 -0
- package/src/types/raw/space/Details.ts +359 -0
- package/src/types/raw/tweet/Bookmark.ts +14 -0
- package/src/types/raw/tweet/Details.ts +210 -0
- package/src/types/raw/tweet/DetailsBulk.ts +338 -0
- package/src/types/raw/tweet/Like.ts +14 -0
- package/src/types/raw/tweet/Likers.ts +200 -0
- package/src/types/raw/tweet/Post.ts +150 -0
- package/src/types/raw/tweet/Replies.ts +539 -0
- package/src/types/raw/tweet/Retweet.ts +31 -0
- package/src/types/raw/tweet/Retweeters.ts +208 -0
- package/src/types/raw/tweet/Schedule.ts +18 -0
- package/src/types/raw/tweet/Search.ts +597 -0
- package/src/types/raw/tweet/Unbookmark.ts +14 -0
- package/src/types/raw/tweet/Unlike.ts +14 -0
- package/src/types/raw/tweet/Unpost.ts +20 -0
- package/src/types/raw/tweet/Unretweet.ts +31 -0
- package/src/types/raw/tweet/Unschedule.ts +14 -0
- package/src/types/raw/user/Affiliates.ts +179 -0
- package/src/types/raw/user/Analytics.ts +23 -0
- package/src/types/raw/user/BookmarkFolderTweets.ts +53 -0
- package/src/types/raw/user/BookmarkFolders.ts +41 -0
- package/src/types/raw/user/Bookmarks.ts +637 -0
- package/src/types/raw/user/Details.ts +185 -0
- package/src/types/raw/user/DetailsBulk.ts +104 -0
- package/src/types/raw/user/Follow.ts +280 -0
- package/src/types/raw/user/Followed.ts +1942 -0
- package/src/types/raw/user/Followers.ts +215 -0
- package/src/types/raw/user/Following.ts +215 -0
- package/src/types/raw/user/Highlights.ts +1287 -0
- package/src/types/raw/user/Likes.ts +1254 -0
- package/src/types/raw/user/Lists.ts +378 -0
- package/src/types/raw/user/Media.ts +1738 -0
- package/src/types/raw/user/Notifications.ts +499 -0
- package/src/types/raw/user/ProfileUpdate.ts +80 -0
- package/src/types/raw/user/Recommended.ts +2319 -0
- package/src/types/raw/user/Scheduled.ts +37 -0
- package/src/types/raw/user/Search.ts +230 -0
- package/src/types/raw/user/Subscriptions.ts +176 -0
- package/src/types/raw/user/Tweets.ts +1254 -0
- package/src/types/raw/user/TweetsAndReplies.ts +1254 -0
- package/src/types/raw/user/Unfollow.ts +280 -0
- package/tsconfig.json +97 -0
|
@@ -0,0 +1,886 @@
|
|
|
1
|
+
import { statSync } from 'fs';
|
|
2
|
+
|
|
3
|
+
import { Extractors } from '../../collections/Extractors';
|
|
4
|
+
import { ResourceType } from '../../enums/Resource';
|
|
5
|
+
import { TweetRepliesSortType } from '../../enums/Tweet';
|
|
6
|
+
import { CursoredData } from '../../models/data/CursoredData';
|
|
7
|
+
import { Tweet } from '../../models/data/Tweet';
|
|
8
|
+
import { User } from '../../models/data/User';
|
|
9
|
+
|
|
10
|
+
import { RettiwtConfig } from '../../models/RettiwtConfig';
|
|
11
|
+
import { ITweetFilter } from '../../types/args/FetchArgs';
|
|
12
|
+
import { INewTweet } from '../../types/args/PostArgs';
|
|
13
|
+
import { IMediaInitializeUploadResponse } from '../../types/raw/media/InitalizeUpload';
|
|
14
|
+
|
|
15
|
+
import { ITweetBookmarkResponse } from '../../types/raw/tweet/Bookmark';
|
|
16
|
+
import { ITweetDetailsResponse } from '../../types/raw/tweet/Details';
|
|
17
|
+
import { ITweetDetailsBulkResponse } from '../../types/raw/tweet/DetailsBulk';
|
|
18
|
+
import { ITweetLikeResponse } from '../../types/raw/tweet/Like';
|
|
19
|
+
import { ITweetLikersResponse } from '../../types/raw/tweet/Likers';
|
|
20
|
+
import { ITweetPostResponse } from '../../types/raw/tweet/Post';
|
|
21
|
+
import { ITweetRepliesResponse } from '../../types/raw/tweet/Replies';
|
|
22
|
+
import { ITweetRetweetResponse } from '../../types/raw/tweet/Retweet';
|
|
23
|
+
import { ITweetRetweetersResponse } from '../../types/raw/tweet/Retweeters';
|
|
24
|
+
import { ITweetScheduleResponse } from '../../types/raw/tweet/Schedule';
|
|
25
|
+
import { ITweetSearchResponse } from '../../types/raw/tweet/Search';
|
|
26
|
+
import { ITweetUnbookmarkResponse } from '../../types/raw/tweet/Unbookmark';
|
|
27
|
+
import { ITweetUnlikeResponse } from '../../types/raw/tweet/Unlike';
|
|
28
|
+
import { ITweetUnpostResponse } from '../../types/raw/tweet/Unpost';
|
|
29
|
+
import { ITweetUnretweetResponse } from '../../types/raw/tweet/Unretweet';
|
|
30
|
+
import { ITweetUnscheduleResponse } from '../../types/raw/tweet/Unschedule';
|
|
31
|
+
|
|
32
|
+
import { FetcherService } from './FetcherService';
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Handles interacting with resources related to tweets.
|
|
36
|
+
*
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
export class TweetService extends FetcherService {
|
|
40
|
+
/**
|
|
41
|
+
* @param config - The config object for configuring the Rettiwt instance.
|
|
42
|
+
*
|
|
43
|
+
* @internal
|
|
44
|
+
*/
|
|
45
|
+
public constructor(config: RettiwtConfig) {
|
|
46
|
+
super(config);
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Bookmark a tweet.
|
|
51
|
+
*
|
|
52
|
+
* @param id - The ID of the tweet to be bookmarked.
|
|
53
|
+
*
|
|
54
|
+
* @returns Whether bookmarking was successful or not.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
*
|
|
58
|
+
* ```ts
|
|
59
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
60
|
+
*
|
|
61
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
62
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
63
|
+
*
|
|
64
|
+
* // Bookmarking the Tweet with id '1234567890'
|
|
65
|
+
* rettiwt.tweet.bookmark('1234567890')
|
|
66
|
+
* .then(res => {
|
|
67
|
+
* console.log(res);
|
|
68
|
+
* })
|
|
69
|
+
* .catch(err => {
|
|
70
|
+
* console.log(err);
|
|
71
|
+
* });
|
|
72
|
+
* ```
|
|
73
|
+
*/
|
|
74
|
+
public async bookmark(id: string): Promise<boolean> {
|
|
75
|
+
const resource = ResourceType.TWEET_BOOKMARK;
|
|
76
|
+
|
|
77
|
+
// Favoriting the tweet
|
|
78
|
+
const response = await this.request<ITweetBookmarkResponse>(resource, {
|
|
79
|
+
id: id,
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
// Deserializing response
|
|
83
|
+
const data = Extractors[resource](response) ?? false;
|
|
84
|
+
|
|
85
|
+
return data;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Get the details of one or more tweets.
|
|
90
|
+
*
|
|
91
|
+
* @param id - The ID/IDs of the target tweet/tweets.
|
|
92
|
+
*
|
|
93
|
+
* @returns
|
|
94
|
+
* The details of the tweet with the given ID.
|
|
95
|
+
*
|
|
96
|
+
* If more than one ID is provided, returns a list.
|
|
97
|
+
*
|
|
98
|
+
* If no tweet/tweets matches the given ID/IDs, returns `undefined`/`[]`.
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
*
|
|
102
|
+
* #### Fetching the details of a single tweet
|
|
103
|
+
* ```ts
|
|
104
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
105
|
+
*
|
|
106
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
107
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
108
|
+
*
|
|
109
|
+
* // Fetching the details of the tweet with the id '1234567890'
|
|
110
|
+
* rettiwt.tweet.details('1234567890')
|
|
111
|
+
* .then(res => {
|
|
112
|
+
* console.log(res); # 'res' is a single tweet
|
|
113
|
+
* })
|
|
114
|
+
* .catch(err => {
|
|
115
|
+
* console.log(err);
|
|
116
|
+
* });
|
|
117
|
+
* ```
|
|
118
|
+
*
|
|
119
|
+
* @example
|
|
120
|
+
*
|
|
121
|
+
* #### Fetching the details of multiple tweets
|
|
122
|
+
* ```ts
|
|
123
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
124
|
+
*
|
|
125
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
126
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
127
|
+
*
|
|
128
|
+
* // Fetching the details of the tweets with IDs '123', '456', '789'
|
|
129
|
+
* rettiwt.tweet.details(['123', '456', '789'])
|
|
130
|
+
* .then(res => {
|
|
131
|
+
* console.log(res); # 'res' is an array of tweets
|
|
132
|
+
* })
|
|
133
|
+
* .catch(err => {
|
|
134
|
+
* console.log(err);
|
|
135
|
+
* });
|
|
136
|
+
* ```
|
|
137
|
+
*/
|
|
138
|
+
public async details<T extends string | string[]>(id: T): Promise<T extends string ? Tweet | undefined : Tweet[]> {
|
|
139
|
+
let resource: ResourceType;
|
|
140
|
+
|
|
141
|
+
// If user is authenticated and details of single tweet required
|
|
142
|
+
if (this.config.userId != undefined && typeof id == 'string') {
|
|
143
|
+
resource = ResourceType.TWEET_DETAILS_ALT;
|
|
144
|
+
|
|
145
|
+
// Fetching raw tweet details
|
|
146
|
+
const response = await this.request<ITweetRepliesResponse>(resource, { id: id });
|
|
147
|
+
|
|
148
|
+
// Deserializing response
|
|
149
|
+
const data = Extractors[resource](response, id);
|
|
150
|
+
|
|
151
|
+
return data as T extends string ? Tweet | undefined : Tweet[];
|
|
152
|
+
}
|
|
153
|
+
// If user is authenticated and details of multiple tweets required
|
|
154
|
+
else if (this.config.userId != undefined && Array.isArray(id)) {
|
|
155
|
+
resource = ResourceType.TWEET_DETAILS_BULK;
|
|
156
|
+
|
|
157
|
+
// Fetching raw tweet details
|
|
158
|
+
const response = await this.request<ITweetDetailsBulkResponse>(resource, { ids: id });
|
|
159
|
+
|
|
160
|
+
// Deserializing response
|
|
161
|
+
const data = Extractors[resource](response, id);
|
|
162
|
+
|
|
163
|
+
return data as T extends string ? Tweet | undefined : Tweet[];
|
|
164
|
+
}
|
|
165
|
+
// If user is not authenticated
|
|
166
|
+
else {
|
|
167
|
+
resource = ResourceType.TWEET_DETAILS;
|
|
168
|
+
|
|
169
|
+
// Fetching raw tweet details
|
|
170
|
+
const response = await this.request<ITweetDetailsResponse>(resource, { id: String(id) });
|
|
171
|
+
|
|
172
|
+
// Deserializing response
|
|
173
|
+
const data = Extractors[resource](response, String(id));
|
|
174
|
+
|
|
175
|
+
return data as T extends string ? Tweet | undefined : Tweet[];
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Like a tweet.
|
|
181
|
+
*
|
|
182
|
+
* @param id - The ID of the tweet to be liked.
|
|
183
|
+
*
|
|
184
|
+
* @returns Whether liking was successful or not.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
*
|
|
188
|
+
* ```ts
|
|
189
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
190
|
+
*
|
|
191
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
192
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
193
|
+
*
|
|
194
|
+
* // Liking the Tweet with id '1234567890'
|
|
195
|
+
* rettiwt.tweet.like('1234567890')
|
|
196
|
+
* .then(res => {
|
|
197
|
+
* console.log(res);
|
|
198
|
+
* })
|
|
199
|
+
* .catch(err => {
|
|
200
|
+
* console.log(err);
|
|
201
|
+
* });
|
|
202
|
+
* ```
|
|
203
|
+
*/
|
|
204
|
+
public async like(id: string): Promise<boolean> {
|
|
205
|
+
const resource = ResourceType.TWEET_LIKE;
|
|
206
|
+
|
|
207
|
+
// Favoriting the tweet
|
|
208
|
+
const response = await this.request<ITweetLikeResponse>(resource, {
|
|
209
|
+
id: id,
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
// Deserializing response
|
|
213
|
+
const data = Extractors[resource](response) ?? false;
|
|
214
|
+
|
|
215
|
+
return data;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Get the list of users who liked a tweet. Only works for your own tweets.
|
|
220
|
+
*
|
|
221
|
+
* @param id - The ID of the target tweet.
|
|
222
|
+
* @param count - The number of likers to fetch, must be \<= 100.
|
|
223
|
+
* @param cursor - The cursor to the batch of likers to fetch.
|
|
224
|
+
*
|
|
225
|
+
* @returns The list of users who liked the given tweet.
|
|
226
|
+
*
|
|
227
|
+
* @example
|
|
228
|
+
*
|
|
229
|
+
* ```ts
|
|
230
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
231
|
+
*
|
|
232
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
233
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
234
|
+
*
|
|
235
|
+
* // Fetching the most recent 100 likers of the Tweet with id '1234567890'
|
|
236
|
+
* rettiwt.tweet.likers('1234567890')
|
|
237
|
+
* .then(res => {
|
|
238
|
+
* console.log(res);
|
|
239
|
+
* })
|
|
240
|
+
* .catch(err => {
|
|
241
|
+
* console.log(err);
|
|
242
|
+
* });
|
|
243
|
+
* ```
|
|
244
|
+
*/
|
|
245
|
+
public async likers(id: string, count?: number, cursor?: string): Promise<CursoredData<User>> {
|
|
246
|
+
const resource = ResourceType.TWEET_LIKERS;
|
|
247
|
+
|
|
248
|
+
// Fetching raw likers
|
|
249
|
+
const response = await this.request<ITweetLikersResponse>(resource, {
|
|
250
|
+
id: id,
|
|
251
|
+
count: count,
|
|
252
|
+
cursor: cursor,
|
|
253
|
+
});
|
|
254
|
+
|
|
255
|
+
// Deserializing response
|
|
256
|
+
const data = Extractors[resource](response);
|
|
257
|
+
|
|
258
|
+
return data;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Post a tweet.
|
|
263
|
+
*
|
|
264
|
+
* @param options - The options describing the tweet to be posted. Check {@link TweetArgs} for available options.
|
|
265
|
+
*
|
|
266
|
+
* @returns The ID of the posted tweet.
|
|
267
|
+
*
|
|
268
|
+
* @example
|
|
269
|
+
*
|
|
270
|
+
* #### Posting a simple text
|
|
271
|
+
* ```ts
|
|
272
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
273
|
+
*
|
|
274
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
275
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
276
|
+
*
|
|
277
|
+
* // Posting a tweet to twitter
|
|
278
|
+
* rettiwt.tweet.post({ text: 'Hello World!' })
|
|
279
|
+
* .then(res => {
|
|
280
|
+
* console.log(res);
|
|
281
|
+
* })
|
|
282
|
+
* .catch(err => {
|
|
283
|
+
* console.log(err);
|
|
284
|
+
* });
|
|
285
|
+
* ```
|
|
286
|
+
*
|
|
287
|
+
* @example
|
|
288
|
+
*
|
|
289
|
+
* #### Posting a tweet with an image that has been already uploaded
|
|
290
|
+
* ```ts
|
|
291
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
292
|
+
*
|
|
293
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
294
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
295
|
+
*
|
|
296
|
+
* // Posting a tweet, containing an image with ID '1234567890', to twitter
|
|
297
|
+
* rettiwt.tweet.post({ text: 'What a nice view!', media: [{ id: '1234567890' }] })
|
|
298
|
+
* .then(res => {
|
|
299
|
+
* console.log(res);
|
|
300
|
+
* })
|
|
301
|
+
* .catch(err => {
|
|
302
|
+
* console.log(err);
|
|
303
|
+
* });
|
|
304
|
+
* ```
|
|
305
|
+
*
|
|
306
|
+
* @example
|
|
307
|
+
*
|
|
308
|
+
* #### Posting a reply to a tweet
|
|
309
|
+
* ```ts
|
|
310
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
311
|
+
*
|
|
312
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
313
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
314
|
+
*
|
|
315
|
+
* // Posting a simple text reply, to a tweet with id "1234567890"
|
|
316
|
+
* rettiwt.tweet.post({ text: 'Hello!', replyTo: "1234567890" })
|
|
317
|
+
* .then(res => {
|
|
318
|
+
* console.log(res);
|
|
319
|
+
* })
|
|
320
|
+
* .catch(err => {
|
|
321
|
+
* console.log(err);
|
|
322
|
+
* });
|
|
323
|
+
* ```
|
|
324
|
+
*
|
|
325
|
+
* @example
|
|
326
|
+
*
|
|
327
|
+
* #### Posting a tweet that quotes another tweet
|
|
328
|
+
* ```ts
|
|
329
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
330
|
+
*
|
|
331
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
332
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
333
|
+
*
|
|
334
|
+
* // Posting a simple text tweet, quoting a tweet with id "1234567890"
|
|
335
|
+
* rettiwt.tweet.post({ text: 'Hello!', quote: "1234567890" })
|
|
336
|
+
* .then(res => {
|
|
337
|
+
* console.log(res);
|
|
338
|
+
* })
|
|
339
|
+
* .catch(err => {
|
|
340
|
+
* console.log(err);
|
|
341
|
+
* });
|
|
342
|
+
* ```
|
|
343
|
+
*/
|
|
344
|
+
public async post(options: INewTweet): Promise<string | undefined> {
|
|
345
|
+
const resource = ResourceType.TWEET_POST;
|
|
346
|
+
|
|
347
|
+
// Posting the tweet
|
|
348
|
+
const response = await this.request<ITweetPostResponse>(resource, { tweet: options });
|
|
349
|
+
|
|
350
|
+
// Deserializing response
|
|
351
|
+
const data = Extractors[resource](response);
|
|
352
|
+
|
|
353
|
+
return data;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
/**
|
|
357
|
+
* Get the list of replies to a tweet.
|
|
358
|
+
*
|
|
359
|
+
* If the target tweet is a thread,
|
|
360
|
+
* the first batch always contains all the tweets in the thread,
|
|
361
|
+
* if `sortBy` is set to {@link TweetRepliesSortType.RELEVANCE}.
|
|
362
|
+
*
|
|
363
|
+
* @param id - The ID of the target tweet.
|
|
364
|
+
* @param cursor - The cursor to the batch of replies to fetch.
|
|
365
|
+
* @param sortBy - The sorting order of the replies to fetch. Default is {@link TweetRepliesSortType.RECENT}.
|
|
366
|
+
*
|
|
367
|
+
* @returns The list of replies to the given tweet.
|
|
368
|
+
*
|
|
369
|
+
* @example
|
|
370
|
+
*
|
|
371
|
+
* ```ts
|
|
372
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
373
|
+
*
|
|
374
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
375
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
376
|
+
*
|
|
377
|
+
* // Fetching the first 100 replies to the Tweet with id '1234567890'
|
|
378
|
+
* rettiwt.tweet.replies('1234567890')
|
|
379
|
+
* .then(res => {
|
|
380
|
+
* console.log(res);
|
|
381
|
+
* })
|
|
382
|
+
* .catch(err => {
|
|
383
|
+
* console.log(err);
|
|
384
|
+
* });
|
|
385
|
+
* ```
|
|
386
|
+
*
|
|
387
|
+
* @remarks
|
|
388
|
+
*
|
|
389
|
+
* If the given tweet is the start of/part of a thread, the first batch always contains all the tweets in the thread.
|
|
390
|
+
*/
|
|
391
|
+
public async replies(
|
|
392
|
+
id: string,
|
|
393
|
+
cursor?: string,
|
|
394
|
+
sortBy: TweetRepliesSortType = TweetRepliesSortType.LATEST,
|
|
395
|
+
): Promise<CursoredData<Tweet>> {
|
|
396
|
+
const resource = ResourceType.TWEET_REPLIES;
|
|
397
|
+
|
|
398
|
+
// Fetching raw list of replies
|
|
399
|
+
const response = await this.request<ITweetDetailsResponse>(resource, {
|
|
400
|
+
id: id,
|
|
401
|
+
cursor: cursor,
|
|
402
|
+
sortBy: sortBy,
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
// Deserializing response
|
|
406
|
+
const data = Extractors[resource](response);
|
|
407
|
+
|
|
408
|
+
return data;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
/**
|
|
412
|
+
* Retweet a tweet.
|
|
413
|
+
*
|
|
414
|
+
* @param id - The ID of the target tweet.
|
|
415
|
+
*
|
|
416
|
+
* @returns Whether retweeting was successful or not.
|
|
417
|
+
*
|
|
418
|
+
* @example
|
|
419
|
+
*
|
|
420
|
+
* ```ts
|
|
421
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
422
|
+
*
|
|
423
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
424
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
425
|
+
*
|
|
426
|
+
* // Retweeting the Tweet with id '1234567890'
|
|
427
|
+
* rettiwt.tweet.retweet('1234567890')
|
|
428
|
+
* .then(res => {
|
|
429
|
+
* console.log(res);
|
|
430
|
+
* })
|
|
431
|
+
* .catch(err => {
|
|
432
|
+
* console.log(err);
|
|
433
|
+
* });
|
|
434
|
+
* ```
|
|
435
|
+
*/
|
|
436
|
+
public async retweet(id: string): Promise<boolean> {
|
|
437
|
+
const resource = ResourceType.TWEET_RETWEET;
|
|
438
|
+
|
|
439
|
+
// Retweeting the tweet
|
|
440
|
+
const response = await this.request<ITweetRetweetResponse>(resource, { id: id });
|
|
441
|
+
|
|
442
|
+
// Deserializing response
|
|
443
|
+
const data = Extractors[resource](response) ?? false;
|
|
444
|
+
|
|
445
|
+
return data;
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
/**
|
|
449
|
+
* Get the list of users who retweeted a tweet.
|
|
450
|
+
*
|
|
451
|
+
* @param id - The ID of the target tweet.
|
|
452
|
+
* @param count - The number of retweeters to fetch, must be \<= 100.
|
|
453
|
+
* @param cursor - The cursor to the batch of retweeters to fetch.
|
|
454
|
+
*
|
|
455
|
+
* @returns The list of users who retweeted the given tweet.
|
|
456
|
+
*
|
|
457
|
+
* @example
|
|
458
|
+
*
|
|
459
|
+
* ```ts
|
|
460
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
461
|
+
*
|
|
462
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
463
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
464
|
+
*
|
|
465
|
+
* // Fetching the most recent 100 retweeters of the Tweet with id '1234567890'
|
|
466
|
+
* rettiwt.tweet.retweeters('1234567890')
|
|
467
|
+
* .then(res => {
|
|
468
|
+
* console.log(res);
|
|
469
|
+
* })
|
|
470
|
+
* .catch(err => {
|
|
471
|
+
* console.log(err);
|
|
472
|
+
* });
|
|
473
|
+
* ```
|
|
474
|
+
*/
|
|
475
|
+
public async retweeters(id: string, count?: number, cursor?: string): Promise<CursoredData<User>> {
|
|
476
|
+
const resource = ResourceType.TWEET_RETWEETERS;
|
|
477
|
+
|
|
478
|
+
// Fetching raw list of retweeters
|
|
479
|
+
const response = await this.request<ITweetRetweetersResponse>(resource, {
|
|
480
|
+
id: id,
|
|
481
|
+
count: count,
|
|
482
|
+
cursor: cursor,
|
|
483
|
+
});
|
|
484
|
+
|
|
485
|
+
// Deserializing response
|
|
486
|
+
const data = Extractors[resource](response);
|
|
487
|
+
|
|
488
|
+
return data;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* Schedule a tweet.
|
|
493
|
+
*
|
|
494
|
+
* @param options - The options describing the tweet to be posted. Check {@link TweetArgs} for available options.
|
|
495
|
+
*
|
|
496
|
+
* @returns The ID of the schedule.
|
|
497
|
+
*
|
|
498
|
+
* @example
|
|
499
|
+
*
|
|
500
|
+
* #### Scheduling a simple text
|
|
501
|
+
* ```ts
|
|
502
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
503
|
+
*
|
|
504
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
505
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
506
|
+
*
|
|
507
|
+
* // Scheduling a tweet to posted at 19th of August, 2024, at 11:59:00 AM, in local time
|
|
508
|
+
* rettiwt.tweet.schedule({ text: 'Hello World!', scheduleFor: new Date('2024-08-19 23:59:00') })
|
|
509
|
+
* .then(res => {
|
|
510
|
+
* console.log(res);
|
|
511
|
+
* })
|
|
512
|
+
* .catch(err => {
|
|
513
|
+
* console.log(err);
|
|
514
|
+
* });
|
|
515
|
+
* ```
|
|
516
|
+
*
|
|
517
|
+
* @remarks
|
|
518
|
+
*
|
|
519
|
+
* Scheduling a tweet is similar to {@link post}ing, except that an extra parameter called `scheduleFor` is used.
|
|
520
|
+
*/
|
|
521
|
+
public async schedule(options: INewTweet): Promise<string | undefined> {
|
|
522
|
+
const resource = ResourceType.TWEET_SCHEDULE;
|
|
523
|
+
|
|
524
|
+
// Scheduling the tweet
|
|
525
|
+
const response = await this.request<ITweetScheduleResponse>(resource, { tweet: options });
|
|
526
|
+
|
|
527
|
+
// Deserializing response
|
|
528
|
+
const data = Extractors[resource](response);
|
|
529
|
+
|
|
530
|
+
return data;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* Search for tweets using a filter.
|
|
535
|
+
*
|
|
536
|
+
* @param filter - The filter to be used for searching the tweets.
|
|
537
|
+
* @param count - The number of tweets to fetch, must be \<= 20.
|
|
538
|
+
* @param cursor - The cursor to the batch of tweets to fetch.
|
|
539
|
+
* @param results - The type of search results to fetch. Default is {@link ESearchResultType.LATEST}.
|
|
540
|
+
*
|
|
541
|
+
* @returns The list of tweets that match the given filter.
|
|
542
|
+
*
|
|
543
|
+
* @example
|
|
544
|
+
*
|
|
545
|
+
* ```ts
|
|
546
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
547
|
+
*
|
|
548
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
549
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
550
|
+
*
|
|
551
|
+
* // Fetching the most recent 5 tweets from user 'user1'
|
|
552
|
+
* rettiwt.tweet.search({ fromUsers: ['user1'] }, 5)
|
|
553
|
+
* .then(res => {
|
|
554
|
+
* console.log(res);
|
|
555
|
+
* })
|
|
556
|
+
* .catch(err => {
|
|
557
|
+
* console.log(err);
|
|
558
|
+
* });
|
|
559
|
+
* ```
|
|
560
|
+
*
|
|
561
|
+
* @remarks
|
|
562
|
+
*
|
|
563
|
+
* For details about available filters, refer to {@link TweetFilter}
|
|
564
|
+
*/
|
|
565
|
+
public async search(filter: ITweetFilter, count?: number, cursor?: string): Promise<CursoredData<Tweet>> {
|
|
566
|
+
const resource = ResourceType.TWEET_SEARCH;
|
|
567
|
+
|
|
568
|
+
// Fetching raw list of filtered tweets
|
|
569
|
+
const response = await this.request<ITweetSearchResponse>(resource, {
|
|
570
|
+
filter: filter,
|
|
571
|
+
count: count,
|
|
572
|
+
cursor: cursor,
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
// Deserializing response
|
|
576
|
+
const data = Extractors[resource](response);
|
|
577
|
+
|
|
578
|
+
// Sorting the tweets by date, from recent to oldest
|
|
579
|
+
data.list.sort((a, b) => new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf());
|
|
580
|
+
|
|
581
|
+
return data;
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
/**
|
|
585
|
+
* Stream tweets in pseudo real-time using a filter.
|
|
586
|
+
*
|
|
587
|
+
* @param filter - The filter to be used for searching the tweets.
|
|
588
|
+
* @param pollingInterval - The interval in milliseconds to poll for new tweets. Default interval is 60000 ms.
|
|
589
|
+
*
|
|
590
|
+
* @returns An async generator that yields matching tweets as they are found.
|
|
591
|
+
*
|
|
592
|
+
* @example
|
|
593
|
+
*
|
|
594
|
+
* ```ts
|
|
595
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
596
|
+
*
|
|
597
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
598
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
599
|
+
*
|
|
600
|
+
* // Creating a function that streams all new tweets from the user 'user1'
|
|
601
|
+
* async function streamTweets() {
|
|
602
|
+
* try {
|
|
603
|
+
* // Awaiting for the tweets returned by the AsyncGenerator returned by the method
|
|
604
|
+
* for await (const tweet of rettiwt.tweet.stream({ fromUsers: ['user1'] }, 5000)) {
|
|
605
|
+
* console.log(tweet.fullText);
|
|
606
|
+
* }
|
|
607
|
+
* }
|
|
608
|
+
* catch (err) {
|
|
609
|
+
* console.log(err);
|
|
610
|
+
* }
|
|
611
|
+
* }
|
|
612
|
+
*
|
|
613
|
+
* // Calling the function
|
|
614
|
+
* streamTweets();
|
|
615
|
+
* ```
|
|
616
|
+
*/
|
|
617
|
+
public async *stream(filter: ITweetFilter, pollingInterval = 60000): AsyncGenerator<Tweet> {
|
|
618
|
+
const startDate = new Date();
|
|
619
|
+
|
|
620
|
+
let cursor: string | undefined = undefined;
|
|
621
|
+
let sinceId: string | undefined = undefined;
|
|
622
|
+
let nextSinceId: string | undefined = undefined;
|
|
623
|
+
|
|
624
|
+
while (true) {
|
|
625
|
+
// Pause execution for the specified polling interval before proceeding to the next iteration
|
|
626
|
+
await new Promise((resolve) => setTimeout(resolve, pollingInterval));
|
|
627
|
+
|
|
628
|
+
// Search for tweets
|
|
629
|
+
const tweets = await this.search({ ...filter, startDate: startDate, sinceId: sinceId }, undefined, cursor);
|
|
630
|
+
|
|
631
|
+
// Yield the matching tweets
|
|
632
|
+
for (const tweet of tweets.list) {
|
|
633
|
+
yield tweet;
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
// Store the most recent tweet ID from this batch
|
|
637
|
+
if (tweets.list.length > 0 && cursor === undefined) {
|
|
638
|
+
nextSinceId = tweets.list[0].id;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
// If there are more tweets to fetch, adjust the cursor value
|
|
642
|
+
if (tweets.list.length > 0 && tweets.next) {
|
|
643
|
+
cursor = tweets.next;
|
|
644
|
+
}
|
|
645
|
+
// Else, start the next iteration from this batch's most recent tweet
|
|
646
|
+
else {
|
|
647
|
+
sinceId = nextSinceId;
|
|
648
|
+
cursor = undefined;
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Unbookmark a tweet.
|
|
655
|
+
*
|
|
656
|
+
* @param id - The ID of the target tweet.
|
|
657
|
+
*
|
|
658
|
+
* @returns Whether unbookmarking was successful or not.
|
|
659
|
+
*
|
|
660
|
+
* @example
|
|
661
|
+
*
|
|
662
|
+
* ```ts
|
|
663
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
664
|
+
*
|
|
665
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
666
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
667
|
+
*
|
|
668
|
+
* // Unbookmarking the tweet with id '1234567890'
|
|
669
|
+
* rettiwt.tweet.unbookmark('1234567890')
|
|
670
|
+
* .then(res => {
|
|
671
|
+
* console.log(res);
|
|
672
|
+
* })
|
|
673
|
+
* .catch(err => {
|
|
674
|
+
* console.log(err);
|
|
675
|
+
* });
|
|
676
|
+
* ```
|
|
677
|
+
*/
|
|
678
|
+
public async unbookmark(id: string): Promise<boolean> {
|
|
679
|
+
const resource = ResourceType.TWEET_UNBOOKMARK;
|
|
680
|
+
|
|
681
|
+
// Unliking the tweet
|
|
682
|
+
const response = await this.request<ITweetUnbookmarkResponse>(resource, { id: id });
|
|
683
|
+
|
|
684
|
+
// Deserializing the response
|
|
685
|
+
const data = Extractors[resource](response) ?? false;
|
|
686
|
+
|
|
687
|
+
return data;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
/**
|
|
691
|
+
* Unlike a tweet.
|
|
692
|
+
*
|
|
693
|
+
* @param id - The ID of the target tweet.
|
|
694
|
+
*
|
|
695
|
+
* @returns Whether unliking was successful or not.
|
|
696
|
+
*
|
|
697
|
+
* @example
|
|
698
|
+
*
|
|
699
|
+
* ```ts
|
|
700
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
701
|
+
*
|
|
702
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
703
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
704
|
+
*
|
|
705
|
+
* // Unliking the Tweet with id '1234567890'
|
|
706
|
+
* rettiwt.tweet.unlike('1234567890')
|
|
707
|
+
* .then(res => {
|
|
708
|
+
* console.log(res);
|
|
709
|
+
* })
|
|
710
|
+
* .catch(err => {
|
|
711
|
+
* console.log(err);
|
|
712
|
+
* });
|
|
713
|
+
* ```
|
|
714
|
+
*/
|
|
715
|
+
public async unlike(id: string): Promise<boolean> {
|
|
716
|
+
const resource = ResourceType.TWEET_UNLIKE;
|
|
717
|
+
|
|
718
|
+
// Unliking the tweet
|
|
719
|
+
const response = await this.request<ITweetUnlikeResponse>(resource, { id: id });
|
|
720
|
+
|
|
721
|
+
// Deserializing the response
|
|
722
|
+
const data = Extractors[resource](response) ?? false;
|
|
723
|
+
|
|
724
|
+
return data;
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
/**
|
|
728
|
+
* Unpost a tweet.
|
|
729
|
+
*
|
|
730
|
+
* @param id - The ID of the target tweet.
|
|
731
|
+
*
|
|
732
|
+
* @returns Whether unposting was successful or not.
|
|
733
|
+
*
|
|
734
|
+
* @example
|
|
735
|
+
*
|
|
736
|
+
* ```ts
|
|
737
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
738
|
+
*
|
|
739
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
740
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
741
|
+
*
|
|
742
|
+
* // Unposting the Tweet with id '1234567890'
|
|
743
|
+
* rettiwt.tweet.unpost('1234567890')
|
|
744
|
+
* .then(res => {
|
|
745
|
+
* console.log(res);
|
|
746
|
+
* })
|
|
747
|
+
* .catch(err => {
|
|
748
|
+
* console.log(err);
|
|
749
|
+
* });
|
|
750
|
+
* ```
|
|
751
|
+
*/
|
|
752
|
+
public async unpost(id: string): Promise<boolean> {
|
|
753
|
+
const resource = ResourceType.TWEET_UNPOST;
|
|
754
|
+
|
|
755
|
+
// Unposting the tweet
|
|
756
|
+
const response = await this.request<ITweetUnpostResponse>(resource, { id: id });
|
|
757
|
+
|
|
758
|
+
// Deserializing the response
|
|
759
|
+
const data = Extractors[resource](response) ?? false;
|
|
760
|
+
|
|
761
|
+
return data;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
/**
|
|
765
|
+
* Unretweet a tweet.
|
|
766
|
+
*
|
|
767
|
+
* @param id - The ID of the target tweet.
|
|
768
|
+
*
|
|
769
|
+
* @returns Whether unretweeting was successful or not.
|
|
770
|
+
*
|
|
771
|
+
* @example
|
|
772
|
+
*
|
|
773
|
+
* ```ts
|
|
774
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
775
|
+
*
|
|
776
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
777
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
778
|
+
*
|
|
779
|
+
* // Unretweeting the Tweet with id '1234567890'
|
|
780
|
+
* rettiwt.tweet.unretweet('1234567890')
|
|
781
|
+
* .then(res => {
|
|
782
|
+
* console.log(res);
|
|
783
|
+
* })
|
|
784
|
+
* .catch(err => {
|
|
785
|
+
* console.log(err);
|
|
786
|
+
* });
|
|
787
|
+
* ```
|
|
788
|
+
*/
|
|
789
|
+
public async unretweet(id: string): Promise<boolean> {
|
|
790
|
+
const resource = ResourceType.TWEET_UNRETWEET;
|
|
791
|
+
|
|
792
|
+
// Unretweeting the tweet
|
|
793
|
+
const response = await this.request<ITweetUnretweetResponse>(resource, { id: id });
|
|
794
|
+
|
|
795
|
+
// Deserializing the response
|
|
796
|
+
const data = Extractors[resource](response) ?? false;
|
|
797
|
+
|
|
798
|
+
return data;
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
/**
|
|
802
|
+
* Unschedule a tweet.
|
|
803
|
+
*
|
|
804
|
+
* @param id - The ID of the scheduled tweet.
|
|
805
|
+
*
|
|
806
|
+
* @returns Whether unscheduling was successful or not.
|
|
807
|
+
*
|
|
808
|
+
* @example
|
|
809
|
+
*
|
|
810
|
+
* ```ts
|
|
811
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
812
|
+
*
|
|
813
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
814
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
815
|
+
*
|
|
816
|
+
* // Unscheduling the Tweet with id '1234567890'
|
|
817
|
+
* rettiwt.tweet.unschedule('1234567890')
|
|
818
|
+
* .then(res => {
|
|
819
|
+
* console.log(res);
|
|
820
|
+
* })
|
|
821
|
+
* .catch(err => {
|
|
822
|
+
* console.log(err);
|
|
823
|
+
* });
|
|
824
|
+
* ```
|
|
825
|
+
*/
|
|
826
|
+
public async unschedule(id: string): Promise<boolean> {
|
|
827
|
+
const resource = ResourceType.TWEET_UNSCHEDULE;
|
|
828
|
+
|
|
829
|
+
// Unscheduling the tweet
|
|
830
|
+
const response = await this.request<ITweetUnscheduleResponse>(resource, { id: id });
|
|
831
|
+
|
|
832
|
+
// Deserializing the response
|
|
833
|
+
const data = Extractors[resource](response) ?? false;
|
|
834
|
+
|
|
835
|
+
return data;
|
|
836
|
+
}
|
|
837
|
+
|
|
838
|
+
/**
|
|
839
|
+
* Upload a media file to Twitter.
|
|
840
|
+
*
|
|
841
|
+
* @param media - The path or ArrayBuffer to the media file to upload.
|
|
842
|
+
*
|
|
843
|
+
* @returns The ID of the uploaded media.
|
|
844
|
+
*
|
|
845
|
+
* @example
|
|
846
|
+
*
|
|
847
|
+
* ```ts
|
|
848
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
849
|
+
*
|
|
850
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
851
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
852
|
+
*
|
|
853
|
+
* // Uploading a file called mountains.jpg
|
|
854
|
+
* rettiwt.tweet.upload('mountains.jpg')
|
|
855
|
+
* .then(res => {
|
|
856
|
+
* console.log(res);
|
|
857
|
+
* })
|
|
858
|
+
* .catch(err => {
|
|
859
|
+
* console.log(err);
|
|
860
|
+
* });
|
|
861
|
+
* ```
|
|
862
|
+
*
|
|
863
|
+
* @remarks
|
|
864
|
+
*
|
|
865
|
+
* - The uploaded media exists for 24 hrs within which it can be included in a tweet to be posted.
|
|
866
|
+
* If not posted in a tweet within this period, the uploaded media is removed.
|
|
867
|
+
* - Instead of a path to the media, an ArrayBuffer containing the media can also be uploaded.
|
|
868
|
+
*/
|
|
869
|
+
public async upload(media: string | ArrayBuffer): Promise<string> {
|
|
870
|
+
// INITIALIZE
|
|
871
|
+
const size = typeof media == 'string' ? statSync(media).size : media.byteLength;
|
|
872
|
+
const id: string = (
|
|
873
|
+
await this.request<IMediaInitializeUploadResponse>(ResourceType.MEDIA_UPLOAD_INITIALIZE, {
|
|
874
|
+
upload: { size: size },
|
|
875
|
+
})
|
|
876
|
+
).media_id_string;
|
|
877
|
+
|
|
878
|
+
// APPEND
|
|
879
|
+
await this.request<unknown>(ResourceType.MEDIA_UPLOAD_APPEND, { upload: { id: id, media: media } });
|
|
880
|
+
|
|
881
|
+
// FINALIZE
|
|
882
|
+
await this.request<unknown>(ResourceType.MEDIA_UPLOAD_FINALIZE, { upload: { id: id } });
|
|
883
|
+
|
|
884
|
+
return id;
|
|
885
|
+
}
|
|
886
|
+
}
|