@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,1154 @@
|
|
|
1
|
+
import { Extractors } from '../../collections/Extractors';
|
|
2
|
+
import { RawAnalyticsGranularity, RawAnalyticsMetric } from '../../enums/raw/Analytics';
|
|
3
|
+
import { ResourceType } from '../../enums/Resource';
|
|
4
|
+
import { ProfileUpdateOptions } from '../../models/args/ProfileArgs';
|
|
5
|
+
import { Analytics } from '../../models/data/Analytics';
|
|
6
|
+
import { BookmarkFolder } from '../../models/data/BookmarkFolder';
|
|
7
|
+
import { CursoredData } from '../../models/data/CursoredData';
|
|
8
|
+
import { List } from '../../models/data/List';
|
|
9
|
+
import { Notification } from '../../models/data/Notification';
|
|
10
|
+
import { Tweet } from '../../models/data/Tweet';
|
|
11
|
+
import { User } from '../../models/data/User';
|
|
12
|
+
import { RettiwtConfig } from '../../models/RettiwtConfig';
|
|
13
|
+
import { IProfileUpdateOptions } from '../../types/args/ProfileArgs';
|
|
14
|
+
import { IUserAffiliatesResponse } from '../../types/raw/user/Affiliates';
|
|
15
|
+
import { IUserAnalyticsResponse } from '../../types/raw/user/Analytics';
|
|
16
|
+
import { IUserBookmarkFoldersResponse } from '../../types/raw/user/BookmarkFolders';
|
|
17
|
+
import { IUserBookmarkFolderTweetsResponse } from '../../types/raw/user/BookmarkFolderTweets';
|
|
18
|
+
import { IUserBookmarksResponse } from '../../types/raw/user/Bookmarks';
|
|
19
|
+
import { IUserDetailsResponse } from '../../types/raw/user/Details';
|
|
20
|
+
import { IUserDetailsBulkResponse } from '../../types/raw/user/DetailsBulk';
|
|
21
|
+
import { IUserFollowResponse } from '../../types/raw/user/Follow';
|
|
22
|
+
import { IUserFollowedResponse } from '../../types/raw/user/Followed';
|
|
23
|
+
import { IUserFollowersResponse } from '../../types/raw/user/Followers';
|
|
24
|
+
import { IUserFollowingResponse } from '../../types/raw/user/Following';
|
|
25
|
+
import { IUserHighlightsResponse } from '../../types/raw/user/Highlights';
|
|
26
|
+
import { IUserLikesResponse } from '../../types/raw/user/Likes';
|
|
27
|
+
import { IUserListsResponse } from '../../types/raw/user/Lists';
|
|
28
|
+
import { IUserMediaResponse } from '../../types/raw/user/Media';
|
|
29
|
+
import { IUserNotificationsResponse } from '../../types/raw/user/Notifications';
|
|
30
|
+
import { IUserProfileUpdateResponse } from '../../types/raw/user/ProfileUpdate';
|
|
31
|
+
import { IUserRecommendedResponse } from '../../types/raw/user/Recommended';
|
|
32
|
+
import { IUserSearchResponse } from '../../types/raw/user/Search';
|
|
33
|
+
import { IUserSubscriptionsResponse } from '../../types/raw/user/Subscriptions';
|
|
34
|
+
import { IUserTweetsResponse } from '../../types/raw/user/Tweets';
|
|
35
|
+
import { IUserTweetsAndRepliesResponse } from '../../types/raw/user/TweetsAndReplies';
|
|
36
|
+
import { IUserUnfollowResponse } from '../../types/raw/user/Unfollow';
|
|
37
|
+
|
|
38
|
+
import { FetcherService } from './FetcherService';
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Handles interacting with resources related to user account
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export class UserService extends FetcherService {
|
|
46
|
+
/**
|
|
47
|
+
* @param config - The config object for configuring the Rettiwt instance.
|
|
48
|
+
*
|
|
49
|
+
* @internal
|
|
50
|
+
*/
|
|
51
|
+
public constructor(config: RettiwtConfig) {
|
|
52
|
+
super(config);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get the list affiliates of a user.
|
|
57
|
+
*
|
|
58
|
+
* @param id - The ID of the target user. If no id is provided, the logged-in user's id is used.
|
|
59
|
+
* @param count - The number of affiliates to fetch, must be \<= 100.
|
|
60
|
+
* @param cursor - The cursor to the batch of affiliates to fetch.
|
|
61
|
+
*
|
|
62
|
+
* @returns The list of users affiliated to the target user.
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
*
|
|
66
|
+
* ```ts
|
|
67
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
68
|
+
*
|
|
69
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
70
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
71
|
+
*
|
|
72
|
+
* // Fetching the first 100 affiliates of the User with id '1234567890'
|
|
73
|
+
* rettiwt.user.affiliates('1234567890')
|
|
74
|
+
* .then(res => {
|
|
75
|
+
* console.log(res);
|
|
76
|
+
* })
|
|
77
|
+
* .catch(err => {
|
|
78
|
+
* console.log(err);
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
public async affiliates(id?: string, count?: number, cursor?: string): Promise<CursoredData<User>> {
|
|
83
|
+
const resource = ResourceType.USER_AFFILIATES;
|
|
84
|
+
|
|
85
|
+
// Fetching raw list of affiliates
|
|
86
|
+
const response = await this.request<IUserAffiliatesResponse>(resource, {
|
|
87
|
+
id: id ?? this.config.userId,
|
|
88
|
+
count: count,
|
|
89
|
+
cursor: cursor,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
// Deserializing response
|
|
93
|
+
const data = Extractors[resource](response);
|
|
94
|
+
|
|
95
|
+
return data;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Get the analytics overview of the logged in user.
|
|
100
|
+
*
|
|
101
|
+
* @param fromTime - The start time of the analytics period. Defaults to 7 days ago.
|
|
102
|
+
* @param toTime - The end time of the analytics period. Defaults to now.
|
|
103
|
+
* @param granularity - The granularity of the analytics data. Defaults to daily.
|
|
104
|
+
* @param metrics - The metrics to include in the analytics data. Defaults to all available metrics available.
|
|
105
|
+
* @param showVerifiedFollowers - Whether to include verified follower count and relationship counts in the response. Defaults to true.
|
|
106
|
+
*
|
|
107
|
+
* @returns The raw analytics data of the user.
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
*
|
|
111
|
+
* ```ts
|
|
112
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
113
|
+
*
|
|
114
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
115
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
116
|
+
*
|
|
117
|
+
* // Fetching the analytics overview of the logged in user
|
|
118
|
+
* rettiwt.user.analytics().then(res => {
|
|
119
|
+
* console.log(res);
|
|
120
|
+
* })
|
|
121
|
+
* .catch(err => {
|
|
122
|
+
* console.log(err);
|
|
123
|
+
* });
|
|
124
|
+
* ```
|
|
125
|
+
*/
|
|
126
|
+
public async analytics(
|
|
127
|
+
fromTime?: Date,
|
|
128
|
+
toTime?: Date,
|
|
129
|
+
granularity?: RawAnalyticsGranularity,
|
|
130
|
+
metrics?: RawAnalyticsMetric[],
|
|
131
|
+
showVerifiedFollowers?: boolean,
|
|
132
|
+
): Promise<Analytics> {
|
|
133
|
+
const resource = ResourceType.USER_ANALYTICS;
|
|
134
|
+
|
|
135
|
+
// Define default values if not provided
|
|
136
|
+
fromTime = fromTime ?? new Date(Date.now() - 7 * 24 * 60 * 60 * 1000);
|
|
137
|
+
toTime = toTime ?? new Date();
|
|
138
|
+
granularity = granularity ?? RawAnalyticsGranularity.DAILY;
|
|
139
|
+
metrics = metrics ?? Object.values(RawAnalyticsMetric);
|
|
140
|
+
showVerifiedFollowers = showVerifiedFollowers ?? true;
|
|
141
|
+
|
|
142
|
+
// Fetching raw analytics
|
|
143
|
+
const response = await this.request<IUserAnalyticsResponse>(resource, {
|
|
144
|
+
fromTime,
|
|
145
|
+
toTime,
|
|
146
|
+
granularity,
|
|
147
|
+
metrics,
|
|
148
|
+
showVerifiedFollowers,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
const data = Extractors[resource](response);
|
|
152
|
+
|
|
153
|
+
return data;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Get the list of tweets in a specific bookmark folder of the logged in user.
|
|
158
|
+
*
|
|
159
|
+
* @param folderId - The ID of the bookmark folder.
|
|
160
|
+
* @param count - The number of tweets to fetch, must be \<= 100.
|
|
161
|
+
* @param cursor - The cursor to the batch of tweets to fetch.
|
|
162
|
+
*
|
|
163
|
+
* @returns The list of tweets in the bookmark folder.
|
|
164
|
+
*
|
|
165
|
+
* @example
|
|
166
|
+
*
|
|
167
|
+
* ```ts
|
|
168
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
169
|
+
*
|
|
170
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
171
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
172
|
+
*
|
|
173
|
+
* // Fetching the first 100 tweets from bookmark folder with ID '2001752149647049173'
|
|
174
|
+
* rettiwt.user.bookmarkFolderTweets('2001752149647049173')
|
|
175
|
+
* .then(res => {
|
|
176
|
+
* console.log(res);
|
|
177
|
+
* })
|
|
178
|
+
* .catch(err => {
|
|
179
|
+
* console.log(err);
|
|
180
|
+
* });
|
|
181
|
+
* ```
|
|
182
|
+
*/
|
|
183
|
+
public async bookmarkFolderTweets(folderId: string, count?: number, cursor?: string): Promise<CursoredData<Tweet>> {
|
|
184
|
+
const resource = ResourceType.USER_BOOKMARK_FOLDER_TWEETS;
|
|
185
|
+
|
|
186
|
+
// Fetching raw list of tweets from folder
|
|
187
|
+
const response = await this.request<IUserBookmarkFolderTweetsResponse>(resource, {
|
|
188
|
+
id: folderId,
|
|
189
|
+
count: count,
|
|
190
|
+
cursor: cursor,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// Deserializing response
|
|
194
|
+
const data = Extractors[resource](response);
|
|
195
|
+
|
|
196
|
+
return data;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Get the list of bookmark folders of the logged in user.
|
|
201
|
+
*
|
|
202
|
+
* @param cursor - The cursor to the batch of bookmark folders to fetch.
|
|
203
|
+
*
|
|
204
|
+
* @returns The list of bookmark folders.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
*
|
|
208
|
+
* ```ts
|
|
209
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
210
|
+
*
|
|
211
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
212
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
213
|
+
*
|
|
214
|
+
* // Fetching all bookmark folders of the logged in user
|
|
215
|
+
* rettiwt.user.bookmarkFolders()
|
|
216
|
+
* .then(res => {
|
|
217
|
+
* console.log(res);
|
|
218
|
+
* })
|
|
219
|
+
* .catch(err => {
|
|
220
|
+
* console.log(err);
|
|
221
|
+
* });
|
|
222
|
+
* ```
|
|
223
|
+
*/
|
|
224
|
+
public async bookmarkFolders(cursor?: string): Promise<CursoredData<BookmarkFolder>> {
|
|
225
|
+
const resource = ResourceType.USER_BOOKMARK_FOLDERS;
|
|
226
|
+
|
|
227
|
+
// Fetching raw list of bookmark folders
|
|
228
|
+
const response = await this.request<IUserBookmarkFoldersResponse>(resource, {
|
|
229
|
+
cursor: cursor,
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
// Deserializing response
|
|
233
|
+
const data = Extractors[resource](response);
|
|
234
|
+
|
|
235
|
+
return data;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Get the list of bookmarks of the logged in user.
|
|
240
|
+
*
|
|
241
|
+
* @param count - The number of bookmakrs to fetch, must be \<= 100.
|
|
242
|
+
* @param cursor - The cursor to the batch of bookmarks to fetch.
|
|
243
|
+
*
|
|
244
|
+
* @returns The list of tweets bookmarked by the target user.
|
|
245
|
+
*
|
|
246
|
+
* @example
|
|
247
|
+
*
|
|
248
|
+
* ```ts
|
|
249
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
250
|
+
*
|
|
251
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
252
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
253
|
+
*
|
|
254
|
+
* // Fetching the most recent 100 liked Tweets of the logged in User
|
|
255
|
+
* rettiwt.user.bookmarks()
|
|
256
|
+
* .then(res => {
|
|
257
|
+
* console.log(res);
|
|
258
|
+
* })
|
|
259
|
+
* .catch(err => {
|
|
260
|
+
* console.log(err);
|
|
261
|
+
* });
|
|
262
|
+
* ```
|
|
263
|
+
*/
|
|
264
|
+
public async bookmarks(count?: number, cursor?: string): Promise<CursoredData<Tweet>> {
|
|
265
|
+
const resource = ResourceType.USER_BOOKMARKS;
|
|
266
|
+
|
|
267
|
+
// Fetching raw list of likes
|
|
268
|
+
const response = await this.request<IUserBookmarksResponse>(resource, {
|
|
269
|
+
count: count,
|
|
270
|
+
cursor: cursor,
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
// Deserializing response
|
|
274
|
+
const data = Extractors[resource](response);
|
|
275
|
+
|
|
276
|
+
return data;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* Get the details of the logged in user.
|
|
281
|
+
*
|
|
282
|
+
* @returns The details of the user.
|
|
283
|
+
*
|
|
284
|
+
* @example
|
|
285
|
+
*
|
|
286
|
+
* ```ts
|
|
287
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
288
|
+
*
|
|
289
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
290
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
291
|
+
*
|
|
292
|
+
* // Fetching the details of the User
|
|
293
|
+
* rettiwt.user.details()
|
|
294
|
+
* .then(res => {
|
|
295
|
+
* console.log(res);
|
|
296
|
+
* })
|
|
297
|
+
* .catch(err => {
|
|
298
|
+
* console.log(err);
|
|
299
|
+
* });
|
|
300
|
+
* ```
|
|
301
|
+
*/
|
|
302
|
+
public async details(): Promise<User | undefined>;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Get the details of a user.
|
|
306
|
+
*
|
|
307
|
+
* @param id - The ID/username of the target user.
|
|
308
|
+
*
|
|
309
|
+
* @returns The details of the user.
|
|
310
|
+
*
|
|
311
|
+
* @example
|
|
312
|
+
*
|
|
313
|
+
* #### Fetching the details of a single user using username
|
|
314
|
+
* ```ts
|
|
315
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
316
|
+
*
|
|
317
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
318
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
319
|
+
*
|
|
320
|
+
* // Fetching the details of the User with username 'user1' or '@user1'
|
|
321
|
+
* rettiwt.user.details('user1') // or @user1
|
|
322
|
+
* .then(res => {
|
|
323
|
+
* console.log(res);
|
|
324
|
+
* })
|
|
325
|
+
* .catch(err => {
|
|
326
|
+
* console.log(err);
|
|
327
|
+
* });
|
|
328
|
+
* ```
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
*
|
|
332
|
+
* #### Fetching the details of a single user using ID
|
|
333
|
+
* ```ts
|
|
334
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
335
|
+
*
|
|
336
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
337
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
338
|
+
*
|
|
339
|
+
* // Fetching the details of the User with id '1234567890'
|
|
340
|
+
* rettiwt.user.details('1234567890')
|
|
341
|
+
* .then(res => {
|
|
342
|
+
* console.log(res); # 'res' is a single tweet
|
|
343
|
+
* })
|
|
344
|
+
* .catch(err => {
|
|
345
|
+
* console.log(err);
|
|
346
|
+
* });
|
|
347
|
+
* ```
|
|
348
|
+
*/
|
|
349
|
+
public async details(id: string): Promise<User | undefined>;
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Get the details of multiple users in bulk.
|
|
353
|
+
*
|
|
354
|
+
* @param id - The list of IDs of the target users.
|
|
355
|
+
*
|
|
356
|
+
* @returns The details of the users.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
*
|
|
360
|
+
* ```ts
|
|
361
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
362
|
+
*
|
|
363
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
364
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
365
|
+
*
|
|
366
|
+
* // Fetching the details of the users with IDs '123', '456', '789'
|
|
367
|
+
* rettiwt.user.details(['123', '456', '789'])
|
|
368
|
+
* .then(res => {
|
|
369
|
+
* console.log(res); # 'res' is an array of users
|
|
370
|
+
* })
|
|
371
|
+
* .catch(err => {
|
|
372
|
+
* console.log(err);
|
|
373
|
+
* });
|
|
374
|
+
* ```
|
|
375
|
+
*/
|
|
376
|
+
public async details(id: string[]): Promise<User[]>;
|
|
377
|
+
|
|
378
|
+
public async details(id?: string | string[]): Promise<User | User[] | undefined> {
|
|
379
|
+
let resource: ResourceType;
|
|
380
|
+
|
|
381
|
+
// If details of multiple users required
|
|
382
|
+
if (Array.isArray(id)) {
|
|
383
|
+
resource = ResourceType.USER_DETAILS_BY_IDS_BULK;
|
|
384
|
+
|
|
385
|
+
// Fetching raw details
|
|
386
|
+
const response = await this.request<IUserDetailsBulkResponse>(resource, { ids: id });
|
|
387
|
+
|
|
388
|
+
// Deserializing response
|
|
389
|
+
const data = Extractors[resource](response, id);
|
|
390
|
+
|
|
391
|
+
return data;
|
|
392
|
+
}
|
|
393
|
+
// If details of single user required
|
|
394
|
+
else {
|
|
395
|
+
// If username is given
|
|
396
|
+
if (id && isNaN(Number(id))) {
|
|
397
|
+
resource = ResourceType.USER_DETAILS_BY_USERNAME;
|
|
398
|
+
if (id?.startsWith('@')) {
|
|
399
|
+
id = id.slice(1);
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
// If id is given (or not, for self details)
|
|
403
|
+
else {
|
|
404
|
+
resource = ResourceType.USER_DETAILS_BY_ID;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// If no ID is given, and not authenticated, skip
|
|
408
|
+
if (!id && !this.config.userId) {
|
|
409
|
+
return undefined;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
// Fetching raw details
|
|
413
|
+
const response = await this.request<IUserDetailsResponse>(resource, { id: id ?? this.config.userId });
|
|
414
|
+
|
|
415
|
+
// Deserializing response
|
|
416
|
+
const data = Extractors[resource](response);
|
|
417
|
+
|
|
418
|
+
return data;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* Follow a user.
|
|
424
|
+
*
|
|
425
|
+
* @param id - The ID the user to be followed.
|
|
426
|
+
*
|
|
427
|
+
* @returns Whether following was successful or not.
|
|
428
|
+
*
|
|
429
|
+
* @throws Code 108 if given user id is invalid.
|
|
430
|
+
*
|
|
431
|
+
* @example
|
|
432
|
+
*
|
|
433
|
+
* ```ts
|
|
434
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
435
|
+
*
|
|
436
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
437
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
438
|
+
*
|
|
439
|
+
* // Following the User with id '1234567890'
|
|
440
|
+
* rettiwt.user.follow('1234567890')
|
|
441
|
+
* .then(res => {
|
|
442
|
+
* console.log(res);
|
|
443
|
+
* })
|
|
444
|
+
* .catch(err => {
|
|
445
|
+
* console.log(err);
|
|
446
|
+
* });
|
|
447
|
+
* ```
|
|
448
|
+
*/
|
|
449
|
+
public async follow(id: string): Promise<boolean> {
|
|
450
|
+
const resource = ResourceType.USER_FOLLOW;
|
|
451
|
+
|
|
452
|
+
// Following the user
|
|
453
|
+
const response = await this.request<IUserFollowResponse>(ResourceType.USER_FOLLOW, { id: id });
|
|
454
|
+
|
|
455
|
+
// Deserializing the response
|
|
456
|
+
const data = Extractors[resource](response) ?? false;
|
|
457
|
+
|
|
458
|
+
return data;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* Get the followed feed of the logged in user.
|
|
463
|
+
*
|
|
464
|
+
* @param cursor - The cursor to the batch of feed items to fetch.
|
|
465
|
+
*
|
|
466
|
+
* @returns - The followed feed of the logged-in user.
|
|
467
|
+
*
|
|
468
|
+
* @example
|
|
469
|
+
*
|
|
470
|
+
* ```ts
|
|
471
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
472
|
+
*
|
|
473
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
474
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
475
|
+
*
|
|
476
|
+
* // Fetching the first 35 followed feed items of the logged-in user
|
|
477
|
+
* rettiwt.user.followed()
|
|
478
|
+
* .then(res => {
|
|
479
|
+
* console.log(res);
|
|
480
|
+
* })
|
|
481
|
+
* .catch(err => {
|
|
482
|
+
* console.log(err);
|
|
483
|
+
* });
|
|
484
|
+
* ```
|
|
485
|
+
*
|
|
486
|
+
* @remarks Always returns 35 feed items, with no way to customize the count.
|
|
487
|
+
*/
|
|
488
|
+
public async followed(cursor?: string): Promise<CursoredData<Tweet>> {
|
|
489
|
+
const resource = ResourceType.USER_FEED_FOLLOWED;
|
|
490
|
+
|
|
491
|
+
// Fetching raw list of tweets
|
|
492
|
+
const response = await this.request<IUserFollowedResponse>(resource, {
|
|
493
|
+
cursor: cursor,
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
// Deserializing response
|
|
497
|
+
const data = Extractors[resource](response);
|
|
498
|
+
|
|
499
|
+
return data;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/**
|
|
503
|
+
* Get the list followers of a user.
|
|
504
|
+
*
|
|
505
|
+
* @param id - The ID of the target user. If no ID is provided, the logged-in user's ID is used.
|
|
506
|
+
* @param count - The number of followers to fetch, must be \<= 100.
|
|
507
|
+
* @param cursor - The cursor to the batch of followers to fetch.
|
|
508
|
+
*
|
|
509
|
+
* @returns The list of users following the target user.
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
*
|
|
513
|
+
* ```ts
|
|
514
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
515
|
+
*
|
|
516
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
517
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
518
|
+
*
|
|
519
|
+
* // Fetching the first 100 followers of the User with id '1234567890'
|
|
520
|
+
* rettiwt.user.followers('1234567890')
|
|
521
|
+
* .then(res => {
|
|
522
|
+
* console.log(res);
|
|
523
|
+
* })
|
|
524
|
+
* .catch(err => {
|
|
525
|
+
* console.log(err);
|
|
526
|
+
* });
|
|
527
|
+
* ```
|
|
528
|
+
*/
|
|
529
|
+
public async followers(id?: string, count?: number, cursor?: string): Promise<CursoredData<User>> {
|
|
530
|
+
const resource = ResourceType.USER_FOLLOWERS;
|
|
531
|
+
|
|
532
|
+
// Fetching raw list of followers
|
|
533
|
+
const response = await this.request<IUserFollowersResponse>(resource, {
|
|
534
|
+
id: id ?? this.config.userId,
|
|
535
|
+
count: count,
|
|
536
|
+
cursor: cursor,
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
// Deserializing response
|
|
540
|
+
const data = Extractors[resource](response);
|
|
541
|
+
|
|
542
|
+
return data;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
/**
|
|
546
|
+
* Get the list of users who are followed by a user.
|
|
547
|
+
*
|
|
548
|
+
* @param id - The ID of the target user. If no ID is provided, the logged-in user's ID is used.
|
|
549
|
+
* @param count - The number of following to fetch, must be \<= 100.
|
|
550
|
+
* @param cursor - The cursor to the batch of following to fetch.
|
|
551
|
+
*
|
|
552
|
+
* @returns The list of users followed by the target user.
|
|
553
|
+
*
|
|
554
|
+
* @example
|
|
555
|
+
*
|
|
556
|
+
* ```ts
|
|
557
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
558
|
+
*
|
|
559
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
560
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
561
|
+
*
|
|
562
|
+
* // Fetching the first 100 following of the User with id '1234567890'
|
|
563
|
+
* rettiwt.user.following('1234567890')
|
|
564
|
+
* .then(res => {
|
|
565
|
+
* console.log(res);
|
|
566
|
+
* })
|
|
567
|
+
* .catch(err => {
|
|
568
|
+
* console.log(err);
|
|
569
|
+
* });
|
|
570
|
+
* ```
|
|
571
|
+
*/
|
|
572
|
+
public async following(id?: string, count?: number, cursor?: string): Promise<CursoredData<User>> {
|
|
573
|
+
const resource = ResourceType.USER_FOLLOWING;
|
|
574
|
+
|
|
575
|
+
// Fetching raw list of following
|
|
576
|
+
const response = await this.request<IUserFollowingResponse>(resource, {
|
|
577
|
+
id: id ?? this.config.userId,
|
|
578
|
+
count: count,
|
|
579
|
+
cursor: cursor,
|
|
580
|
+
});
|
|
581
|
+
|
|
582
|
+
// Deserializing response
|
|
583
|
+
const data = Extractors[resource](response);
|
|
584
|
+
|
|
585
|
+
return data;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
/**
|
|
589
|
+
* Get the highlighted tweets of a user.
|
|
590
|
+
*
|
|
591
|
+
* @param id - The ID of the target user. If no ID is provided, the logged-in user's ID is used.
|
|
592
|
+
* @param count - The number of followers to fetch, must be \<= 100.
|
|
593
|
+
* @param cursor - The cursor to the batch of followers to fetch.
|
|
594
|
+
*
|
|
595
|
+
* @returns The list of highlighted tweets of the target user.
|
|
596
|
+
*
|
|
597
|
+
* @example
|
|
598
|
+
*
|
|
599
|
+
* ```ts
|
|
600
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
601
|
+
*
|
|
602
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
603
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
604
|
+
*
|
|
605
|
+
* // Fetching the top 100 highlights of the User with id '1234567890'
|
|
606
|
+
* rettiwt.user.highlights('1234567890')
|
|
607
|
+
* .then(res => {
|
|
608
|
+
* console.log(res);
|
|
609
|
+
* })
|
|
610
|
+
* .catch(err => {
|
|
611
|
+
* console.log(err);
|
|
612
|
+
* });
|
|
613
|
+
* ```
|
|
614
|
+
*/
|
|
615
|
+
public async highlights(id?: string, count?: number, cursor?: string): Promise<CursoredData<Tweet>> {
|
|
616
|
+
const resource = ResourceType.USER_HIGHLIGHTS;
|
|
617
|
+
|
|
618
|
+
// Fetching raw list of highlights
|
|
619
|
+
const response = await this.request<IUserHighlightsResponse>(resource, {
|
|
620
|
+
id: id ?? this.config.userId,
|
|
621
|
+
count: count,
|
|
622
|
+
cursor: cursor,
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
// Deserializing response
|
|
626
|
+
const data = Extractors[resource](response);
|
|
627
|
+
|
|
628
|
+
return data;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Get the list of tweets liked by the logged in user.
|
|
633
|
+
*
|
|
634
|
+
* @param count - The number of likes to fetch, must be \<= 100.
|
|
635
|
+
* @param cursor - The cursor to the batch of likes to fetch.
|
|
636
|
+
*
|
|
637
|
+
* @returns The list of tweets liked by the target user.
|
|
638
|
+
*
|
|
639
|
+
* @example
|
|
640
|
+
*
|
|
641
|
+
* ```ts
|
|
642
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
643
|
+
*
|
|
644
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
645
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
646
|
+
*
|
|
647
|
+
* // Fetching the most recent 100 liked Tweets of the logged in User
|
|
648
|
+
* rettiwt.user.likes()
|
|
649
|
+
* .then(res => {
|
|
650
|
+
* console.log(res);
|
|
651
|
+
* })
|
|
652
|
+
* .catch(err => {
|
|
653
|
+
* console.log(err);
|
|
654
|
+
* });
|
|
655
|
+
* ```
|
|
656
|
+
*/
|
|
657
|
+
public async likes(count?: number, cursor?: string): Promise<CursoredData<Tweet>> {
|
|
658
|
+
const resource = ResourceType.USER_LIKES;
|
|
659
|
+
|
|
660
|
+
// Fetching raw list of likes
|
|
661
|
+
const response = await this.request<IUserLikesResponse>(resource, {
|
|
662
|
+
id: this.config.userId,
|
|
663
|
+
count: count,
|
|
664
|
+
cursor: cursor,
|
|
665
|
+
});
|
|
666
|
+
|
|
667
|
+
// Deserializing response
|
|
668
|
+
const data = Extractors[resource](response);
|
|
669
|
+
|
|
670
|
+
return data;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Get the list of of the the logged in user. Includes both followed and owned.
|
|
675
|
+
*
|
|
676
|
+
* @param count - The number of lists to fetch, must be \<= 100.
|
|
677
|
+
* @param cursor - The cursor to the batch of likes to fetch.
|
|
678
|
+
*
|
|
679
|
+
* @returns The list of tweets liked by the target user.
|
|
680
|
+
*
|
|
681
|
+
* @example
|
|
682
|
+
*
|
|
683
|
+
* ```ts
|
|
684
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
685
|
+
*
|
|
686
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
687
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
688
|
+
*
|
|
689
|
+
* // Fetching the first 100 Lists of the logged in User
|
|
690
|
+
* rettiwt.user.lists()
|
|
691
|
+
* .then(res => {
|
|
692
|
+
* console.log(res);
|
|
693
|
+
* })
|
|
694
|
+
* .catch(err => {
|
|
695
|
+
* console.log(err);
|
|
696
|
+
* });
|
|
697
|
+
* ```
|
|
698
|
+
*/
|
|
699
|
+
public async lists(count?: number, cursor?: string): Promise<CursoredData<List>> {
|
|
700
|
+
const resource = ResourceType.USER_LISTS;
|
|
701
|
+
|
|
702
|
+
// Fetching raw list of lists
|
|
703
|
+
const response = await this.request<IUserListsResponse>(resource, {
|
|
704
|
+
id: this.config.userId,
|
|
705
|
+
count: count,
|
|
706
|
+
cursor: cursor,
|
|
707
|
+
});
|
|
708
|
+
|
|
709
|
+
// Deserializing response
|
|
710
|
+
const data = Extractors[resource](response);
|
|
711
|
+
|
|
712
|
+
return data;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Get the media timeline of a user.
|
|
717
|
+
*
|
|
718
|
+
* @param id - The ID of the target user. If no ID is provided, the logged-in user's ID is used.
|
|
719
|
+
* @param count - The number of media to fetch, must be \<= 100.
|
|
720
|
+
* @param cursor - The cursor to the batch of media to fetch
|
|
721
|
+
*
|
|
722
|
+
* @returns The media timeline of the target user.
|
|
723
|
+
*
|
|
724
|
+
* @example
|
|
725
|
+
*
|
|
726
|
+
* ```ts
|
|
727
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
728
|
+
*
|
|
729
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
730
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
731
|
+
*
|
|
732
|
+
* // Fetching the first 100 timeline media tweets of the User with id '1234567890'
|
|
733
|
+
* rettiwt.user.timeline('1234567890')
|
|
734
|
+
* .then(res => {
|
|
735
|
+
* console.log(res);
|
|
736
|
+
* })
|
|
737
|
+
* .catch(err => {
|
|
738
|
+
* console.log(err);
|
|
739
|
+
* });
|
|
740
|
+
* ```
|
|
741
|
+
*/
|
|
742
|
+
public async media(id?: string, count?: number, cursor?: string): Promise<CursoredData<Tweet>> {
|
|
743
|
+
const resource = ResourceType.USER_MEDIA;
|
|
744
|
+
|
|
745
|
+
// Fetching raw list of media
|
|
746
|
+
const response = await this.request<IUserMediaResponse>(resource, {
|
|
747
|
+
id: id ?? this.config.userId,
|
|
748
|
+
count: count,
|
|
749
|
+
cursor: cursor,
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
// Deserializing response
|
|
753
|
+
const data = Extractors[resource](response);
|
|
754
|
+
|
|
755
|
+
return data;
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
/**
|
|
759
|
+
* Stream notifications of the logged in user in pseudo real-time.
|
|
760
|
+
*
|
|
761
|
+
* @param pollingInterval - The interval in milliseconds to poll for new tweets. Default interval is 60000 ms.
|
|
762
|
+
*
|
|
763
|
+
* @returns An async generator that yields new notifications as they are received.
|
|
764
|
+
*
|
|
765
|
+
* @example
|
|
766
|
+
*
|
|
767
|
+
* ```ts
|
|
768
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
769
|
+
*
|
|
770
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
771
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
772
|
+
*
|
|
773
|
+
* // Creating a function that streams all new notifications
|
|
774
|
+
* async function streamNotifications() {
|
|
775
|
+
* try {
|
|
776
|
+
* // Awaiting for the notifications returned by the AsyncGenerator returned by the method
|
|
777
|
+
* for await (const notification of rettiwt.user.notifications(5000)) {
|
|
778
|
+
* console.log(notification.message);
|
|
779
|
+
* }
|
|
780
|
+
* }
|
|
781
|
+
* catch (err) {
|
|
782
|
+
* console.log(err);
|
|
783
|
+
* }
|
|
784
|
+
* }
|
|
785
|
+
*
|
|
786
|
+
* // Calling the function
|
|
787
|
+
* streamNotifications();
|
|
788
|
+
* ```
|
|
789
|
+
*/
|
|
790
|
+
public async *notifications(pollingInterval = 60000): AsyncGenerator<Notification> {
|
|
791
|
+
const resource = ResourceType.USER_NOTIFICATIONS;
|
|
792
|
+
|
|
793
|
+
/** Whether it's the first batch of notifications or not. */
|
|
794
|
+
let first = true;
|
|
795
|
+
|
|
796
|
+
/** The cursor to the last notification received. */
|
|
797
|
+
let cursor: string | undefined = undefined;
|
|
798
|
+
|
|
799
|
+
while (true) {
|
|
800
|
+
// Pause execution for the specified polling interval before proceeding to the next iteration
|
|
801
|
+
await new Promise((resolve) => setTimeout(resolve, pollingInterval));
|
|
802
|
+
|
|
803
|
+
// Get the batch of notifications after the given cursor
|
|
804
|
+
const response = await this.request<IUserNotificationsResponse>(resource, {
|
|
805
|
+
count: 40,
|
|
806
|
+
cursor: cursor,
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
// Deserializing response
|
|
810
|
+
const notifications = Extractors[resource](response);
|
|
811
|
+
|
|
812
|
+
// Sorting the notifications by time, from oldest to recent
|
|
813
|
+
notifications.list.sort((a, b) => new Date(a.receivedAt).valueOf() - new Date(b.receivedAt).valueOf());
|
|
814
|
+
|
|
815
|
+
// If not first batch, return new notifications
|
|
816
|
+
if (!first) {
|
|
817
|
+
// Yield the notifications
|
|
818
|
+
for (const notification of notifications.list) {
|
|
819
|
+
yield notification;
|
|
820
|
+
}
|
|
821
|
+
}
|
|
822
|
+
// Else do nothing, do nothing since first batch is notifications that have already been received
|
|
823
|
+
else {
|
|
824
|
+
first = false;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
cursor = notifications.next;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
/**
|
|
832
|
+
* Get the recommended feed of the logged in user.
|
|
833
|
+
*
|
|
834
|
+
* @param cursor - The cursor to the batch of feed items to fetch.
|
|
835
|
+
*
|
|
836
|
+
* @returns - The recommended feed of the logged-in user.
|
|
837
|
+
*
|
|
838
|
+
* @example
|
|
839
|
+
*
|
|
840
|
+
* ```ts
|
|
841
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
842
|
+
*
|
|
843
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
844
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
845
|
+
*
|
|
846
|
+
* // Fetching the first 35 recommended feed items of the logged-in user
|
|
847
|
+
* rettiwt.user.recommended()
|
|
848
|
+
* .then(res => {
|
|
849
|
+
* console.log(res);
|
|
850
|
+
* })
|
|
851
|
+
* .catch(err => {
|
|
852
|
+
* console.log(err);
|
|
853
|
+
* });
|
|
854
|
+
* ```
|
|
855
|
+
*
|
|
856
|
+
* @remarks Always returns 35 feed items, with no way to customize the count.
|
|
857
|
+
*/
|
|
858
|
+
public async recommended(cursor?: string): Promise<CursoredData<Tweet>> {
|
|
859
|
+
const resource = ResourceType.USER_FEED_RECOMMENDED;
|
|
860
|
+
|
|
861
|
+
// Fetching raw list of tweets
|
|
862
|
+
const response = await this.request<IUserRecommendedResponse>(resource, {
|
|
863
|
+
cursor: cursor,
|
|
864
|
+
});
|
|
865
|
+
|
|
866
|
+
// Deserializing response
|
|
867
|
+
const data = Extractors[resource](response);
|
|
868
|
+
|
|
869
|
+
return data;
|
|
870
|
+
}
|
|
871
|
+
|
|
872
|
+
/**
|
|
873
|
+
* Get the reply timeline of a user.
|
|
874
|
+
*
|
|
875
|
+
* @param id - The ID of the target user. If no ID is provided, the logged-in user's ID is used.
|
|
876
|
+
* @param count - The number of replies to fetch, must be \<= 20.
|
|
877
|
+
* @param cursor - The cursor to the batch of replies to fetch.
|
|
878
|
+
*
|
|
879
|
+
* @returns The reply timeline of the target user.
|
|
880
|
+
*
|
|
881
|
+
* @example
|
|
882
|
+
*
|
|
883
|
+
* ```ts
|
|
884
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
885
|
+
*
|
|
886
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
887
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
888
|
+
*
|
|
889
|
+
* // Fetching the first 100 timeline replies of the User with id '1234567890'
|
|
890
|
+
* rettiwt.user.replies('1234567890')
|
|
891
|
+
* .then(res => {
|
|
892
|
+
* console.log(res);
|
|
893
|
+
* })
|
|
894
|
+
* .catch(err => {
|
|
895
|
+
* console.log(err);
|
|
896
|
+
* });
|
|
897
|
+
* ```
|
|
898
|
+
*
|
|
899
|
+
* @remarks
|
|
900
|
+
*
|
|
901
|
+
* If the target user has a pinned tweet, the returned reply timeline has one item extra and this is always the pinned tweet.
|
|
902
|
+
*/
|
|
903
|
+
public async replies(id?: string, count?: number, cursor?: string): Promise<CursoredData<Tweet>> {
|
|
904
|
+
const resource = ResourceType.USER_TIMELINE_AND_REPLIES;
|
|
905
|
+
|
|
906
|
+
// Fetching raw list of replies
|
|
907
|
+
const response = await this.request<IUserTweetsAndRepliesResponse>(resource, {
|
|
908
|
+
id: id ?? this.config.userId,
|
|
909
|
+
count: count,
|
|
910
|
+
cursor: cursor,
|
|
911
|
+
});
|
|
912
|
+
|
|
913
|
+
// Deserializing response
|
|
914
|
+
const data = Extractors[resource](response);
|
|
915
|
+
|
|
916
|
+
return data;
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/**
|
|
920
|
+
* Search for a username.
|
|
921
|
+
*
|
|
922
|
+
* @param userName - The username to search for.
|
|
923
|
+
* @param count - The number of results to fetch, must be \<= 20.
|
|
924
|
+
* @param cursor - The cursor to the batch of results to fetch.
|
|
925
|
+
*
|
|
926
|
+
* @returns The list of users that match the given username.
|
|
927
|
+
*
|
|
928
|
+
* @example
|
|
929
|
+
*
|
|
930
|
+
* ```ts
|
|
931
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
932
|
+
*
|
|
933
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
934
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
935
|
+
*
|
|
936
|
+
* // Fetching the top 5 matching users for the username 'user1'
|
|
937
|
+
* rettiwt.user.search('user1')
|
|
938
|
+
* .then(res => {
|
|
939
|
+
* console.log(res);
|
|
940
|
+
* })
|
|
941
|
+
* .catch(err => {
|
|
942
|
+
* console.log(err);
|
|
943
|
+
* });
|
|
944
|
+
* ```
|
|
945
|
+
*/
|
|
946
|
+
public async search(userName: string, count?: number, cursor?: string): Promise<CursoredData<User>> {
|
|
947
|
+
const resource = ResourceType.USER_SEARCH;
|
|
948
|
+
|
|
949
|
+
// Fetching raw list of filtered tweets
|
|
950
|
+
const response = await this.request<IUserSearchResponse>(resource, {
|
|
951
|
+
id: userName,
|
|
952
|
+
count: count,
|
|
953
|
+
cursor: cursor,
|
|
954
|
+
});
|
|
955
|
+
|
|
956
|
+
// Deserializing response
|
|
957
|
+
const data = Extractors[resource](response);
|
|
958
|
+
|
|
959
|
+
return data;
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
/**
|
|
963
|
+
* Get the list of subscriptions of a user.
|
|
964
|
+
*
|
|
965
|
+
* @param id - The ID of the target user. If no ID is provided, the logged-in user's ID is used.
|
|
966
|
+
* @param count - The number of subscriptions to fetch, must be \<= 100.
|
|
967
|
+
* @param cursor - The cursor to the batch of subscriptions to fetch.
|
|
968
|
+
*
|
|
969
|
+
* @returns The list of subscriptions by the target user.
|
|
970
|
+
*
|
|
971
|
+
* @example
|
|
972
|
+
*
|
|
973
|
+
* ```ts
|
|
974
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
975
|
+
*
|
|
976
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
977
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
978
|
+
*
|
|
979
|
+
* // Fetching the first 100 subscriptions of the User with id '1234567890'
|
|
980
|
+
* rettiwt.user.subscriptions('1234567890')
|
|
981
|
+
* .then(res => {
|
|
982
|
+
* console.log(res);
|
|
983
|
+
* })
|
|
984
|
+
* .catch(err => {
|
|
985
|
+
* console.log(err);
|
|
986
|
+
* });
|
|
987
|
+
* ```
|
|
988
|
+
*/
|
|
989
|
+
public async subscriptions(id?: string, count?: number, cursor?: string): Promise<CursoredData<User>> {
|
|
990
|
+
const resource = ResourceType.USER_SUBSCRIPTIONS;
|
|
991
|
+
|
|
992
|
+
// Fetching raw list of subscriptions
|
|
993
|
+
const response = await this.request<IUserSubscriptionsResponse>(resource, {
|
|
994
|
+
id: id ?? this.config.userId,
|
|
995
|
+
count: count,
|
|
996
|
+
cursor: cursor,
|
|
997
|
+
});
|
|
998
|
+
|
|
999
|
+
// Deserializing response
|
|
1000
|
+
const data = Extractors[resource](response);
|
|
1001
|
+
|
|
1002
|
+
return data;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
/**
|
|
1006
|
+
* Get the tweet timeline of a user.
|
|
1007
|
+
*
|
|
1008
|
+
* @param id - The ID of the target user. If no ID is provided, the logged-in user's ID is used.
|
|
1009
|
+
* @param count - The number of timeline items to fetch, must be \<= 20.
|
|
1010
|
+
* @param cursor - The cursor to the batch of timeline items to fetch.
|
|
1011
|
+
*
|
|
1012
|
+
* @returns The timeline of the target user.
|
|
1013
|
+
*
|
|
1014
|
+
* @example
|
|
1015
|
+
*
|
|
1016
|
+
* ```ts
|
|
1017
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
1018
|
+
*
|
|
1019
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
1020
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
1021
|
+
*
|
|
1022
|
+
* // Fetching the first 20 timeline tweets of the User with id '1234567890'
|
|
1023
|
+
* rettiwt.user.timeline('1234567890')
|
|
1024
|
+
* .then(res => {
|
|
1025
|
+
* console.log(res);
|
|
1026
|
+
* })
|
|
1027
|
+
* .catch(err => {
|
|
1028
|
+
* console.log(err);
|
|
1029
|
+
* });
|
|
1030
|
+
* ```
|
|
1031
|
+
*
|
|
1032
|
+
* @remarks
|
|
1033
|
+
*
|
|
1034
|
+
* - If the target user has a pinned tweet, the returned timeline has one item extra and this is always the pinned tweet.
|
|
1035
|
+
* - If timeline is fetched without authenticating, then the most popular tweets of the target user are returned instead.
|
|
1036
|
+
*/
|
|
1037
|
+
public async timeline(id?: string, count?: number, cursor?: string): Promise<CursoredData<Tweet>> {
|
|
1038
|
+
const resource = ResourceType.USER_TIMELINE;
|
|
1039
|
+
|
|
1040
|
+
// Fetching raw list of tweets
|
|
1041
|
+
const response = await this.request<IUserTweetsResponse>(resource, {
|
|
1042
|
+
id: id ?? this.config.userId,
|
|
1043
|
+
count: count,
|
|
1044
|
+
cursor: cursor,
|
|
1045
|
+
});
|
|
1046
|
+
|
|
1047
|
+
// Deserializing response
|
|
1048
|
+
const data = Extractors[resource](response);
|
|
1049
|
+
|
|
1050
|
+
return data;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/**
|
|
1054
|
+
* Unfollow a user.
|
|
1055
|
+
*
|
|
1056
|
+
* @param id - The ID the user to be unfollowed.
|
|
1057
|
+
*
|
|
1058
|
+
* @returns Whether unfollowing was successful or not.
|
|
1059
|
+
*
|
|
1060
|
+
* @example
|
|
1061
|
+
*
|
|
1062
|
+
* ```ts
|
|
1063
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
1064
|
+
*
|
|
1065
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
1066
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
1067
|
+
*
|
|
1068
|
+
* // Unfollowing the User with id '12345678'
|
|
1069
|
+
* rettiwt.user.unfollow('12345678')
|
|
1070
|
+
* .then(res => {
|
|
1071
|
+
* console.log(res);
|
|
1072
|
+
* })
|
|
1073
|
+
* .catch(err => {
|
|
1074
|
+
* console.log(err);
|
|
1075
|
+
* });
|
|
1076
|
+
* ```
|
|
1077
|
+
*/
|
|
1078
|
+
public async unfollow(id: string): Promise<boolean> {
|
|
1079
|
+
const resource = ResourceType.USER_UNFOLLOW;
|
|
1080
|
+
|
|
1081
|
+
// Unfollowing the user
|
|
1082
|
+
const response = await this.request<IUserUnfollowResponse>(ResourceType.USER_UNFOLLOW, { id: id });
|
|
1083
|
+
|
|
1084
|
+
// Deserializing the response
|
|
1085
|
+
const data = Extractors[resource](response) ?? false;
|
|
1086
|
+
|
|
1087
|
+
return data;
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
/**
|
|
1091
|
+
* Update the logged in user's profile.
|
|
1092
|
+
*
|
|
1093
|
+
* @param options - The profile update options.
|
|
1094
|
+
*
|
|
1095
|
+
* @returns Whether the profile update was successful or not.
|
|
1096
|
+
*
|
|
1097
|
+
* @example
|
|
1098
|
+
*
|
|
1099
|
+
* #### Updating only the display name
|
|
1100
|
+
* ```ts
|
|
1101
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
1102
|
+
*
|
|
1103
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
1104
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
1105
|
+
*
|
|
1106
|
+
* // Updating the display name of the logged in user
|
|
1107
|
+
* rettiwt.user.updateProfile({ name: 'New Display Name' })
|
|
1108
|
+
* .then(res => {
|
|
1109
|
+
* console.log(res);
|
|
1110
|
+
* })
|
|
1111
|
+
* .catch(err => {
|
|
1112
|
+
* console.log(err);
|
|
1113
|
+
* });
|
|
1114
|
+
* ```
|
|
1115
|
+
*
|
|
1116
|
+
* @example
|
|
1117
|
+
*
|
|
1118
|
+
* #### Updating multiple profile fields
|
|
1119
|
+
* ```ts
|
|
1120
|
+
* import { Rettiwt } from 'rettiwt-api';
|
|
1121
|
+
*
|
|
1122
|
+
* // Creating a new Rettiwt instance using the given 'API_KEY'
|
|
1123
|
+
* const rettiwt = new Rettiwt({ apiKey: API_KEY });
|
|
1124
|
+
*
|
|
1125
|
+
* // Updating multiple profile fields
|
|
1126
|
+
* rettiwt.user.updateProfile({
|
|
1127
|
+
* name: 'New Display Name',
|
|
1128
|
+
* location: 'Istanbul',
|
|
1129
|
+
* description: 'Hello world!',
|
|
1130
|
+
* url: 'https://example.com'
|
|
1131
|
+
* })
|
|
1132
|
+
* .then(res => {
|
|
1133
|
+
* console.log(res);
|
|
1134
|
+
* })
|
|
1135
|
+
* .catch(err => {
|
|
1136
|
+
* console.log(err);
|
|
1137
|
+
* });
|
|
1138
|
+
* ```
|
|
1139
|
+
*/
|
|
1140
|
+
public async updateProfile(options: IProfileUpdateOptions): Promise<boolean> {
|
|
1141
|
+
const resource = ResourceType.USER_PROFILE_UPDATE;
|
|
1142
|
+
|
|
1143
|
+
// Validating the options
|
|
1144
|
+
const validatedOptions = new ProfileUpdateOptions(options);
|
|
1145
|
+
|
|
1146
|
+
// Updating the profile
|
|
1147
|
+
const response = await this.request<IUserProfileUpdateResponse>(resource, { profileOptions: validatedOptions });
|
|
1148
|
+
|
|
1149
|
+
// Deserializing the response
|
|
1150
|
+
const data = Extractors[resource](response) ?? false;
|
|
1151
|
+
|
|
1152
|
+
return data;
|
|
1153
|
+
}
|
|
1154
|
+
}
|