I have just finished typing the script out at 23:08!

How I removed my LinkedIn connections in bulk

Martin Džejky Jakubik
6 min readFeb 5, 2019

And how I had to write a custom javascript logic to do it.

NOTE: This article is quite old and the code in it might no longer work on LinkedIn. However, the principles behind it are still valid.

I opened my LinkedIn profile the other day and I realized that I had over 250 connections. Not only that but most of them were not even relevant to me. I decided to clean my list of connections all at once.

But, on LinkedIn, it is only possible to remove a single connection at once and it takes 3 clicks to get it done!

I knew I wanted to get rid of around 100 connections. Doing that by hand would take me a lot of time and a lot of clicks. So I decided to write my own custom code which would inject a couple of checkboxes and buttons to the page which would make the necessary clicks for me. Additionally, this was a great opportunity to learn to use the MutationObserver.

This post describes what I did and how my custom code functioned.

Please note that it is your own responsibility for using any code in this post.

Injecting custom code

I did not want to spend any time making a custom Chrome extension. So I decided to use this existing extension to allow me to inject my custom code to the LinkedIn page. I like this particular extension because it offers a nice editor to write the code, too.

Data persistence

I started with handling the data for my script. The logic is very simple. The script adds a global __f object to hold all the data. This object is then loaded from localStorage upon initialization and saved to it before the page unloads. The code looks like this:

Sidenote: why __f? I actually don’t know. It came to me while I was on a toilet…

This part of the code is very straightforward and does not use anything magical. The only interesting part is the use of the beforeunload event to save the data before exiting the page. It also sets the default values if not data was stored before.

Initializing a MutationObserver

Let me first elaborate on why I chose the MutationObserver. Well, my first idea was to simply use load event. But, that did not work because I could not easily detect when the relevant HTML elements appear. I did not want to use some weird logic with setInterval to keep checking for them.

MutationObserver lets you get notified when there are any changes to the DOM. This means that I could run my own logic when the relevant elements were added to the DOM. Here’s how I registered my callback function:

Enhancing the connection cards

The next step was to add my own logic to the connection cards. There are HTML elements on the page which show the connection details. They also allow the user to perform actions with this connection.

Here’s how one connection card looks

My goal was simple — to add a checkbox somewhere to this card and handle the logic of selecting and de-selecting cards. First, I tried to remove the button and add a checkbox. But, I decided later to reuse the existing button and redefine its behavior.

This code is very straightforward. When it receives a mutation change, it checks whether it is a connection card. If it is, it calls a handler to set up custom logic for that card. This way, the code handles all the connection cards, even those that are loaded later as I scroll the page. Let’s have a look at the card handler function.

I used the names to identify the connections. The handler function first gets the name from the card. Then it changes the button text and registers custom behavior. Finally, handles style changes when the card is selected.

Now it was possible for me to select all the connections that I wanted to get rid of. And thanks to the use of MutationObserver and localStorage, I could even reload the page. The connections would still remain selected. Perfect!

Removing connections in bulk

What we all have been waiting for…

It was time to make the final piece of the puzzle — the ability to remove the selected connections. I started by checking the network request that is made when I manually remove a connection. It turned out that the browser made a request such as this:

DELETE
https://www.linkedin.com/voyager/api/relationships/connections/<ID>

The request contained a mysterious ID which I could not find in the DOM. So I decided that instead of making HTTP requests, the script would only click on buttons. But first, I needed to add a START REMOVING button which would start the process. I modified the observeCallback function to this:

As you can see, the script is waiting for the connections header element to appear in the DOM. When it does, the script calls a handler function. This handler then inserts a button which triggers the start of removing. Here’s how it looks:

There’s a lot happening inside this code snippet! The first function handler is called from the MutationObserver callback function. It attaches a large red button to the header.

When this button is clicked, it calls the startRemoving function. This one checks whether there is anything to remove in the first place. If there is, it sets the global state and calls the keepRemoving function. The keepRemoving function tries to find the correct connection card for the first selected name. It does this by getting all cards and finding the one with the correct name. When it finds the correct card, it finds its dropdown button and clicks it. The rest of the functionality happens in the MutationObserver callback function. Let’s take a look at it again:

As you can see, when the callback sees an added dropdown button, it clicks it. Then when it registers the confirmation modal, it clicks its confirm button. This all works because the LinkedIn page is inserting and removing DOM elements to show the dropdown and the modal.

Detecting removed connections

Finally, I wanted to deselect a connection once it was removed. Then I wanted to keep removing the rest of the selected connections. For that, I needed to detect when the connection card has been removed from the DOM. Let’s get back to the MutationObserver callback function:

I had to use querySelector instead of matches on the removed node. This is because the callback function only gets the top removed element and not the connection card element itself. In this case, it was the li parent element of the card.

The handler function checks whether the script is currently removing this connection. If it is, the name is removed from the list of selected connections. Then the process continues by calling startRemoving again.

So there you have it! Running this script on the LinkedIn page allows you to bulk remove your connections. It does so by using the MutationObserver. It allows you to toggle which connections to remove and then removes them by pressing the buttons in the DOM for you. Easy!

Here’s the final version of the script:

If you have any suggestions for the code let me know in the comments. Please note that this is not production-grade code at all! 😄

Thank you for reading this post. If you like it, make sure to give it a 👏 and follow me for more awesome goodies. Have a nice day!

--

--

Martin Džejky Jakubik

Frontend developer @ Exponea. Writing about things I learn along the way.