이 번 글에서는 마지막으로 이 카테고리의 주제인 "에지브라우저에서 chatGPT 탭으로 메시지 전송후 대화" 부분 까지 진행해 보도록 하겠습니다.

이 전 글에서 기본 javascript를 사용해서 크롬의 메시지 송수신을 하는 부분 까지 진행했습니다. 이번 글에서는 

- Content Script (콘텐트 스크립트), - Popup (팝업): 에서 써드파티 라이브러리 사용법에 대해서 추가로 알아보고 바로 탭에서 수신한 메시지를 기존 new Chat Dom에 추가 하고 질문을 수행하는 부분까지 진행하도록 하겠습니다.

 

예제코드 : tistory_openapi/edgeGpt4 at master · a3040/tistory_openapi · GitHub 

 

- Content Script (콘텐트 스크립트), - Popup (팝업): 에서 써드파티 라이브러리 사용법이 각각 다릅니다.

 

- Popup (팝업)에서는 popup.html에서 직접 참조해서 사용하는 방식입니다.

<script src="./scripts/jquery.min.js"></script>
<script src="./scripts/axios.min.js"></script>

- Content Script (콘텐트 스크립트)는 manifest 설정을 통해 자동 주입해주는 형태입니다.

- 그게 아니면 dom 제어를 통해서 직접 추가 해주는 방식도 사용가능 합니다.

아래 예제 코드 설명에서 설명을 조금더 하겠습니다.

 

아래 이미지는 예제 코드를 실행한 상태입니다.

브라우저에서 메시지 전송 전

1.popup.html에 기본 주제를 적어둘 inputbox를 추가했습니다.

2. input box에 원하는 주제를 입력하고 "메시지전송" 버튼을 클릭합니다.

 

아래 이미지는 메시지 전송 버튼을 클릭한 이후 이미지 입니다.

gpt와 의 연결

1. "메시지전송" 버튼을 클릭으로 수신한 메시지 정보입니다.

2. 수신 메시지를 gpt DOM으로 넘겨 주는 메시지 입니다.

3. gpt DOM의 대화 상자로 popup에서 작성한 메시지가 전송된 상태입니다.

4. gpt DOM에 메시지를 전송후 openai에게 전송하는 부분입니다. 보통 엔터나 종이비행기 버튼을 클릭하는 액션을 수행하는 부분입니다.

 

예제코드 설명

manifest.json 설정파일 입니다.

{
    "name": "Hello4",
    "version": "0.0.1",
    "manifest_version": 3,
    "description": "Hello",
    "action": {
        "default_popup": "popup.html"
    },
    "permissions": [
        "debugger",
        "tabs",
        "scripting"
    ],
    "content_scripts": [
        {
            "matches": [
                "https://chat.openai.com/*"
            ],
            "js": [
                "scripts/jquery.min.js",
                "content.js"
            ]
        }
    ]
}

- 권한 부분과 콘텐츠 스크립트에서 사용할 "content_scripts"의 js 부분에 jquery.min.js를 추가했습니다. 추가가 되면 확장 프로그램이 해당 스크립트를 matches탭에 추가 해줍니다. 순서를 jquery 추가 하고 content.js를 추가해서 content.js에서 jquery를 사용할수 있습니다.

 

popup.html  popup.js에서 jquery를 사용하기 위해 직접 불러오고 있습니다.

<html>
<meta charset="utf-8" />

<body style="width:200px;">
    hello
    <input type="text" id="msg" value="" />
    <button type="button" id="sendMsg" style="width:50px">메시지전송</button>
    <script src="./scripts/jquery.min.js"></script>
    <script src="./scripts/popup.js"></script>
</body>

</html>

popup.js 기존 코드에서 jquery를 사용하는 방식으로 바뀌었습니다. jquery사용 예시용으로 변경했습니다.

console.log(`팝업 js 불림, 폴더구조확인용 scripts/popup.js`);

function send_to_content(msg){
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
        console.log("현재탭에 붙어있는 content에 msg보냄");
        const response = chrome.tabs.sendMessage(
            tabs[0].id,
            {
                from: 'popup',
                to: 'content',
                msg: msg,
                // topics: extactTopics
            },
            function (response) {
                console.log(response);
                window.close();
            }
        );
    })
}

$(document).ready(function () {  //jquery사용
    $("#sendMsg").on("click", function () {
        console.log("clicked");
        const msg = $("#msg").val();
        send_to_content(msg);
    });
});

content.js 마지막 파일입니다. 직접 chatGPT DOM과 연동되는 부분입니다. 역시 jquery 예시를 위해 jquery로 부분 변환했습니다.

메시지를 수신하고 수신한 메시지를 chatGPT DOM의 대화 창에 추가 한후 키보드 이벤트를 발생시켜 submit하는 코드입니다.

jquery 예제 추가후 아래의 예시 코드는 주석을 해제해도 동작하지 않습니다. 원인을 확인 해본 결과 jquery와 충돌하는 듯 합니다. 수정방법은 manifest에서 jquery 제거, 관련 jquery 제거 후 gpt_textarea.value 값 설정, dispatchEvent를 발생 시키면 정상적으로 동작하게 됩니다.

console.log(`js 불림, 폴더구조확인용 content.js`);

chrome.runtime.onMessage.addListener(function (message, sender, sendResponse) {
    if (message.from === 'popup') {
        try {
            console.log('메시지 수신1:', message);
            sendResponse('메시지를 수신했습니다.');
            bridge(message.msg);
        }catch(error){
            console.error(error);
        }
    }
});

function bridge(msg){

    const gpt_textarea = document.querySelector('form textarea');            
    const gpt_button = document.querySelector('form button[class*="bottom"]')
    gpt_button.disabled = true;
    gpt_textarea.value = msg; 
    console.log(`수신한 msg->gpt에게 넘김:${msg}`);
    /*
    // 새로운 키보드 이벤트 생성
    const event = new KeyboardEvent('keydown', {
        key: 'Enter',
        keyCode: 13,
        code: 'Enter',
        which: 13,
        keyIdentifier: 'Enter',
        view: window,
        bubbles: true,
        cancelable: true,
    });
    
    // 이벤트를 원하는 요소로 보내기 
    gpt_textarea.dispatchEvent(event); 
    */
    console.log(`주석 해제후 gpt_textarea에 엔터 키보드 이벤트전송시 질문이 openai로 전송됨`);
}

function insertDiv(){
    var div = document.createElement("div");
    div.style.height = "100px";
    div.style.backgroundColor = "blue";
  
    var body = document.body;
    var lastChild = body.lastElementChild;
  
    // body 요소의 맨 마지막에 div 요소를 추가합니다.
    body.insertBefore(div, lastChild.nextSibling);
}

function jinsertDiv(){
    var div = $("<div></div>").css({
        "height": "100px",
        "background-color": "red"
    });
    
    var lastChild = $("body").children().last();
    
    // body 요소의 맨 마지막에 div 요소를 추가합니다.
    lastChild.after(div);
}

jinsertDiv();
// insertDiv();

스크린샷 다 만든 후에 엔터키 이벤트가 충돌나는것을 발견 했습니다. 필요하신 분이 생기면 다음 글 작성하면서 예제코드를 하나 더 만들겠습니다. 지금은 동작하는 예시 하나 스크린샷하고 이번 카테고리 글은 마무리하겠습니다.

동일한 구조로 동작하는 확장프로그램입니다. jquery는 사용하지 않았습니다. 확장아이콘 클릭시 값이 초기화 되어 localStorage에 저정하고 불러오는 구조로 작업했습니다.

이상으로 에지브라우저에서 chatGPT 탭으로 메시지 전송후 대화에 대한 글을 마치겠습니다.

 

참고

이런걸 쓰면 content.js 작업할때 gpt dom사용이 편할것 같습니다. 

chatgptjs/chatgpt.js: 🤖 A powerful client-side JavaScript library for ChatGPT (github.com)

 

GitHub - chatgptjs/chatgpt.js: 🤖 A powerful client-side JavaScript library for ChatGPT

🤖 A powerful client-side JavaScript library for ChatGPT - GitHub - chatgptjs/chatgpt.js: 🤖 A powerful client-side JavaScript library for ChatGPT

github.com

 

+ Recent posts