feat(route/twitter): support official api with user credentials (#21139)
* feat(route/twitter): support official api with user credentials (act as a logged user) support * fix: update namespace docs * fix(route/twitter): use optional chaining for access tokens
This commit is contained in:
parent
5310e6a61b
commit
4c4339c625
|
|
@ -206,6 +206,8 @@ type ConfigEnvKeys =
|
|||
| 'TUMBLR_REFRESH_TOKEN'
|
||||
| 'TWITTER_CONSUMER_KEY'
|
||||
| 'TWITTER_CONSUMER_SECRET'
|
||||
| 'TWITTER_ACCESS_TOKEN'
|
||||
| 'TWITTER_ACCESS_SECRET'
|
||||
// | 'TWITTER_USERNAME'
|
||||
// | 'TWITTER_PASSWORD'
|
||||
// | 'TWITTER_AUTHENTICATION_SECRET'
|
||||
|
|
@ -621,6 +623,8 @@ export type Config = {
|
|||
twitter: {
|
||||
consumerKey?: string;
|
||||
consumerSecret?: string;
|
||||
accessToken?: string;
|
||||
accessSecret?: string;
|
||||
// username?: string[];
|
||||
// password?: string[];
|
||||
// authenticationSecret?: string[];
|
||||
|
|
@ -1108,6 +1112,8 @@ const calculateValue = () => {
|
|||
twitter: {
|
||||
consumerKey: envs.TWITTER_CONSUMER_KEY,
|
||||
consumerSecret: envs.TWITTER_CONSUMER_SECRET,
|
||||
accessToken: envs.TWITTER_ACCESS_TOKEN,
|
||||
accessSecret: envs.TWITTER_ACCESS_SECRET,
|
||||
// username: envs.TWITTER_USERNAME?.split(','),
|
||||
// password: envs.TWITTER_PASSWORD?.split(','),
|
||||
// authenticationSecret: envs.TWITTER_AUTHENTICATION_SECRET?.split(','),
|
||||
|
|
|
|||
|
|
@ -6,7 +6,12 @@ import ConfigNotFoundError from '@/errors/types/config-not-found';
|
|||
import InvalidParameterError from '@/errors/types/invalid-parameter';
|
||||
import cache from '@/utils/cache';
|
||||
|
||||
const appClients: TwitterApiReadOnly[] = [];
|
||||
interface ClientWrapper {
|
||||
client: TwitterApiReadOnly;
|
||||
isUserAuth: boolean;
|
||||
}
|
||||
|
||||
const appClients: ClientWrapper[] = [];
|
||||
let index = -1;
|
||||
|
||||
const init = () => {
|
||||
|
|
@ -19,18 +24,37 @@ const init = () => {
|
|||
|
||||
const consumerKeys = config.twitter.consumerKey.split(',');
|
||||
const consumerSecrets = config.twitter.consumerSecret.split(',');
|
||||
const accessTokens = config.twitter.accessToken?.split(',') || [];
|
||||
const accessSecrets = config.twitter.accessSecret?.split(',') || [];
|
||||
|
||||
for (const [index, consumerKey] of consumerKeys.entries()) {
|
||||
const consumerSecret = consumerSecrets[index];
|
||||
const accessToken = accessTokens[index];
|
||||
const accessSecret = accessSecrets[index];
|
||||
|
||||
if (!consumerKey || !consumerSecret) {
|
||||
continue;
|
||||
}
|
||||
appClients.push(
|
||||
new TwitterApi({
|
||||
appKey: consumerKey,
|
||||
appSecret: consumerSecret,
|
||||
}).readOnly
|
||||
);
|
||||
|
||||
if (accessToken && accessSecret) {
|
||||
appClients.push({
|
||||
client: new TwitterApi({
|
||||
appKey: consumerKey,
|
||||
appSecret: consumerSecret,
|
||||
accessToken,
|
||||
accessSecret,
|
||||
}).readOnly,
|
||||
isUserAuth: true,
|
||||
});
|
||||
} else {
|
||||
appClients.push({
|
||||
client: new TwitterApi({
|
||||
appKey: consumerKey,
|
||||
appSecret: consumerSecret,
|
||||
}).readOnly,
|
||||
isUserAuth: false,
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -40,7 +64,10 @@ export const getAppClient = async () => {
|
|||
throw new ConfigNotFoundError('Twitter API is not configured');
|
||||
}
|
||||
index += 1;
|
||||
return await appClients[index % appClients.length].appLogin();
|
||||
|
||||
const currentWrapper = appClients[index % appClients.length];
|
||||
|
||||
return currentWrapper.isUserAuth ? currentWrapper.client : await currentWrapper.client.appLogin();
|
||||
};
|
||||
|
||||
const mapUserToLegacy = (user: Record<string, any>) =>
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ Currently supports two authentication methods:
|
|||
~~- Using \`TWITTER_USERNAME\` \`TWITTER_PASSWORD\` and \`TWITTER_AUTHENTICATION_SECRET\`: Configure a comma-separated list of Twitter username and password. RSSHub will use this information to log in to Twitter and obtain data using the mobile API. Please note that if you have not logged in with the current IP address before, it is easy to trigger Twitter's risk control mechanism.~~ This no longer works since mobile client attestation has been implemented in October 2025.
|
||||
|
||||
- Using \`TWITTER_CONSUMER_KEY\` and \`TWITTER_CONSUMER_SECRET\`: Configure a comma-separated list of Twitter API keys and secrets. RSSHub will use this information to access Twitter's Pay-Per-Use developer API to obtain data.
|
||||
- OPTIONAL: Using \`TWITTER_ACCESS_TOKEN\` and \`TWITTER_ACCESS_SECRET\`: Configure a comma-separated list of Twitter API access tokens and secrets. RSSHub will use this information to access Twitter's Pay-Per-Use developer API with user authentication to obtain data. If not provided, RSSHub will only use app authentication, which may only access to public information.
|
||||
|
||||
`,
|
||||
lang: 'en',
|
||||
|
|
|
|||
Loading…
Reference in New Issue