rettiwt-api 6.0.7 → 6.1.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 (220) hide show
  1. package/.github/ISSUE_TEMPLATE/bug-report.yml +57 -0
  2. package/.github/ISSUE_TEMPLATE/feature-request.yml +20 -0
  3. package/.github/ISSUE_TEMPLATE/question.yml +15 -0
  4. package/.github/PULL_REQUEST_TEMPLATE.md +32 -0
  5. package/.github/workflows/ci.yml +33 -0
  6. package/.nvmrc +1 -0
  7. package/README.md +30 -6
  8. package/dist/Rettiwt.d.ts +3 -0
  9. package/dist/Rettiwt.js +4 -0
  10. package/dist/Rettiwt.js.map +1 -1
  11. package/dist/cli.js +2 -0
  12. package/dist/cli.js.map +1 -1
  13. package/dist/collections/Extractors.d.ts +24 -0
  14. package/dist/collections/Extractors.js +14 -0
  15. package/dist/collections/Extractors.js.map +1 -1
  16. package/dist/collections/Groups.js +11 -0
  17. package/dist/collections/Groups.js.map +1 -1
  18. package/dist/collections/Requests.js +12 -0
  19. package/dist/collections/Requests.js.map +1 -1
  20. package/dist/commands/DirectMessage.d.ts +10 -0
  21. package/dist/commands/DirectMessage.js +57 -0
  22. package/dist/commands/DirectMessage.js.map +1 -0
  23. package/dist/commands/List.js +44 -3
  24. package/dist/commands/List.js.map +1 -1
  25. package/dist/commands/Tweet.js +29 -1
  26. package/dist/commands/Tweet.js.map +1 -1
  27. package/dist/commands/User.js +39 -1
  28. package/dist/commands/User.js.map +1 -1
  29. package/dist/enums/Data.d.ts +3 -1
  30. package/dist/enums/Data.js +2 -0
  31. package/dist/enums/Data.js.map +1 -1
  32. package/dist/enums/Resource.d.ts +11 -0
  33. package/dist/enums/Resource.js +12 -0
  34. package/dist/enums/Resource.js.map +1 -1
  35. package/dist/enums/raw/Analytics.d.ts +6 -3
  36. package/dist/enums/raw/Analytics.js +5 -2
  37. package/dist/enums/raw/Analytics.js.map +1 -1
  38. package/dist/index.d.ts +15 -0
  39. package/dist/index.js +8 -0
  40. package/dist/index.js.map +1 -1
  41. package/dist/models/args/FetchArgs.d.ts +9 -0
  42. package/dist/models/args/FetchArgs.js +16 -0
  43. package/dist/models/args/FetchArgs.js.map +1 -1
  44. package/dist/models/args/PostArgs.d.ts +1 -0
  45. package/dist/models/args/PostArgs.js +2 -0
  46. package/dist/models/args/PostArgs.js.map +1 -1
  47. package/dist/models/data/Analytics.d.ts +43 -0
  48. package/dist/models/data/Analytics.js +92 -0
  49. package/dist/models/data/Analytics.js.map +1 -0
  50. package/dist/models/data/Conversation.d.ts +93 -0
  51. package/dist/models/data/Conversation.js +293 -0
  52. package/dist/models/data/Conversation.js.map +1 -0
  53. package/dist/models/data/CursoredData.d.ts +2 -1
  54. package/dist/models/data/CursoredData.js +6 -1
  55. package/dist/models/data/CursoredData.js.map +1 -1
  56. package/dist/models/data/DirectMessage.d.ts +105 -0
  57. package/dist/models/data/DirectMessage.js +284 -0
  58. package/dist/models/data/DirectMessage.js.map +1 -0
  59. package/dist/models/data/Inbox.d.ts +44 -0
  60. package/dist/models/data/Inbox.js +106 -0
  61. package/dist/models/data/Inbox.js.map +1 -0
  62. package/dist/models/data/List.d.ts +20 -0
  63. package/dist/models/data/List.js +50 -1
  64. package/dist/models/data/List.js.map +1 -1
  65. package/dist/models/data/Tweet.d.ts +6 -6
  66. package/dist/models/data/Tweet.js +4 -2
  67. package/dist/models/data/Tweet.js.map +1 -1
  68. package/dist/models/data/User.d.ts +2 -0
  69. package/dist/models/data/User.js +6 -0
  70. package/dist/models/data/User.js.map +1 -1
  71. package/dist/requests/DirectMessage.d.ts +28 -0
  72. package/dist/requests/DirectMessage.js +149 -0
  73. package/dist/requests/DirectMessage.js.map +1 -0
  74. package/dist/requests/List.d.ts +10 -0
  75. package/dist/requests/List.js +52 -0
  76. package/dist/requests/List.js.map +1 -1
  77. package/dist/requests/Tweet.d.ts +8 -0
  78. package/dist/requests/Tweet.js +30 -0
  79. package/dist/requests/Tweet.js.map +1 -1
  80. package/dist/requests/User.d.ts +8 -1
  81. package/dist/requests/User.js +67 -8
  82. package/dist/requests/User.js.map +1 -1
  83. package/dist/services/public/DirectMessageService.d.ts +100 -0
  84. package/dist/services/public/DirectMessageService.js +143 -0
  85. package/dist/services/public/DirectMessageService.js.map +1 -0
  86. package/dist/services/public/FetcherService.d.ts +3 -2
  87. package/dist/services/public/FetcherService.js +64 -3
  88. package/dist/services/public/FetcherService.js.map +1 -1
  89. package/dist/services/public/ListService.d.ts +85 -0
  90. package/dist/services/public/ListService.js +111 -0
  91. package/dist/services/public/ListService.js.map +1 -1
  92. package/dist/services/public/TweetService.d.ts +56 -0
  93. package/dist/services/public/TweetService.js +72 -0
  94. package/dist/services/public/TweetService.js.map +1 -1
  95. package/dist/services/public/UserService.d.ts +61 -2
  96. package/dist/services/public/UserService.js +89 -0
  97. package/dist/services/public/UserService.js.map +1 -1
  98. package/dist/types/args/FetchArgs.d.ts +69 -12
  99. package/dist/types/args/PostArgs.d.ts +29 -11
  100. package/dist/types/data/Analytics.d.ts +42 -0
  101. package/dist/types/data/Analytics.js +3 -0
  102. package/dist/types/data/Analytics.js.map +1 -0
  103. package/dist/types/data/Conversation.d.ts +32 -0
  104. package/dist/types/data/Conversation.js +3 -0
  105. package/dist/types/data/Conversation.js.map +1 -0
  106. package/dist/types/data/CursoredData.d.ts +4 -1
  107. package/dist/types/data/DirectMessage.d.ts +25 -0
  108. package/dist/types/data/DirectMessage.js +3 -0
  109. package/dist/types/data/DirectMessage.js.map +1 -0
  110. package/dist/types/data/Inbox.d.ts +18 -0
  111. package/dist/types/data/Inbox.js +3 -0
  112. package/dist/types/data/Inbox.js.map +1 -0
  113. package/dist/types/data/List.d.ts +5 -1
  114. package/dist/types/data/Tweet.d.ts +6 -6
  115. package/dist/types/data/User.d.ts +4 -0
  116. package/dist/types/raw/base/Analytic.d.ts +6 -1
  117. package/dist/types/raw/base/Message.d.ts +16 -0
  118. package/dist/types/raw/base/Message.js +4 -0
  119. package/dist/types/raw/base/Message.js.map +1 -0
  120. package/dist/types/raw/base/Tweet.d.ts +6 -6
  121. package/dist/types/raw/base/User.d.ts +2 -1
  122. package/dist/types/raw/composite/TimelineList.d.ts +9 -0
  123. package/dist/types/raw/composite/TimelineList.js +3 -0
  124. package/dist/types/raw/composite/TimelineList.js.map +1 -0
  125. package/dist/types/raw/dm/Conversation.d.ts +55 -0
  126. package/dist/types/raw/dm/Conversation.js +4 -0
  127. package/dist/types/raw/dm/Conversation.js.map +1 -0
  128. package/dist/types/raw/dm/InboxInitial.d.ts +137 -0
  129. package/dist/types/raw/dm/InboxInitial.js +4 -0
  130. package/dist/types/raw/dm/InboxInitial.js.map +1 -0
  131. package/dist/types/raw/dm/InboxTimeline.d.ts +287 -0
  132. package/dist/types/raw/dm/InboxTimeline.js +4 -0
  133. package/dist/types/raw/dm/InboxTimeline.js.map +1 -0
  134. package/dist/types/raw/dm/UserUpdates.d.ts +41 -0
  135. package/dist/types/raw/dm/UserUpdates.js +4 -0
  136. package/dist/types/raw/dm/UserUpdates.js.map +1 -0
  137. package/dist/types/raw/list/AddMember.d.ts +151 -0
  138. package/dist/types/raw/list/AddMember.js +4 -0
  139. package/dist/types/raw/list/AddMember.js.map +1 -0
  140. package/dist/types/raw/list/Details.d.ts +44 -13
  141. package/dist/types/raw/list/RemoveMember.d.ts +150 -0
  142. package/dist/types/raw/list/RemoveMember.js +4 -0
  143. package/dist/types/raw/list/RemoveMember.js.map +1 -0
  144. package/dist/types/raw/tweet/Bookmark.d.ts +12 -0
  145. package/dist/types/raw/tweet/Bookmark.js +4 -0
  146. package/dist/types/raw/tweet/Bookmark.js.map +1 -0
  147. package/dist/types/raw/tweet/Unbookmark.d.ts +11 -0
  148. package/dist/types/raw/tweet/Unbookmark.js +4 -0
  149. package/dist/types/raw/tweet/Unbookmark.js.map +1 -0
  150. package/dist/types/raw/user/Analytics.d.ts +6 -18
  151. package/dist/types/raw/user/Analytics.js +0 -1
  152. package/dist/types/raw/user/Analytics.js.map +1 -1
  153. package/dist/types/raw/user/Lists.d.ts +319 -0
  154. package/dist/types/raw/user/Lists.js +4 -0
  155. package/dist/types/raw/user/Lists.js.map +1 -0
  156. package/eslint.config.mjs +1 -1
  157. package/package.json +13 -6
  158. package/playground/.env.example +1 -0
  159. package/playground/README.md +53 -0
  160. package/playground/index.js +15 -0
  161. package/playground/package.json +15 -0
  162. package/src/Rettiwt.ts +5 -0
  163. package/src/cli.ts +2 -0
  164. package/src/collections/Extractors.ts +29 -0
  165. package/src/collections/Groups.ts +11 -0
  166. package/src/collections/Requests.ts +20 -0
  167. package/src/commands/DirectMessage.ts +62 -0
  168. package/src/commands/List.ts +44 -3
  169. package/src/commands/Tweet.ts +29 -1
  170. package/src/commands/User.ts +65 -1
  171. package/src/enums/Data.ts +2 -0
  172. package/src/enums/Resource.ts +13 -0
  173. package/src/enums/raw/Analytics.ts +5 -2
  174. package/src/index.ts +15 -0
  175. package/src/models/args/FetchArgs.ts +17 -0
  176. package/src/models/args/PostArgs.ts +2 -0
  177. package/src/models/data/Analytics.ts +97 -0
  178. package/src/models/data/Conversation.ts +344 -0
  179. package/src/models/data/CursoredData.ts +7 -2
  180. package/src/models/data/DirectMessage.ts +335 -0
  181. package/src/models/data/Inbox.ts +124 -0
  182. package/src/models/data/List.ts +60 -1
  183. package/src/models/data/Tweet.ts +10 -8
  184. package/src/models/data/User.ts +6 -0
  185. package/src/requests/DirectMessage.ts +233 -0
  186. package/src/requests/List.ts +58 -0
  187. package/src/requests/Tweet.ts +32 -0
  188. package/src/requests/User.ts +70 -7
  189. package/src/services/public/DirectMessageService.ts +159 -0
  190. package/src/services/public/FetcherService.ts +86 -4
  191. package/src/services/public/ListService.ts +127 -0
  192. package/src/services/public/TweetService.ts +82 -0
  193. package/src/services/public/UserService.ts +110 -2
  194. package/src/types/args/FetchArgs.ts +77 -12
  195. package/src/types/args/PostArgs.ts +31 -11
  196. package/src/types/data/Analytics.ts +58 -0
  197. package/src/types/data/Conversation.ts +44 -0
  198. package/src/types/data/CursoredData.ts +4 -1
  199. package/src/types/data/DirectMessage.ts +33 -0
  200. package/src/types/data/Inbox.ts +23 -0
  201. package/src/types/data/List.ts +7 -1
  202. package/src/types/data/Tweet.ts +6 -6
  203. package/src/types/data/User.ts +6 -0
  204. package/src/types/raw/base/Analytic.ts +7 -1
  205. package/src/types/raw/base/Message.ts +22 -0
  206. package/src/types/raw/base/Tweet.ts +6 -6
  207. package/src/types/raw/base/User.ts +2 -1
  208. package/src/types/raw/composite/TimelineList.ts +10 -0
  209. package/src/types/raw/dm/Conversation.ts +59 -0
  210. package/src/types/raw/dm/InboxInitial.ts +155 -0
  211. package/src/types/raw/dm/InboxTimeline.ts +301 -0
  212. package/src/types/raw/dm/UserUpdates.ts +46 -0
  213. package/src/types/raw/list/AddMember.ts +175 -0
  214. package/src/types/raw/list/Details.ts +52 -13
  215. package/src/types/raw/list/RemoveMember.ts +174 -0
  216. package/src/types/raw/tweet/Bookmark.ts +14 -0
  217. package/src/types/raw/tweet/Unbookmark.ts +14 -0
  218. package/src/types/raw/user/Analytics.ts +6 -22
  219. package/src/types/raw/user/Lists.ts +378 -0
  220. package/tsconfig.json +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rettiwt-api",
3
- "version": "6.0.7",
3
+ "version": "6.1.0",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "description": "An API for fetching data from TwitterAPI, without any rate limits!",
@@ -11,9 +11,10 @@
11
11
  "build": "tsc",
12
12
  "prepare": "tsc",
13
13
  "format": "prettier --write .",
14
+ "format:check": "prettier --check .",
14
15
  "lint": "eslint --max-warnings 0 --fix .",
15
- "docs": "typedoc --excludePrivate --excludeProtected --excludeInternal src/index.ts",
16
- "debug": "nodemon ./dist/index.js --inspect=0.0.0.0:9229"
16
+ "lint:check": "eslint --max-warnings 0 .",
17
+ "docs": "typedoc --excludePrivate --excludeProtected --excludeInternal src/index.ts"
17
18
  },
18
19
  "repository": {
19
20
  "type": "git",
@@ -29,10 +30,11 @@
29
30
  },
30
31
  "homepage": "https://rishikant181.github.io/Rettiwt-API/",
31
32
  "engines": {
32
- "node": "^22.13.1"
33
+ "node": "^22.21.0"
33
34
  },
34
35
  "devDependencies": {
35
36
  "@types/cookiejar": "^2.1.5",
37
+ "@types/jsdom": "^27.0.0",
36
38
  "@types/node": "^22.13.1",
37
39
  "@typescript-eslint/eslint-plugin": "^8.24.0",
38
40
  "@typescript-eslint/parser": "^8.24.0",
@@ -50,7 +52,12 @@
50
52
  "commander": "^11.1.0",
51
53
  "cookiejar": "^2.1.4",
52
54
  "https-proxy-agent": "^7.0.6",
55
+ "jsdom": "^27.2.0",
53
56
  "node-html-parser": "^7.0.1",
54
- "x-client-transaction-id-glacier": "^1.0.0"
55
- }
57
+ "x-client-transaction-id": "^0.1.8"
58
+ },
59
+ "workspaces": [
60
+ "playground",
61
+ "src"
62
+ ]
56
63
  }
@@ -0,0 +1 @@
1
+ ACCESS_TOKEN=""
@@ -0,0 +1,53 @@
1
+ # Rettiwt Playground
2
+
3
+ This playground is intended for developers to test and experiment with features from the Rettiwt-API package in a local development environment.
4
+
5
+ ## Getting Started
6
+
7
+ ### Prerequisites
8
+
9
+ - Node.js (v22 or higher recommended)
10
+ - npm (v7+ recommended for workspace support)
11
+
12
+ ### Setup
13
+
14
+ 1. **Install dependencies**
15
+ From the root of the monorepo, run:
16
+
17
+ ```sh
18
+ npm install
19
+ ```
20
+
21
+ This will install dependencies for all workspaces, including `playground` and `src`.
22
+
23
+ 2. **Environment Variables**
24
+ Create a `.env` file in the `playground` directory with your API credentials:
25
+ ```env
26
+ ACCESS_TOKEN=your_access_token_here
27
+ ```
28
+
29
+ ### Usage
30
+
31
+ - The main entry point is [`index.js`](./index.js), which demonstrates usage of the Rettiwt-API.
32
+ - To run the playground:
33
+ ```sh
34
+ npm start --workspace=playground
35
+ ```
36
+ or from the `playground` directory:
37
+ ```sh
38
+ npm start
39
+ ```
40
+
41
+ ### Modifying Playground Code
42
+
43
+ - Edit `index.js` to try different API features or test new functionality.
44
+ - The `rettiwt-api` dependency is linked via npm workspaces, so changes in `src` are immediately available in the playground after rebuilding if necessary.
45
+
46
+ ## Notes
47
+
48
+ - This playground is for development and testing only. Do not use production credentials.
49
+ - For more advanced usage, add scripts or files as needed.
50
+
51
+ ---
52
+
53
+ For questions or issues, see the main project README or open an issue.
@@ -0,0 +1,15 @@
1
+ import { Rettiwt } from 'rettiwt-api';
2
+ import 'dotenv/config';
3
+
4
+ const rettiwt = new Rettiwt({ apiKey: process.env.ACCESS_TOKEN });
5
+
6
+ async function userDetails() {
7
+ try {
8
+ const user = await rettiwt.user.details();
9
+ console.log(user);
10
+ } catch (error) {
11
+ console.error('Error fetching user details:', error);
12
+ }
13
+ }
14
+
15
+ await userDetails();
@@ -0,0 +1,15 @@
1
+ {
2
+ "name": "rettiwt-playground",
3
+ "version": "1.0.0",
4
+ "description": "A playground for testing Rettiwt-API features and functionalities.",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "start": "node index.js",
9
+ "test": "echo \"No tests specified\" && exit 0"
10
+ },
11
+ "dependencies": {
12
+ "dotenv": "^17.2.0",
13
+ "rettiwt-api": "workspace"
14
+ }
15
+ }
package/src/Rettiwt.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { RettiwtConfig } from './models/RettiwtConfig';
2
+ import { DirectMessageService } from './services/public/DirectMessageService';
2
3
  import { ListService } from './services/public/ListService';
3
4
  import { TweetService } from './services/public/TweetService';
4
5
  import { UserService } from './services/public/UserService';
@@ -49,6 +50,9 @@ export class Rettiwt {
49
50
  /** The configuration for Rettiwt. */
50
51
  private _config: RettiwtConfig;
51
52
 
53
+ /** The instance used to fetch data related to direct messages. */
54
+ public dm: DirectMessageService;
55
+
52
56
  /** The instance used to fetch data related to lists. */
53
57
  public list: ListService;
54
58
 
@@ -65,6 +69,7 @@ export class Rettiwt {
65
69
  */
66
70
  public constructor(config?: IRettiwtConfig) {
67
71
  this._config = new RettiwtConfig(config);
72
+ this.dm = new DirectMessageService(this._config);
68
73
  this.list = new ListService(this._config);
69
74
  this.tweet = new TweetService(this._config);
70
75
  this.user = new UserService(this._config);
package/src/cli.ts CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { createCommand } from 'commander';
4
4
 
5
+ import dm from './commands/DirectMessage';
5
6
  import list from './commands/List';
6
7
  import tweet from './commands/Tweet';
7
8
  import user from './commands/User';
@@ -38,6 +39,7 @@ const RettiwtInstance = new Rettiwt({
38
39
  });
39
40
 
40
41
  // Adding sub-commands
42
+ Program.addCommand(dm(RettiwtInstance));
41
43
  Program.addCommand(list(RettiwtInstance));
42
44
  Program.addCommand(tweet(RettiwtInstance));
43
45
  Program.addCommand(user(RettiwtInstance));
@@ -1,11 +1,22 @@
1
1
  import { BaseType } from '../enums/Data';
2
+ import { Analytics } from '../models/data/Analytics';
3
+ import { Conversation } from '../models/data/Conversation';
2
4
  import { CursoredData } from '../models/data/CursoredData';
5
+ import { Inbox } from '../models/data/Inbox';
6
+ import { List } from '../models/data/List';
3
7
  import { Notification } from '../models/data/Notification';
4
8
  import { Tweet } from '../models/data/Tweet';
5
9
  import { User } from '../models/data/User';
10
+ import { IConversationTimelineResponse } from '../types/raw/dm/Conversation';
11
+ import { IInboxInitialResponse } from '../types/raw/dm/InboxInitial';
12
+ import { IInboxTimelineResponse } from '../types/raw/dm/InboxTimeline';
13
+ import { IListMemberAddResponse } from '../types/raw/list/AddMember';
14
+ import { IListDetailsResponse } from '../types/raw/list/Details';
6
15
  import { IListMembersResponse } from '../types/raw/list/Members';
16
+ import { IListMemberRemoveResponse } from '../types/raw/list/RemoveMember';
7
17
  import { IListTweetsResponse } from '../types/raw/list/Tweets';
8
18
  import { IMediaInitializeUploadResponse } from '../types/raw/media/InitalizeUpload';
19
+ import { ITweetBookmarkResponse } from '../types/raw/tweet/Bookmark';
9
20
  import { ITweetDetailsResponse } from '../types/raw/tweet/Details';
10
21
  import { ITweetDetailsBulkResponse } from '../types/raw/tweet/DetailsBulk';
11
22
  import { ITweetLikeResponse } from '../types/raw/tweet/Like';
@@ -16,11 +27,13 @@ import { ITweetRetweetResponse } from '../types/raw/tweet/Retweet';
16
27
  import { ITweetRetweetersResponse } from '../types/raw/tweet/Retweeters';
17
28
  import { ITweetScheduleResponse } from '../types/raw/tweet/Schedule';
18
29
  import { ITweetSearchResponse } from '../types/raw/tweet/Search';
30
+ import { ITweetUnbookmarkResponse } from '../types/raw/tweet/Unbookmark';
19
31
  import { ITweetUnlikeResponse } from '../types/raw/tweet/Unlike';
20
32
  import { ITweetUnpostResponse } from '../types/raw/tweet/Unpost';
21
33
  import { ITweetUnretweetResponse } from '../types/raw/tweet/Unretweet';
22
34
  import { ITweetUnscheduleResponse } from '../types/raw/tweet/Unschedule';
23
35
  import { IUserAffiliatesResponse } from '../types/raw/user/Affiliates';
36
+ import { IUserAnalyticsResponse } from '../types/raw/user/Analytics';
24
37
  import { IUserBookmarksResponse } from '../types/raw/user/Bookmarks';
25
38
  import { IUserDetailsResponse } from '../types/raw/user/Details';
26
39
  import { IUserDetailsBulkResponse } from '../types/raw/user/DetailsBulk';
@@ -30,6 +43,7 @@ import { IUserFollowersResponse } from '../types/raw/user/Followers';
30
43
  import { IUserFollowingResponse } from '../types/raw/user/Following';
31
44
  import { IUserHighlightsResponse } from '../types/raw/user/Highlights';
32
45
  import { IUserLikesResponse } from '../types/raw/user/Likes';
46
+ import { IUserListsResponse } from '../types/raw/user/Lists';
33
47
  import { IUserMediaResponse } from '../types/raw/user/Media';
34
48
  import { IUserNotificationsResponse } from '../types/raw/user/Notifications';
35
49
  import { IUserRecommendedResponse } from '../types/raw/user/Recommended';
@@ -46,8 +60,13 @@ import { IUserUnfollowResponse } from '../types/raw/user/Unfollow';
46
60
  export const Extractors = {
47
61
  /* eslint-disable @typescript-eslint/naming-convention */
48
62
 
63
+ LIST_DETAILS: (response: IListDetailsResponse, id: string): List | undefined => List.single(response, id),
49
64
  LIST_MEMBERS: (response: IListMembersResponse): CursoredData<User> =>
50
65
  new CursoredData<User>(response, BaseType.USER),
66
+ LIST_MEMBER_ADD: (response: IListMemberAddResponse): number | undefined =>
67
+ response.data?.list?.member_count ?? undefined,
68
+ LIST_MEMBER_REMOVE: (response: IListMemberRemoveResponse): number | undefined =>
69
+ response.data?.list?.member_count ?? undefined,
51
70
  LIST_TWEETS: (response: IListTweetsResponse): CursoredData<Tweet> =>
52
71
  new CursoredData<Tweet>(response, BaseType.TWEET),
53
72
 
@@ -56,6 +75,12 @@ export const Extractors = {
56
75
  MEDIA_UPLOAD_INITIALIZE: (response: IMediaInitializeUploadResponse): string =>
57
76
  response.media_id_string ?? undefined,
58
77
 
78
+ DM_CONVERSATION: (response: IConversationTimelineResponse): Conversation | undefined =>
79
+ Conversation.fromConversationTimeline(response),
80
+ DM_INBOX_INITIAL_STATE: (response: IInboxInitialResponse): Inbox => new Inbox(response),
81
+ DM_INBOX_TIMELINE: (response: IInboxTimelineResponse): Inbox => new Inbox(response),
82
+
83
+ TWEET_BOOKMARK: (response: ITweetBookmarkResponse): boolean => response?.data?.tweet_bookmark_put === 'Done',
59
84
  TWEET_DETAILS: (response: ITweetDetailsResponse, id: string): Tweet | undefined => Tweet.single(response, id),
60
85
  TWEET_DETAILS_ALT: (response: ITweetRepliesResponse, id: string): Tweet | undefined => Tweet.single(response, id),
61
86
  TWEET_DETAILS_BULK: (response: ITweetDetailsBulkResponse, ids: string[]): Tweet[] => Tweet.multiple(response, ids),
@@ -72,6 +97,7 @@ export const Extractors = {
72
97
  TWEET_SCHEDULE: (response: ITweetScheduleResponse): string => response?.data?.tweet?.rest_id ?? undefined,
73
98
  TWEET_SEARCH: (response: ITweetSearchResponse): CursoredData<Tweet> =>
74
99
  new CursoredData<Tweet>(response, BaseType.TWEET),
100
+ TWEET_UNBOOKMARK: (response: ITweetUnbookmarkResponse): boolean => response?.data?.tweet_bookmark_delete === 'Done',
75
101
  TWEET_UNLIKE: (response: ITweetUnlikeResponse): boolean => (response?.data?.unfavorite_tweet ? true : false),
76
102
  TWEET_UNPOST: (response: ITweetUnpostResponse): boolean => (response?.data?.delete_tweet ? true : false),
77
103
  TWEET_UNRETWEET: (response: ITweetUnretweetResponse): boolean =>
@@ -80,6 +106,8 @@ export const Extractors = {
80
106
 
81
107
  USER_AFFILIATES: (response: IUserAffiliatesResponse): CursoredData<User> =>
82
108
  new CursoredData<User>(response, BaseType.USER),
109
+ USER_ANALYTICS: (response: IUserAnalyticsResponse): Analytics =>
110
+ new Analytics(response.data.viewer_v2.user_results.result),
83
111
  USER_BOOKMARKS: (response: IUserBookmarksResponse): CursoredData<Tweet> =>
84
112
  new CursoredData<Tweet>(response, BaseType.TWEET),
85
113
  USER_DETAILS_BY_USERNAME: (response: IUserDetailsResponse): User | undefined => User.single(response),
@@ -97,6 +125,7 @@ export const Extractors = {
97
125
  new CursoredData<User>(response, BaseType.USER),
98
126
  USER_HIGHLIGHTS: (response: IUserHighlightsResponse): CursoredData<Tweet> =>
99
127
  new CursoredData<Tweet>(response, BaseType.TWEET),
128
+ USER_LISTS: (response: IUserListsResponse): CursoredData<List> => new CursoredData<List>(response, BaseType.LIST),
100
129
  USER_LIKES: (response: IUserLikesResponse): CursoredData<Tweet> =>
101
130
  new CursoredData<Tweet>(response, BaseType.TWEET),
102
131
  USER_MEDIA: (response: IUserMediaResponse): CursoredData<Tweet> =>
@@ -17,8 +17,12 @@ export const AllowGuestAuthenticationGroup = [
17
17
  * @internal
18
18
  */
19
19
  export const FetchResourcesGroup = [
20
+ ResourceType.LIST_DETAILS,
20
21
  ResourceType.LIST_MEMBERS,
21
22
  ResourceType.LIST_TWEETS,
23
+ ResourceType.DM_CONVERSATION,
24
+ ResourceType.DM_INBOX_INITIAL_STATE,
25
+ ResourceType.DM_INBOX_TIMELINE,
22
26
  ResourceType.TWEET_DETAILS,
23
27
  ResourceType.TWEET_DETAILS_ALT,
24
28
  ResourceType.TWEET_DETAILS_BULK,
@@ -27,6 +31,7 @@ export const FetchResourcesGroup = [
27
31
  ResourceType.TWEET_RETWEETERS,
28
32
  ResourceType.TWEET_SEARCH,
29
33
  ResourceType.USER_AFFILIATES,
34
+ ResourceType.USER_ANALYTICS,
30
35
  ResourceType.USER_BOOKMARKS,
31
36
  ResourceType.USER_DETAILS_BY_USERNAME,
32
37
  ResourceType.USER_DETAILS_BY_ID,
@@ -37,6 +42,7 @@ export const FetchResourcesGroup = [
37
42
  ResourceType.USER_FOLLOWERS,
38
43
  ResourceType.USER_HIGHLIGHTS,
39
44
  ResourceType.USER_LIKES,
45
+ ResourceType.USER_LISTS,
40
46
  ResourceType.USER_MEDIA,
41
47
  ResourceType.USER_NOTIFICATIONS,
42
48
  ResourceType.USER_SUBSCRIPTIONS,
@@ -50,13 +56,18 @@ export const FetchResourcesGroup = [
50
56
  * @internal
51
57
  */
52
58
  export const PostResourcesGroup = [
59
+ ResourceType.LIST_MEMBER_ADD,
60
+ ResourceType.LIST_MEMBER_REMOVE,
53
61
  ResourceType.MEDIA_UPLOAD_APPEND,
54
62
  ResourceType.MEDIA_UPLOAD_FINALIZE,
55
63
  ResourceType.MEDIA_UPLOAD_INITIALIZE,
64
+ ResourceType.DM_DELETE_CONVERSATION,
65
+ ResourceType.TWEET_BOOKMARK,
56
66
  ResourceType.TWEET_LIKE,
57
67
  ResourceType.TWEET_POST,
58
68
  ResourceType.TWEET_RETWEET,
59
69
  ResourceType.TWEET_SCHEDULE,
70
+ ResourceType.TWEET_UNBOOKMARK,
60
71
  ResourceType.TWEET_UNLIKE,
61
72
  ResourceType.TWEET_UNPOST,
62
73
  ResourceType.TWEET_UNRETWEET,
@@ -1,6 +1,7 @@
1
1
  import { AxiosRequestConfig } from 'axios';
2
2
 
3
3
  import { ResourceType } from '../enums/Resource';
4
+ import { DMRequests } from '../requests/DirectMessage';
4
5
  import { ListRequests } from '../requests/List';
5
6
  import { MediaRequests } from '../requests/Media';
6
7
  import { TweetRequests } from '../requests/Tweet';
@@ -18,13 +19,22 @@ import { TweetRepliesSortTypeMap } from './Tweet';
18
19
  export const Requests: { [key in keyof typeof ResourceType]: (args: IFetchArgs | IPostArgs) => AxiosRequestConfig } = {
19
20
  /* eslint-disable @typescript-eslint/naming-convention */
20
21
 
22
+ LIST_DETAILS: (args: IFetchArgs) => ListRequests.details(args.id!),
21
23
  LIST_MEMBERS: (args: IFetchArgs) => ListRequests.members(args.id!, args.count, args.cursor),
24
+ LIST_MEMBER_ADD: (args: IPostArgs) => ListRequests.addMember(args.id!, args.userId!),
25
+ LIST_MEMBER_REMOVE: (args: IPostArgs) => ListRequests.removeMember(args.id!, args.userId!),
22
26
  LIST_TWEETS: (args: IFetchArgs) => ListRequests.tweets(args.id!, args.count, args.cursor),
23
27
 
24
28
  MEDIA_UPLOAD_APPEND: (args: IPostArgs) => MediaRequests.appendUpload(args.upload!.id!, args.upload!.media!),
25
29
  MEDIA_UPLOAD_FINALIZE: (args: IPostArgs) => MediaRequests.finalizeUpload(args.upload!.id!),
26
30
  MEDIA_UPLOAD_INITIALIZE: (args: IPostArgs) => MediaRequests.initializeUpload(args.upload!.size!),
27
31
 
32
+ DM_CONVERSATION: (args: IFetchArgs) => DMRequests.conversation(args.conversationId!, args.maxId),
33
+ DM_INBOX_INITIAL_STATE: () => DMRequests.inboxInitial(),
34
+ DM_INBOX_TIMELINE: (args: IFetchArgs) => DMRequests.inboxTimeline(args.maxId),
35
+ DM_DELETE_CONVERSATION: (args: IPostArgs) => DMRequests.deleteConversation(args.conversationId!),
36
+
37
+ TWEET_BOOKMARK: (args: IPostArgs) => TweetRequests.bookmark(args.id!),
28
38
  TWEET_DETAILS: (args: IFetchArgs) => TweetRequests.details(args.id!),
29
39
  TWEET_DETAILS_ALT: (args: IFetchArgs) => TweetRequests.replies(args.id!),
30
40
  TWEET_DETAILS_BULK: (args: IFetchArgs) => TweetRequests.bulkDetails(args.ids!),
@@ -37,12 +47,21 @@ export const Requests: { [key in keyof typeof ResourceType]: (args: IFetchArgs |
37
47
  TWEET_RETWEETERS: (args: IFetchArgs) => TweetRequests.retweeters(args.id!, args.count, args.cursor),
38
48
  TWEET_SCHEDULE: (args: IPostArgs) => TweetRequests.schedule(args.tweet!),
39
49
  TWEET_SEARCH: (args: IFetchArgs) => TweetRequests.search(args.filter!, args.count, args.cursor),
50
+ TWEET_UNBOOKMARK: (args: IPostArgs) => TweetRequests.unbookmark(args.id!),
40
51
  TWEET_UNLIKE: (args: IPostArgs) => TweetRequests.unlike(args.id!),
41
52
  TWEET_UNPOST: (args: IPostArgs) => TweetRequests.unpost(args.id!),
42
53
  TWEET_UNRETWEET: (args: IPostArgs) => TweetRequests.unretweet(args.id!),
43
54
  TWEET_UNSCHEDULE: (args: IPostArgs) => TweetRequests.unschedule(args.id!),
44
55
 
45
56
  USER_AFFILIATES: (args: IFetchArgs) => UserRequests.affiliates(args.id!, args.count, args.cursor),
57
+ USER_ANALYTICS: (args: IFetchArgs) =>
58
+ UserRequests.analytics(
59
+ args.fromTime!,
60
+ args.toTime!,
61
+ args.granularity!,
62
+ args.metrics!,
63
+ args.showVerifiedFollowers!,
64
+ ),
46
65
  USER_BOOKMARKS: (args: IFetchArgs) => UserRequests.bookmarks(args.count, args.cursor),
47
66
  USER_DETAILS_BY_USERNAME: (args: IFetchArgs) => UserRequests.detailsByUsername(args.id!),
48
67
  USER_DETAILS_BY_ID: (args: IFetchArgs) => UserRequests.detailsById(args.id!),
@@ -54,6 +73,7 @@ export const Requests: { [key in keyof typeof ResourceType]: (args: IFetchArgs |
54
73
  USER_FOLLOWERS: (args: IFetchArgs) => UserRequests.followers(args.id!, args.count, args.cursor),
55
74
  USER_HIGHLIGHTS: (args: IFetchArgs) => UserRequests.highlights(args.id!, args.count, args.cursor),
56
75
  USER_LIKES: (args: IFetchArgs) => UserRequests.likes(args.id!, args.count, args.cursor),
76
+ USER_LISTS: (args: IFetchArgs) => UserRequests.lists(args.id!, args.count, args.cursor),
57
77
  USER_MEDIA: (args: IFetchArgs) => UserRequests.media(args.id!, args.count, args.cursor),
58
78
  USER_NOTIFICATIONS: (args: IFetchArgs) => UserRequests.notifications(args.count, args.cursor),
59
79
  USER_SUBSCRIPTIONS: (args: IFetchArgs) => UserRequests.subscriptions(args.id!, args.count, args.cursor),
@@ -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;
@@ -11,12 +11,39 @@ import { Rettiwt } from '../Rettiwt';
11
11
  */
12
12
  function createListCommand(rettiwt: Rettiwt): Command {
13
13
  // Creating the 'list' command
14
- const list = createCommand('list').description('Access resources releated to lists');
14
+ const list = createCommand('list').description('Access resources related to lists');
15
+
16
+ // Add member
17
+ list.command('add-member')
18
+ .description('Add a new member to a list')
19
+ .argument('<list-id>', 'The ID of the tweet list')
20
+ .argument('<user-id>', 'The ID of the user to add')
21
+ .action(async (listId: string, userId: string) => {
22
+ try {
23
+ const memberCount = await rettiwt.list.addMember(listId, userId);
24
+ output(memberCount);
25
+ } catch (error) {
26
+ output(error);
27
+ }
28
+ });
29
+
30
+ // Details
31
+ list.command('details')
32
+ .description('Fetch the details of a list')
33
+ .argument('<id>', 'The ID of the tweet list')
34
+ .action(async (id: string) => {
35
+ try {
36
+ const details = await rettiwt.list.details(id);
37
+ output(details);
38
+ } catch (error) {
39
+ output(error);
40
+ }
41
+ });
15
42
 
16
43
  // Members
17
44
  list.command('members')
18
45
  .description('Fetch the list of members of the given tweet list')
19
- .argument('<id>', 'The id of the tweet list')
46
+ .argument('<id>', 'The ID of the tweet list')
20
47
  .argument('[count]', 'The number of members to fetch')
21
48
  .argument('[cursor]', 'The cursor to the batch of members to fetch')
22
49
  .action(async (id: string, count?: string, cursor?: string) => {
@@ -28,10 +55,24 @@ function createListCommand(rettiwt: Rettiwt): Command {
28
55
  }
29
56
  });
30
57
 
58
+ // Remove member
59
+ list.command('remove-member')
60
+ .description('Remove a new member from a list')
61
+ .argument('<list-id>', 'The ID of the tweet list')
62
+ .argument('<user-id>', 'The ID of the user to remove')
63
+ .action(async (listId: string, userId: string) => {
64
+ try {
65
+ const memberCount = await rettiwt.list.removeMember(listId, userId);
66
+ output(memberCount);
67
+ } catch (error) {
68
+ output(error);
69
+ }
70
+ });
71
+
31
72
  // Tweets
32
73
  list.command('tweets')
33
74
  .description('Fetch the list of tweets in the tweet list with the given id')
34
- .argument('<id>', 'The id of the tweet list')
75
+ .argument('<id>', 'The ID of the tweet list')
35
76
  .argument('[count]', 'The number of tweets to fetch')
36
77
  .argument('[cursor]', 'The cursor to the batch of tweets to fetch')
37
78
  .action(async (id: string, count?: string, cursor?: string) => {
@@ -14,7 +14,21 @@ import { ITweetFilter } from '../types/args/FetchArgs';
14
14
  */
15
15
  function createTweetCommand(rettiwt: Rettiwt): Command {
16
16
  // Creating the 'tweet' command
17
- const tweet = createCommand('tweet').description('Access resources releated to tweets');
17
+ const tweet = createCommand('tweet').description('Access resources related to tweets');
18
+
19
+ // Bookmark
20
+ tweet
21
+ .command('bookmark')
22
+ .description('Bookmark a tweet')
23
+ .argument('<id>', 'The tweet to bookmark')
24
+ .action(async (id: string) => {
25
+ try {
26
+ const result = await rettiwt.tweet.bookmark(id);
27
+ output(result);
28
+ } catch (error) {
29
+ output(error);
30
+ }
31
+ });
18
32
 
19
33
  // Details
20
34
  tweet
@@ -243,6 +257,20 @@ function createTweetCommand(rettiwt: Rettiwt): Command {
243
257
  }
244
258
  });
245
259
 
260
+ // Unbookmark
261
+ tweet
262
+ .command('unbookmark')
263
+ .description('Unbookmark a tweet')
264
+ .argument('<id>', 'The id of the tweet')
265
+ .action(async (id: string) => {
266
+ try {
267
+ const result = await rettiwt.tweet.unbookmark(id);
268
+ output(result);
269
+ } catch (error) {
270
+ output(error);
271
+ }
272
+ });
273
+
246
274
  // Unlike
247
275
  tweet
248
276
  .command('unlike')
@@ -1,5 +1,6 @@
1
1
  import { Command, createCommand } from 'commander';
2
2
 
3
+ import { RawAnalyticsGranularity, RawAnalyticsMetric } from '../enums/raw/Analytics';
3
4
  import { output } from '../helper/CliUtils';
4
5
  import { Rettiwt } from '../Rettiwt';
5
6
 
@@ -11,7 +12,7 @@ import { Rettiwt } from '../Rettiwt';
11
12
  */
12
13
  function createUserCommand(rettiwt: Rettiwt): Command {
13
14
  // Creating the 'user' command
14
- const user = createCommand('user').description('Access resources releated to users');
15
+ const user = createCommand('user').description('Access resources related to users');
15
16
 
16
17
  // Affiliates
17
18
  user.command('affiliates')
@@ -28,6 +29,44 @@ function createUserCommand(rettiwt: Rettiwt): Command {
28
29
  }
29
30
  });
30
31
 
32
+ // Analytics
33
+ user.command('analytics')
34
+ .description('Fetch the analytics of the logged-in user (premium accounts only)')
35
+ .option('-f, --from-time <string>', 'The start time for fetching analytics')
36
+ .option('-t, --to-time <string>', 'The end time for fetching analytics')
37
+ .option(
38
+ '-g, --granularity <string>',
39
+ 'The granularity of the analytics data. Defaults to daily. Check https://rishikant181.github.io/Rettiwt-API/enums/RawAnalyticsGranularity.html for granularity options',
40
+ )
41
+ .option(
42
+ '-m, --metrics <string>',
43
+ 'Comma-separated list of metrics required. Check https://rishikant181.github.io/Rettiwt-API/enums/RawAnalyticsMetric.html for available metrics',
44
+ )
45
+ .option(
46
+ '-v, --verified-followers',
47
+ 'Whether to include verified follower count and relationship counts in the response. Defaults to true',
48
+ )
49
+ .action(async (options?: UserAnalyticsOptions) => {
50
+ try {
51
+ const analytics = await rettiwt.user.analytics(
52
+ options?.fromTime ? new Date(options.fromTime) : undefined,
53
+ options?.toTime ? new Date(options.toTime) : undefined,
54
+ options?.granularity
55
+ ? RawAnalyticsGranularity[options.granularity as keyof typeof RawAnalyticsGranularity]
56
+ : undefined,
57
+ options?.metrics
58
+ ? options.metrics
59
+ .split(',')
60
+ .map((item) => RawAnalyticsMetric[item as keyof typeof RawAnalyticsMetric])
61
+ : undefined,
62
+ options?.verifiedFollowers,
63
+ );
64
+ output(analytics);
65
+ } catch (error) {
66
+ output(error);
67
+ }
68
+ });
69
+
31
70
  user.command('bookmarks')
32
71
  .description('Fetch your list of bookmarks')
33
72
  .argument('[count]', 'The number of bookmarks to fetch')
@@ -150,6 +189,20 @@ function createUserCommand(rettiwt: Rettiwt): Command {
150
189
  }
151
190
  });
152
191
 
192
+ // Lists
193
+ user.command('lists')
194
+ .description('Fetch your lists')
195
+ .argument('[count]', 'The number of lists to fetch')
196
+ .argument('[cursor]', 'The cursor to the batch of lists to fetch')
197
+ .action(async (count?: string, cursor?: string) => {
198
+ try {
199
+ const lists = await rettiwt.user.lists(count ? parseInt(count) : undefined, cursor);
200
+ output(lists);
201
+ } catch (error) {
202
+ output(error);
203
+ }
204
+ });
205
+
153
206
  // Media
154
207
  user.command('media')
155
208
  .description('Fetch the media timeline the given user')
@@ -224,4 +277,15 @@ function createUserCommand(rettiwt: Rettiwt): Command {
224
277
  return user;
225
278
  }
226
279
 
280
+ /**
281
+ * The options for fetching user analytics.
282
+ */
283
+ type UserAnalyticsOptions = {
284
+ fromTime?: string;
285
+ toTime?: string;
286
+ granularity?: string;
287
+ metrics?: string;
288
+ verifiedFollowers?: boolean;
289
+ };
290
+
227
291
  export default createUserCommand;
package/src/enums/Data.ts CHANGED
@@ -4,7 +4,9 @@
4
4
  * @internal
5
5
  */
6
6
  export enum BaseType {
7
+ DIRECT_MESSAGE = 'DIRECT_MESSAGE',
7
8
  NOTIFICATION = 'NOTIFICATION',
8
9
  TWEET = 'TWEET',
9
10
  USER = 'USER',
11
+ LIST = 'LIST',
10
12
  }