linkedin connections | Cell 3 | connect add friends linkedin | Search

This code automates LinkedIn interactions by retrieving a list of connections and sending connection requests to specified profiles.

Run example

npm run import -- "connect on linkedin"

connect on linkedin

var importer = require('../Core');
var fs = require('fs');

var PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
var project = PROFILE_PATH + '/Collections/conversations';

function listAllConnections(list) {
    var friends = [];
    // TODO: create utility function for managing time critical files like this.
    if (fs.existsSync(project + '/new-connections.json')) {
        return Promise.resolve(JSON.parse(
            fs.readFileSync(project + '/new-connections.json')));
    }
    return client
        .getUrl()
        .then(url => {
            if(list && list.includes('linkedin.com')) {
                return client
                    .url(list)
                    .pause(3000);
            }
            return client
                .url('https://www.linkedin.com/mynetwork/')
                .pause(3000);
        })
        .then(() => getAllUntil(
            false,
            '//a[contains(@href, "/in/")]/@href',
            friends,
            (a, b) => a === b,
            (i) => i < 10
        ))
        .then(r => r.filter((l, i, arr) => arr.indexOf(l) === i))
        .then(r => {
            fs.writeFileSync(
                project + '/new-connections.json',
                JSON.stringify(r, null, 4));
            return r;
        })
        .catch(e => console.log(e))
};

function connectLinkedin(profile) {
    return client
        .then(() => clickSpa('https://linkedin.com' + profile))
        .pause(3000)
        .isExisting('//button[contains(., "Connect")]')
        .then(is => {
            console.log(is + ' - ' + profile);
            return is
              ? client
                  .isVisible('//button[contains(., "Connect")]')
                  .then(is => is
                        ? client
                            .click('//button[contains(., "Connect")]')
                            .pause(1000)
                        : [])
              : client
                  .isExisting('//button[contains(., "More")]')
                  .then(is => is ? client.click('//button[contains(., "More")]').pause(500) : [])
                  .isVisible('//button[contains(., "Connect")][not(contains(., "Remove"))]')
                  .then(is => is
                        ? client
                            .click('//button[contains(., "Connect")][not(contains(., "Remove"))]')
                            .pause(1000)
                        : [])
        })
        .isExisting('//button[contains(., "Send now")]')
        .then(is => is
              ? client
              .isVisible('//button[contains(., "Send now")]')
              .then(is => is
                    ? client
                        .click('//button[contains(., "Send now")]')
                        .pause(2000)
                    : [])
              : [])
        .pause(1000)
        .catch(e => console.log(e))
}

module.exports = {
    listAllConnections,
    connectLinkedin
};

What the code could have been:

const fs = require('fs');
const client = require('../Core');

const PROFILE_PATH = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE;
const project = `${PROFILE_PATH}/Collections/conversations`;
const NEW_CONNECTIONS_FILE = `${project}/new-connections.json`;

class ConnectionManager {
  async listAllConnections(list) {
    if (fs.existsSync(NEW_CONNECTIONS_FILE)) {
      try {
        return JSON.parse(fs.readFileSync(NEW_CONNECTIONS_FILE));
      } catch (error) {
        console.error('Error reading new connections file:', error);
      }
    }

    try {
      const url = await client.getUrl();
      if (list && list.includes('linkedin.com')) {
        await client.url(list).pause(3000);
      } else {
        await client.url('https://www.linkedin.com/mynetwork/').pause(3000);
      }

      const friends = await this.getAllUntil(false, '//a[contains(@href, "/in/")]/@href', []);
      const uniqueFriends = [...new Set(friends)];

      fs.writeFileSync(NEW_CONNECTIONS_FILE, JSON.stringify(uniqueFriends, null, 4));
      return uniqueFriends;
    } catch (error) {
      console.error('Error listing connections:', error);
    }
  }

  async getAllUntil(isAsync, selector, result, equality, condition) {
    try {
      const element = await client.isVisible(selector);
      if (element) {
        const elements = await client.getElements(selector);
        result = result.concat(elements.map((element) => element.getAttribute('href')));

        if (equality(result[result.length - 1], result[result.length - 2])) {
          return result;
        }

        if (condition(result.length)) {
          return result;
        }

        return this.getAllUntil(isAsync, selector, result, equality, condition);
      }
    } catch (error) {
      console.error('Error getting elements:', error);
    }
  }

  async connectLinkedin(profile) {
    try {
      await client.clickSpa(`https://linkedin.com${profile}`).pause(3000);
      const connectButton = await client.isVisible('//button[contains(., "Connect")]');
      if (connectButton) {
        await client.click('//button[contains(., "Connect")]').pause(1000);
      } else {
        const moreButton = await client.isVisible('//button[contains(., "More")]');
        if (moreButton) {
          await client.click('//button[contains(., "More")]').pause(500);
          const connectButton = await client.isVisible('//button[contains(., "Connect")][not(contains(., "Remove"))]');
          if (connectButton) {
            await client.click('//button[contains(., "Connect")][not(contains(., "Remove"))]').pause(1000);
          }
        }
      }

      const sendNowButton = await client.isVisible('//button[contains(., "Send now")]');
      if (sendNowButton) {
        await client.click('//button[contains(., "Send now")]').pause(2000);
      }

      return true;
    } catch (error) {
      console.error('Error connecting to LinkedIn:', error);
      return false;
    }
  }
}

module.exports = new ConnectionManager();

This code snippet defines two functions, listAllConnections and connectLinkedin, that automate interactions with LinkedIn, specifically focusing on retrieving a list of connections and sending connection requests.

Here's a breakdown:

  1. listAllConnections Function:

  2. connectLinkedin Function:

Purpose:

This code provides a way to programmatically scrape LinkedIn for a list of connections and send connection requests to specific profiles.