I am developing a Chrome extension to intercept user messages sent to ChatGPT. The goal is to verify whether the message contains sensitive data before sending it to the ChatGPT API.
Here’s the flow I want to achieve:
-
When the user types a message and clicks “Send” (or presses Enter), the Chrome extension intercepts the message.
-
The extension sends the intercepted message to my backend API.
-
The backend API analyzes the message to determine if it contains sensitive data.
-
If sensitive data is found, the backend masks the sensitive content and returns the modified
message. -
The modified (or original) message is then sent to ChatGPT.
I would like to know:
-
How can I intercept the message from the ChatGPT input box before it’s sent?
-
How can I send this intercepted message to my backend API from the extension and wait for the response?
-
Once the response is received, how can I modify the original input to send the filtered message to ChatGPT?
Here’s what I’ve tried so far:
- I’ve looked into using chrome.webRequest but it seems more suited for network requests rather than DOM manipulation.
- I’ve considered injecting a content script to access the DOM and listen to input events, but I’m unsure how to modify the message programmatically before submission.
Content.js
// content.js
console.log("ChatGPT Message Interceptor content script loaded.");
// Wait for the DOM to be fully loaded
document.addEventListener("DOMContentLoaded", () => {
const sendButton = document.querySelector('[aria-label="Send prompt"]'); // Adjust the selector based on the actual element
const inputField = document.querySelector("textarea"); // Adjust if necessary
if (sendButton && inputField) {
console.log("Send button and input field found.");
// Listen for the click event on the send button
sendButton.addEventListener("click", async (event) => {
event.preventDefault(); // Prevent sending the message directly
const userMessage = inputField.value;
console.log("Intercepted message:", userMessage);
// Send the message to your backend API for verification and filtering
try {
const response = await fetch("http://localhost:3001/verify", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ message: userMessage }),
});
const data = await response.json();
if (data.isSensitive) {
// If the message is sensitive, show the filtered version
console.log(
"Sensitive data detected. Filtered message:",
data.filteredMessage
);
// Set the filtered message in the input field
inputField.value = data.filteredMessage;
} else {
console.log("No sensitive data detected.");
}
// Trigger the send button again with the filtered message
sendButton.click(); // Resend the message (either original or filtered)
} catch (error) {
console.error("Error while sending message to backend:", error);
}
});
} else {
console.log("Send button or input field not found.");
}
});
manifest.json
{
"manifest_version": 3,
"name": "ChatGPT Message Interceptor",
"version": "1.0",
"description": "Intercept and modify messages sent to ChatGPT",
"permissions": [
"activeTab",
"storage"
],
"host_permissions": [
"http://localhost:3001/*" // This grants access to your local API
],
"content_scripts": [
{
"matches": ["https://chatgpt.com/*", "https://*.chat.openai.com/*"],
"js": ["content.js"]
}
],
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "images/icon-16.png",
"48": "images/icon-48.png",
"128": "images/icon-128.png"
}
}
}
background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log("Message received in background script:", message);
if (message.action === "logMessage") {
console.log("Log message from content script:", message.data);
sendResponse({ status: "Message logged" });
}
});
popup.js
document.getElementById("activateButton").addEventListener("click", () => {
chrome.runtime.sendMessage({ action: "activateInterceptor" }, (response) => {
alert("Interceptor activated!");
});
});
popup.html
<!DOCTYPE html>
<html>
<head>
<title>ChatGPT Message Interceptor</title>
<style>
body {
width: 200px;
padding: 10px;
}
button {
width: 100%;
padding: 10px;
font-size: 16px;
cursor: pointer;
}
</style>
</head>
<body>
<h3>Activate Interceptor</h3>
<button id="activateButton">Activate</button>
<script src="popup.js"></script>
</body>
</html>