Rishikant181 / Rettiwt-API

A CLI tool and an API for fetching data from Twitter for free!
https://rishikant181.github.io/Rettiwt-API/
MIT License
487 stars 46 forks source link

Incorrect Username Error when Logging in with User Credentials #583

Closed sam-schorb closed 3 months ago

sam-schorb commented 3 months ago

I am experiencing an issue with the rettiwt-api library when attempting to log in using user credentials. The steps I am following are:

  1. Guest Authentication: Successfully logging in as a guest and fetching user details using the guest authentication method.
  2. User Authentication: Attempting to log in with user credentials using the login method.

The script successfully fetches user details as a guest, confirming that the username is correct. However, when trying to log in using the same username, I receive an "Incorrect username given for the given Twitter account" error. I have been able to get an API key so the details must work.

Steps to Reproduce

  1. Create a new instance of Rettiwt.
  2. Use the guest authentication method to log in and fetch user details.
  3. Attempt to log in with user credentials (email, username, password).
const { Rettiwt } = require('rettiwt-api');

const email = '';
const username = '';
const password = '';

const guestAuthAndFetch = async () => {
  const rettiwtGuest = new Rettiwt();
  const guestKey = await rettiwtGuest.auth.guest();
  const rettiwtWithGuest = new Rettiwt({ guestKey });
  const userDetails = await rettiwtWithGuest.user.details(username);

  if (!userDetails || !userDetails.id) {
    throw new Error('Failed to fetch user details or userDetails.id is undefined');
  }

  return userDetails.id;
};

const fetchFollowersAndFollowing = async (userId) => {
  const rettiwt = new Rettiwt();
  const apiKey = await rettiwt.auth.login(email, username, password);

  const rettiwtWithAuth = new Rettiwt({ apiKey });

  const followersResponse = await rettiwtWithAuth.user.followers(userId, 100);
  const followingResponse = await rettiwtWithAuth.user.following(userId, 100);

  const followers = followersResponse.list.map(user => user.userName);
  const following = followingResponse.list.map(user => user.userName);

  const mutualFollowers = following.filter(user => followers.includes(user));

  return {
    followers,
    following,
    mutualFollowers
  };
};

const main = async () => {
  try {
    const userId = await guestAuthAndFetch();
    const result = await fetchFollowersAndFollowing(userId);
    console.log(result); // This line is just to display the result; can be removed
  } catch (error) {
    console.error('Error in main process:', error.message || error);
  }
};

main();
Rishikant181 commented 3 months ago

Can you post the full error?

sam-schorb commented 3 months ago

Sorry, yes. Thank you for replying.

You can see here that from the logs that it is able to log in as guest but not as a user. I have successfully used these credentials to retrieve an API key previously. But now if I try to do that I get the {} response that I've seen others get. Perhaps that is the reason it is unable to log in?

Here it is with lots of additional logging:

const { Rettiwt } = require('rettiwt-api');
const fs = require('fs');

// Replace with your actual email, username, and password
const email = '';
const username = '';
const password = '';

// Function to save list to a file
const saveListToFile = (listData, filename) => {
  console.log(`Saving ${listData.length} items to ${filename}`);
  fs.writeFileSync(filename, listData.join('\n'), 'utf8');
};

// Guest Authentication and Fetch User ID
const guestAuthAndFetch = async () => {
  try {
    console.log('Creating a new Rettiwt instance as guest...');
    const rettiwtGuest = new Rettiwt();

    console.log('Logging in as a guest...');
    const guestKey = await rettiwtGuest.auth.guest();
    console.log('Guest key obtained:', guestKey);

    // Creating a new Rettiwt instance with the guest key
    const rettiwtWithGuest = new Rettiwt({ guestKey });

    console.log(`Fetching user details for username: ${username}...`);
    const userDetails = await rettiwtWithGuest.user.details(username);

    console.log('User Details Response:', userDetails);

    if (!userDetails || !userDetails.id) {
      throw new Error('Failed to fetch user details or userDetails.id is undefined');
    }

    return userDetails.id;
  } catch (error) {
    console.error('Error during guest authentication and fetching user details:', error.message || error);
    throw error;
  }
};

// Fetch Followers and Following
const fetchFollowersAndFollowing = async (userId) => {
  console.log('Creating a new Rettiwt instance...');
  const rettiwt = new Rettiwt();

  console.log('Logging in with user credentials...');
  console.log(`Email: ${email}, Username: ${username}`);

  rettiwt.auth.login(email, username, password)
    .then(apiKey => {
      console.log('Logged in successfully. API_KEY obtained.');

      // Creating a new Rettiwt instance with the API_KEY
      const rettiwtWithAuth = new Rettiwt({ apiKey });

      // Fetching the first 100 followers of the User
      console.log(`Fetching the first 100 followers of the user with ID: ${userId}...`);
      rettiwtWithAuth.user.followers(userId, 100)
        .then(followersResponse => {
          console.log('Followers:', followersResponse);
          saveListToFile(followersResponse.list.map(user => user.userName), 'followers.txt');
        })
        .catch(error => {
          console.error('Error fetching followers:', error.message || error);
        });

      // Fetching the first 100 users followed by the User
      console.log(`Fetching the first 100 users followed by the user with ID: ${userId}...`);
      rettiwtWithAuth.user.following(userId, 100)
        .then(followingResponse => {
          console.log('Following:', followingResponse);
          saveListToFile(followingResponse.list.map(user => user.userName), 'following.txt');
        })
        .catch(error => {
          console.error('Error fetching following:', error.message || error);
        });

      // Finding mutual followers
      console.log('Finding mutual followers...');
      Promise.all([
        rettiwtWithAuth.user.followers(userId, 100),
        rettiwtWithAuth.user.following(userId, 100)
      ])
        .then(([followersResponse, followingResponse]) => {
          const followers = followersResponse.list.map(user => user.userName);
          const following = followingResponse.list.map(user => user.userName);

          const mutualFollowers = following.filter(user => followers.includes(user));
          console.log(`Found ${mutualFollowers.length} mutual followers.`);
          saveListToFile(mutualFollowers, 'mutual_followers.txt');
        })
        .catch(error => {
          console.error('Error finding mutual followers:', error.message || error);
        });

    })
    .catch(error => {
      console.error('Error logging in:', error.message || error);
    });
};

// Main function to orchestrate the flow
const main = async () => {
  try {
    const userId = await guestAuthAndFetch();
    await fetchFollowersAndFollowing(userId);
  } catch (error) {
    console.error('Error in main process:', error.message || error);
  }
};

// Run the main function
main();

here is the response I get:

(base) clam@Clams-MacBook-Air twitterBot % node fetchData.js
Creating a new Rettiwt instance as guest...
Logging in as a guest...
Guest key obtained: 1234567890
Fetching user details for username: xxxxxxx
User Details Response: User {
  id: 'xxxxxx',
  userName: 'xxxxxxx,
  fullName: '',
  createdAt: 'Wed Jul 17 13:35:55 +0000 2024',
  description: '',
  isVerified: false,
  likeCount: 0,
  followersCount: 61,
  followingsCount: 359,
  statusesCount: 6,
  location: '',
  pinnedTweet: undefined,
  profileBanner: '',
  profileImage: ''
}
Creating a new Rettiwt instance...
Logging in with user credentials...
Email: user@gmail.com, Username: xxxxxxx
Error logging in: Incorrect username given for the given Twitter account
(base) clam@Clams-MacBook-Air twitterBot % 
Rishikant181 commented 3 months ago

console.error('Error logging in:', error.message || error);

Not just the error message, I want the full error, i.e, the line should be: console.error('Error logging in:', error);

On a side node, you should never be obtaining an API_KEY on each run. It always advised to use the CLI to generate and API_KEY once, then use it until it expires. Sometimes, repeated API_KEY generation flags Twitter anti-bot measures (since the API_KEY generation mimics logging in from browser). Are you receiving some king of one-time code or something on the associated email/phone?

sam-schorb commented 3 months ago

I'm not receiving a one-time code but thank you for the information, I was unclear on that. I'll make sure not to do that anymore then.

the only information I can get from that error is:

Error logging in: Incorrect username given for the given Twitter account

I've tried getting more details and that seems to be all there is. Thank you for your help

Rishikant181 commented 3 months ago

Further discussion and updates will be posted at #586

Rishikant181 commented 3 months ago

Duplicate of #586