9 minutes to read - Mar 30, 2023

How to use Cohere tutorial: How to create a Cohere powered summarization Chrome Extension

VISIT
How to use Cohere tutorial: How to create a Cohere powered summarization Chrome Extension
Hello! Have you ever had to do something urgent, and you really wanted to read an article, even though it was a very long one? In this tutorial, you will learn how to create a Google Chrome extension that will allow you to summarize an article and reduce reading time. So let's get started!
Table of Contents
1❓ How to create a Chrome extension?
2📚 Manifest file
3🔁 Load extension to browser
4📜 popup.html
5🎨 index.css
6🤖 index.js
7Okay so now we can use it! Let's go to Medium and try it out!

This tutorial requires some HTML, CSS, JavaScript knowledge, but it is not something that cannot be learned quickly!

❓ How to create a Chrome extension?

So, we will start creating an extension by creating the appropriate files. My file structure looks like this:

popup directory contains .html file for extension popup, we will not use it that much I will just put extension name here.

scripts directory contains .js file for extension logic - generating buttons and summarization.

Styles directory contains .css file for extension styling.

manifest.json is a file that contains all the information about the extension. We will start with it.

📚 Manifest file

As I wrote before, manifest.json is a file that contains all the information about the extension. It is a JSON format file. This will be our content for this file:

What will be the most important for us:

css - Path to our css file

js - Path to our js file

matches - List of domains where we want to use our extension (in my case, I want to use it on medium.com, towardsai.net, towardsdatascience.com, levelup.gitconnected.com, but there are more domains that you can use, feel free to add some more. For me it will be enough)

🔁 Load extension to browser

To load extension, go to browser, then to settings > extensions. Turn on developer mode and load extension with button in top left corner. Select your extension folder and you are done!

📜 popup.html

To this file I will just put basic html template, with extension name.

🎨 index.css

Here I will put some styles for buttons we will use for summarization. They will not be beautiful, but for now they are to fulfill their role. I will explain why I will use such classes in the next section.

🤖 index.js

Here we will put our logic for extension. First, we will create a function that will generate buttons for summarization. We will use document.createElement to create buttons and document.body.appendChild to append them to the body of the page. We will also add event listeners to buttons, so when we click on them, we will call function for summarization.

We want to put out button next to out user photo. To do it we have to append it to two places - sidebar, which is available for desktop view, and bottom bar - for mobile view. To do it I will got to page and using dev tools I will take element selectors for these elements. There are two possible situations - we will go to main page and the choose one of articles, or we will go directly to article. The selectors are slightly different in both options, which will be included in the guide.

We will create three functions that will be used in the tutorial - loadButtons, prediction, cohereReq.

We will start with loading buttons. We want to load them when the page loads, but not the home page. If we go to the main page, it will be better to load them on click or scroll - when we enter the article from the main page, the onload event is not performed, so it will be the right solution for us. Let's code it:

const loadButtons = () => {

  // don't want to add these buttons to main page

  // so if there is nothing after e.g. 'medium.com/' url we will just return 

  if (window.location.pathname.length < 2) return;

  // Bottom button

  // add if there isn't already one (we can performe some events more than once, but don't want to add more than one button)

  if (!document.querySelector(".btn-bottom")) {

    const bottomBar = (

      document.querySelector("#root > div > div.l.c > div > div > div.v.w.x.y.z.ab.ac.ae.af > nav > div:nth-child(3) > div > div.ec.an.dp.ed > div") || 

      document.querySelector("#root > div > div.y.c > div > div > div.jc.jd.je.jf.jg.jh.ji.jj.jk > nav > div:nth-child(3) > div > div > div")

    )

    // here we are creating structure for button

    const btnBottom = document.createElement("a")

    btnBottom.classList.add("btn-bottom")

    btnBottom.classList.add("btn-summary")

    btnBottom.textContent = "S"

    // we will create container for button

    const btnBottomContainer = document.createElement("div")

    btnBottomContainer?.classList.add("btn-container")

    // and then append container with button to the bar

    btnBottomContainer?.appendChild(btnBottom)

    bottomBar?.appendChild(btnBottomContainer)

  }

  // Side button

  if (document.querySelector(".btn-side")) return

  const sideBar = (

    document.querySelector("#root > div > div.l.c > div > div > div.v.w.x.y.z.ab.ac.ae.af > nav > div.ag.h.k.j.i.cv > div") || 

    document.querySelector("#root > div > div.y.c > div > div > div.jc.jd.je.jf.jg.jh.ji.jj.jk > nav > div.cx.h.k.j.i.hz > div")

  )

  const btnSide = document.createElement("a")

  btnSide.classList.add("btn-side")

  btnSide.classList.add("btn-summary")

  btnSide.textContent = "SUM"

  const btnSideContainer = document.createElement("div")

  btnSideContainer?.classList.add("btn-container")

  btnSideContainer?.appendChild(btnSide)

  sideBar?.appendChild(btnSideContainer)

  // for all buttons we want to add event listener that will call function for summarization

  const allButtons = document.querySelectorAll(".btn-summary")

  allButtons.forEach(btn => btn.addEventListener("click", prediction))

}

To load buttons on particular event we will use window.onload event:

Now let's code functions for summarization. We will use cohereReq function to get summary from Cohere API.

// request to cohere xlarge model

const cohereReq = async prompt => {

  const modelSettings = JSON.stringify({

    model: "xlarge",

    prompt,

    max_tokens: 1024,

    temperature: 0.6,

    k: 0,

    p: 0.75

  })

  const reqBody = {

    method: "POST",

    mode: 'cors',

    headers: {

        "Authorization": "BEARER {YOUR_COHERE_API_KEY}",  // replace with your API key

        "Content-Type": "application/json", 

        "Cohere-Version": "2021-11-08",   // model version

        // I added some headers to prevent CORS errors

        "Access-Control-Allow-Origin": "*",

        "Access-Control-Allow-Methods": "DELETE, POST, GET, OPTIONS",

        "Access-Control-Allow-Headers": "Content-Type, Authorization, X-Requested-With"

    },

    body: modelSettings,

    redirect: "follow"

  };

  // make request

  let response = await fetch("https://api.cohere.ai/generate", reqBody);

  response = response.json();

  return response;

}

Now let's implement logic for extracting data from page and calling cohereReq function. We will use prediction function for it.

const prediction = async e => {

  const articleElement = document.querySelector("section > div > div:nth-child(2)")

  // extract headings, text, skip images

  let texts = []

  const heading = articleElement.querySelector("h1")?.textContent

  // get text from each element

  for (const node of (articleElement.childNodes || [])) 

    if (node.textContent !== heading) 

      texts.push(node.textContent.split(" "));

  // flatten array

  texts = texts.flat()

  // remove empty strings

  texts = texts.filter(text => text !== ""  && text !== " ")

  const prompt = `Summarize shortly this article, without code! If you want to finish use '--'. Article:

Article heading: ${heading || texts[0]}

Article content: ${texts.slice(0, 800).join(" ")}

  const response = await cohereReq(prompt)

  // from response get generations (if response exists), from generations get first element (if generations exist), and from it get text (if theres is element exists)

  const text = response?.generations?.shift()?.text

  console.log(text)

}

Okay so now we can use it! Let's go to Medium and try it out!

As you can see, we can only get the answer in the console. I did it specifically to leave the improvement for you. Think of it as a challenge! Try to improve the performance of the model by editing the prompt. Create a nice popup in popup.html, and generate a popup for the received reply. Create spinner during waiting for reply. You can also edit the main button.

Article source
loading...