Browsing Assist 크롬 익스텐션 - 6

홍범선·2024년 12월 25일
0

Browsing-Assist

목록 보기
6/8

✔️ AI 핵심 문장 추천


📄 많은 HTML 코드 중에서 본문 태그 찾는 법

처음에는 자식 노드 중에서 p 태그가 가장 많은 태그를 찾았습니다.

하지만 예외가 너무 많았고, 워킹 데이가 많지 않아서 라이브러리를 사용했습니다.


바로 ReadAbility라는 라이브러리 입니다.

이 라이브러리를 통해서 본문 내용을 전부 가져올 수 있었습니다.




📄 크롬 익스텐션 팝업창 데이터 전송

그 전에 Content Script에서 popup으로 body.innerHTML을 전달해야 합니다.

그래야지 팝업창에서 ReadAbility 라이브러리를 사용할 수 있기 때문이죠


Content Script에서 익스텐션 팝업창으로 보내기 위해선
chrome.runtime.sendMessage 메서드가 필요합니다.


코드로 살펴볼까요?

	chrome.runtime.sendMessage({
        type: "SEND_BROWSER_INFO",
        hostName: getDomain(),
        resultArr: resultArr,
        HTMLContent: document.documentElement.outerHTML,
        accessToken: result.GETSBEE_LOGIN.accessToken,
        refreshToken: result.GETSBEE_LOGIN.refreshToken,
        userState: result.GETSBEE_LOGIN.userState,
      });

이렇게 하여 popup창으로 데이터를 보낼 수 있습니다.




📄 background.js 메시지 전달 중개

background.js는 말 그대로 백그라운드 작업을 담당합니다.

실시간 메시지를 수신하고 전달하는 역할을 하죠

코드로 살펴봅시다.

if (message.type === "SEND_BROWSER_INFO") {
    // 저장: chrome.storage.local 또는 chrome.storage.sync에 데이터 저장
    // eslint-disable-next-line no-undef
    accessToken = message.accessToken;
    refreshToken = message.refreshToken;

    chrome.runtime.sendMessage({
      type: "SEND_DATA",
      data: {
        hostName: message.hostName,
        resultArr: message.resultArr,
        HTMLContent: message.HTMLContent,
        accessToken: message.accessToken,
        refreshToken: message.refreshToken,
        userState: message.userState,
      },
    });
  }

Content Script에서 SEND_BROWSER_INFO를 보내면, 백그라운드에서 이를 수신하고 해당 코드를 처리합니다.

마찬가지로 크롬 팝업창에 메시지를 보내야겠죠?

chrome.runtime.sendMessage를 통해 보낼 수 있습니다.




📄 Gemini API로 핵심 문장 추천 받기

이제 popup에서 body.innerHTML을 전달받았으므로, Readability를 사용해 본문을 추출할 수 있습니다.

해당 본문을 토대로 Gemini API를 호출하여 핵심 문장을 추천받으면 끝이 납니다.

코드로 알아볼까요?

async function run(model) {
    try {
      let prompt = `
      다음 문장 배열에서 중요하다고 생각되는 문장들을 배열형식으로 추천해 주세요. 다음 조건을 만족해야 합니다:
      1  그리고 꼭 배열의 크기가 5를 넘으면 안됩니다.
      2. JSON형식으로 보내주세요 예를 들어, [{"중요 문장1의 인덱스" : "중요 문장1"}, {"중요 문장2의 인덱스" : "중요 문장2"}, {"중요 문장3의 인덱스" : "중요 문장3"}] 형식으로 응답해 주세요.
      3. 전체적인 내용을 빠르게 파악할 수 있는 핵심 문장들을 추천해주세요, 기존 배열에서 순서에 맞게 제공해주어야 합니다. 
      4. 또한 기존 문장에서 문장을 추가하지말고 그냥 있는 그대로 중요 문장을 추출해주세요.
    
      `;
      
      if (textContents.length === 0) {
        setLoading(false);
        setErrorMessage("내용이 부족합니다.");
        setError(true);
        return;
      }

      const result1 = textContents.reduce((acc, item, index) => {
        acc[index] = item;
        return acc;
      }, {});
      prompt += JSON.stringify(result1);

      const result = await model.generateContent(prompt);
      const response = await result.response;
      const text = await response.text();
      let jsonData = "";

      try {
        jsonData = text.split("```")[1].split("json")[1];
      } catch (er) {
        jsonData = text;
      }

      const parsedData = JSON.parse(jsonData);

      const sortedKeys = parsedData
        .map((item) => {
          const key = Object.keys(item)[0]; 
          return parseInt(key, 10); 
        })
        .sort((a, b) => a - b); 
      const sortedTextContents = sortedKeys.map((key) => textContents[key]);

      setResult(sortedTextContents);
      // console.log(textContents, sortedValues);
      chrome.runtime.sendMessage({
        type: "RECOMMEND_CLICKED",
        resultArr: sortedTextContents,
      });
    }

Gemini API 문서를 토대로 호출한다음 응답받은 값을 sendMessage를 통해서 background에 보냅니다.

마찬가지로 background에서 수신하고 ContentScript에 전달하면 끝이 납니다.


여기까지 AI 기반 핵심 문장 추천 구현이였습니다.

profile
알고리즘 정리 블로그입니다.

0개의 댓글