본문 바로가기

Etc.

Github API issue + JS로 댓글 기능 만들기

HTML + CSS + JavaScript로 대학생활 포트폴리오를 만들다가 댓글 기능을 추가하고 싶은 욕심이 생겼다. github.io로 배포도 해놨으니 다른 사람들도 와서 구경하면서 댓글을 달아주는.. 그런 상상을 하면서 말이다.

먼저 댓글 기능을 열심히 검색해봐도 jekyll로 만든 블로그에 disqus을 사용하는 방법밖에 나오지 않았다. jekyll로 안 만들었으니 이건 불가능하고, 그렇다고 WAS를 만들고 AWS에 배포하고 이런 작업들을 하기는 좀 오바하는 것 같았다.

그러다 문득 javable에 참여할 때 댓글을 github issue로 관리하던 것을 본 것 같아서 그걸로 구현하면 되겠다 생각했다.

API 문서에 워낙 잘 나와 있어서 얼마 안 걸릴 줄 알았는데 꽤 삽질했던 작업이라 적용하는 과정을 천천히 글로 남겨볼 생각이다.


토큰 생성

먼저 github api를 인증받기 위해 토큰을 생성 해야 한다. Github API는 인증을 하지 않아도 사용할 수 있지만, 요청이 1시간에 60번으로 제한된다. 인증할 경우 1시간에 5000번까지 요청할 수 있다. 1시간에 60번은 테스트만 하다가 끝나버릴지도 모르니까 꼭 인증해두자.

오른쪽 상단 프로필을 클릭하고 Settings를 클릭한다.

왼쪽 메뉴에서 Developer settings 클릭

왼쪽 메뉴에서 Personal access tokens 클릭

중앙 상단에 Generate new token 클릭

Note에는 이 token에 대한 간단한 설명을 적어준다. 대충 auto create issue라고 적어주었다. 또 issue만 사용할 것이기 때문에 repo를 체크한다. issue는 repo에 포함되어 있다. 마지막으로 하단에 Generate token을 클릭해주자.

그러면 아래와 같은 화면이 나오는데 여기서 초록색 배경에 있는 토큰 값을 꼭 복사해서 저장해두자. 이 화면에서 나가면 더 볼 수 없다. 잃어버렸다면 다시 토큰을 만들어야 한다.

이러면 토큰 생성은 끝이다.

API 호출

github issue에 댓글을 저장해 놓을 것이기 때문에 댓글을 불러오는 get과 댓글을 생성하는 post만 사용할 생각이다. 가볍게 보는 포트폴리오와 가볍게 다는 댓글이라 수정과 삭제는 사용자 기능에 추가하지 않았다. 내가 하고 싶으면 issue에서 하면 된다.

issue 전부 가져오기

이슈를 전부 불러오는 get 호출은 js로 아래와 같이 작성하였다. 코드에 있는 토큰 값은 임의로 작성한 것이다. 아까 복사해뒀던 토큰 값을 사용하면 된다.

const auth1 = "ghp_Juqwe";
const auth2 = "VjDELWSPHzxc";
const auth3 = "45nuF4qwe2";
const auth4 = "2c52Nq123Z";

loadComments(auth1 + auth2 + auth3 + auth4);

function loadComments(auth) {
  fetch("https://api.github.com/repos/dundung/campus-life-portfolio/issues", {
    method: "GET",
    headers: {
      Authorization: "token " + auth,
    },
  })
    .then((response) => response.json())
    .then((issues) => {
        // HTML에 추가하는 내용
    });
}

하나의 토큰값을 auth1 ~ auth4 4개로 나눠놨는데 이유가 있다. 처음엔 한 줄로 해서 header에 추가해줬는데 아래와 같은 메일이 오면서 토큰을 쓸 수 없게 되었다.

안녕하세요 DunDung,
유효한 OAuth, GitHub 앱 또는 개인 액세스 토큰이 GitHub 저장소에 커밋되었음을 확인했습니다. 유효한 액세스 토큰을 공개하면 다른 사람들이 귀하를 대신하여 GitHub와 상호 작용하여 잠재적으로 데이터, 귀하의 연락처 정보 및 청구 데이터를 변경할 수 있습니다.
예방 조치로 토큰을 취소했습니다. 앱이 GitHub에 인증하려면 새 토큰을 생성해야합니다.

토큰값을 github 저장소에 올리면 보안상의 이유로 토큰을 못 쓰게 만든다는 내용이다.

그러면 토큰값은 gitignore 되어있는 js 파일에 올리고 그 값을 주입받아 사용하는 방식으로 github 저장소에는 토큰값을 올리지 않고 사용해야 하지만 github page에 배포할 내용이라 저장소에도 반드시 올려야하기 때문에 그 방식은 불가능하다. private repository와 서브 모듈을 사용하는 방법도 있겠지만 간단한 웹페이지에 간단한 댓글 기능을 추구했기 때문에 오버엔지니어링이라고 생각했다.

그래서 github에서 감지할 수 없게 편법으로 저렇게 토큰값을 쪼개놓고 header에서 합해주는 방법을 사용했다. 물론 옳지 않은 방법이긴 하다.. 하하😅

호출한 api uri는 각자 저장소와 github 닉네임에 맞게 수정해야 한다.
https://api.github.com/repos/{github-nickname}/{repository-name}/issues
을 나한테 맞게 수정해서 아래와 같은 uri가 나왔다.
https://api.github.com/repos/dundung/campus-life-portfolio/issues

then에 있는 내용도 각자 html에 맞게 수정하자. 난 response에서 title과 created_at, body만 사용하였다.

issue 생성하기

생성도 findAll과 비슷하다. 코드를 살펴보자.

const auth1 = "ghp_Juqwe";
const auth2 = "VjDELWSPHzxc";
const auth3 = "45nuF4qwe2";
const auth4 = "2c52Nq123Z";

registerComment(auth1 + auth2 + auth3 + auth4);

function registerComment(auth) {
  fetch("https://api.github.com/repos/dundung/campus-life-portfolio/issues",
    {
      method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: "token " + auth,
        },
        body: JSON.stringify({
          title: // issue 제목
          body: // issue 본문
        }),
        }
      ).then(() => {
        // input 초기화 하기
      });
    }
  });

설명할 내용은 딱히 없고 각자 html에 맞게 수정하면 된다. http method가 GET에서 POST로 바뀐 점만 보면 된다.


댓글 작성 시 mail 알림

완성된 대학생활 포트폴리오를 친한 친구들에게 보여줬는데 누군가가 보기 민망한 장난 댓글을 달아놓았다. 근데 그것도 모르고 며칠동안 그 댓글을 방치해뒀었다. 매일 댓글을 확인할 수도 없고 해서 해결책을 모색했다,.

처음엔 github login 후 댓글을 달 수 있게 만들까 고민했지만, 로그인이라는 과정 없이 간단하게 익명으로 달 수 있는 댓글 기능을 처음부터 원했기에 금방 포기했다.

결론적으로 장난 댓글이 수시로 달리는 건 아니기에 댓글이 달렸을 때 mail이 와서 폰으로 바로 알림이 오고 내가 바로 확인할 수 있게끔 기능을 추가했다.

mail 전송 기능은 진짜 편하고 간단하게 메일을 보낼 수 있는 EmailJS를 사용했다. 설치부터 사용법까지 문서가 너무 잘돼있어서 별다른 삽질없이 금방 mail 기능을 만들었다.

장난 댓글의 빈도가 높아지는 등 악의적으로 누군가 댓글을 자주 어지럽힌다면 댓글 작성 시 github api로 만들어진 issue에 lock을 걸고 내가 확인하고 unlock 하는 구조로 바꿀 생각이다.


결과

github page로 배포해도 문제없이 댓글 기능과 댓글 작성 시 메일 알림 기능이 잘 작동한다.

이렇게 완성된 내 대학생활 포트폴리오는 여기서 볼 수 있다. 나름 재밌다ㅎ

github page로 배포하고 github issue를 db처럼 사용하면 100% 무료로 배포할 수 있고 간단하니까 너무 좋은 것 같다. 두고두고 사용할 것 같아서 블로그에 글로 남겨둔다.

또 EmailJS를 알게 된 것도 큰 수확이다. 바닐라 JS, react, vue 에서 전부 간편하게 사용할 수 있고 배포 시에도 문제가 없어서 자주 사용할 것 같다.

'Etc.' 카테고리의 다른 글

Mac에서 git 자동 완성(tab) 사용하기  (2) 2021.07.12
Springboot + vue.js 업로드한 pdf 파일 열기, 다운로드  (2) 2021.07.01
API vs Library vs Framework  (0) 2021.01.12
HTTP  (0) 2020.09.24
HTTP Cache  (0) 2020.09.11