Chrome App 개발하기

이윤준·2021년 9월 7일
1

Project

목록 보기
2/3

개인적인 이유로, Youtube Live에서 강의를 꾸준히 듣게 되었다.
라이브 방송이기 때문에, 질문을 챗팅으로 바로바로 할 수 있는데,
채팅을 할 때 [A조_3번_홍길동] {채팅내용} 이런 식으로
특정 양식에 맞춰서 채팅을 해달라고 했다.

매번 이걸 일일히 치는 것이 번거로워서, 크롬 앱으로 알아서 정해진 형식을 입력해주는 크롬 앱을 만들어보기로 했다.

크롬 앱 만들기

1. manifest.json 파일 만들기

크롬 웹스토어 앱을 배포하기 위해서는, 구글에서 제공하는 양식에 맞춰서 manifest.json 파일을 작성해야한다.

{
    "name": "AUTOFORM", //확장 프로그램 이름
    "description": "Automatically Make your Form",
    "version": "1.2",
    "manifest_version": 3,
    "permissions": [ // 필요한 권한 목록
        "storage", //브라우더 저장소 API 사용 권한
        "activeTab", //활성화된 탭에 사용할 수 있는 API 사용 권한
        "scripting" // js 및 css를 웹 페이지에 삽입하게 해주는 API 사용 권한
    ],
    "action": {
        "default_popup": "popup.html", //팝업 창으로 보여질 페이지
        "default_icon": {
            "16": "/images/logo16.png",
            "32": "/images/logo32.png",
            "48": "/images/logo48.png",
            "128": "/images/logo128.png"
        }
    },
    "icons": {
        "16": "/images/logo16.png",
        "32": "/images/logo32.png",
        "48": "/images/logo48.png",
        "128": "/images/logo128.png"
    },
    "options_page": "options.html",
    "content_scripts": [
        {
            "matches": [
                "*://*/*"
            ],
            "all_frames": true,
            "js": [
                "popup.js"
            ]
        }
    ]
}

앱을 사용한데는 필요없는 권한 사항을 등록하면, 앱 검토할 때 거절 당하니, 꼭 필요한 권한들만 작성해야 한다.

화면 만들기

인제 화면에 보여질 팝업 창인 popup.html 파일을 작성해보자

<!DOCTYPE html>
<html>
<head>
    <link rel="stylesheet" href="./css/bootstrap.min.css">
</head>

<body>
    <div class="form-group mx-sm-1 mb-2">
        <input class="form-control" type="text" id="formText" value="Enter your Form">
    </div>
    <button class="btn btn-primary mb-2" id="start">형식 제출</button>
    <button class="btn btn-primary mb-2" id="stop">중지</button>
    <script src="popup.js"></script>
</body>

</html>

화면에 작게 보여질 팝업창인 만큼, 코드도 짧다.
형식 제출 버튼을 누르면, input창에 입력된 형식이 자동으로 채팅 창에 만들어지게 할 것이다. 그것도 중지 버튼을 누르기 전까지 계속 만들어지게 할 것이다.

기능 구현하기

인제 이 팝업창을 통해, 자동으로 채팅 형식을 입력해줄 popup.js을 작성해보자

일단 각 요소를 이렇게 가져왔다.

let startBtn = document.getElementById("start");
let stopBtn = document.getElementById("stop");
let formText = document.getElementById("formText");

그리고, startBtn에 눌렀을 때 발동될 start함수를 작성했다.
정말 간단하게, 저장된 값을 채팅창에 입력해주는 코드이다.
유튜브 라이브 사이트에서, 열심히 화면을 분석한 결과 유튜브 채팅창은 id가 chatframe인 iframe에 띄워져 있었다.
거기서 querySelector를 이용해 채팅창을 가져올 수 있었다.


function start() {

  let makeForm = setInterval(() => {
    chrome.storage.local.get(["formText"], function (result) {

      var chat = document.querySelector(
        "div#input.style-scope.yt-live-chat-text-input-field-renderer"
      );
      if (chat != null) {
        if (chat.innerText == "") {
          chat.innerText = result.formText;
        }
      } else {
        var chatFrame = document.querySelector("#chatframe").contentDocument;
        var chatInput = chatFrame.querySelector("div#input.yt-live-chat-text-input-field-renderer");
        var chatBtn = chatFrame.querySelector(
          "div#send-button.style-scope.yt-live-chat-message-input-renderer"
        );

        if (chatInput.innerText == "") {
          chatInput.innerText = result.formText;
          chatInput.removeAttribute("aria-invalid");

        }
      }
}

그리고 이벤트리스너를 이용하여 startBtn에 달아줬다

startBtn.addEventListener("click", async () => {
  let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

  let inputText = document.getElementById("formText").value;
  chrome.storage.local.set({ formText: inputText }, function () {
    console.log("value is set to " + inputText);
  });

  chrome.scripting.executeScript({
    target: {
      tabId: tab.id,
    },
    function: start,
  });
});

여기서, input 창에 있는 텍스트를 Storage에 저장하고, start 함수에서 그 값을 계속 꺼내서, 자동으로 형식을 입력해준다.

그리고, 자동완성을 그만하고 싶을 때를 위해 stop 함수도 작성하여서 stopBtn에 달아줬다.

function stop() {
  chrome.storage.local.get(["makeForm"], function (result) {
    clearInterval(result.makeForm);
  });
}

stopBtn.addEventListener("click", async () => {
  let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });

  chrome.scripting.executeScript({
    target: {
      tabId: tab.id,
    },
    function: stop,
  });
});

이렇게만 하면 일단, 목적한 기능들은 다 구현되었다.

여담

이 프로그램은 setInterval 함수를 사용하기 때문에, 어느정도 브라우저에 부담을 준다고 생각할 수 있다.
하지만 그리 복잡한 함수가 아니기 때문에, 리소스를 많이 잡아먹을 것이라고 생각되지는 않는다.
사실 좀 더 가볍게 하기 위해서, setInterval함수를 이용하지 않고,
채팅창을 클릭했을 때 자동 형식을 완성하도록 작성했었다.
하지만, 그렇게 하면 사용자의 커서가 완성된 형식 텍스트의 앞에 위치하게 되서,
일일히 클릭을 한번 더해서 커서를 형식 텍스트 뒤로 옮겨주어야 했다.

물론 키보드의 end키를 사용하면 되긴 하지만, 사용법을 모르는 사람도 있을 것을 고려해
setInterval로 구현하였다.

배포 후

앱을 배포한 후 사용해본 지인들의 의견을 들어보니, 채팅을 예약해서 보낼 수 있는 기능이 있었으면 좋겠다고 하여
채팅 예약 기능을 만들었다.
채팅 예약 기능은 옵션 페이지를 따로 만들어서 진행했다.
코드도 그리 복잡하지 않아서 따로 업로드 하진 않을 예정이다.
채팅을 자동으로 전송하는 것 까지 구현하고 싶었으니
유튜브가 누군가 채팅 테러하는 것을 방지하기 위해서 사용자의 키보드로 입력이 추가적으로 들어와야만
채팅이 실제로 입력되었기에, 이부분은 실패했다.

크롬 앱을 처음 만들어본 것이기에, 공부하는 시간을 많이 갖지 않고, 공식 가이드를 조금 들춰가보며
만들었기 때문에, 정확하게 안되는 이유는 알 수는 없어서 아쉽다.

추후 계획

위에서 말한 구현 실패한 기능을 구현할 수 있는 좋은 아이디어가 생기면 업데이트 할 예정이다.
또한, 전체 화면에서도 채팅 창을 화면에 띄워주고 자동으로 채팅 형식을 만들어주는 기능을 구현해볼까(?)하고 고민중이다.

아래는 내가 만든 크롬 앱이다.


AutoForm 링크

profile
욕심쟁이 개발자

0개의 댓글