All work

Safire · Code Kshetra 2.0 winner · Chrome extension · Gemini

Safire, a Chrome extension that hides harassment in LinkedIn messages and keeps the evidence

Safire sits inside LinkedIn's messages. When someone sends an abusive or creepy message, it hides it behind a warning before you have to read it, saves the evidence, and can turn a sender's messages into a PDF report when you want to report them. Four of us built it, and as team Pixel Minds it won Code Kshetra 2.0, a 36-hour hackathon with more than 14,000 registrations. It also won HackWIE 3.0.

Result

Won Code Kshetra 2.0 and HackWIE 3.0

Team

Four people

My part

Project setup, the in-chat warning, server changes

Stack

Plasmo extension, Express, MongoDB, Gemini, Next.js

Why we built Safire

LinkedIn is meant to be a professional network, but plenty of people, women especially, get messages there that are anything but: comments on how they look, "are you single?", and worse. The usual options are to read it, feel awful, and block, and by then the damage is done. Reporting is hard too, because the evidence is scattered across chats and easy to lose once you block someone.

We wanted the message to be caught before you read it, and the evidence to be kept for you, so that reporting is a button and not a project.

We took it to Code Kshetra 2.0, a 36-hour hackathon run by JIMS Rohini and Geek Room in February 2025, with 14,713 registrations and only the top 150 teams in the final rounds. Our team, Pixel Minds, won it.

What Safire does

Hides harassment as it arrives

Inside LinkedIn's messages, an abusive message is replaced with "Harassment detected in this message", and the chat list shows a warning instead of the message preview. You can still choose to show it.

Keeps the evidence

After signing in, hidden messages are saved with the sender's name, profile link, time and the message itself.

PDF evidence reports

A sender's saved messages can be turned into one PDF report, so you have everything in one place when you report them.

Hide a person completely

One click hides everything from a sender, in the chat and in the inbox list.

Flags repeat harassers

Once more than five different people have hidden someone, their profile shows a "# Harasser" tag to every Safire user.

Your own word list and a dashboard

You can add words that should always be hidden, and see saved messages, hidden people, reports and settings in the extension and on a web dashboard.

How Safire decides a message is harassment

A plain list of bad words catches the obvious cases fast, but harassment is often polite on the surface. "Do you have a boyfriend?" has no bad words in it, and it's still out of place from a stranger on a work platform. So Safire checks every message in two ways.

First, a list of blocked words, which each person can add to, runs right in the browser. Then the message goes to our server, which asks Google's Gemini model to judge it. Gemini answers in a fixed JSON format with yes or no for harassment, vulgarity, threats, sexual content and general offensiveness, plus a short explanation. If the answer says it's harassment, the extension hides the message.

The part I like most is that the check knows which platform the message came from. The prompt tells the model that a question like "do you have a boyfriend?" is harassment on LinkedIn, a professional network, but might be normal on Instagram. The same words get judged differently depending on where they were sent.

What the model is asked to return

{
  "isHarassment": true,
  "isVulgar": false,
  "isThreatening": false,
  "isSexuallyExplicit": false,
  "isPotentiallyOffensive": true,
  "analysis": "A personal question about relationships from a stranger on a professional platform."
}
A fixed shape, so the extension reads one yes or no instead of parsing free text.

Making the AI check dependable

Models sometimes wrap JSON in markdown, or don't return JSON at all

The server tries to read the reply as JSON, then tries again with the markdown stripped, and as a last resort looks for words like "harassment" in the text, so a messy reply never crashes the check.

Bad input from the extension

The server rejects a missing or empty username or message with a clear error before any model call is made.

The AI call is slower than a word list

The word list runs first, in the browser, so obvious messages are hidden instantly while the AI check catches the subtler ones.

From a new message to a saved report

The extension does the reading and hiding in the browser. The server does the AI check and keeps the evidence.

The extension reads the chat

extension/src/content.tsx

  • Finds each message on LinkedIn's messaging pages
  • Notes the sender's name, profile link and time

Blocked words, then Gemini

extension/src/background/messages/detectMsg.ts

  • The word list runs in the browser
  • The server asks Gemini, with the platform as context

Hide it behind a warning

  • The message and its preview are replaced
  • Buttons to show it, make a report or hide the user

Save the evidence

server/src/api/user/report.js

  • Stored in MongoDB with who sent it and when
  • Turned into a PDF report on request

Who built what

Four of us built Safire together. These are the parts each person owned, going by the commits.

Me

Set up the project, built the harassment detection and warning UI inside LinkedIn chats, added the buttons on that warning, and made changes to the server.

Rajveer

Most of the extension and the web dashboard, sharing the sign-in between the two, and after the hackathon a separate moderation service and the move to the name Safire.

Anamika

Saving a harasser's messages to the database with their profile, name and time, tagging harassers, hiding users, and calling the server only when needed.

Anushree

The landing page.

Screenshots

The team's own screenshots from LinkedIn. People who aren't on the team are blurred.

LinkedIn messages with Safire: a red warning says harassment was detected and the message is hidden, with buttons to show messages, make a legal report or hide the user
A harassing message, hidden as it arrives, with a warning in the chat list too.
Hidden messages in a LinkedIn chat with a prompt to sign in and save them
Sign in to keep the hidden messages as evidence.
Safire website: Stay safe online, hassle-free
The website.