feat(twitter): support batch account
This commit is contained in:
parent
1d1ac4a58e
commit
943ec2e740
|
|
@ -259,11 +259,9 @@ export type Config = {
|
|||
cookie?: string;
|
||||
};
|
||||
twitter: {
|
||||
oauthTokens?: string[];
|
||||
oauthTokenSecrets?: string[];
|
||||
username?: string;
|
||||
password?: string;
|
||||
authenticationSecret?: string;
|
||||
username?: string[];
|
||||
password?: string[];
|
||||
authenticationSecret?: string[];
|
||||
cookie?: string;
|
||||
authToken?: string[];
|
||||
};
|
||||
|
|
@ -622,11 +620,9 @@ const calculateValue = () => {
|
|||
cookie: envs.TOPHUB_COOKIE,
|
||||
},
|
||||
twitter: {
|
||||
oauthTokens: envs.TWITTER_OAUTH_TOKEN?.split(','),
|
||||
oauthTokenSecrets: envs.TWITTER_OAUTH_TOKEN_SECRET?.split(','),
|
||||
username: envs.TWITTER_USERNAME,
|
||||
password: envs.TWITTER_PASSWORD,
|
||||
authenticationSecret: envs.TWITTER_AUTHENTICATION_SECRET,
|
||||
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(','),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
import { baseUrl, gqlMap, gqlFeatures, consumerKey, consumerSecret } from './constants';
|
||||
import { config } from '@/config';
|
||||
import logger from '@/utils/logger';
|
||||
import got from '@/utils/got';
|
||||
import OAuth from 'oauth-1.0a';
|
||||
import CryptoJS from 'crypto-js';
|
||||
import queryString from 'query-string';
|
||||
import { initToken, getToken } from './token';
|
||||
import { getToken } from './token';
|
||||
import cache from '@/utils/cache';
|
||||
import InvalidParameterError from '@/errors/types/invalid-parameter';
|
||||
import ofetch from '@/utils/ofetch';
|
||||
|
||||
const twitterGot = async (url, params) => {
|
||||
const token = await getToken();
|
||||
|
||||
const oauth = OAuth({
|
||||
const oauth = new OAuth({
|
||||
consumer: {
|
||||
key: consumerKey,
|
||||
secret: consumerSecret,
|
||||
|
|
@ -36,11 +36,14 @@ const twitterGot = async (url, params) => {
|
|||
},
|
||||
};
|
||||
|
||||
const response = await got(requestData.url, {
|
||||
const response = await ofetch.raw(requestData.url, {
|
||||
headers: oauth.toHeader(oauth.authorize(requestData, token)),
|
||||
});
|
||||
if (response.status === 401) {
|
||||
cache.globalCache.set(token.cacheKey, '');
|
||||
}
|
||||
|
||||
return response.data;
|
||||
return response._data;
|
||||
};
|
||||
|
||||
const paginationTweets = async (endpoint, userId, variables, path) => {
|
||||
|
|
@ -279,5 +282,5 @@ export default {
|
|||
excludeRetweet,
|
||||
getSearch,
|
||||
getUserTweet,
|
||||
init: initToken,
|
||||
init: () => void 0,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4,16 +4,12 @@ import { bearerToken, guestActivateUrl } from './constants';
|
|||
import got from '@/utils/got';
|
||||
import ofetch from '@/utils/ofetch';
|
||||
import crypto from 'crypto';
|
||||
import { config } from '@/config';
|
||||
import { v5 as uuidv5 } from 'uuid';
|
||||
import { authenticator } from 'otplib';
|
||||
import logger from '@/utils/logger';
|
||||
import cache from '@/utils/cache';
|
||||
|
||||
const NAMESPACE = 'd41d092b-b007-48f7-9129-e9538d2d8fe9';
|
||||
const username = config.twitter.username;
|
||||
const password = config.twitter.password;
|
||||
const authenticationSecret = config.twitter.authenticationSecret;
|
||||
|
||||
let authentication = null;
|
||||
|
||||
|
|
@ -29,8 +25,8 @@ const headers = {
|
|||
Authorization: bearerToken,
|
||||
};
|
||||
|
||||
async function login() {
|
||||
return await cache.tryGet(
|
||||
async function login({ username, password, authenticationSecret }) {
|
||||
return (await cache.tryGet(
|
||||
`twitter:authentication:${username}`,
|
||||
async () => {
|
||||
logger.debug('Twitter login start.');
|
||||
|
|
@ -179,7 +175,10 @@ async function login() {
|
|||
},
|
||||
60 * 60 * 24 * 30, // 30 days
|
||||
false
|
||||
);
|
||||
)) as {
|
||||
oauth_token: string;
|
||||
oauth_token_secret: string;
|
||||
} | null;
|
||||
}
|
||||
|
||||
export default login;
|
||||
|
|
|
|||
|
|
@ -3,35 +3,29 @@ import login from './login';
|
|||
import ConfigNotFoundError from '@/errors/types/config-not-found';
|
||||
|
||||
let tokenIndex = 0;
|
||||
let authentication = null;
|
||||
let first = true;
|
||||
|
||||
async function initToken() {
|
||||
if (config.twitter.username && config.twitter.password && !authentication && first) {
|
||||
authentication = await login();
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
|
||||
function getToken() {
|
||||
async function getToken() {
|
||||
let token;
|
||||
if (config.twitter.username && config.twitter.password) {
|
||||
if (authentication) {
|
||||
const index = tokenIndex++ % config.twitter.username.length;
|
||||
const username = config.twitter.username[index];
|
||||
const password = config.twitter.password[index];
|
||||
const authenticationSecret = config.twitter.authenticationSecret?.[index];
|
||||
if (username && password) {
|
||||
const authentication = await login({
|
||||
username,
|
||||
password,
|
||||
authenticationSecret,
|
||||
});
|
||||
if (!authentication) {
|
||||
throw new ConfigNotFoundError(`Invalid twitter configs: ${username}`);
|
||||
}
|
||||
token = {
|
||||
key: authentication.oauth_token,
|
||||
secret: authentication.oauth_token_secret,
|
||||
cacheKey: `twitter:authentication:${username}`,
|
||||
};
|
||||
}
|
||||
} else if (config.twitter.oauthTokens?.length && config.twitter.oauthTokenSecrets.length && config.twitter.oauthTokens.length === config.twitter.oauthTokenSecrets.length) {
|
||||
token = {
|
||||
key: config.twitter.oauthTokens[tokenIndex],
|
||||
secret: config.twitter.oauthTokenSecrets[tokenIndex],
|
||||
};
|
||||
|
||||
tokenIndex++;
|
||||
if (tokenIndex >= config.twitter.oauthTokens.length) {
|
||||
tokenIndex = 0;
|
||||
}
|
||||
} else {
|
||||
throw new ConfigNotFoundError('Invalid twitter configs');
|
||||
}
|
||||
|
|
@ -39,4 +33,4 @@ function getToken() {
|
|||
return token;
|
||||
}
|
||||
|
||||
export { initToken, getToken };
|
||||
export { getToken };
|
||||
|
|
|
|||
Loading…
Reference in New Issue