This commit is contained in:
@@ -1,4 +1,3 @@
|
||||
import { randomBytes, randomUUID } from 'node:crypto';
|
||||
import { runtimeQueryIds } from './runtime-query-ids.js';
|
||||
import { type OperationName, QUERY_IDS, TARGET_QUERY_ID_OPERATIONS } from './twitter-client-constants.js';
|
||||
import type { CurrentUserResult, TwitterClientOptions } from './twitter-client-types.js';
|
||||
@@ -16,22 +15,14 @@ export type Mixin<TBase extends AbstractConstructor<TwitterClientBase>, TAdded>
|
||||
|
||||
export abstract class TwitterClientBase {
|
||||
protected relayBaseUrl: string;
|
||||
protected userAgent: string;
|
||||
protected timeoutMs?: number;
|
||||
protected quoteDepth: number;
|
||||
protected clientUuid: string;
|
||||
protected clientDeviceId: string;
|
||||
protected clientUserId?: string;
|
||||
|
||||
constructor(options: TwitterClientOptions) {
|
||||
this.relayBaseUrl = this.normalizeRelayBaseUrl(options.relayBaseUrl ?? process.env.TWITTER_RELAY_BASE_URL);
|
||||
this.userAgent =
|
||||
options.userAgent ||
|
||||
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36';
|
||||
this.timeoutMs = options.timeoutMs;
|
||||
this.quoteDepth = normalizeQuoteDepth(options.quoteDepth);
|
||||
this.clientUuid = randomUUID();
|
||||
this.clientDeviceId = randomUUID();
|
||||
}
|
||||
|
||||
protected abstract getCurrentUser(): Promise<CurrentUserResult>;
|
||||
@@ -82,11 +73,7 @@ export abstract class TwitterClientBase {
|
||||
}
|
||||
|
||||
protected getHeaders(): Record<string, string> {
|
||||
return this.getJsonHeaders();
|
||||
}
|
||||
|
||||
protected createTransactionId(): string {
|
||||
return randomBytes(16).toString('hex');
|
||||
return {};
|
||||
}
|
||||
|
||||
private normalizeRelayBaseUrl(value: string | undefined): string {
|
||||
@@ -105,37 +92,12 @@ export abstract class TwitterClientBase {
|
||||
return `${this.relayBaseUrl}${parsed.pathname}${parsed.search}`;
|
||||
}
|
||||
|
||||
protected getBaseHeaders(): Record<string, string> {
|
||||
const headers: Record<string, string> = {
|
||||
accept: '*/*',
|
||||
'accept-language': 'en-US,en;q=0.9',
|
||||
'x-twitter-active-user': 'yes',
|
||||
'x-twitter-client-language': 'en',
|
||||
'x-client-uuid': this.clientUuid,
|
||||
'x-twitter-client-deviceid': this.clientDeviceId,
|
||||
'x-client-transaction-id': this.createTransactionId(),
|
||||
'user-agent': this.userAgent,
|
||||
origin: 'https://x.com',
|
||||
referer: 'https://x.com/',
|
||||
};
|
||||
|
||||
if (this.clientUserId) {
|
||||
headers['x-twitter-client-user-id'] = this.clientUserId;
|
||||
}
|
||||
|
||||
return headers;
|
||||
}
|
||||
|
||||
protected getJsonHeaders(): Record<string, string> {
|
||||
return {
|
||||
...this.getBaseHeaders(),
|
||||
'content-type': 'application/json',
|
||||
};
|
||||
return { 'content-type': 'application/json' };
|
||||
}
|
||||
|
||||
protected getUploadHeaders(): Record<string, string> {
|
||||
// Note: do not set content-type; URLSearchParams/FormData need to set it (incl boundary) themselves.
|
||||
return this.getBaseHeaders();
|
||||
return {};
|
||||
}
|
||||
|
||||
protected async ensureClientUserId(): Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user