Skip to content

Commit 3711139

Browse files
committed
Merge branch 'feat/v2-endpoints-3-10'
2 parents dff1db6 + 9c714d3 commit 3711139

File tree

9 files changed

+116
-21
lines changed

9 files changed

+116
-21
lines changed

doc/v2.md

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,10 @@ For streaming API, see [Streaming part](./streaming.md).
4343
* [Unfollow someone](#Unfollowsomeone)
4444
* [Block someone](#Blocksomeone)
4545
* [Unblock someone](#Unblocksomeone)
46-
* [Get users that are blocked by a user](#Getusersthatareblockedbyauser)
46+
* [Get users that are blocked by you](#Getusersthatareblockedbyyou)
4747
* [Mute someone](#Mutesomeone)
4848
* [Unmute someone](#Unmutesomeone)
49+
* [Get users that are muted by you](#Getusersthataremutedbyyou)
4950
* [Spaces](#Spaces)
5051
* [Space by ID](#SpacebyID)
5152
* [Spaces by ID](#SpacesbyID)
@@ -614,9 +615,9 @@ await client.v2.block('12', '1903892');
614615
await client.v2.unblock('12', '1903892');
615616
```
616617

617-
### <a name='Getusersthatareblockedbyauser'></a>Get users that are blocked by a user
618+
### <a name='Getusersthatareblockedbyyou'></a>Get users that are blocked by you
618619

619-
Get users blocked by a specific user.
620+
Get users blocked by the authenticating user.
620621
Get to know how [paginators work here](./paginators.md).
621622

622623
**Method**: `.userBlockingUsers()`
@@ -626,17 +627,16 @@ Get to know how [paginators work here](./paginators.md).
626627
**Right level**: `Read-only`
627628

628629
**Arguments**:
629-
- `userId: string`
630630
- `options?: UserV2TimelineParams`
631631

632632
**Returns**: `UserBlockingUsersV2Paginator`
633633

634634
**Example**
635635
```ts
636-
const blockedPaginator = await client.v2.userBlockingUsers('12');
636+
const blockedPaginator = await client.v2.userBlockingUsers();
637637

638638
for await (const blockedUser of blockedPaginator) {
639-
console.log(`Jack is blocking @${blockedUser.username}.`);
639+
console.log(`You are blocking @${blockedUser.username}.`);
640640
}
641641
```
642642

@@ -678,6 +678,31 @@ await client.v2.mute('12', '1903892');
678678
await client.v2.unmute('12', '1903892');
679679
```
680680

681+
### <a name='Getusersthataremutedbyyou'></a>Get users that are muted by you
682+
683+
Get users muted by authenticated user.
684+
Get to know how [paginators work here](./paginators.md).
685+
686+
**Method**: `.userMutingUsers()`
687+
688+
**Endpoint**: `users/:id/muting`
689+
690+
**Right level**: `Read-only`
691+
692+
**Arguments**:
693+
- `options?: UserV2TimelineParams`
694+
695+
**Returns**: `UserMutingUsersV2Paginator`
696+
697+
**Example**
698+
```ts
699+
const mutedPaginator = await client.v2.userMutingUsers();
700+
701+
for await (const mutedUser of mutedPaginator) {
702+
console.log(`You are blocking @${mutedUser.username}.`);
703+
}
704+
```
705+
681706
## <a name='Spaces'></a>Spaces
682707

683708
### <a name='SpacebyID'></a>Space by ID

src/client.base.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TClientTokens, TwitterApiBasicAuth, TwitterApiOAuth2Init, TwitterApiTokens, TwitterRateLimit, TwitterResponse } from './types';
1+
import { TClientTokens, TwitterApiBasicAuth, TwitterApiOAuth2Init, TwitterApiTokens, TwitterRateLimit, TwitterResponse, UserV1 } from './types';
22
import {
33
ClientRequestMaker,
44
TCustomizableRequestArgs,
@@ -35,6 +35,7 @@ export type TStreamClientRequestArgs = TCustomizableRequestArgs & {
3535
*/
3636
export default abstract class TwitterApiBase extends ClientRequestMaker {
3737
protected _prefix: string | undefined;
38+
protected _currentUser: UserV1 | null = null;
3839

3940
/**
4041
* Create a new TwitterApi object without authentification.
@@ -98,6 +99,8 @@ export default abstract class TwitterApiBase extends ClientRequestMaker {
9899
}
99100
}
100101

102+
/* Prefix/Token handling */
103+
101104
protected setPrefix(prefix: string | undefined) {
102105
this._prefix = prefix;
103106
}
@@ -134,6 +137,8 @@ export default abstract class TwitterApiBase extends ClientRequestMaker {
134137
return { type: 'none' };
135138
}
136139

140+
/* Rate limit cache */
141+
137142
/**
138143
* Tells if you hit the Twitter rate limit for {endpoint}.
139144
* (local data only, this should not ask anything to Twitter)
@@ -168,6 +173,23 @@ export default abstract class TwitterApiBase extends ClientRequestMaker {
168173
return this._rateLimits[endpointWithPrefix];
169174
}
170175

176+
/* Current user cache */
177+
178+
/** Get cached current user. */
179+
protected async getCurrentUserObject(forceFetch = false) {
180+
if (!forceFetch && this._currentUser) {
181+
return this._currentUser;
182+
}
183+
184+
const currentUser = await this.get<UserV1>(
185+
'account/verify_credentials.json',
186+
{ tweet_mode: 'extended' },
187+
{ prefix: 'https://api.twitter.com/1.1/' },
188+
);
189+
this._currentUser = currentUser;
190+
191+
return currentUser;
192+
}
171193

172194
/* Direct HTTP methods */
173195

src/client/readonly.ts

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import {
1212
} from '../types';
1313
import TwitterApiv1ReadOnly from '../v1/client.v1.read';
1414
import TwitterApiv2ReadOnly from '../v2/client.v2.read';
15-
import { UserV1 } from '../types';
1615
import { OAuth2Helper } from '../client-mixins/oauth2.helper';
1716

1817
/**
@@ -21,7 +20,6 @@ import { OAuth2Helper } from '../client-mixins/oauth2.helper';
2120
export default class TwitterApiReadOnly extends TwitterApiBase {
2221
protected _v1?: TwitterApiv1ReadOnly;
2322
protected _v2?: TwitterApiv2ReadOnly;
24-
protected _currentUser?: UserV1;
2523

2624
/* Direct access to subclients */
2725

@@ -45,11 +43,7 @@ export default class TwitterApiReadOnly extends TwitterApiBase {
4543
* Next calls to this methods will use the cached user, unless `forceFetch: true` is given.
4644
*/
4745
public async currentUser(forceFetch = false) {
48-
if (!forceFetch && this._currentUser) {
49-
return this._currentUser;
50-
}
51-
52-
return (this._currentUser = await this.v1.verifyCredentials());
46+
return await this.getCurrentUserObject(forceFetch);
5347
}
5448

5549
/* Shortcuts to endpoints */

src/helpers.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { TwitterApiV2Settings } from './settings';
2+
13
export function arrayWrap<T>(value: T | T[]) : T[] {
24
if (Array.isArray(value)) {
35
return value;
@@ -26,3 +28,32 @@ export function hasMultipleItems(item: string | string[]) {
2628
}
2729
return item.toString().includes(',');
2830
}
31+
32+
/* Deprecation warnings */
33+
34+
export interface IDeprecationWarning {
35+
instance: string;
36+
method: string;
37+
problem: string;
38+
resolution: string;
39+
}
40+
41+
const deprecationWarningsCache = new Set<string>();
42+
43+
export function safeDeprecationWarning(message: IDeprecationWarning) {
44+
if (typeof console === 'undefined' || !console.warn || !TwitterApiV2Settings.deprecationWarnings) {
45+
return;
46+
}
47+
48+
const hash = `${message.instance}-${message.method}-${message.problem}`;
49+
if (deprecationWarningsCache.has(hash)) {
50+
return;
51+
}
52+
53+
const formattedMsg = `[twitter-api-v2] Deprecation warning: In ${message.instance}.${message.method}() call` +
54+
`, ${message.problem}.\n${message.resolution}.`;
55+
56+
console.warn(formattedMsg);
57+
console.warn('To disable this message, import TwitterApiV2Settings from twitter-api-v2 and set TwitterApiV2Settings.deprecationWarnings to false.');
58+
deprecationWarningsCache.add(hash);
59+
}

src/paginators/user.paginator.v2.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,10 @@ export class UserBlockingUsersV2Paginator extends UserTimelineV2Paginator<UserV2
9898
protected _endpoint = 'users/:id/blocking';
9999
}
100100

101+
export class UserMutingUsersV2Paginator extends UserTimelineV2Paginator<UserV2TimelineResult, UserV2TimelineParams, { id: string }> {
102+
protected _endpoint = 'users/:id/muting';
103+
}
104+
101105
export class UserFollowersV2Paginator extends UserTimelineV2Paginator<UserV2TimelineResult, UserV2TimelineParams, { id: string }> {
102106
protected _endpoint = 'users/:id/followers';
103107
}

src/settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11

22
export const TwitterApiV2Settings = {
33
debug: false,
4+
deprecationWarnings: true,
45
};

src/types/auth.types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type TwitterApi from '../client';
22
import { TypeOrArrayOf } from './shared.types';
33

44
export type TOAuth2Scope = 'tweet.read' | 'users.read' | 'account.follows.read' | 'account.follows.write'
5-
| 'offline.access' | 'spaces.read';
5+
| 'offline.access' | 'space.read';
66

77
export interface BuildOAuth2RequestLinkArgs {
88
scope?: TypeOrArrayOf<TOAuth2Scope> | TypeOrArrayOf<string>;

src/v2/client.v2.read.ts

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ import {
5151
TweetV2UserLikedTweetsPaginator,
5252
} from '../paginators';
5353
import TwitterApiv2LabsReadOnly from '../v2-labs/client.v2.labs.read';
54-
import { UserBlockingUsersV2Paginator, UserFollowersV2Paginator, UserFollowingV2Paginator } from '../paginators/user.paginator.v2';
54+
import { UserBlockingUsersV2Paginator, UserFollowersV2Paginator, UserFollowingV2Paginator, UserMutingUsersV2Paginator } from '../paginators/user.paginator.v2';
5555
import { isTweetStreamV2ErrorPayload } from '../helpers';
5656

5757
/**
@@ -316,7 +316,7 @@ export default class TwitterApiv2ReadOnly extends TwitterApiSubClient {
316316
}
317317

318318
/**
319-
* Returns a list of users who are blocked by the specified user ID. User ID must be the authenticating user.
319+
* Returns a list of users who are blocked by the authenticating user.
320320
* https://developer.twitter.com/en/docs/twitter-api/users/blocks/api-reference/get-users-blocking
321321
*/
322322
public async userBlockingUsers(userId: string, options: Partial<UserV2TimelineParams> = {}) {
@@ -332,13 +332,31 @@ export default class TwitterApiv2ReadOnly extends TwitterApiSubClient {
332332
});
333333
}
334334

335+
/**
336+
* Returns a list of users who are muted by the authenticating user.
337+
* https://developer.twitter.com/en/docs/twitter-api/users/mutes/api-reference/get-users-muting
338+
*/
339+
public async userMutingUsers(options: Partial<UserV2TimelineParams> = {}) {
340+
const { id_str: userId } = await this.getCurrentUserObject();
341+
const params = { id: userId };
342+
const initialRq = await this.get<UserV2TimelineResult>('users/:id/muting', options, { fullResponse: true, params });
343+
344+
return new UserMutingUsersV2Paginator({
345+
realData: initialRq.data,
346+
rateLimit: initialRq.rateLimit!,
347+
instance: this,
348+
queryParams: { ...options },
349+
sharedParams: params,
350+
});
351+
}
352+
335353
/* Spaces */
336354

337355
/**
338356
* Get a single space by ID.
339357
* https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-id
340358
*
341-
* OAuth2 scopes: `tweet.read`, `users.read`, `spaces.read`.
359+
* OAuth2 scopes: `tweet.read`, `users.read`, `space.read`.
342360
*/
343361
public space(spaceId: string, options: Partial<SpaceV2FieldsParams> = {}) {
344362
return this.get<SpaceV2SingleResult>('spaces/:id', options, { params: { id: spaceId } });
@@ -348,7 +366,7 @@ export default class TwitterApiv2ReadOnly extends TwitterApiSubClient {
348366
* Get spaces using their IDs.
349367
* https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces
350368
*
351-
* OAuth2 scopes: `tweet.read`, `users.read`, `spaces.read`.
369+
* OAuth2 scopes: `tweet.read`, `users.read`, `space.read`.
352370
*/
353371
public spaces(spaceIds: string | string[], options: Partial<SpaceV2FieldsParams> = {}) {
354372
return this.get<SpaceV2LookupResult>('spaces', { ids: spaceIds, ...options });
@@ -358,7 +376,7 @@ export default class TwitterApiv2ReadOnly extends TwitterApiSubClient {
358376
* Get spaces using their creator user ID(s). (no pagination available)
359377
* https://developer.twitter.com/en/docs/twitter-api/spaces/lookup/api-reference/get-spaces-by-creator-ids
360378
*
361-
* OAuth2 scopes: `tweet.read`, `users.read`, `spaces.read`.
379+
* OAuth2 scopes: `tweet.read`, `users.read`, `space.read`.
362380
*/
363381
public spacesByCreators(creatorIds: string | string[], options: Partial<SpaceV2CreatorLookupParams> = {}) {
364382
return this.get<SpaceV2LookupResult>('spaces/by/creator_ids', { user_ids: creatorIds, ...options });

src/v2/client.v2.write.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ export default class TwitterApiv2ReadWrite extends TwitterApiv2ReadOnly {
8484
* **Note**: You must specify the currently logged user ID ; you can obtain it through v1.1 API.
8585
*/
8686
public retweet(loggedUserId: string, targetTweetId: string) {
87-
return this.post<TweetV2RetweetResult>(`users/:id/retweets`, { tweet_id: targetTweetId }, { params: { id: loggedUserId } });
87+
return this.post<TweetV2RetweetResult>('users/:id/retweets', { tweet_id: targetTweetId }, { params: { id: loggedUserId } });
8888
}
8989

9090
/**

0 commit comments

Comments
 (0)