Create your own ChatGPT extension in Chrome

Aaron Yu
4 min readJul 6, 2023

ChatGPT has truly blown us away with the remarkable quality of content it generates, leaving us in awe. It has quickly become a go-to productivity tool for not just me, but many others as well. The possibilities are endless, and I can’t help but feel excited about incorporating it into various applications. Rather than waiting for someone else to launch a similar product, like Microsoft Copilot for O365, my enthusiasm drives me to take matters into my own hands. I can’t wait to create my very own copilot solution using a Chrome extension. The potential for innovation and enhanced productivity is simply exhilarating!

The idea &the plan

If I can plug ChatGPT into Chrome and make it available on most of the web applications that I use, I can access ChatGPT power more directly and even optimise the process. It will greatly help increase my productivity.

I need to create my own Chrome extension and hook it up with ChatGPT. I want to create my own menu on my mouse right-click to invoke ChatGPT services and send content back to my browser.

I want to create 3 functions: rewrite a selected paragraph on any page (e.g. my Gmail, WhatsApp, etc.); summarise a selected article; compose a reply based on a selected conversation log.

Some basics

Chrome has an entire framework that you can use to create powerful extension. It basically injects background Javascript to work with Chrome APIs and content Javascript to manipulate DOM objects.

ChatGPT on the other hand is much easier to work with. It provides a RESTful API which you can consume with a few lines of code.

The solution

  1. Create a local project with the background JS and content JS

2. The background.js is used to register a Context Menu to mouse right-click so that I can interact with it. https://developer.chrome.com/docs/extensions/reference/contextMenus/

3. The content.js is used to find the selected content on a page, then pass it to ChatGPT API. Once a reply is given by ChatGPT, displays it on the respective page.

The result

Let’s try it out. On the website where I enabled the extension, I can simply select a paragraph, right-click and go to the ChatGPT menu to ask ChatGPT to rewrite the paragraph or summarise it or compose a reply. As a result, the response is displayed just below the section I selected.

Codes for your reference if you are interested. If there are enough interests from the community, I may publish it to Chrome Marketplace as well. :D

manifest.js

Key configurations: 
Set the right permission
"permissions": [
"tabs",
"contextMenus",
"scripting"
],
Load the required scripts
"content_scripts": [
{
"js": ["scripts/jquery-3.7.0.min.js", "scripts/content.js"],
"matches": [
"https://developer.chrome.com/docs/*"
]
}

background.js

//3. use messaging to pass the event to frondend content.js
// https://developer.chrome.com/docs/extensions/mv3/messaging/
function fnCallGPTService(menuItemId){
console.log("fnCallGPTService called");
(async () => {
const [tab] = await chrome.tabs.query({active: true, lastFocusedWindow: true});
const response = await chrome.tabs.sendMessage(tab.id,
{userAction: "GPT_REWRITE", menuItemId: menuItemId});
console.log(response);
})();
}

//1. Register the menu entry
chrome.runtime.onInstalled.addListener(async () => {
chrome.contextMenus.create({
id: 'rewrite',
title: 'Smart Rewrite',
type: 'normal',
contexts: ['page','selection'],
});
});


//2. Add listener to handle the click event
// Open a new search tab when the user clicks a context menu
chrome.contextMenus.onClicked.addListener((item, tab) => {
console.log("contextMenus onClicked");
fnCallGPTService(item.menuItemId);
});

content.js


function fnGptRequest(action){
let text = "";
if (window.getSelection) {
text = window.getSelection().toString();
} else if (document.selection && document.selection.type != "Control") {
text = document.selection.createRange().text;
}
console.log(`text: ${text}`);

let basePrompt = create your own base prompt
if(action == "summerize")
basePrompt = create your own base prompt
if(action == "compose")
basePrompt = create your own base prompt
var settings = {
"url": replace with your API endpoint,
"method": "POST",
"timeout": 0,
"headers": {
"Content-Type": "application/json",
"Authorization": replace with your access token
},
"data": JSON.stringify({
"model": choose your model,
"messages": [
{
"role": "user",
"content": basePrompt + text
}
]
}),
};
console.log("Sending to ChatGPT");

$.ajax(settings).done(function (response) {
const reply = response.choices[0].message.content
const replyHTML = fnGetPopupTemplate(reply);
$("body").append(replyHTML);
});

}

//4. add listener to receive message from extension.
chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if (request.userAction === "GPT_REWRITE"){
if(request.menuItemId == 'rewrite'){
sendResponse({frondendMsg: "Received GPT_REWRITE rewrite request"});
fnGptRequest("rewrite");
}else if(request.menuItemId == 'summerize'){
sendResponse({frondendMsg: "Received GPT_REWRITE summerize request"});
fnGptRequest("summerize");
}else if(request.menuItemId == 'compose'){
sendResponse({frondendMsg: "Received GPT_REWRITE compose request"});
fnGptRequest("compose");
}
}
}

);

function fnGetPopupTemplate(textToDisplay){
//create your own function to display the reply whatever way you want
}

--

--

Aaron Yu

I am not a coder, but I like solving problems programmably