@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.
Files changed (165) hide show
  1. package/.eslintrc.js +166 -0
  2. package/.gitattributes +3 -0
  3. package/.github/FUNDING.yml +4 -0
  4. package/.github/ISSUE_TEMPLATE/bug-report.yml +57 -0
  5. package/.github/ISSUE_TEMPLATE/feature-request.yml +20 -0
  6. package/.github/ISSUE_TEMPLATE/question.yml +15 -0
  7. package/.github/PULL_REQUEST_TEMPLATE.md +32 -0
  8. package/.github/workflows/ci.yml +32 -0
  9. package/.github/workflows/publish.yml +23 -0
  10. package/.nvmrc +1 -0
  11. package/.prettierignore +3 -0
  12. package/.prettierrc +13 -0
  13. package/LICENSE +21 -0
  14. package/README.md +566 -0
  15. package/dist/cli.js +43 -0
  16. package/eslint.config.mjs +17 -0
  17. package/package.json +50 -0
  18. package/src/Rettiwt.ts +97 -0
  19. package/src/cli.ts +48 -0
  20. package/src/collections/Extractors.ts +155 -0
  21. package/src/collections/Groups.ts +81 -0
  22. package/src/collections/Requests.ts +89 -0
  23. package/src/collections/Tweet.ts +17 -0
  24. package/src/commands/DirectMessage.ts +62 -0
  25. package/src/commands/List.ts +90 -0
  26. package/src/commands/Tweet.ts +437 -0
  27. package/src/commands/User.ts +367 -0
  28. package/src/enums/Api.ts +10 -0
  29. package/src/enums/Authentication.ts +10 -0
  30. package/src/enums/Data.ts +13 -0
  31. package/src/enums/Logging.ts +14 -0
  32. package/src/enums/Media.ts +10 -0
  33. package/src/enums/Notification.ts +12 -0
  34. package/src/enums/Resource.ts +69 -0
  35. package/src/enums/Tweet.ts +8 -0
  36. package/src/enums/raw/Analytics.ts +32 -0
  37. package/src/enums/raw/Media.ts +10 -0
  38. package/src/enums/raw/Notification.ts +11 -0
  39. package/src/enums/raw/Tweet.ts +20 -0
  40. package/src/helper/CliUtils.ts +17 -0
  41. package/src/helper/JsonUtils.ts +70 -0
  42. package/src/index.ts +128 -0
  43. package/src/models/RettiwtConfig.ts +101 -0
  44. package/src/models/args/FetchArgs.ts +169 -0
  45. package/src/models/args/PostArgs.ts +93 -0
  46. package/src/models/args/ProfileArgs.ts +68 -0
  47. package/src/models/auth/AuthCookie.ts +58 -0
  48. package/src/models/auth/AuthCredential.ts +83 -0
  49. package/src/models/data/Analytics.ts +97 -0
  50. package/src/models/data/BookmarkFolder.ts +73 -0
  51. package/src/models/data/Conversation.ts +344 -0
  52. package/src/models/data/CursoredData.ts +64 -0
  53. package/src/models/data/DirectMessage.ts +335 -0
  54. package/src/models/data/Inbox.ts +124 -0
  55. package/src/models/data/List.ts +113 -0
  56. package/src/models/data/Notification.ts +84 -0
  57. package/src/models/data/Tweet.ts +388 -0
  58. package/src/models/data/User.ts +187 -0
  59. package/src/models/errors/TwitterError.ts +65 -0
  60. package/src/models/params/Variables.ts +62 -0
  61. package/src/requests/DirectMessage.ts +229 -0
  62. package/src/requests/List.ts +203 -0
  63. package/src/requests/Media.ts +67 -0
  64. package/src/requests/Tweet.ts +607 -0
  65. package/src/requests/User.ts +1191 -0
  66. package/src/services/internal/AuthService.ts +115 -0
  67. package/src/services/internal/ErrorService.ts +41 -0
  68. package/src/services/internal/LogService.ts +34 -0
  69. package/src/services/public/DirectMessageService.ts +159 -0
  70. package/src/services/public/FetcherService.ts +366 -0
  71. package/src/services/public/ListService.ts +241 -0
  72. package/src/services/public/TweetService.ts +886 -0
  73. package/src/services/public/UserService.ts +1154 -0
  74. package/src/types/ErrorHandler.ts +13 -0
  75. package/src/types/Fetch.ts +3 -0
  76. package/src/types/RettiwtConfig.ts +48 -0
  77. package/src/types/args/FetchArgs.ts +233 -0
  78. package/src/types/args/PostArgs.ts +142 -0
  79. package/src/types/args/ProfileArgs.ts +33 -0
  80. package/src/types/auth/AuthCookie.ts +22 -0
  81. package/src/types/auth/AuthCredential.ts +28 -0
  82. package/src/types/auth/TransactionHeader.ts +8 -0
  83. package/src/types/data/Analytics.ts +58 -0
  84. package/src/types/data/BookmarkFolder.ts +12 -0
  85. package/src/types/data/Conversation.ts +44 -0
  86. package/src/types/data/CursoredData.ts +24 -0
  87. package/src/types/data/DirectMessage.ts +33 -0
  88. package/src/types/data/Inbox.ts +23 -0
  89. package/src/types/data/List.ts +33 -0
  90. package/src/types/data/Notification.ts +26 -0
  91. package/src/types/data/Tweet.ts +99 -0
  92. package/src/types/data/User.ts +54 -0
  93. package/src/types/errors/TwitterError.ts +37 -0
  94. package/src/types/params/Variables.ts +41 -0
  95. package/src/types/raw/base/Analytic.ts +32 -0
  96. package/src/types/raw/base/BookmarkFolder.ts +12 -0
  97. package/src/types/raw/base/Cursor.ts +13 -0
  98. package/src/types/raw/base/Error.ts +38 -0
  99. package/src/types/raw/base/LimitedVisibilityTweet.ts +40 -0
  100. package/src/types/raw/base/List.ts +50 -0
  101. package/src/types/raw/base/Media.ts +53 -0
  102. package/src/types/raw/base/Message.ts +22 -0
  103. package/src/types/raw/base/Notification.ts +66 -0
  104. package/src/types/raw/base/Space.ts +35 -0
  105. package/src/types/raw/base/Tweet.ts +139 -0
  106. package/src/types/raw/base/User.ts +182 -0
  107. package/src/types/raw/composite/DataResult.ts +8 -0
  108. package/src/types/raw/composite/TimelineList.ts +10 -0
  109. package/src/types/raw/composite/TimelineTweet.ts +14 -0
  110. package/src/types/raw/composite/TimelineUser.ts +13 -0
  111. package/src/types/raw/dm/Conversation.ts +59 -0
  112. package/src/types/raw/dm/InboxInitial.ts +155 -0
  113. package/src/types/raw/dm/InboxTimeline.ts +301 -0
  114. package/src/types/raw/dm/UserUpdates.ts +46 -0
  115. package/src/types/raw/generic/Response.ts +10 -0
  116. package/src/types/raw/list/AddMember.ts +175 -0
  117. package/src/types/raw/list/Details.ts +176 -0
  118. package/src/types/raw/list/Members.ts +154 -0
  119. package/src/types/raw/list/RemoveMember.ts +174 -0
  120. package/src/types/raw/list/Tweets.ts +2296 -0
  121. package/src/types/raw/media/FinalizeUpload.ts +20 -0
  122. package/src/types/raw/media/InitalizeUpload.ts +12 -0
  123. package/src/types/raw/media/LiveVideoStream.ts +21 -0
  124. package/src/types/raw/space/Details.ts +359 -0
  125. package/src/types/raw/tweet/Bookmark.ts +14 -0
  126. package/src/types/raw/tweet/Details.ts +210 -0
  127. package/src/types/raw/tweet/DetailsBulk.ts +338 -0
  128. package/src/types/raw/tweet/Like.ts +14 -0
  129. package/src/types/raw/tweet/Likers.ts +200 -0
  130. package/src/types/raw/tweet/Post.ts +150 -0
  131. package/src/types/raw/tweet/Replies.ts +539 -0
  132. package/src/types/raw/tweet/Retweet.ts +31 -0
  133. package/src/types/raw/tweet/Retweeters.ts +208 -0
  134. package/src/types/raw/tweet/Schedule.ts +18 -0
  135. package/src/types/raw/tweet/Search.ts +597 -0
  136. package/src/types/raw/tweet/Unbookmark.ts +14 -0
  137. package/src/types/raw/tweet/Unlike.ts +14 -0
  138. package/src/types/raw/tweet/Unpost.ts +20 -0
  139. package/src/types/raw/tweet/Unretweet.ts +31 -0
  140. package/src/types/raw/tweet/Unschedule.ts +14 -0
  141. package/src/types/raw/user/Affiliates.ts +179 -0
  142. package/src/types/raw/user/Analytics.ts +23 -0
  143. package/src/types/raw/user/BookmarkFolderTweets.ts +53 -0
  144. package/src/types/raw/user/BookmarkFolders.ts +41 -0
  145. package/src/types/raw/user/Bookmarks.ts +637 -0
  146. package/src/types/raw/user/Details.ts +185 -0
  147. package/src/types/raw/user/DetailsBulk.ts +104 -0
  148. package/src/types/raw/user/Follow.ts +280 -0
  149. package/src/types/raw/user/Followed.ts +1942 -0
  150. package/src/types/raw/user/Followers.ts +215 -0
  151. package/src/types/raw/user/Following.ts +215 -0
  152. package/src/types/raw/user/Highlights.ts +1287 -0
  153. package/src/types/raw/user/Likes.ts +1254 -0
  154. package/src/types/raw/user/Lists.ts +378 -0
  155. package/src/types/raw/user/Media.ts +1738 -0
  156. package/src/types/raw/user/Notifications.ts +499 -0
  157. package/src/types/raw/user/ProfileUpdate.ts +80 -0
  158. package/src/types/raw/user/Recommended.ts +2319 -0
  159. package/src/types/raw/user/Scheduled.ts +37 -0
  160. package/src/types/raw/user/Search.ts +230 -0
  161. package/src/types/raw/user/Subscriptions.ts +176 -0
  162. package/src/types/raw/user/Tweets.ts +1254 -0
  163. package/src/types/raw/user/TweetsAndReplies.ts +1254 -0
  164. package/src/types/raw/user/Unfollow.ts +280 -0
  165. package/tsconfig.json +97 -0
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@glagan/rettiwt-api",
3
+ "version": "7.0.0",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "description": "An API for fetching data from TwitterAPI, without any rate limits!",
7
+ "bin": {
8
+ "rettiwt": "dist/cli.js"
9
+ },
10
+ "scripts": {
11
+ "build": "bun tsc",
12
+ "prepare": "bun tsc",
13
+ "format": "prettier --write .",
14
+ "format:check": "prettier --check .",
15
+ "lint": "eslint --max-warnings 0 --fix .",
16
+ "lint:check": "eslint --max-warnings 0 ."
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/Glagan/Rettiwt-API.git"
21
+ },
22
+ "author": {
23
+ "email": "rishikantsahu181@gmail.com",
24
+ "name": "Rishikant Sahu"
25
+ },
26
+ "license": "ISC",
27
+ "bugs": {
28
+ "url": "https://github.com/Glagan/Rettiwt-API/issues"
29
+ },
30
+ "homepage": "https://rishikant181.github.io/Rettiwt-API/",
31
+ "devDependencies": {
32
+ "@types/cookiejar": "^2.1.5",
33
+ "@types/jsdom": "^27.0.0",
34
+ "@types/node": "^22.13.1",
35
+ "@typescript-eslint/eslint-plugin": "^8.24.0",
36
+ "@typescript-eslint/parser": "^8.24.0",
37
+ "eslint": "^9.20.1",
38
+ "eslint-plugin-import": "^2.31.0",
39
+ "prettier": "^3.5.1",
40
+ "typescript": "^5.7.3"
41
+ },
42
+ "dependencies": {
43
+ "commander": "^14.0.2",
44
+ "cookiejar": "^2.1.4",
45
+ "https-proxy-agent": "^7.0.6",
46
+ "jsdom": "^27.2.0",
47
+ "ofetch": "^1.5.1",
48
+ "x-client-transaction-id": "^0.1.9"
49
+ }
50
+ }
package/src/Rettiwt.ts ADDED
@@ -0,0 +1,97 @@
1
+ import { RettiwtConfig } from './models/RettiwtConfig';
2
+ import { DirectMessageService } from './services/public/DirectMessageService';
3
+ import { ListService } from './services/public/ListService';
4
+ import { TweetService } from './services/public/TweetService';
5
+ import { UserService } from './services/public/UserService';
6
+ import { IRettiwtConfig } from './types/RettiwtConfig';
7
+
8
+ /**
9
+ * The class for accessing Twitter API.
10
+ *
11
+ * The created Rettiwt instance can be configured by passing in a configuration object to the constructor.
12
+ *
13
+ * For details regarding the available configuration options, refer to {@link IRettiwtConfig}
14
+ *
15
+ * @example Creating a Rettiwt instance with 'guest' authentication:
16
+ * ```
17
+ * import { Rettiwt } from 'rettiwt-api';
18
+ *
19
+ * // Creating a new Rettiwt instance
20
+ * const rettiwt = new Rettiwt();
21
+ * ```
22
+ *
23
+ * @example Creating a Rettiwt instance with 'guest' authentication, using a pre-generated guest key:
24
+ * ```
25
+ * import { Rettiwt } from 'rettiwt-api';
26
+ *
27
+ * // Creating a new Rettiwt instance
28
+ * const rettiwt = new Rettiwt({ guestKey: 'GUEST_KEY' });
29
+ * ```
30
+ *
31
+ * @example Creating a Rettiwt instance with 'user' authentication:
32
+ * ```
33
+ * import { Rettiwt } from 'rettiwt-api';
34
+ *
35
+ * // Creating a new Rettiwt instance
36
+ * const rettiwt = new Rettiwt({ apiKey: 'API_KEY' });
37
+ * ```
38
+ *
39
+ * @example Creating a Rettiwt instance with 'user'authentication, along with enabling debug logs and using a proxy:
40
+ * ```
41
+ * import { Rettiwt } from 'rettiwt-api';
42
+ *
43
+ * // Creating a new Rettiwt instance
44
+ * const rettiwt = new Rettiwt({ apiKey: 'API_KEY', logging: true, proxyUrl: 'URL_TO_PROXY_SERVER' });
45
+ * ```
46
+ *
47
+ * @public
48
+ */
49
+ export class Rettiwt {
50
+ /** The configuration for Rettiwt. */
51
+ private _config: RettiwtConfig;
52
+
53
+ /** The instance used to fetch data related to direct messages. */
54
+ public dm: DirectMessageService;
55
+
56
+ /** The instance used to fetch data related to lists. */
57
+ public list: ListService;
58
+
59
+ /** The instance used to fetch data related to tweets. */
60
+ public tweet: TweetService;
61
+
62
+ /** The instance used to fetch data related to users. */
63
+ public user: UserService;
64
+
65
+ /**
66
+ * Initializes a new Rettiwt instance using the given api key.
67
+ *
68
+ * @param config - The config object for configuring the Rettiwt instance.
69
+ */
70
+ public constructor(config?: IRettiwtConfig) {
71
+ this._config = new RettiwtConfig(config);
72
+ this.dm = new DirectMessageService(this._config);
73
+ this.list = new ListService(this._config);
74
+ this.tweet = new TweetService(this._config);
75
+ this.user = new UserService(this._config);
76
+ }
77
+
78
+ /** Get the current API key associated with this instance. */
79
+ public get apiKey(): string | undefined {
80
+ return this._config.apiKey;
81
+ }
82
+
83
+ /** Set the API key for the current instance. */
84
+ public set apiKey(apiKey: string | undefined) {
85
+ this._config.apiKey = apiKey;
86
+ }
87
+
88
+ /** Set the custom headers for the current instance. */
89
+ public set headers(headers: { [key: string]: string }) {
90
+ this._config.headers = headers;
91
+ }
92
+
93
+ /** Set the proxy URL for the current instance. */
94
+ public set proxyUrl(proxyUrl: URL) {
95
+ this._config.proxyUrl = proxyUrl;
96
+ }
97
+ }
package/src/cli.ts ADDED
@@ -0,0 +1,48 @@
1
+ #! /usr/bin/env node
2
+
3
+ import { createCommand } from 'commander';
4
+
5
+ import dm from './commands/DirectMessage';
6
+ import list from './commands/List';
7
+ import tweet from './commands/Tweet';
8
+ import user from './commands/User';
9
+ import { Rettiwt } from './Rettiwt';
10
+
11
+ // Creating a new commandline program
12
+ const Program = createCommand('rettiwt')
13
+ .description('A CLI tool for accessing the Twitter API for free!')
14
+ .passThroughOptions()
15
+ .enablePositionalOptions();
16
+
17
+ // Adding options
18
+ Program.option('-k, --key <string>', 'The API key to use for authentication')
19
+ .option('-l, --log', 'Enable logging to console')
20
+ .option('-p, --proxy <string>', 'The URL to the proxy to use')
21
+ .option('-t, --timeout <number>', 'The timout (in milli-seconds) to use for requests')
22
+ .option(
23
+ '-r, --retries <number>',
24
+ 'The maximum number of retries to use, a value of 5 combined with a delay of 1000 is recommended',
25
+ )
26
+ .option('-d, --delay <number>', 'The delay in milliseconds to use in-between successive requests');
27
+
28
+ // Parsing the program to get supplied options
29
+ Program.parse();
30
+
31
+ // Initializing Rettiwt instance using the given options
32
+ const RettiwtInstance = new Rettiwt({
33
+ apiKey: process.env.API_KEY ?? (Program.opts().key as string),
34
+ logging: Program.opts().log ? true : false,
35
+ proxyUrl: Program.opts().proxy as URL,
36
+ timeout: Program.opts().timeout ? Number(Program.opts().timeout) : undefined,
37
+ maxRetries: Program.opts().retries as number,
38
+ delay: Program.opts().delay as number,
39
+ });
40
+
41
+ // Adding sub-commands
42
+ Program.addCommand(dm(RettiwtInstance));
43
+ Program.addCommand(list(RettiwtInstance));
44
+ Program.addCommand(tweet(RettiwtInstance));
45
+ Program.addCommand(user(RettiwtInstance));
46
+
47
+ // Finalizing the CLI
48
+ Program.parse();
@@ -0,0 +1,155 @@
1
+ import { BaseType } from '../enums/Data';
2
+ import { Analytics } from '../models/data/Analytics';
3
+ import { BookmarkFolder } from '../models/data/BookmarkFolder';
4
+ import { Conversation } from '../models/data/Conversation';
5
+ import { CursoredData } from '../models/data/CursoredData';
6
+ import { Inbox } from '../models/data/Inbox';
7
+ import { List } from '../models/data/List';
8
+ import { Notification } from '../models/data/Notification';
9
+ import { Tweet } from '../models/data/Tweet';
10
+ import { User } from '../models/data/User';
11
+ import { IConversationTimelineResponse } from '../types/raw/dm/Conversation';
12
+ import { IInboxInitialResponse } from '../types/raw/dm/InboxInitial';
13
+ import { IInboxTimelineResponse } from '../types/raw/dm/InboxTimeline';
14
+ import { IListMemberAddResponse } from '../types/raw/list/AddMember';
15
+ import { IListDetailsResponse } from '../types/raw/list/Details';
16
+ import { IListMembersResponse } from '../types/raw/list/Members';
17
+ import { IListMemberRemoveResponse } from '../types/raw/list/RemoveMember';
18
+ import { IListTweetsResponse } from '../types/raw/list/Tweets';
19
+ import { IMediaInitializeUploadResponse } from '../types/raw/media/InitalizeUpload';
20
+ import { ITweetBookmarkResponse } from '../types/raw/tweet/Bookmark';
21
+ import { ITweetDetailsResponse } from '../types/raw/tweet/Details';
22
+ import { ITweetDetailsBulkResponse } from '../types/raw/tweet/DetailsBulk';
23
+ import { ITweetLikeResponse } from '../types/raw/tweet/Like';
24
+ import { ITweetLikersResponse } from '../types/raw/tweet/Likers';
25
+ import { ITweetPostResponse } from '../types/raw/tweet/Post';
26
+ import { ITweetRepliesResponse } from '../types/raw/tweet/Replies';
27
+ import { ITweetRetweetResponse } from '../types/raw/tweet/Retweet';
28
+ import { ITweetRetweetersResponse } from '../types/raw/tweet/Retweeters';
29
+ import { ITweetScheduleResponse } from '../types/raw/tweet/Schedule';
30
+ import { ITweetSearchResponse } from '../types/raw/tweet/Search';
31
+ import { ITweetUnbookmarkResponse } from '../types/raw/tweet/Unbookmark';
32
+ import { ITweetUnlikeResponse } from '../types/raw/tweet/Unlike';
33
+ import { ITweetUnpostResponse } from '../types/raw/tweet/Unpost';
34
+ import { ITweetUnretweetResponse } from '../types/raw/tweet/Unretweet';
35
+ import { ITweetUnscheduleResponse } from '../types/raw/tweet/Unschedule';
36
+ import { IUserAffiliatesResponse } from '../types/raw/user/Affiliates';
37
+ import { IUserAnalyticsResponse } from '../types/raw/user/Analytics';
38
+ import { IUserBookmarkFoldersResponse } from '../types/raw/user/BookmarkFolders';
39
+ import { IUserBookmarkFolderTweetsResponse } from '../types/raw/user/BookmarkFolderTweets';
40
+ import { IUserBookmarksResponse } from '../types/raw/user/Bookmarks';
41
+ import { IUserDetailsResponse } from '../types/raw/user/Details';
42
+ import { IUserDetailsBulkResponse } from '../types/raw/user/DetailsBulk';
43
+ import { IUserFollowResponse } from '../types/raw/user/Follow';
44
+ import { IUserFollowedResponse } from '../types/raw/user/Followed';
45
+ import { IUserFollowersResponse } from '../types/raw/user/Followers';
46
+ import { IUserFollowingResponse } from '../types/raw/user/Following';
47
+ import { IUserHighlightsResponse } from '../types/raw/user/Highlights';
48
+ import { IUserLikesResponse } from '../types/raw/user/Likes';
49
+ import { IUserListsResponse } from '../types/raw/user/Lists';
50
+ import { IUserMediaResponse } from '../types/raw/user/Media';
51
+ import { IUserNotificationsResponse } from '../types/raw/user/Notifications';
52
+ import { IUserProfileUpdateResponse } from '../types/raw/user/ProfileUpdate';
53
+ import { IUserRecommendedResponse } from '../types/raw/user/Recommended';
54
+ import { IUserSearchResponse } from '../types/raw/user/Search';
55
+ import { IUserSubscriptionsResponse } from '../types/raw/user/Subscriptions';
56
+ import { IUserTweetsResponse } from '../types/raw/user/Tweets';
57
+ import { IUserTweetsAndRepliesResponse } from '../types/raw/user/TweetsAndReplies';
58
+ import { IUserUnfollowResponse } from '../types/raw/user/Unfollow';
59
+
60
+ /**
61
+ * Collection of data extractors for each resource.
62
+ *
63
+ * @internal
64
+ */
65
+ export const Extractors = {
66
+ /* eslint-disable @typescript-eslint/naming-convention */
67
+
68
+ LIST_DETAILS: (response: IListDetailsResponse, id: string): List | undefined => List.single(response, id),
69
+ LIST_MEMBERS: (response: IListMembersResponse): CursoredData<User> =>
70
+ new CursoredData<User>(response, BaseType.USER),
71
+ LIST_MEMBER_ADD: (response: IListMemberAddResponse): number | undefined =>
72
+ response.data?.list?.member_count ?? undefined,
73
+ LIST_MEMBER_REMOVE: (response: IListMemberRemoveResponse): number | undefined =>
74
+ response.data?.list?.member_count ?? undefined,
75
+ LIST_TWEETS: (response: IListTweetsResponse): CursoredData<Tweet> =>
76
+ new CursoredData<Tweet>(response, BaseType.TWEET),
77
+
78
+ MEDIA_UPLOAD_APPEND: (): void => undefined,
79
+ MEDIA_UPLOAD_FINALIZE: (): void => undefined,
80
+ MEDIA_UPLOAD_INITIALIZE: (response: IMediaInitializeUploadResponse): string =>
81
+ response.media_id_string ?? undefined,
82
+
83
+ DM_CONVERSATION: (response: IConversationTimelineResponse): Conversation | undefined =>
84
+ Conversation.fromConversationTimeline(response),
85
+ DM_INBOX_INITIAL_STATE: (response: IInboxInitialResponse): Inbox => new Inbox(response),
86
+ DM_INBOX_TIMELINE: (response: IInboxTimelineResponse): Inbox => new Inbox(response),
87
+
88
+ TWEET_BOOKMARK: (response: ITweetBookmarkResponse): boolean => response?.data?.tweet_bookmark_put === 'Done',
89
+ TWEET_DETAILS: (response: ITweetDetailsResponse, id: string): Tweet | undefined => Tweet.single(response, id),
90
+ TWEET_DETAILS_ALT: (response: ITweetRepliesResponse, id: string): Tweet | undefined => Tweet.single(response, id),
91
+ TWEET_DETAILS_BULK: (response: ITweetDetailsBulkResponse, ids: string[]): Tweet[] => Tweet.multiple(response, ids),
92
+ TWEET_LIKE: (response: ITweetLikeResponse): boolean => (response?.data?.favorite_tweet ? true : false),
93
+ TWEET_LIKERS: (response: ITweetLikersResponse): CursoredData<User> =>
94
+ new CursoredData<User>(response, BaseType.USER),
95
+ TWEET_POST: (response: ITweetPostResponse): string =>
96
+ response?.data?.create_tweet?.tweet_results?.result?.rest_id ?? undefined,
97
+ TWEET_REPLIES: (response: ITweetDetailsResponse): CursoredData<Tweet> =>
98
+ new CursoredData<Tweet>(response, BaseType.TWEET),
99
+ TWEET_RETWEET: (response: ITweetRetweetResponse): boolean => (response?.data?.create_retweet ? true : false),
100
+ TWEET_RETWEETERS: (response: ITweetRetweetersResponse): CursoredData<User> =>
101
+ new CursoredData<User>(response, BaseType.USER),
102
+ TWEET_SCHEDULE: (response: ITweetScheduleResponse): string => response?.data?.tweet?.rest_id ?? undefined,
103
+ TWEET_SEARCH: (response: ITweetSearchResponse): CursoredData<Tweet> =>
104
+ new CursoredData<Tweet>(response, BaseType.TWEET),
105
+ TWEET_UNBOOKMARK: (response: ITweetUnbookmarkResponse): boolean => response?.data?.tweet_bookmark_delete === 'Done',
106
+ TWEET_UNLIKE: (response: ITweetUnlikeResponse): boolean => (response?.data?.unfavorite_tweet ? true : false),
107
+ TWEET_UNPOST: (response: ITweetUnpostResponse): boolean => (response?.data?.delete_tweet ? true : false),
108
+ TWEET_UNRETWEET: (response: ITweetUnretweetResponse): boolean =>
109
+ response?.data?.unretweet?.source_tweet_results?.result ? true : false,
110
+ TWEET_UNSCHEDULE: (response: ITweetUnscheduleResponse): boolean => response?.data?.scheduledtweet_delete == 'Done',
111
+
112
+ USER_AFFILIATES: (response: IUserAffiliatesResponse): CursoredData<User> =>
113
+ new CursoredData<User>(response, BaseType.USER),
114
+ USER_ANALYTICS: (response: IUserAnalyticsResponse): Analytics =>
115
+ new Analytics(response.data.viewer_v2.user_results.result),
116
+ USER_BOOKMARKS: (response: IUserBookmarksResponse): CursoredData<Tweet> =>
117
+ new CursoredData<Tweet>(response, BaseType.TWEET),
118
+ USER_BOOKMARK_FOLDERS: (response: IUserBookmarkFoldersResponse): CursoredData<BookmarkFolder> =>
119
+ new CursoredData<BookmarkFolder>(response, BaseType.BOOKMARK_FOLDER),
120
+ USER_BOOKMARK_FOLDER_TWEETS: (response: IUserBookmarkFolderTweetsResponse): CursoredData<Tweet> =>
121
+ new CursoredData<Tweet>(response, BaseType.TWEET),
122
+ USER_DETAILS_BY_USERNAME: (response: IUserDetailsResponse): User | undefined => User.single(response),
123
+ USER_DETAILS_BY_ID: (response: IUserDetailsResponse): User | undefined => User.single(response),
124
+ USER_DETAILS_BY_IDS_BULK: (response: IUserDetailsBulkResponse, ids: string[]): User[] =>
125
+ User.multiple(response, ids),
126
+ USER_FEED_FOLLOWED: (response: IUserFollowedResponse): CursoredData<Tweet> =>
127
+ new CursoredData<Tweet>(response, BaseType.TWEET),
128
+ USER_FEED_RECOMMENDED: (response: IUserRecommendedResponse): CursoredData<Tweet> =>
129
+ new CursoredData<Tweet>(response, BaseType.TWEET),
130
+ USER_FOLLOW: (response: IUserFollowResponse): boolean => (response?.id ? true : false),
131
+ USER_FOLLOWING: (response: IUserFollowingResponse): CursoredData<User> =>
132
+ new CursoredData<User>(response, BaseType.USER),
133
+ USER_FOLLOWERS: (response: IUserFollowersResponse): CursoredData<User> =>
134
+ new CursoredData<User>(response, BaseType.USER),
135
+ USER_HIGHLIGHTS: (response: IUserHighlightsResponse): CursoredData<Tweet> =>
136
+ new CursoredData<Tweet>(response, BaseType.TWEET),
137
+ USER_LISTS: (response: IUserListsResponse): CursoredData<List> => new CursoredData<List>(response, BaseType.LIST),
138
+ USER_LIKES: (response: IUserLikesResponse): CursoredData<Tweet> =>
139
+ new CursoredData<Tweet>(response, BaseType.TWEET),
140
+ USER_MEDIA: (response: IUserMediaResponse): CursoredData<Tweet> =>
141
+ new CursoredData<Tweet>(response, BaseType.TWEET),
142
+ USER_NOTIFICATIONS: (response: IUserNotificationsResponse): CursoredData<Notification> =>
143
+ new CursoredData<Notification>(response, BaseType.NOTIFICATION),
144
+ USER_SEARCH: (response: IUserSearchResponse): CursoredData<User> => new CursoredData<User>(response, BaseType.USER),
145
+ USER_SUBSCRIPTIONS: (response: IUserSubscriptionsResponse): CursoredData<User> =>
146
+ new CursoredData<User>(response, BaseType.USER),
147
+ USER_TIMELINE: (response: IUserTweetsResponse): CursoredData<Tweet> =>
148
+ new CursoredData<Tweet>(response, BaseType.TWEET),
149
+ USER_TIMELINE_AND_REPLIES: (response: IUserTweetsAndRepliesResponse): CursoredData<Tweet> =>
150
+ new CursoredData<Tweet>(response, BaseType.TWEET),
151
+ USER_UNFOLLOW: (response: IUserUnfollowResponse): boolean => (response?.id ? true : false),
152
+ USER_PROFILE_UPDATE: (response: IUserProfileUpdateResponse): boolean => (response?.name ? true : false),
153
+
154
+ /* eslint-enable @typescript-eslint/naming-convention */
155
+ };
@@ -0,0 +1,81 @@
1
+ import { ResourceType } from '../enums/Resource';
2
+
3
+ /**
4
+ * Collection of resources that allow guest authentication.
5
+ *
6
+ * @internal
7
+ */
8
+ export const AllowGuestAuthenticationGroup = [
9
+ ResourceType.TWEET_DETAILS,
10
+ ResourceType.USER_DETAILS_BY_USERNAME,
11
+ ResourceType.USER_TIMELINE,
12
+ ];
13
+
14
+ /**
15
+ * Collection of resources that can be fetched.
16
+ *
17
+ * @internal
18
+ */
19
+ export const FetchResourcesGroup = [
20
+ ResourceType.LIST_DETAILS,
21
+ ResourceType.LIST_MEMBERS,
22
+ ResourceType.LIST_TWEETS,
23
+ ResourceType.DM_CONVERSATION,
24
+ ResourceType.DM_INBOX_INITIAL_STATE,
25
+ ResourceType.DM_INBOX_TIMELINE,
26
+ ResourceType.TWEET_DETAILS,
27
+ ResourceType.TWEET_DETAILS_ALT,
28
+ ResourceType.TWEET_DETAILS_BULK,
29
+ ResourceType.TWEET_LIKERS,
30
+ ResourceType.TWEET_REPLIES,
31
+ ResourceType.TWEET_RETWEETERS,
32
+ ResourceType.TWEET_SEARCH,
33
+ ResourceType.USER_AFFILIATES,
34
+ ResourceType.USER_ANALYTICS,
35
+ ResourceType.USER_BOOKMARKS,
36
+ ResourceType.USER_BOOKMARK_FOLDERS,
37
+ ResourceType.USER_BOOKMARK_FOLDER_TWEETS,
38
+ ResourceType.USER_DETAILS_BY_USERNAME,
39
+ ResourceType.USER_DETAILS_BY_ID,
40
+ ResourceType.USER_DETAILS_BY_IDS_BULK,
41
+ ResourceType.USER_FEED_FOLLOWED,
42
+ ResourceType.USER_FEED_RECOMMENDED,
43
+ ResourceType.USER_FOLLOWING,
44
+ ResourceType.USER_FOLLOWERS,
45
+ ResourceType.USER_HIGHLIGHTS,
46
+ ResourceType.USER_LIKES,
47
+ ResourceType.USER_LISTS,
48
+ ResourceType.USER_MEDIA,
49
+ ResourceType.USER_NOTIFICATIONS,
50
+ ResourceType.USER_SEARCH,
51
+ ResourceType.USER_SUBSCRIPTIONS,
52
+ ResourceType.USER_TIMELINE,
53
+ ResourceType.USER_TIMELINE_AND_REPLIES,
54
+ ];
55
+
56
+ /**
57
+ * Collection of resources that can be posted.
58
+ *
59
+ * @internal
60
+ */
61
+ export const PostResourcesGroup = [
62
+ ResourceType.LIST_MEMBER_ADD,
63
+ ResourceType.LIST_MEMBER_REMOVE,
64
+ ResourceType.MEDIA_UPLOAD_APPEND,
65
+ ResourceType.MEDIA_UPLOAD_FINALIZE,
66
+ ResourceType.MEDIA_UPLOAD_INITIALIZE,
67
+ ResourceType.DM_DELETE_CONVERSATION,
68
+ ResourceType.TWEET_BOOKMARK,
69
+ ResourceType.TWEET_LIKE,
70
+ ResourceType.TWEET_POST,
71
+ ResourceType.TWEET_RETWEET,
72
+ ResourceType.TWEET_SCHEDULE,
73
+ ResourceType.TWEET_UNBOOKMARK,
74
+ ResourceType.TWEET_UNLIKE,
75
+ ResourceType.TWEET_UNPOST,
76
+ ResourceType.TWEET_UNRETWEET,
77
+ ResourceType.TWEET_UNSCHEDULE,
78
+ ResourceType.USER_FOLLOW,
79
+ ResourceType.USER_UNFOLLOW,
80
+ ResourceType.USER_PROFILE_UPDATE,
81
+ ];
@@ -0,0 +1,89 @@
1
+ import { ResourceType } from '../enums/Resource';
2
+ import { DMRequests } from '../requests/DirectMessage';
3
+ import { ListRequests } from '../requests/List';
4
+ import { MediaRequests } from '../requests/Media';
5
+ import { TweetRequests } from '../requests/Tweet';
6
+ import { UserRequests } from '../requests/User';
7
+ import { IFetchArgs } from '../types/args/FetchArgs';
8
+ import { IPostArgs } from '../types/args/PostArgs';
9
+ import { FetchConfig } from '../types/Fetch';
10
+
11
+ import { TweetRepliesSortTypeMap } from './Tweet';
12
+
13
+ /**
14
+ * Collection of requests to various resources.
15
+ *
16
+ * @internal
17
+ */
18
+ export const Requests: { [key in keyof typeof ResourceType]: (args: IFetchArgs | IPostArgs) => FetchConfig } = {
19
+ /* eslint-disable @typescript-eslint/naming-convention */
20
+
21
+ LIST_DETAILS: (args: IFetchArgs) => ListRequests.details(args.id!),
22
+ LIST_MEMBERS: (args: IFetchArgs) => ListRequests.members(args.id!, args.count, args.cursor),
23
+ LIST_MEMBER_ADD: (args: IPostArgs) => ListRequests.addMember(args.id!, args.userId!),
24
+ LIST_MEMBER_REMOVE: (args: IPostArgs) => ListRequests.removeMember(args.id!, args.userId!),
25
+ LIST_TWEETS: (args: IFetchArgs) => ListRequests.tweets(args.id!, args.count, args.cursor),
26
+
27
+ MEDIA_UPLOAD_APPEND: (args: IPostArgs) => MediaRequests.appendUpload(args.upload!.id!, args.upload!.media!),
28
+ MEDIA_UPLOAD_FINALIZE: (args: IPostArgs) => MediaRequests.finalizeUpload(args.upload!.id!),
29
+ MEDIA_UPLOAD_INITIALIZE: (args: IPostArgs) => MediaRequests.initializeUpload(args.upload!.size!),
30
+
31
+ DM_CONVERSATION: (args: IFetchArgs) => DMRequests.conversation(args.conversationId!, args.maxId),
32
+ DM_INBOX_INITIAL_STATE: () => DMRequests.inboxInitial(),
33
+ DM_INBOX_TIMELINE: (args: IFetchArgs) => DMRequests.inboxTimeline(args.maxId),
34
+ DM_DELETE_CONVERSATION: (args: IPostArgs) => DMRequests.deleteConversation(args.conversationId!),
35
+
36
+ TWEET_BOOKMARK: (args: IPostArgs) => TweetRequests.bookmark(args.id!),
37
+ TWEET_DETAILS: (args: IFetchArgs) => TweetRequests.details(args.id!),
38
+ TWEET_DETAILS_ALT: (args: IFetchArgs) => TweetRequests.replies(args.id!),
39
+ TWEET_DETAILS_BULK: (args: IFetchArgs) => TweetRequests.bulkDetails(args.ids!),
40
+ TWEET_LIKE: (args: IPostArgs) => TweetRequests.like(args.id!),
41
+ TWEET_LIKERS: (args: IFetchArgs) => TweetRequests.likers(args.id!, args.count, args.cursor),
42
+ TWEET_POST: (args: IPostArgs) => TweetRequests.post(args.tweet!),
43
+ TWEET_REPLIES: (args: IFetchArgs) =>
44
+ TweetRequests.replies(args.id!, args.cursor, args.sortBy ? TweetRepliesSortTypeMap[args.sortBy] : undefined),
45
+ TWEET_RETWEET: (args: IPostArgs) => TweetRequests.retweet(args.id!),
46
+ TWEET_RETWEETERS: (args: IFetchArgs) => TweetRequests.retweeters(args.id!, args.count, args.cursor),
47
+ TWEET_SCHEDULE: (args: IPostArgs) => TweetRequests.schedule(args.tweet!),
48
+ TWEET_SEARCH: (args: IFetchArgs) => TweetRequests.search(args.filter!, args.count, args.cursor),
49
+ TWEET_UNBOOKMARK: (args: IPostArgs) => TweetRequests.unbookmark(args.id!),
50
+ TWEET_UNLIKE: (args: IPostArgs) => TweetRequests.unlike(args.id!),
51
+ TWEET_UNPOST: (args: IPostArgs) => TweetRequests.unpost(args.id!),
52
+ TWEET_UNRETWEET: (args: IPostArgs) => TweetRequests.unretweet(args.id!),
53
+ TWEET_UNSCHEDULE: (args: IPostArgs) => TweetRequests.unschedule(args.id!),
54
+
55
+ USER_AFFILIATES: (args: IFetchArgs) => UserRequests.affiliates(args.id!, args.count, args.cursor),
56
+ USER_ANALYTICS: (args: IFetchArgs) =>
57
+ UserRequests.analytics(
58
+ args.fromTime!,
59
+ args.toTime!,
60
+ args.granularity!,
61
+ args.metrics!,
62
+ args.showVerifiedFollowers!,
63
+ ),
64
+ USER_BOOKMARKS: (args: IFetchArgs) => UserRequests.bookmarks(args.count, args.cursor),
65
+ USER_BOOKMARK_FOLDERS: (args: IFetchArgs) => UserRequests.bookmarkFolders(args.cursor),
66
+ USER_BOOKMARK_FOLDER_TWEETS: (args: IFetchArgs) =>
67
+ UserRequests.bookmarkFolderTweets(args.id!, args.count, args.cursor),
68
+ USER_DETAILS_BY_USERNAME: (args: IFetchArgs) => UserRequests.detailsByUsername(args.id!),
69
+ USER_DETAILS_BY_ID: (args: IFetchArgs) => UserRequests.detailsById(args.id!),
70
+ USER_DETAILS_BY_IDS_BULK: (args: IFetchArgs) => UserRequests.bulkDetailsByIds(args.ids!),
71
+ USER_FEED_FOLLOWED: (args: IFetchArgs) => UserRequests.followed(args.count, args.cursor),
72
+ USER_FEED_RECOMMENDED: (args: IFetchArgs) => UserRequests.recommended(args.count, args.cursor),
73
+ USER_FOLLOW: (args: IPostArgs) => UserRequests.follow(args.id!),
74
+ USER_FOLLOWING: (args: IFetchArgs) => UserRequests.following(args.id!, args.count, args.cursor),
75
+ USER_FOLLOWERS: (args: IFetchArgs) => UserRequests.followers(args.id!, args.count, args.cursor),
76
+ USER_HIGHLIGHTS: (args: IFetchArgs) => UserRequests.highlights(args.id!, args.count, args.cursor),
77
+ USER_LIKES: (args: IFetchArgs) => UserRequests.likes(args.id!, args.count, args.cursor),
78
+ USER_LISTS: (args: IFetchArgs) => UserRequests.lists(args.id!, args.count, args.cursor),
79
+ USER_MEDIA: (args: IFetchArgs) => UserRequests.media(args.id!, args.count, args.cursor),
80
+ USER_NOTIFICATIONS: (args: IFetchArgs) => UserRequests.notifications(args.count, args.cursor),
81
+ USER_SEARCH: (args: IFetchArgs) => UserRequests.search(args.id!, args.count, args.cursor),
82
+ USER_SUBSCRIPTIONS: (args: IFetchArgs) => UserRequests.subscriptions(args.id!, args.count, args.cursor),
83
+ USER_TIMELINE: (args: IFetchArgs) => UserRequests.tweets(args.id!, args.count, args.cursor),
84
+ USER_TIMELINE_AND_REPLIES: (args: IFetchArgs) => UserRequests.tweetsAndReplies(args.id!, args.count, args.cursor),
85
+ USER_UNFOLLOW: (args: IPostArgs) => UserRequests.unfollow(args.id!),
86
+ USER_PROFILE_UPDATE: (args: IPostArgs) => UserRequests.updateProfile(args.profileOptions!),
87
+
88
+ /* eslint-enable @typescript-eslint/naming-convention */
89
+ };
@@ -0,0 +1,17 @@
1
+ import { RawTweetRepliesSortType } from '../enums/raw/Tweet';
2
+ import { TweetRepliesSortType } from '../enums/Tweet';
3
+
4
+ /**
5
+ * Collection of mapping from parsed reply sort type to raw reply sort type.
6
+ *
7
+ * @internal
8
+ */
9
+ export const TweetRepliesSortTypeMap: { [key in keyof typeof TweetRepliesSortType]: RawTweetRepliesSortType } = {
10
+ /* eslint-disable @typescript-eslint/naming-convention */
11
+
12
+ LATEST: RawTweetRepliesSortType.LATEST,
13
+ LIKES: RawTweetRepliesSortType.LIKES,
14
+ RELEVANCE: RawTweetRepliesSortType.RELEVACE,
15
+
16
+ /* eslint-enable @typescript-eslint/naming-convention */
17
+ };
@@ -0,0 +1,62 @@
1
+ import { Command, createCommand } from 'commander';
2
+
3
+ import { output } from '../helper/CliUtils';
4
+ import { Rettiwt } from '../Rettiwt';
5
+
6
+ /**
7
+ * Creates a new 'dm' command which uses the given Rettiwt instance.
8
+ *
9
+ * @param rettiwt - The Rettiwt instance to use.
10
+ * @returns The created 'dm' command.
11
+ */
12
+ function createDirectMessageCommand(rettiwt: Rettiwt): Command {
13
+ // Creating the 'dm' command
14
+ const dm = createCommand('dm').description('Access resources related to direct messages');
15
+
16
+ // Conversation
17
+ dm.command('conversation')
18
+ .description('Get the full conversation history for a specific conversation')
19
+ .argument('<conversation-id>', 'The ID of the conversation (e.g., "394028042-1712730991884689408")')
20
+ .argument('[cursor]', 'The cursor for pagination (maxId from previous response)')
21
+ .action(async (conversationId: string, cursor?: string) => {
22
+ try {
23
+ const conversation = await rettiwt.dm.conversation(conversationId, cursor);
24
+ output(conversation);
25
+ } catch (error) {
26
+ output(error);
27
+ }
28
+ });
29
+
30
+ // Delete conversation
31
+ dm.command('delete-conversation')
32
+ .description('Delete a conversation (you will leave the conversation and it will be removed from your inbox)')
33
+ .argument('<conversation-id>', 'The ID of the conversation to delete')
34
+ .action(async (conversationId: string) => {
35
+ try {
36
+ await rettiwt.dm.deleteConversation(conversationId);
37
+ output({ success: true, message: 'Conversation deleted successfully' });
38
+ } catch (error) {
39
+ output(error);
40
+ }
41
+ });
42
+
43
+ // Inbox
44
+ dm.command('inbox')
45
+ .description('Get your DM inbox')
46
+ .argument(
47
+ '[cursor]',
48
+ 'The cursor to the batch of conversations to fetch. If not provided, initial inbox is fetched',
49
+ )
50
+ .action(async (cursor?: string) => {
51
+ try {
52
+ const inbox = await rettiwt.dm.inbox(cursor);
53
+ output(inbox);
54
+ } catch (error) {
55
+ output(error);
56
+ }
57
+ });
58
+
59
+ return dm;
60
+ }
61
+
62
+ export default createDirectMessageCommand;