feat: support relay profile selection
CI / test (push) Successful in 10m2s

This commit is contained in:
2026-06-24 18:30:24 +09:00
parent 7a036e244d
commit 3f370cc4b6
24 changed files with 160 additions and 25 deletions
+10 -3
View File
@@ -15,12 +15,14 @@ export type Mixin<TBase extends AbstractConstructor<TwitterClientBase>, TAdded>
export abstract class TwitterClientBase {
protected relayBaseUrl: string;
protected profileName?: string;
protected timeoutMs?: number;
protected quoteDepth: number;
protected clientUserId?: string;
constructor(options: TwitterClientOptions) {
this.relayBaseUrl = this.normalizeRelayBaseUrl(options.relayBaseUrl ?? process.env.TWITTER_RELAY_BASE_URL);
this.profileName = this.normalizeProfileName(options.profileName);
this.timeoutMs = options.timeoutMs;
this.quoteDepth = normalizeQuoteDepth(options.quoteDepth);
}
@@ -73,7 +75,7 @@ export abstract class TwitterClientBase {
}
protected getHeaders(): Record<string, string> {
return {};
return this.profileName ? { 'x-profile-name': this.profileName } : {};
}
private normalizeRelayBaseUrl(value: string | undefined): string {
@@ -84,6 +86,11 @@ export abstract class TwitterClientBase {
return trimmed.replace(TRAILING_SLASHES, '');
}
private normalizeProfileName(value: string | undefined): string | undefined {
const trimmed = value?.trim();
return trimmed || undefined;
}
private toRelayUrl(url: string): string {
const parsed = new URL(url);
if (!['x.com', 'twitter.com', 'api.twitter.com', 'upload.twitter.com'].includes(parsed.hostname)) {
@@ -93,11 +100,11 @@ export abstract class TwitterClientBase {
}
protected getJsonHeaders(): Record<string, string> {
return { 'content-type': 'application/json' };
return { 'content-type': 'application/json', ...this.getHeaders() };
}
protected getUploadHeaders(): Record<string, string> {
return {};
return this.getHeaders();
}
protected async ensureClientUserId(): Promise<void> {
+1
View File
@@ -326,6 +326,7 @@ export interface FollowingResult {
export interface TwitterClientOptions {
relayBaseUrl?: string;
profileName?: string;
timeoutMs?: number;
// Max depth for quoted tweets (0 disables). Defaults to 1.
quoteDepth?: number;