Skip to content

Commit

Permalink
feat: save cookie generated from twitter token
Browse files Browse the repository at this point in the history
  • Loading branch information
DIYgod committed Jul 13, 2024
1 parent 9fbbed6 commit 1db30b3
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 52 deletions.
2 changes: 0 additions & 2 deletions lib/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,6 @@ export type Config = {
username?: string[];
password?: string[];
authenticationSecret?: string[];
cookie?: string;
authToken?: string[];
};
weibo: {
Expand Down Expand Up @@ -639,7 +638,6 @@ const calculateValue = () => {
username: envs.TWITTER_USERNAME?.split(','),
password: envs.TWITTER_PASSWORD?.split(','),
authenticationSecret: envs.TWITTER_AUTHENTICATION_SECRET?.split(','),
cookie: envs.TWITTER_COOKIE,
authToken: envs.TWITTER_AUTH_TOKEN?.split(','),
},
weibo: {
Expand Down
2 changes: 1 addition & 1 deletion lib/routes/twitter/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import webApi from './web-api/api';
import { config } from '@/config';

const enableMobileApi = config.twitter.username && config.twitter.password;
const enableWebApi = config.twitter.cookie || config.twitter.authToken;
const enableWebApi = config.twitter.authToken;

type ApiItem = (id: string, params?: Record<string, any>) => Promise<Record<string, any>> | Record<string, any> | null;
let api: {
Expand Down
93 changes: 44 additions & 49 deletions lib/routes/twitter/api/web-api/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,63 +5,53 @@ import got from '@/utils/got';
import queryString from 'query-string';
import { Cookie, CookieJar } from 'tough-cookie';
import { CookieAgent } from 'http-cookie-agent/undici';
import cache from '@/utils/cache';
import logger from '@/utils/logger';

const dispatchers = {};
let authTokenIndex = 0;

const token2Cookie = (token) =>
cache.tryGet(`twitter:cookie:${token}`, async () => {
const jar = new CookieJar();
jar.setCookieSync(`auth_token=${token}`, 'https://x.com');
try {
await got('https://x.com', {
dispatcher: new CookieAgent({ cookies: { jar } }),
});
return JSON.stringify(jar.serializeSync());
} catch {
// ignore
return '';
}
});

export const twitterGot = async (url, params) => {
if (!config.twitter.cookie && !config.twitter.authToken) {
if (!config.twitter.authToken) {
throw new ConfigNotFoundError('Twitter cookie is not configured');
}
let requestData;
if (config.twitter.cookie) {
const jsonCookie = Object.fromEntries(
config.twitter.cookie
.split(';')
.map((c) => Cookie.parse(c)?.toJSON())
.map((c) => [c?.key, c?.value])
);
if (!jsonCookie || !jsonCookie.auth_token || !jsonCookie.ct0) {
throw new ConfigNotFoundError('Twitter cookie is not valid');
}

requestData = {
headers: {
cookie: config.twitter.cookie,
'x-csrf-token': jsonCookie.ct0,
},
};
} else if (config.twitter.authToken) {
const token = config.twitter.authToken[authTokenIndex++ % config.twitter.authToken.length];
if (!dispatchers[token]) {
const jar = new CookieJar();
jar.setCookieSync(`auth_token=${token}`, 'https://x.com');
dispatchers[token] = {
jar,
agent: new CookieAgent({ cookies: { jar } }),
};
try {
await got('https://x.com', {
dispatcher: dispatchers[token].agent,
});
} catch {
// ignore
}
const token = config.twitter.authToken[authTokenIndex++ % config.twitter.authToken.length];
let cookie = await token2Cookie(token);
if (cookie) {
logger.debug(`Got twitter cookie for token ${token}`);
if (typeof cookie === 'string') {
cookie = JSON.parse(cookie);
}
const jsonCookie = Object.fromEntries(
dispatchers[token].jar
.getCookieStringSync(url)
.split(';')
.map((c) => Cookie.parse(c)?.toJSON())
.map((c) => [c?.key, c?.value])
);
requestData = {
headers: {
'x-csrf-token': jsonCookie.ct0,
},
dispatcher: dispatchers[token].agent,
const jar = CookieJar.deserializeSync(cookie as any);
dispatchers[token] = {
jar,
agent: new CookieAgent({ cookies: { jar } }),
};
} else {
throw new ConfigNotFoundError(`Twitter cookie for token ${token} is not valid`);
}
const jsonCookie = Object.fromEntries(
dispatchers[token].jar
.getCookieStringSync(url)
.split(';')
.map((c) => Cookie.parse(c)?.toJSON())
.map((c) => [c?.key, c?.value])
);

const response = await got(`${url}?${queryString.stringify(params)}`, {
headers: {
Expand All @@ -77,11 +67,16 @@ export const twitterGot = async (url, params) => {
'x-twitter-active-user': 'yes',
'x-twitter-auth-type': 'OAuth2Session',
'x-twitter-client-language': 'en',
...requestData.headers,
'x-csrf-token': jsonCookie.ct0,
},
dispatcher: requestData.dispatcher,
dispatcher: dispatchers[token].agent,
});

if (token) {
logger.debug(`Reset twitter cookie for token ${token}`);
await cache.set(`twitter:cookie:${token}`, JSON.stringify(dispatchers[token].jar.serializeSync()), config.cache.contentExpire);
}

return response.data;
};

Expand Down

0 comments on commit 1db30b3

Please sign in to comment.