twitter-api-v2
Advanced tools
Comparing version 0.2.3 to 0.3.0
@@ -0,1 +1,7 @@ | ||
0.3.0 | ||
----- | ||
- Add the four API v2 user endpoints | ||
- Improve type definitions | ||
- Minor v2 search refactor | ||
0.2.3 | ||
@@ -2,0 +8,0 @@ ----- |
@@ -8,8 +8,10 @@ import TwitterApiBase from './client.base'; | ||
constructor(instance: TwitterApiBase); | ||
get<T = any>(url: string, full_response?: boolean): Promise<T | TwitterResponse<T>>; | ||
get<T = any>(url: string, parameters?: Record<string, string | undefined>, full_response?: false, prefix?: string): Promise<T>; | ||
get<T = any>(url: string, parameters?: Record<string, string | undefined>, full_response?: true, prefix?: string): Promise<TwitterResponse<T>>; | ||
delete<T = any>(url: string, full_response?: boolean): Promise<T | TwitterResponse<T>>; | ||
delete<T = any>(url: string, parameters?: Record<string, string | undefined>, full_response?: false, prefix?: string): Promise<T>; | ||
delete<T = any>(url: string, parameters?: Record<string, string | undefined>, full_response?: true, prefix?: string): Promise<TwitterResponse<T>>; | ||
get<T = any>(url: string, full_response?: false): Promise<T>; | ||
get<T = any>(url: string, full_response: true): Promise<TwitterResponse<T>>; | ||
get<T = any>(url: string, parameters: Record<string, string | number | undefined>, full_response?: false, prefix?: string): Promise<T>; | ||
get<T = any>(url: string, parameters: Record<string, string | number | undefined>, full_response: true, prefix?: string): Promise<TwitterResponse<T>>; | ||
delete<T = any>(url: string, full_response?: false): Promise<T>; | ||
delete<T = any>(url: string, full_response: true): Promise<TwitterResponse<T>>; | ||
delete<T = any>(url: string, parameters: Record<string, string | number | undefined>, full_response?: false, prefix?: string): Promise<T>; | ||
delete<T = any>(url: string, parameters: Record<string, string | number | undefined>, full_response: true, prefix?: string): Promise<TwitterResponse<T>>; | ||
} |
import TwitterApiSubClient from '../client.subclient'; | ||
import TweetPaginator from './TweetPaginator'; | ||
import { Tweetv2SearchParams } from './types.v2'; | ||
import { Tweetv2SearchParams, UserResult, UsersResult, UsersV2Params } from './types.v2'; | ||
/** | ||
@@ -9,3 +9,7 @@ * Base Twitter v2 client with only read right. | ||
protected _prefix: string; | ||
search(what: string, options?: Partial<Tweetv2SearchParams>): Promise<TweetPaginator>; | ||
search(query: string, options?: Partial<Tweetv2SearchParams>): Promise<TweetPaginator>; | ||
user(userId: string, options?: Partial<UsersV2Params>): Promise<UserResult>; | ||
users(userIds: string | string[], options?: Partial<UsersV2Params>): Promise<UsersResult>; | ||
userByUsername(username: string, options?: Partial<UsersV2Params>): Promise<UserResult>; | ||
usersByUsernames(usernames: string | string[], options?: Partial<UsersV2Params>): Promise<UsersResult>; | ||
} |
@@ -17,12 +17,22 @@ "use strict"; | ||
} | ||
async search(what, options = {}) { | ||
var _a; | ||
options.query = what; | ||
options.max_results = (_a = options.max_results) !== null && _a !== void 0 ? _a : '10'; | ||
const initialRq = await this.get('tweets/search/recent', options, true); | ||
return new TweetPaginator_1.default(initialRq.data, initialRq.rateLimit, this, { | ||
query: options, | ||
}); | ||
async search(query, options = {}) { | ||
const queryParams = Object.assign(Object.assign({}, options), { query }); | ||
const initialRq = await this.get('tweets/search/recent', queryParams, true); | ||
return new TweetPaginator_1.default(initialRq.data, initialRq.rateLimit, this, queryParams); | ||
} | ||
user(userId, options = {}) { | ||
return this.get(`users/${userId}`, options); | ||
} | ||
users(userIds, options = {}) { | ||
const ids = Array.isArray(userIds) ? userIds.join(',') : userIds; | ||
return this.get(`users`, Object.assign(Object.assign({}, options), { ids })); | ||
} | ||
userByUsername(username, options = {}) { | ||
return this.get(`users/by/username/${username}`, options); | ||
} | ||
usersByUsernames(usernames, options = {}) { | ||
usernames = Array.isArray(usernames) ? usernames.join(',') : usernames; | ||
return this.get(`users/by`, Object.assign(Object.assign({}, options), { usernames })); | ||
} | ||
} | ||
exports.default = TwitterApiv2ReadOnly; |
import { TwitterRateLimit } from '../types'; | ||
import TwitterApiv2ReadOnly from './client.v2.read'; | ||
import { Tweetv2SearchParams, Tweetv2SearchResult } from './types.v2'; | ||
export interface PaginatorParams { | ||
query: Partial<Tweetv2SearchParams>; | ||
} | ||
/** | ||
@@ -38,4 +35,4 @@ * Represents a Twitter search with v2 API. | ||
protected _instance: TwitterApiv2ReadOnly; | ||
protected _options: PaginatorParams; | ||
constructor(_realData: Tweetv2SearchResult, _rateLimit: TwitterRateLimit, _instance: TwitterApiv2ReadOnly, _options: PaginatorParams); | ||
protected _queryParams: Partial<Tweetv2SearchParams>; | ||
constructor(_realData: Tweetv2SearchResult, _rateLimit: TwitterRateLimit, _instance: TwitterApiv2ReadOnly, _queryParams: Partial<Tweetv2SearchParams>); | ||
/** | ||
@@ -42,0 +39,0 @@ * Next page. |
@@ -55,7 +55,7 @@ "use strict"; | ||
class TweetPaginator { | ||
constructor(_realData, _rateLimit, _instance, _options) { | ||
constructor(_realData, _rateLimit, _instance, _queryParams) { | ||
this._realData = _realData; | ||
this._rateLimit = _rateLimit; | ||
this._instance = _instance; | ||
this._options = _options; | ||
this._queryParams = _queryParams; | ||
} | ||
@@ -66,10 +66,5 @@ /** | ||
async next(maxResults) { | ||
const untilId = this._realData.meta.oldest_id; | ||
const query = Object.assign({}, this._options.query); | ||
query.until_id = untilId; | ||
if (maxResults) { | ||
query.max_results = String(maxResults); | ||
} | ||
const result = await this._instance.get('tweets/search/recent', query, true); | ||
return new TweetPaginator(result.data, result.rateLimit, this._instance, { query }); | ||
const queryParams = Object.assign(Object.assign(Object.assign({}, this._queryParams), { until_id: this._realData.meta.oldest_id }), (maxResults ? { max_results: maxResults } : {})); | ||
const result = await this._instance.get('tweets/search/recent', queryParams, true); | ||
return new TweetPaginator(result.data, result.rateLimit, this._instance, queryParams); | ||
} | ||
@@ -80,9 +75,4 @@ /** | ||
async fetchNext(maxResults) { | ||
const untilId = this._realData.meta.oldest_id; | ||
const query = Object.assign({}, this._options.query); | ||
query.until_id = untilId; | ||
if (maxResults) { | ||
query.max_results = String(maxResults); | ||
} | ||
const response = await this._instance.get('tweets/search/recent', query, true); | ||
const queryParams = Object.assign(Object.assign(Object.assign({}, this._queryParams), { until_id: this._realData.meta.oldest_id }), (maxResults ? { max_results: maxResults } : {})); | ||
const response = await this._instance.get('tweets/search/recent', queryParams, true); | ||
const result = response.data; | ||
@@ -101,10 +91,7 @@ this._rateLimit = response.rateLimit; | ||
async fetchLast(count) { | ||
const untilId = this._realData.meta.oldest_id; | ||
const query = Object.assign({}, this._options.query); | ||
query.until_id = untilId; | ||
query.max_results = '100'; | ||
const queryParams = Object.assign(Object.assign({}, this._queryParams), { until_id: this._realData.meta.oldest_id, max_results: 100 }); | ||
let resultCount = 0; | ||
// Break at rate limit limit | ||
while (resultCount < count && this._isRateLimitOk) { | ||
const response = await this._instance.get('tweets/search/recent', query, true); | ||
const response = await this._instance.get('tweets/search/recent', queryParams, true); | ||
const result = response.data; | ||
@@ -117,4 +104,5 @@ this._rateLimit = response.rateLimit; | ||
resultCount += result.data.length; | ||
if (!result.data.length || !result.meta.next_token) | ||
if (!result.data.length || !result.meta.next_token) { | ||
break; | ||
} | ||
} | ||
@@ -127,7 +115,5 @@ return this; | ||
async previous() { | ||
const sinceId = this._realData.meta.newest_id; | ||
const query = Object.assign({}, this._options.query); | ||
query.since_id = sinceId; | ||
const result = await this._instance.get('tweets/search/recent', query, true); | ||
return new TweetPaginator(result.data, result.rateLimit, this._instance, { query }); | ||
const queryParams = Object.assign(Object.assign({}, this._queryParams), { sinceId: this._realData.meta.newest_id }); | ||
const result = await this._instance.get('tweets/search/recent', queryParams, true); | ||
return new TweetPaginator(result.data, result.rateLimit, this._instance, queryParams); | ||
} | ||
@@ -138,6 +124,4 @@ /** | ||
async fetchPrevious() { | ||
const sinceId = this._realData.meta.newest_id; | ||
const query = Object.assign({}, this._options.query); | ||
query.since_id = sinceId; | ||
const response = await this._instance.get('tweets/search/recent', query, true); | ||
const queryParams = Object.assign(Object.assign({}, this._queryParams), { sinceId: this._realData.meta.newest_id }); | ||
const response = await this._instance.get('tweets/search/recent', queryParams, true); | ||
const result = response.data; | ||
@@ -144,0 +128,0 @@ this._rateLimit = response.rateLimit; |
@@ -6,3 +6,3 @@ export interface Tweetv2SearchParams extends Partial<Tweetv2FieldsParams> { | ||
start_time?: string; | ||
max_results?: string; | ||
max_results?: number | string; | ||
next_token?: string; | ||
@@ -22,3 +22,3 @@ query: string; | ||
export interface Tweet { | ||
[query: string]: any; | ||
[field: string]: any; | ||
} | ||
@@ -34,1 +34,71 @@ export interface Tweetv2SearchResult { | ||
} | ||
interface Entity { | ||
start: number; | ||
end: number; | ||
} | ||
interface UrlEntity extends Entity { | ||
url: string; | ||
expanded_url: string; | ||
display_url: string; | ||
} | ||
interface HashtagEntity extends Entity { | ||
hashtag: string; | ||
} | ||
interface CashtagEntity extends Entity { | ||
cashtag: string; | ||
} | ||
interface MentionEntity extends Entity { | ||
username: string; | ||
} | ||
export interface UsersV2Params { | ||
expansions: 'pinned_tweet_id'; | ||
'tweet.fields': string; | ||
'user.fields': string; | ||
} | ||
export interface User { | ||
id: string; | ||
name: string; | ||
username: string; | ||
created_at?: string; | ||
protected?: boolean; | ||
withheld?: { | ||
country_codes?: string[]; | ||
scope?: 'user'; | ||
}; | ||
location?: string; | ||
url?: string; | ||
description?: string; | ||
verified?: boolean; | ||
entities?: { | ||
url?: { | ||
urls: UrlEntity[]; | ||
}; | ||
description: { | ||
urls?: UrlEntity[]; | ||
hashtags?: HashtagEntity[]; | ||
cashtags?: CashtagEntity[]; | ||
mentions?: MentionEntity[]; | ||
}; | ||
}; | ||
profile_image_url?: string; | ||
public_metrics?: { | ||
followers_count?: number; | ||
following_count?: number; | ||
tweet_count?: number; | ||
listed_count?: number; | ||
}; | ||
pinned_tweet_id?: string; | ||
} | ||
export interface UserResult { | ||
data: User; | ||
includes?: { | ||
tweets: [Tweet]; | ||
}; | ||
} | ||
export interface UsersResult { | ||
data: User[]; | ||
includes?: { | ||
tweets: Tweet[]; | ||
}; | ||
} | ||
export {}; |
{ | ||
"name": "twitter-api-v2", | ||
"version": "0.2.3", | ||
"version": "0.3.0", | ||
"description": "Twitter api v1 and v2 client for node", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
@@ -34,6 +34,18 @@ # Twitter API V2 | ||
// Manually call the API | ||
const tweets = await twitterClient.v2.get('tweets/search/recent', {query: 'nodeJS', max_results: '100'}); | ||
const tweets = await twitterClient.v1.tweet('Hello, this is a test.'), | ||
const tweets = await twitterClient.v1.uploadMedia(await fs.promises.readFile(path), { type: 'jpg' }) | ||
// Play with the built in methods | ||
await twitterClient.v2.userByUsername('plhery').data.id; | ||
await twitterClient.v1.tweet('Hello, this is a test.'); | ||
await twitterClient.v1.uploadMedia(await fs.promises.readFile(path), { type: 'jpg' }) | ||
// the search utils | ||
const results = await twitterClient.v2.search('hello'); | ||
console.log(results.tweets); // 10 tweets | ||
await results.fetchNext(100); | ||
await results.fetchNext(100); | ||
console.log(results.tweets, results.rateLimit); // 210 tweets | ||
// Or manually call the API | ||
await twitterClient.v2.get('tweets/search/recent', {query: 'nodeJS', max_results: '100'}); | ||
const tweets = await twitterClient.get('https://api.twitter.com/2/tweets/search/recent?query=nodeJS&max_results=100'); | ||
@@ -63,3 +75,3 @@ ``` | ||
- [ ] Twitter API V2 tweets methods | ||
- [ ] Twitter API V2 users methods | ||
- [x] Twitter API V2 users methods | ||
- [ ] Auto pagination | ||
@@ -66,0 +78,0 @@ - [ ] Error code enums |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
86225
1810
105
1