whats your 2020 twitter account warmup method?

Yes, it's fairly straight forward if you spend a day or so understanding the Puppeteer API: https://github.com/puppeteer/puppeteer

Then all you need to do is install Node: https://nodejs.org/en/download/ and run your script. You can write it any editor or IDE, I use JetBrains products, but many people love VSCode which is free: https://code.visualstudio.com/

There are lots of starter scripts that you can find on the Puppeteer repo, but here is my base class that I build my Actors on top of:

Code:
const puppeteer = require('puppeteer');
const _ = require('lodash');

class Actor {

    // ================ Setup ================

    browser;
    page;

    identity;
    config;

    pos;

    ready = false;

    /**
     * Accept construction variables
     *
     * @param config
     * @param identity
     */

    constructor(config, identity) {
        this.identity = identity; // Login information etc
        this.config = config; // Platform specific variables

    }

    /**
     * Initialize plugins and set stat to ready
     *
     * @returns {Promise<void>}
     */

    async init() {
        return new Promise(async (resolve, reject) => {
            try {

                this.browser = await puppeteer.launch({
                                                          headless: false,
                                                          args: [
                                                              '--no-sandbox',
                                                              '--disable-setuid-sandbox',
                                                              '--user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.129 Safari/537.36',
                                                              '--lang=en-US,en;q=0.9'
                                                          ],
                                                          userDataDir: this.identity.cookies, // Eg: './storage/identities/username'
                                                          defaultViewport: this.identity.browser.viewport
                                                      });

                this.page = await this.browser.newPage();

                this.ready = true;

            } catch (error) {
                reject(this.error(error));
            }
        });
    }

    /**
     * Your primary browse function, can rename to whatever you like
     *
     * @returns {Promise<void>}
     */

    async browse() {
        return new Promise(async (resolve, reject) => {
            try {

                // This is where you would build your bot actions

            } catch (error) {
                reject(this.error(error));
            }
        });
    }

    /**
     * Scroll the page, optionally with a direction or distance
     *
     * @returns {Promise<void>}
     * @param direction
     * @param distance
     */

    async scroll(direction, distance) {
        return new Promise(async (resolve, reject) => {
            try {

                this.logStart('Scroll');

                const noise = this.config.noise;
                const selectors = this.config.selectors;
                const viewport = this.identity.browser.viewport;

                // Limit to viewport
                let limits = {
                    min: Math.ceil(viewport.height * 0.30),
                    max: Math.ceil(viewport.height * 0.85)
                };

                distance = distance ? distance : _.random(limits.min, limits.max);

                if (!direction || (direction !== 'up' && direction !== 'down')) {
                    // Roll scroll direction
                    direction = await this.chance(noise.scroll.probability) ? 'down' : 'up';

                    // Detect header or footer tag
                    const footer = await this.page.$(selectors.footer);

                    if (footer && await footer.isIntersectingViewport()) {
                        direction = 'up';
                    }
                    else {
                        const header = await this.page.$(selectors.header);

                        if (header && await header.isIntersectingViewport()) {
                            direction = 'down';
                        }
                    }
                }

                distance = direction === 'down' ? distance : (distance * -1);

                await this.page.evaluate(async distance => {
                    return new Promise((resolve, reject) => {
                        try {
                            window.scrollBy(0, distance);
                            resolve();
                        } catch (error) {
                            reject(this.error(error));
                        }
                    });

                }, distance);

                await this.delay(100, 500);

                resolve();

            } catch (error) {
                reject(this.error(error));
            }
        });
    }

    /**
     * Handles delays with noise
     *
     * @returns {Promise<void>}
     * @param min
     * @param max
     */

    async delay(min, max) {
        return new Promise(async (resolve, reject) => {
            try {

                const noise = this.config.noise;

                let delay = _.random(min ? min : noise.delay.min, max ? max : noise.delay.max);

                await this.page.waitFor(delay);

                resolve();

            } catch (error) {
                reject(this.error(error));
            }
        });
    }

    /**
     * Moves the mouse to a position and adds noise
     *
     * @returns {Promise<void>}
     * @param pos
     * @param delay
     */

    async moveMouseTo(pos, delay) {
        return new Promise(async (resolve, reject) => {
            try {

                delay = delay ? delay : _.random(10, 80);
                await this.page.mouse.move(pos.x + _.random(0, 2), pos.y + _.random(0, 2));
                await this.delay(delay, (delay + 8));
                this.pos = pos;

                resolve();

            } catch (error) {
                reject(this.error(error));
            }
        });
    }

    /**
     * Move the mouse a set or random number of times around the page
     *
     * @returns {Promise<void>}
     * @param count
     */

    async randomMouseMovement(count) {
        return new Promise(async (resolve, reject) => {
            try {

                const noise = this.config.noise;

                await this.delay(50, 80);

                count = count ? parseInt(count) : _.random(noise.mouse.sequence.min, noise.mouse.sequence.max);

                for (let i = 0; i < count; i++) {

                    let startPos = await this.getCurrentMousePosition();
                    let endPos = await this.getRandomMousePosition();

                    await this.panMouse(startPos, endPos); // You will need to implement your own panning function

                }

                await this.delay(50, 1000);

                resolve();
            } catch (error) {
                reject(this.error(error));
            }
        });
    }

    /**
     * Select a new random mouse position from within the viewport
     *
     * @returns {Promise<void>}
     */

    async getRandomMousePosition() {

        return new Promise(async (resolve, reject) => {
            try {

                const viewport = this.identity.browser.viewport;

                let pos = {
                    x: Math.ceil(viewport.width * _.random(0.10, 0.90)),
                    y: Math.ceil(viewport.height * _.random(0.10, 0.90))
                };

                resolve(pos);

            } catch (error) {
                reject(this.error(error));
            }
        });

    }

    /**
     * Finds a dom element on the page
     *
     * @returns {Promise<void>}
     * @param selector
     */

    async getElement(selector) {
        return new Promise(async (resolve, reject) => {
            try {

                const element = (typeof selector === 'string') ? (await this.page.$(selector)) : selector;

                resolve(element);

            } catch (error) {
                reject(this.error(error));
            }
        });

    }

    /**
     * Gets the x,y position of a dom element
     *
     * @returns {Promise<void>}
     * @param selector
     */

    async getElementPosition(selector) {

        return new Promise(async (resolve, reject) => {
            try {

                const element = await this.getElement(selector);

                if (element) {

                    const boundingBox = await element.boundingBox();

                    let pos = {
                        x: Math.ceil(boundingBox.x + (boundingBox.width * _.random(0.3, 0.7))),
                        y: Math.ceil(boundingBox.x + (boundingBox.height * _.random(0.3, 0.7))),
                    };

                    resolve(pos);

                }
                else {
                    resolve();
                }

            } catch (error) {
                reject(this.error(error));
            }
        });

    }

    /**
     * Returns the current mouse position or starts at a new position if none found
     *
     * @returns {Promise<void>}
     */

    async getCurrentMousePosition() {
        return new Promise(async (resolve, reject) => {
            try {

                let pos = this.pos;

                if (!(pos && pos.x && pos.y)) {
                    pos = await this.getRandomMousePosition();
                    this.pos = pos;
                }

                resolve(pos);

            } catch (error) {
                reject(this.error(error));
            }
        });
    }

    /**
     * Helper function for handling randomness
     *
     * @returns {Promise<void>}
     * @param probability
     */

    async chance(probability) {
        return new Promise(async (resolve, reject) => {
            try {
                probability = probability ? parseInt(probability) : 50;

                resolve(!!_.random(0, 100) < probability);
            } catch (error) {
                reject(this.error(error));
            }
        });
    }

    /**
     * Error handler that prints error
     *
     * @returns {Promise<void>}
     * @param error
     */

    error(error) {

        const string = _.get(error, 'message', error);

        console.error(string);

        return error;
    }

}

module.exports = Actor;



damn ill check it out thanks
 
@Sebastiann Great work, man
I'm working with twitter very close and I pretty sure(99.9%) that twitter dont track mouse emulation.
And you need to save session instead of each time log in
 
@Sebastiann Great work, man
I'm working with twitter very close and I pretty sure(99.9%) that twitter dont track mouse emulation.
And you need to save session instead of each time log in

I 100% agree - for any sort of marketing-related use-case where it's reasonably safe to burn an account upon detection, it's very likely overkill.
But if you need long-to-perpetual account lifespans across many platforms and a high level of deniability; it's not Twitter itself I'm designing for with that level of detail, its the third-party bot detection services that provide risk-scores to the platforms (either presently or in the future), who monitor things right down to the number of milliseconds between a mouseUp and mouseDown event as well as any actions you are taking off-platform where their service is deployed.
 
@Sebastiann Great work, man
I'm working with twitter very close and I pretty sure(99.9%) that twitter dont track mouse emulation.
And you need to save session instead of each time log in
Do you have a bot that does that? If so which is it?
 
I'm surprised how meticulous most people on this thread are going about it.
I've always had newly created accounts following up to 30/day the 1st week, posting up to 10x from the 1st day and replying to tweets 25/day.

I've lost only 1 account in the last 2 months.
 
I'm surprised how meticulous most people on this thread are going about it.
I've always had newly created accounts following up to 30/day the 1st week, posting up to 10x from the 1st day and replying to tweets 25/day.

I've lost only 1 account in the last 2 months.
Wow.What bot are you running? Do it use sessions?
 
This is not related to the thread but OP you should change your anti-Semitic profile picture asap.
 
Back
Top