twitterapi-io-client 1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 jorvixsky
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,145 @@
1
+ # TwitterAPI.io TypeScript Client
2
+
3
+ A TypeScript client library for the [TwitterAPI.io](https://docs.twitterapi.io) API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install twitterapi-io-client
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { TwitterAPIIOClient } from 'twitterapi-io-client';
15
+
16
+ const client = new TwitterAPIIOClient({
17
+ apiKey: 'your-api-key'
18
+ });
19
+ ```
20
+
21
+ ## Supported Endpoints
22
+
23
+ ### ✅ User Endpoint
24
+
25
+ | Endpoint | Method | Status | Notes |
26
+ |----------|--------|--------|-------|
27
+ | Get User Profile About | `GET /twitter/user_about` | ✅ Supported | `client.users.getUserProfileAbout(userName)` |
28
+ | Get User Info | `GET /twitter/user/info` | ✅ Supported | `client.users.getUserInfo(userName)` |
29
+ | Get User Last Tweets | `GET /twitter/user/latest_tweets` | ✅ Supported | `client.users.getUserLatestTweets(userId?, userName?, cursor?, pageSize?, includeReplies?)` |
30
+ | Get User Followers | `GET /twitter/user/followers` | ✅ Supported | `client.users.getUserFollowers(userName, cursor?, pageSize?)` |
31
+ | Get User Followings | `GET /twitter/user/followings` | ✅ Supported | `client.users.getUserFollowings(userName, cursor?, pageSize?)` |
32
+ | Get User Mentions | `GET /twitter/user/mentions` | ✅ Supported | `client.users.getUserMentions(username, sinceTime, untilTime, cursor?)` |
33
+ | Check Follow Relationship | `GET /twitter/user/check_follow_relationship` | ✅ Supported | `client.users.checkFollowRelationship(sourceUserName, targetUserName)` |
34
+ | Search user by keyword | `GET /twitter/user/search` | ✅ Supported | `client.users.searchUserByKeyword(query, cursor?)` |
35
+ | Get User Verified Followers | `GET /twitter/user/verifiedFollowers` | ✅ Supported | `client.users.getUserVerifiedFollowers(userId, cursor?)` |
36
+ | Batch Get User Info By UserIds | `GET /twitter/user/batch` | ❌ Not Supported | - |
37
+
38
+ ### ✅ List Endpoint
39
+
40
+ | Endpoint | Method | Status | Notes |
41
+ |----------|--------|--------|-------|
42
+ | Get List Followers | `GET /twitter/list/followers` | ✅ Supported | `client.list.getListFollowers(listId, cursor?)` |
43
+ | Get List Members | `GET /twitter/list/members` | ✅ Supported | `client.list.getListMembers(listId, cursor?)` |
44
+
45
+ ### ✅ My Endpoint
46
+
47
+ | Endpoint | Method | Status | Notes |
48
+ |----------|--------|--------|-------|
49
+ | Get My Account Info | `GET /oapi/my/info` | ✅ Supported | `client.myEndpoint.getMyAccountInfo()` |
50
+
51
+ ### ✅ Communities Endpoint
52
+
53
+ | Endpoint | Method | Status | Notes |
54
+ |----------|--------|--------|-------|
55
+ | Get Community Info By Id | `GET /twitter/community/info` | ✅ Supported | `client.communities.getCommunityInfo(communityId)` |
56
+ | Get Community Members | `GET /twitter/community/members` | ✅ Supported | `client.communities.getCommunityMembers(communityId, cursor?)` |
57
+ | Get Community Moderators | `GET /twitter/community/moderators` | ✅ Supported | `client.communities.getCommunityModerators(communityId, cursor?)` |
58
+ | Get Community Tweets | `GET /twitter/community/tweets` | ✅ Supported | `client.communities.getCommunityTweets(communityId, cursor?)` |
59
+ | Search Tweets From All Community | `GET /twitter/community/search` | ✅ Supported | `client.communities.searchCommunityTweets(query, queryType?, cursor?)` |
60
+
61
+ ### ✅ Trend Endpoint
62
+
63
+ | Endpoint | Method | Status | Notes |
64
+ |----------|--------|--------|-------|
65
+ | Get Trends | `GET /twitter/trends` | ✅ Supported | `client.trends.getTrends(woeid)` |
66
+
67
+ ### ✅ Spaces Endpoint
68
+
69
+ | Endpoint | Method | Status | Notes |
70
+ |----------|--------|--------|-------|
71
+ | Get Space Detail | `GET /twitter/space/detail` | ✅ Supported | `client.spaces.getSpaceDetail(spaceId)` |
72
+
73
+ ### ✅ Tweet Endpoint
74
+
75
+ | Endpoint | Method | Status | Notes |
76
+ |----------|--------|--------|-------|
77
+ | Get Tweets by IDs | `GET /twitter/tweet/by_ids` | ✅ Supported | `client.tweets.getTweetsByIds(tweetIds)` |
78
+ | Get Tweet Replies | `GET /twitter/tweet/replies` | ✅ Supported | `client.tweets.getTweetReplies(tweetId, cursor?)` |
79
+ | Get Tweet Quotations | `GET /twitter/tweet/quotations` | ✅ Supported | `client.tweets.getTweetQuotations(tweetId, cursor?)` |
80
+ | Get Tweet Retweeters | `GET /twitter/tweet/retweeters` | ✅ Supported | `client.tweets.getTweetRetweeters(tweetId, cursor?)` |
81
+ | Get Tweet Thread Context | `GET /twitter/tweet/thread_context` | ✅ Supported | `client.tweets.getTweetThreadContext(tweetId)` |
82
+ | Get Article | `GET /twitter/article` | ✅ Supported | `client.tweets.getArticle(articleId)` |
83
+ | Advanced Search | `GET /twitter/search` | ✅ Supported | `client.tweets.searchTweets(query, queryType?, cursor?)` |
84
+
85
+ ## Not Supported Endpoints
86
+
87
+ The following endpoint categories are **not yet implemented**:
88
+
89
+ ### ❌ Post & Action Endpoint V2
90
+
91
+ - `POST /oapi/login` - Log in
92
+ - `POST /oapi/upload/media` - Upload media
93
+ - `POST /oapi/tweet/create` - Create tweet v2
94
+ - `GET /oapi/dm/history` - Get History Messages By UserID
95
+ - `POST /oapi/dm/send` - Send DM V2
96
+ - `POST /oapi/tweet/retweet` - Retweet Tweet
97
+ - `POST /oapi/tweet/delete` - Delete Tweet
98
+ - `POST /oapi/user/follow` - Follow User
99
+ - `POST /oapi/user/unfollow` - Unfollow User
100
+ - `POST /oapi/tweet/like` - Like Tweet
101
+ - `POST /oapi/tweet/unlike` - Unlike Tweet
102
+ - `POST /oapi/community/create` - Create Community V2
103
+ - `POST /oapi/community/delete` - Delete Community V2
104
+ - `POST /oapi/community/join` - Join Community v2
105
+ - `POST /oapi/community/leave` - Leave Community V2
106
+
107
+ ### ❌ Webhook/Websocket Filter Rule
108
+
109
+ - `POST /oapi/webhook/filter/add` - Add Webhook/Websocket Tweet Filter Rule
110
+ - `GET /oapi/webhook/filter/all` - Get ALL test Webhook/Websocket Tweet Filter Rules
111
+ - `POST /oapi/webhook/filter/update` - Update Webhook/Websocket Tweet Filter Rule
112
+ - `DELETE /oapi/webhook/filter/delete` - Delete Webhook/Websocket Tweet Filter Rule
113
+
114
+ ### ❌ Stream Endpoint
115
+
116
+ - `POST /oapi/stream/add` - Add a twitter user to monitor his tweets
117
+ - `POST /oapi/stream/remove` - Remove a user from monitor list
118
+
119
+ ### ❌ Deprecated Endpoints
120
+
121
+ The following endpoints are marked as deprecated in the API documentation and are not implemented:
122
+
123
+ - Login Endpoint (deprecated)
124
+ - `POST /oapi/login/step1` - Login Step 1: by email or username
125
+ - `POST /oapi/login/step2` - Login Step 2: by 2fa code
126
+
127
+ - Tweet Action Endpoint (deprecated)
128
+ - `POST /oapi/tweet/upload_image` - Upload Image
129
+ - `POST /oapi/tweet/post` - Post/reply/quote a tweet
130
+ - `POST /oapi/tweet/like` - Like a tweet
131
+ - `POST /oapi/tweet/retweet` - Retweet a tweet
132
+
133
+ ## Implementation Status Summary
134
+
135
+ - **Fully Supported**: 26 endpoints (9 User endpoints + 2 List endpoints + 1 My endpoint + 5 Communities endpoints + 1 Trend endpoint + 1 Spaces endpoint + 7 Tweet endpoints)
136
+ - **Not Implemented**: ~16+ endpoints across multiple categories
137
+
138
+ ## Contributing
139
+
140
+ Contributions are welcome! If you'd like to add support for additional endpoints, please refer to the existing implementation patterns in the `src/resources/` directory.
141
+
142
+ ## API Documentation
143
+
144
+ For detailed API documentation, visit: [https://docs.twitterapi.io](https://docs.twitterapi.io)
145
+
@@ -0,0 +1,20 @@
1
+ import { type HttpClientOptions } from "./httpClient";
2
+ import { UsersApi } from "./resources/users";
3
+ import { MyEndpointApi } from "./resources/myEndpoint";
4
+ import { ListApi } from "./resources/list";
5
+ import { CommunitiesApi } from "./resources/communities";
6
+ import { TrendsApi } from "./resources/trends";
7
+ import { SpacesApi } from "./resources/spaces";
8
+ import { TweetsApi } from "./resources/tweets";
9
+ export interface TwitterAPIIOClientOptions extends HttpClientOptions {
10
+ }
11
+ export declare class TwitterAPIIOClient {
12
+ readonly users: UsersApi;
13
+ readonly myEndpoint: MyEndpointApi;
14
+ readonly list: ListApi;
15
+ readonly communities: CommunitiesApi;
16
+ readonly trends: TrendsApi;
17
+ readonly spaces: SpacesApi;
18
+ readonly tweets: TweetsApi;
19
+ constructor(options: TwitterAPIIOClientOptions);
20
+ }
package/dist/client.js ADDED
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TwitterAPIIOClient = void 0;
4
+ const httpClient_1 = require("./httpClient");
5
+ const users_1 = require("./resources/users");
6
+ const myEndpoint_1 = require("./resources/myEndpoint");
7
+ const list_1 = require("./resources/list");
8
+ const communities_1 = require("./resources/communities");
9
+ const trends_1 = require("./resources/trends");
10
+ const spaces_1 = require("./resources/spaces");
11
+ const tweets_1 = require("./resources/tweets");
12
+ class TwitterAPIIOClient {
13
+ users;
14
+ myEndpoint;
15
+ list;
16
+ communities;
17
+ trends;
18
+ spaces;
19
+ tweets;
20
+ constructor(options) {
21
+ const http = new httpClient_1.HttpClient(options);
22
+ this.users = new users_1.UsersApi(http);
23
+ this.myEndpoint = new myEndpoint_1.MyEndpointApi(http);
24
+ this.list = new list_1.ListApi(http);
25
+ this.communities = new communities_1.CommunitiesApi(http);
26
+ this.trends = new trends_1.TrendsApi(http);
27
+ this.spaces = new spaces_1.SpacesApi(http);
28
+ this.tweets = new tweets_1.TweetsApi(http);
29
+ }
30
+ }
31
+ exports.TwitterAPIIOClient = TwitterAPIIOClient;
@@ -0,0 +1,10 @@
1
+ export interface HttpClientOptions {
2
+ apiKey: string;
3
+ baseUrl?: string;
4
+ }
5
+ export declare class HttpClient {
6
+ private apiKey;
7
+ private baseUrl;
8
+ constructor({ apiKey, baseUrl }: HttpClientOptions);
9
+ request<T>(path: string, init?: RequestInit): Promise<T>;
10
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpClient = void 0;
4
+ class HttpClient {
5
+ apiKey;
6
+ baseUrl;
7
+ constructor({ apiKey, baseUrl = "https://api.twitterapi.io" }) {
8
+ this.apiKey = apiKey;
9
+ this.baseUrl = baseUrl;
10
+ }
11
+ async request(path, init = {}) {
12
+ const response = await fetch(`${this.baseUrl}${path}`, {
13
+ ...init,
14
+ headers: {
15
+ ...(init.headers ?? {}),
16
+ "X-API-Key": this.apiKey,
17
+ },
18
+ });
19
+ if (!response.ok) {
20
+ throw new Error(response.statusText);
21
+ }
22
+ const json = await response.json();
23
+ return json;
24
+ }
25
+ }
26
+ exports.HttpClient = HttpClient;
@@ -0,0 +1,2 @@
1
+ export * from "./client";
2
+ export * from "./types";
package/dist/index.js ADDED
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ // main client
18
+ __exportStar(require("./client"), exports);
19
+ // types
20
+ __exportStar(require("./types"), exports);
@@ -0,0 +1,11 @@
1
+ import type { HttpClient } from "../httpClient";
2
+ import type { CommunityInfoResponse, CommunityMembersResponse, CommunityModeratorsResponse, CommunityTweetsResponse, CommunitySearchResponse } from "../types/communities";
3
+ export declare class CommunitiesApi {
4
+ private http;
5
+ constructor(http: HttpClient);
6
+ getCommunityInfo(communityId: string): Promise<CommunityInfoResponse>;
7
+ getCommunityMembers(communityId: string, cursor?: string): Promise<CommunityMembersResponse>;
8
+ getCommunityModerators(communityId: string, cursor?: string): Promise<CommunityModeratorsResponse>;
9
+ getCommunityTweets(communityId: string, cursor?: string): Promise<CommunityTweetsResponse>;
10
+ searchCommunityTweets(query: string, queryType?: "latest" | "top", cursor?: string): Promise<CommunitySearchResponse>;
11
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CommunitiesApi = void 0;
4
+ class CommunitiesApi {
5
+ http;
6
+ constructor(http) {
7
+ this.http = http;
8
+ }
9
+ async getCommunityInfo(communityId) {
10
+ const params = new URLSearchParams({ community_id: communityId });
11
+ const response = await this.http.request(`/twitter/community/info?${params.toString()}`);
12
+ return response;
13
+ }
14
+ async getCommunityMembers(communityId, cursor) {
15
+ const params = new URLSearchParams({ community_id: communityId, cursor: cursor ?? "" });
16
+ const response = await this.http.request(`/twitter/community/members?${params.toString()}`);
17
+ return response;
18
+ }
19
+ async getCommunityModerators(communityId, cursor) {
20
+ const params = new URLSearchParams({ community_id: communityId, cursor: cursor ?? "" });
21
+ const response = await this.http.request(`/twitter/community/moderators?${params.toString()}`);
22
+ return response;
23
+ }
24
+ async getCommunityTweets(communityId, cursor) {
25
+ const params = new URLSearchParams({ community_id: communityId, cursor: cursor ?? "" });
26
+ const response = await this.http.request(`/twitter/community/tweets?${params.toString()}`);
27
+ return response;
28
+ }
29
+ async searchCommunityTweets(query, queryType, cursor) {
30
+ const params = new URLSearchParams({ query, queryType: queryType ?? "latest", cursor: cursor ?? "" });
31
+ const response = await this.http.request(`/twitter/community/search?${params.toString()}`);
32
+ return response;
33
+ }
34
+ }
35
+ exports.CommunitiesApi = CommunitiesApi;
@@ -0,0 +1,8 @@
1
+ import type { HttpClient } from "../httpClient";
2
+ import type { ListFollowersResponse, ListMembersResponse } from "../types/list";
3
+ export declare class ListApi {
4
+ private http;
5
+ constructor(http: HttpClient);
6
+ getListFollowers(listId: string, cursor?: string): Promise<ListFollowersResponse>;
7
+ getListMembers(listId: string, cursor?: string): Promise<ListMembersResponse>;
8
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ListApi = void 0;
4
+ class ListApi {
5
+ http;
6
+ constructor(http) {
7
+ this.http = http;
8
+ }
9
+ async getListFollowers(listId, cursor) {
10
+ const params = new URLSearchParams({ list_id: listId, cursor: cursor ?? "" });
11
+ const response = await this.http.request(`/twitter/list/followers?${params.toString()}`);
12
+ return response;
13
+ }
14
+ async getListMembers(listId, cursor) {
15
+ const params = new URLSearchParams({ list_id: listId, cursor: cursor ?? "" });
16
+ const response = await this.http.request(`/twitter/list/members?${params.toString()}`);
17
+ return response;
18
+ }
19
+ }
20
+ exports.ListApi = ListApi;
@@ -0,0 +1,7 @@
1
+ import type { HttpClient } from "../httpClient";
2
+ import type { MyAccountInfoResponse } from "../types/myEndpoint";
3
+ export declare class MyEndpointApi {
4
+ private http;
5
+ constructor(http: HttpClient);
6
+ getMyAccountInfo(): Promise<MyAccountInfoResponse>;
7
+ }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MyEndpointApi = void 0;
4
+ class MyEndpointApi {
5
+ http;
6
+ constructor(http) {
7
+ this.http = http;
8
+ }
9
+ getMyAccountInfo() {
10
+ return this.http.request("/oapi/my/info");
11
+ }
12
+ }
13
+ exports.MyEndpointApi = MyEndpointApi;
@@ -0,0 +1,7 @@
1
+ import type { HttpClient } from "../httpClient";
2
+ import type { SpaceDetailResponse } from "../types/spaces";
3
+ export declare class SpacesApi {
4
+ private http;
5
+ constructor(http: HttpClient);
6
+ getSpaceDetail(spaceId: string): Promise<SpaceDetailResponse>;
7
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SpacesApi = void 0;
4
+ class SpacesApi {
5
+ http;
6
+ constructor(http) {
7
+ this.http = http;
8
+ }
9
+ async getSpaceDetail(spaceId) {
10
+ const params = new URLSearchParams({ space_id: spaceId });
11
+ const response = await this.http.request(`/twitter/space/detail?${params.toString()}`);
12
+ return response;
13
+ }
14
+ }
15
+ exports.SpacesApi = SpacesApi;
@@ -0,0 +1,7 @@
1
+ import type { HttpClient } from "../httpClient";
2
+ import type { TrendsResponse } from "../types/trends";
3
+ export declare class TrendsApi {
4
+ private http;
5
+ constructor(http: HttpClient);
6
+ getTrends(woeid: number): Promise<TrendsResponse>;
7
+ }
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TrendsApi = void 0;
4
+ class TrendsApi {
5
+ http;
6
+ constructor(http) {
7
+ this.http = http;
8
+ }
9
+ async getTrends(woeid) {
10
+ const params = new URLSearchParams({ woeid: woeid.toString() });
11
+ const response = await this.http.request(`/twitter/trends?${params.toString()}`);
12
+ return response;
13
+ }
14
+ }
15
+ exports.TrendsApi = TrendsApi;
@@ -0,0 +1,13 @@
1
+ import type { HttpClient } from "../httpClient";
2
+ import type { TweetsByIdsResponse, TweetRepliesResponse, TweetQuotationsResponse, TweetRetweetersResponse, TweetThreadContextResponse, ArticleResponse, SearchTweetsResponse } from "../types/tweets";
3
+ export declare class TweetsApi {
4
+ private http;
5
+ constructor(http: HttpClient);
6
+ getTweetsByIds(tweetIds: string[]): Promise<TweetsByIdsResponse>;
7
+ getTweetReplies(tweetId: string, cursor?: string): Promise<TweetRepliesResponse>;
8
+ getTweetQuotations(tweetId: string, cursor?: string): Promise<TweetQuotationsResponse>;
9
+ getTweetRetweeters(tweetId: string, cursor?: string): Promise<TweetRetweetersResponse>;
10
+ getTweetThreadContext(tweetId: string): Promise<TweetThreadContextResponse>;
11
+ getArticle(articleId: string): Promise<ArticleResponse>;
12
+ searchTweets(query: string, queryType?: "latest" | "top", cursor?: string): Promise<SearchTweetsResponse>;
13
+ }
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TweetsApi = void 0;
4
+ class TweetsApi {
5
+ http;
6
+ constructor(http) {
7
+ this.http = http;
8
+ }
9
+ async getTweetsByIds(tweetIds) {
10
+ const params = new URLSearchParams({ tweet_ids: tweetIds.join(",") });
11
+ const response = await this.http.request(`/twitter/tweet/by_ids?${params.toString()}`);
12
+ return response;
13
+ }
14
+ async getTweetReplies(tweetId, cursor) {
15
+ const params = new URLSearchParams({ tweet_id: tweetId, cursor: cursor ?? "" });
16
+ const response = await this.http.request(`/twitter/tweet/replies?${params.toString()}`);
17
+ return response;
18
+ }
19
+ async getTweetQuotations(tweetId, cursor) {
20
+ const params = new URLSearchParams({ tweet_id: tweetId, cursor: cursor ?? "" });
21
+ const response = await this.http.request(`/twitter/tweet/quotations?${params.toString()}`);
22
+ return response;
23
+ }
24
+ async getTweetRetweeters(tweetId, cursor) {
25
+ const params = new URLSearchParams({ tweet_id: tweetId, cursor: cursor ?? "" });
26
+ const response = await this.http.request(`/twitter/tweet/retweeters?${params.toString()}`);
27
+ return response;
28
+ }
29
+ async getTweetThreadContext(tweetId) {
30
+ const params = new URLSearchParams({ tweet_id: tweetId });
31
+ const response = await this.http.request(`/twitter/tweet/thread_context?${params.toString()}`);
32
+ return response;
33
+ }
34
+ async getArticle(articleId) {
35
+ const params = new URLSearchParams({ article_id: articleId });
36
+ const response = await this.http.request(`/twitter/article?${params.toString()}`);
37
+ return response;
38
+ }
39
+ async searchTweets(query, queryType, cursor) {
40
+ const params = new URLSearchParams({ query, queryType: queryType ?? "latest", cursor: cursor ?? "" });
41
+ const response = await this.http.request(`/twitter/search?${params.toString()}`);
42
+ return response;
43
+ }
44
+ }
45
+ exports.TweetsApi = TweetsApi;
@@ -0,0 +1,15 @@
1
+ import type { HttpClient } from "../httpClient";
2
+ import type { FollowRelationshipResponse, SearchUserByKeywordResponse, UserFollowersResponse, UserFollowingsResponse, UserInfoResponse, UserLatestTweetsResponse, UserMentionsResponse, UserProfileAboutResponse, UserVerifiedFollowersResponse } from "../types/users";
3
+ export declare class UsersApi {
4
+ private http;
5
+ constructor(http: HttpClient);
6
+ getUserProfileAbout(userName: string): Promise<UserProfileAboutResponse>;
7
+ getUserInfo(userName: string): Promise<UserInfoResponse>;
8
+ getUserLatestTweets(userId?: string, userName?: string, cursor?: string, pageSize?: number, includeReplies?: boolean): Promise<UserLatestTweetsResponse>;
9
+ getUserFollowers(userName: string, cursor?: string, pageSize?: number): Promise<UserFollowersResponse>;
10
+ getUserFollowings(userName: string, cursor?: string, pageSize?: number): Promise<UserFollowingsResponse>;
11
+ getUserMentions(userName: string, sinceTime: number, untilTime: number, cursor?: string): Promise<UserMentionsResponse>;
12
+ checkFollowRelationship(sourceUserName: string, targetUserName: string): Promise<FollowRelationshipResponse>;
13
+ searchUserByKeyword(query: string, cursor?: string): Promise<SearchUserByKeywordResponse>;
14
+ getUserVerifiedFollowers(userId: string, cursor?: string): Promise<UserVerifiedFollowersResponse>;
15
+ }
@@ -0,0 +1,127 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UsersApi = void 0;
4
+ class UsersApi {
5
+ http;
6
+ constructor(http) {
7
+ this.http = http;
8
+ }
9
+ async getUserProfileAbout(userName) {
10
+ const params = new URLSearchParams({ userName });
11
+ const response = await this.http.request(`/twitter/user_about?${params.toString()}`);
12
+ return response;
13
+ }
14
+ async getUserInfo(userName) {
15
+ const params = new URLSearchParams({ userName });
16
+ const response = await this.http.request(`/twitter/user/info?${params.toString()}`);
17
+ return response.data;
18
+ }
19
+ async getUserLatestTweets(userId, userName, cursor, pageSize, includeReplies) {
20
+ if (!userId && !userName) {
21
+ throw new Error("Either userId or userName is required");
22
+ }
23
+ const params = new URLSearchParams();
24
+ if (userId)
25
+ params.append("userId", userId);
26
+ if (userName)
27
+ params.append("userName", userName);
28
+ if (cursor && cursor.trim() !== "")
29
+ params.append("cursor", cursor);
30
+ params.append("pageSize", pageSize?.toString() ?? "200");
31
+ params.append("includeReplies", includeReplies?.toString() ?? "false");
32
+ const url = `/twitter/user/latest_tweets?${params.toString()}`;
33
+ const response = await this.http.request(url);
34
+ // Check if tweets are at the top level (direct response)
35
+ if ('tweets' in response && Array.isArray(response.tweets)) {
36
+ return response;
37
+ }
38
+ // Handle response wrapped in { status, msg, data }
39
+ if ('data' in response && response.data) {
40
+ const data = response.data;
41
+ // Check if data contains tweets array (expected structure per docs)
42
+ if ('tweets' in data && Array.isArray(data.tweets)) {
43
+ return {
44
+ tweets: data.tweets,
45
+ has_next_page: data.has_next_page ?? false,
46
+ next_cursor: data.next_cursor ?? "",
47
+ status: data.status || response.status || "success",
48
+ message: data.message || response.msg
49
+ };
50
+ }
51
+ // If data doesn't have tweets, return empty structure (API might be returning wrong data)
52
+ return {
53
+ tweets: [],
54
+ has_next_page: false,
55
+ next_cursor: "",
56
+ status: response.status || "success",
57
+ message: response.msg
58
+ };
59
+ }
60
+ return response;
61
+ }
62
+ async getUserFollowers(userName, cursor, pageSize) {
63
+ const params = new URLSearchParams({ userName, cursor: cursor ?? "", pageSize: pageSize?.toString() ?? "200" });
64
+ const response = await this.http.request(`/twitter/user/followers?${params.toString()}`);
65
+ return response;
66
+ }
67
+ async getUserFollowings(userName, cursor, pageSize) {
68
+ const params = new URLSearchParams({ userName, cursor: cursor ?? "", pageSize: pageSize?.toString() ?? "200" });
69
+ const response = await this.http.request(`/twitter/user/followings?${params.toString()}`);
70
+ return response;
71
+ }
72
+ async getUserMentions(userName, sinceTime, untilTime, cursor) {
73
+ const params = new URLSearchParams({
74
+ userName,
75
+ sinceTime: sinceTime.toString(),
76
+ untilTime: untilTime.toString()
77
+ });
78
+ if (cursor && cursor.trim() !== "") {
79
+ params.append("cursor", cursor);
80
+ }
81
+ const url = `/twitter/user/mentions?${params.toString()}`;
82
+ const response = await this.http.request(url);
83
+ // Check if tweets are at the top level (direct response)
84
+ if ('tweets' in response && Array.isArray(response.tweets)) {
85
+ return response;
86
+ }
87
+ // Handle response wrapped in { status, msg, data }
88
+ if ('data' in response && response.data) {
89
+ const data = response.data;
90
+ // Check if data contains tweets array (expected structure per docs)
91
+ if ('tweets' in data && Array.isArray(data.tweets)) {
92
+ return {
93
+ tweets: data.tweets,
94
+ has_next_page: data.has_next_page ?? false,
95
+ next_cursor: data.next_cursor ?? "",
96
+ status: data.status || response.status || "success",
97
+ message: data.message || response.msg
98
+ };
99
+ }
100
+ // If data doesn't have tweets, return empty structure
101
+ return {
102
+ tweets: [],
103
+ has_next_page: false,
104
+ next_cursor: "",
105
+ status: response.status || "success",
106
+ message: response.msg
107
+ };
108
+ }
109
+ return response;
110
+ }
111
+ async checkFollowRelationship(sourceUserName, targetUserName) {
112
+ const params = new URLSearchParams({ source_user_name: sourceUserName, target_user_name: targetUserName });
113
+ const response = await this.http.request(`/twitter/user/check_follow_relationship?${params.toString()}`);
114
+ return response;
115
+ }
116
+ async searchUserByKeyword(query, cursor) {
117
+ const params = new URLSearchParams({ query, cursor: cursor ?? "" });
118
+ const response = await this.http.request(`/twitter/user/search?${params.toString()}`);
119
+ return response;
120
+ }
121
+ async getUserVerifiedFollowers(userId, cursor) {
122
+ const params = new URLSearchParams({ user_id: userId, cursor: cursor ?? "" });
123
+ const response = await this.http.request(`/twitter/user/verifiedFollowers?${params.toString()}`);
124
+ return response;
125
+ }
126
+ }
127
+ exports.UsersApi = UsersApi;
@@ -0,0 +1,43 @@
1
+ import type { UserInfoResponse } from "./users";
2
+ import type { Tweet } from "./tweets";
3
+ export interface CommunityInfoResponse {
4
+ id: string;
5
+ name: string;
6
+ description: string;
7
+ member_count: number;
8
+ moderator_count: number;
9
+ created_at: string;
10
+ rules?: string[];
11
+ banner_image?: string;
12
+ profile_image?: string;
13
+ status: string;
14
+ message?: string;
15
+ }
16
+ export interface CommunityMembersResponse {
17
+ members: UserInfoResponse[];
18
+ has_next_page: boolean;
19
+ next_cursor: string;
20
+ status: string;
21
+ msg?: string;
22
+ }
23
+ export interface CommunityModeratorsResponse {
24
+ moderators: UserInfoResponse[];
25
+ has_next_page: boolean;
26
+ next_cursor: string;
27
+ status: string;
28
+ msg?: string;
29
+ }
30
+ export interface CommunityTweetsResponse {
31
+ tweets: Tweet[];
32
+ has_next_page: boolean;
33
+ next_cursor: string;
34
+ status: string;
35
+ message?: string;
36
+ }
37
+ export interface CommunitySearchResponse {
38
+ tweets: Tweet[];
39
+ has_next_page: boolean;
40
+ next_cursor: string;
41
+ status: string;
42
+ message?: string;
43
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,7 @@
1
+ export * from "./users";
2
+ export * from "./tweets";
3
+ export * from "./communities";
4
+ export * from "./spaces";
5
+ export * from "./trends";
6
+ export * from "./list";
7
+ export * from "./myEndpoint";
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./users"), exports);
18
+ __exportStar(require("./tweets"), exports);
19
+ __exportStar(require("./communities"), exports);
20
+ __exportStar(require("./spaces"), exports);
21
+ __exportStar(require("./trends"), exports);
22
+ __exportStar(require("./list"), exports);
23
+ __exportStar(require("./myEndpoint"), exports);
@@ -0,0 +1,15 @@
1
+ import type { UserInfoResponse } from "./users";
2
+ export interface ListFollowersResponse {
3
+ followers: UserInfoResponse[];
4
+ has_next_page: boolean;
5
+ next_cursor: string;
6
+ status: string;
7
+ msg?: string;
8
+ }
9
+ export interface ListMembersResponse {
10
+ members: UserInfoResponse[];
11
+ has_next_page: boolean;
12
+ next_cursor: string;
13
+ status: string;
14
+ msg?: string;
15
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,4 @@
1
+ export interface MyAccountInfoResponse {
2
+ recharge_credits: number;
3
+ total_bonus_credits: number;
4
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,23 @@
1
+ import type { UserInfoResponse } from "./users";
2
+ export interface SpaceDetailResponse {
3
+ id: string;
4
+ state: string;
5
+ title?: string;
6
+ created_at?: string;
7
+ started_at?: string;
8
+ ended_at?: string;
9
+ updated_at?: string;
10
+ host_ids?: string[];
11
+ speaker_ids?: string[];
12
+ creator_id?: string;
13
+ lang?: string;
14
+ is_ticketed?: boolean;
15
+ participant_count?: number;
16
+ subscriber_count?: number;
17
+ scheduled_start?: string;
18
+ creator?: UserInfoResponse;
19
+ hosts?: UserInfoResponse[];
20
+ speakers?: UserInfoResponse[];
21
+ status: string;
22
+ message?: string;
23
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,19 @@
1
+ export interface Trend {
2
+ name: string;
3
+ url: string;
4
+ promoted_content?: unknown;
5
+ query: string;
6
+ tweet_volume?: number;
7
+ }
8
+ export interface TrendLocation {
9
+ name: string;
10
+ woeid: number;
11
+ }
12
+ export interface TrendsResponse {
13
+ trends: Trend[];
14
+ as_of: string;
15
+ created_at: string;
16
+ locations: TrendLocation[];
17
+ status: string;
18
+ message?: string;
19
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,94 @@
1
+ import type { UserInfoResponse } from "./users";
2
+ export interface Tweet {
3
+ type: string;
4
+ id: string;
5
+ url: string;
6
+ text: string;
7
+ source: string;
8
+ retweetCount: number;
9
+ replyCount: number;
10
+ likeCount: number;
11
+ quoteCount: number;
12
+ viewCount: number;
13
+ createdAt: string;
14
+ lang: string;
15
+ bookmarkCount: number;
16
+ isReply: boolean;
17
+ inReplyToId?: string;
18
+ conversationId: string;
19
+ displayTextRange?: number[];
20
+ inReplyToUserId?: string;
21
+ inReplyToUsername?: string;
22
+ author: UserInfoResponse;
23
+ entities: {
24
+ hashtags: {
25
+ indices: number[];
26
+ text: string;
27
+ }[];
28
+ urls: {
29
+ display_url: string;
30
+ expanded_url: string;
31
+ indices: number[];
32
+ url: string;
33
+ }[];
34
+ user_mentions: {
35
+ id_str: string;
36
+ name: string;
37
+ screen_name: string;
38
+ }[];
39
+ };
40
+ quoted_tweet?: unknown;
41
+ retweeted_tweet?: unknown;
42
+ isLimitedReply?: boolean;
43
+ }
44
+ export interface TweetsByIdsResponse {
45
+ tweets: Tweet[];
46
+ status: string;
47
+ message?: string;
48
+ }
49
+ export interface TweetRepliesResponse {
50
+ tweets: Tweet[];
51
+ has_next_page: boolean;
52
+ next_cursor: string;
53
+ status: string;
54
+ message?: string;
55
+ }
56
+ export interface TweetQuotationsResponse {
57
+ tweets: Tweet[];
58
+ has_next_page: boolean;
59
+ next_cursor: string;
60
+ status: string;
61
+ message?: string;
62
+ }
63
+ export interface TweetRetweetersResponse {
64
+ retweeters: UserInfoResponse[];
65
+ has_next_page: boolean;
66
+ next_cursor: string;
67
+ status: string;
68
+ message?: string;
69
+ }
70
+ export interface TweetThreadContextResponse {
71
+ tweets: Tweet[];
72
+ status: string;
73
+ message?: string;
74
+ }
75
+ export interface ArticleResponse {
76
+ article: {
77
+ id: string;
78
+ title: string;
79
+ description?: string;
80
+ url: string;
81
+ author?: UserInfoResponse;
82
+ published_at?: string;
83
+ content?: string;
84
+ };
85
+ status: string;
86
+ message?: string;
87
+ }
88
+ export interface SearchTweetsResponse {
89
+ tweets: Tweet[];
90
+ has_next_page: boolean;
91
+ next_cursor: string;
92
+ status: string;
93
+ message?: string;
94
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,149 @@
1
+ import type { Tweet } from "./tweets";
2
+ export interface UserInfoResponse {
3
+ type: string;
4
+ userName: string;
5
+ url: string;
6
+ id: string;
7
+ name: string;
8
+ isBlueVerified: boolean;
9
+ verifiedType: string;
10
+ profilePicture: string;
11
+ coverPicture: string;
12
+ description: string;
13
+ location: string;
14
+ followers: number;
15
+ following: number;
16
+ canDm: boolean;
17
+ createdAt: string;
18
+ favouritesCount: number;
19
+ hasCustomTimelines: boolean;
20
+ isTranslator: boolean;
21
+ mediaCount: number;
22
+ statusesCount: number;
23
+ withheldInCountries: string[];
24
+ affiliatesHighlightedLabel: unknown;
25
+ possiblySensitive: boolean;
26
+ pinnedTweetIds: string[];
27
+ isAutomated: boolean;
28
+ automatedBy: string;
29
+ unavailable?: boolean;
30
+ message?: string;
31
+ unavailableReason?: string;
32
+ profile_bio: {
33
+ description: string;
34
+ entities: {
35
+ description: {
36
+ urls: {
37
+ url: string;
38
+ expanded_url: string;
39
+ display_url: string;
40
+ indices: number[];
41
+ }[];
42
+ };
43
+ url: {
44
+ urls: {
45
+ url: string;
46
+ expanded_url: string;
47
+ display_url: string;
48
+ indices: number[];
49
+ }[];
50
+ };
51
+ };
52
+ };
53
+ }
54
+ export interface UserFollowersResponse {
55
+ followers: UserInfoResponse[];
56
+ has_next_page: boolean;
57
+ next_cursor: string;
58
+ status: string;
59
+ message?: string;
60
+ }
61
+ export interface UserFollowingsResponse {
62
+ followings: UserInfoResponse[];
63
+ has_next_page: boolean;
64
+ next_cursor: string;
65
+ status: string;
66
+ message?: string;
67
+ }
68
+ export interface UserProfileAboutResponse {
69
+ data: {
70
+ id: string;
71
+ name: string;
72
+ userName: string;
73
+ createdAt: string;
74
+ isBlueVerified: boolean;
75
+ protected: boolean;
76
+ affiliates_highlighted_label?: {
77
+ label: {
78
+ badge?: {
79
+ url: string;
80
+ };
81
+ description: string;
82
+ url?: {
83
+ url: string;
84
+ urlType: string;
85
+ };
86
+ userLabelDisplayType: string;
87
+ userLabelType: string;
88
+ };
89
+ };
90
+ about_profile?: {
91
+ account_based_in?: string;
92
+ location_accurate?: boolean;
93
+ learn_more_url?: string;
94
+ affiliate_username?: string;
95
+ source?: string;
96
+ username_changes?: {
97
+ count: string;
98
+ };
99
+ };
100
+ identity_profile_labels_highlighted_label?: {
101
+ label: {
102
+ description: string;
103
+ badge?: {
104
+ url: string;
105
+ };
106
+ url?: {
107
+ url: string;
108
+ urlType: string;
109
+ };
110
+ userLabelDisplayType: string;
111
+ userLabelType: string;
112
+ };
113
+ };
114
+ };
115
+ }
116
+ export interface UserLatestTweetsResponse {
117
+ tweets: Tweet[];
118
+ has_next_page: boolean;
119
+ next_cursor: string;
120
+ status: string;
121
+ message?: string;
122
+ }
123
+ export interface UserMentionsResponse {
124
+ tweets: Tweet[];
125
+ has_next_page: boolean;
126
+ next_cursor: string;
127
+ status: string;
128
+ message?: string;
129
+ }
130
+ export interface FollowRelationshipResponse {
131
+ data: {
132
+ following: boolean;
133
+ followed_by: boolean;
134
+ };
135
+ status: string;
136
+ message?: string;
137
+ }
138
+ export interface SearchUserByKeywordResponse {
139
+ users: UserInfoResponse[];
140
+ has_next_page: boolean;
141
+ next_cursor: string;
142
+ status: string;
143
+ msg?: string;
144
+ }
145
+ export interface UserVerifiedFollowersResponse {
146
+ followers: UserInfoResponse[];
147
+ status: string;
148
+ message?: string;
149
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "twitterapi-io-client",
3
+ "version": "1.0.0",
4
+ "description": "A TypeScript client library for the TwitterAPI.io API",
5
+ "author": "jorvixsky",
6
+ "license": "MIT",
7
+ "type": "commonjs",
8
+ "main": "dist/index.js",
9
+ "types": "dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md",
19
+ "LICENSE"
20
+ ],
21
+ "scripts": {
22
+ "build": "tsc -p tsconfig.json",
23
+ "prepublishOnly": "npm run build && npm test",
24
+ "test": "vitest run",
25
+ "test:watch": "vitest"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "24.10.0",
29
+ "typescript": "5.9.3",
30
+ "vitest": "4.0.15"
31
+ }
32
+ }