공부, 오류

Chrome extensions 추가해보기

반응형

회사에서 사용하는 Q&A 사이트가 있는데 Socket 등으로 연결이 된 상황이 아니다보니 실시간으로 조회가 안되는 상황

 

그래서 주기적으로 조회를 시켜야 최신화가 되는 상황이었음

 

Q&A 리스트 조회 버튼 누르기 귀찮아서 자동 조회하는 기능을 크롬확장자 느낌으로 만들면 어떨까 하고 간단하게 만들어봤음

 

참고로 기본 틀은 어디서 알았냐면 코딩애플님의 유튜브를 보고 영감을 얻었다.

 

1. 패키지 생성

 

 

2. manifest.json 생성

이걸 생성해주는 이유는 구글이 개발한 새로운 웹 확장 API 로 설명되어있음 자세한건 구글 검색을 통해 알게되었다.

참고문서

 

크롬 매니페스트 V3가 광고 차단기 및 사용자 경험에 미치는 영향

1. 서론

www.jangwook.net

 

 

 

3. 기능 구현

 

분 단위 입력, prompt로 값 입력받기

 

입력 받은 분 단위 기준으로 interval 실행!

 

입력 받은걸 전달 어떻게 함? 이 난관에 빠져서 팝업 간단하게 만들기로 했다.

 

 

html, js 하나씩 만들어주고

js에는 입력 및 버튼 클릭시 동작하도록 이벤트 추가

 

popup.js

document.addEventListener("DOMContentLoaded", () => {
    document.getElementById("startButton").addEventListener("click", () => {
        const minute = parseInt(document.getElementById("minuteInput").value);
        const inputField = document.getElementById("minuteInput");

        if (!isNaN(minute) && minute > 0) {
            chrome.runtime.sendMessage({ action: "startInterval", minute: minute }, (response) => {
                console.log(response.status);
                window.close();
            });
        } else {
            inputField.style.border = "2px solid red";
            inputField.focus();
        }
    });

    document.getElementById("stopButton").addEventListener("click", () => {
        chrome.runtime.sendMessage({ action: "stopInterval" }, (response) => {
            console.log(response.status);
            window.close();
        });
    });
});

 

 

근데 이걸 어딜 거쳐서 현재 보고있는 탭에 전달할지 고민 도중 간단히 서버로 만들어서 response 해주자 생각

background.js

 

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.action === "startInterval") { // interval start
        chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
            if (tabs.length === 0) {
                sendResponse({ status: "No active tab found" });
                return;
            }
            
            // 현재 보고있는 탭만 적용하도록
            chrome.tabs.sendMessage(tabs[0].id, { action: "startInterval", minute: message.minute }, (response) => {
                if (chrome.runtime.lastError) {
                    console.error("Error sending message:", chrome.runtime.lastError.message);
                } else {
                    console.log("Message sent successfully:", response);
                }
                sendResponse({ status: "Interval started" });
            });
        });

        return true; // Async response
    } else if (message.action === "stopInterval") { // stop interval
        chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
            if (tabs.length === 0) {
                sendResponse({ status: "No active tab found" });
                return;
            }

            // 현재 보고있는 탭만 적용하도록
            chrome.tabs.sendMessage(tabs[0].id, { action: "stopInterval" }, (response) => {
                if (chrome.runtime.lastError) {
                    console.error("Error sending message:", chrome.runtime.lastError.message);
                } else {
                    console.log("Message sent successfully:", response);
                }
                sendResponse({ status: "Interval stopped" });
            });
        });

        return true; // Async response
    }
});

 

 

서버로부터 전달받은 동작을 현재 탭에 처리

content.js

let intervalId = null;

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.action === "startInterval") {
        const intervalTime = message.minute * 60 * 1000; // 분 단위 -> 밀리초 단위
        if (intervalId) clearInterval(intervalId);

        var iframe = document.getElementById('ui-tabs-TM');
        var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;

        const doSearchElement = iframeDocument.querySelector('.doSearch');
        console.log(doSearchElement);

        intervalId = setInterval(() => {
            console.log(`자동검색 실행 중 : ${message.minute}분 주기`, doSearchElement);
            if (doSearchElement) {
                doSearchElement.click();
            }
        }, intervalTime);

        sendResponse({ status: "Interval started" });
    }

    if (message.action === 'stopInterval') {
        clearInterval(intervalId);
        sendResponse({ status: "Interval stopped" });
    }
});

 

 

입력 및 전달 받은 분 단위로 interval 동작 !

var iframe = document.getElementById('ui-tabs-TM');

 

위 부분은 현재 리스트 보여주는 table 형태를 realgrid를 사용하고있어서 iframe으로 그리는 상황이라

id = doSearch 버튼 element를 찾지 못하는 상황 발생

 

왜 찾지 못하는지는 다음 업로드 때 작성하도록 하겠음

 

 

4. 확장자 등록

크롬 브라우저 우측 상단에 있는 퍼즐 아이콘 클릭확장 프로그램 관리 클릭

 

페이지 이동 후 좌측 상단에 있는 압축해제된 확장 프로그램을 로드합니다. 클릭

 

패키지 선택 (auto-search) 1번에서 생성한 dir 클릭

 

업로드 확인

 

다시 크롬 우측 상단에 있는 퍼즐 아이콘 클릭 > 생성한 확장프로그램 실행

 

결과

 

 

동작도 잘 되고 로그도 잘 찍힌다.

 

근데 그냥 개발자 도구 열고 interval 돌리면 안됨?

 

맞긴 하다, 나도 그렇게 사용했었음

근데 한번 뭔가 확장자를 만들고 싶어서 찾아낸 억지 사유에 가깝다.

 

근데 만들어보니 재밌고 신기했음

+ 회사 사람들도 몇몇 같이 사용중인데 좋다고 후기들을 남겨주신다.

 

후기 1

 

반응형
소개 | 개인정보처리방침 | 문의

Categories