2018년 10월 21일 일요일

지메일에 새 메일이 오면 확인해서 후처리하기

메일 받는 것들 중에 사람이 읽어서 끝날 게 아니라 뒷처리를 해야 하는 메일이 있다.
매번 수동으로 하다가, 이걸 그냥 코드로 하나 짜면 어떨까 싶어서 찾아봤다.

크게 나눠서, 메일이 왔는지 파악하는 단계와 그 메일을 가져다가 내용에 맞게 처리하는 단계가 있겠다.

우선 메일이 왔는지 파악하는 건 API가 있다. https://developers.google.com/gmail/api/guides/push
내용을 요약하면, 메일함에  변동이 있을 때 알림을 쏘는 위치가 있으니 그 알림을 받기 위한 채널을 설정하고 변동이 있다고 알림을 받으면 실제 변동이 무엇인지 확인하는 절차를 진행하라는 거다.
알림을 받겠다고 한 번 등록하면 한 주 동안 유지되고 계속 등록을 갱신해줘야 하는 구조인 건 특이하다. 서비스 규모가 크니까 알림도 무한정 유지해줄 수 없겠지. (ᅟGCP 웹 콘솔에서 구독을 만들 때는 무한정의 구독도 만들 수 있긴 하다)

알림 채널은 Cloud Pub/Sub API라는 이름인데 RabbitMQ를 써본 입장에서는 그냥 큐가 서비스 형태로 제공된다고 이해된다. Topic이나 Subscription이라고 용어만 다를 뿐.

알림이 어떤 식으로 오는지도 문서에 적혀있다. URL로 푸시를 받는 방식이라면 참고하면 되겠다.
https://cloud.google.com/pubsub/docs/quickstart-console 에서는 gcloud 명령을 통해 pull로 가져오는 방법도 적혀 있다. https://cloud.google.com/pubsub/docs/reference/rest/v1/projects.subscriptions/pull 에는 API로도 설명이 있다.

https://console.cloud.google.com/project/_/cloudpubsub/topicList 콘솔 화면에서 topic을 만들 수도 있고, 지메일 계정에서 푸시를 게시할 수 있게 권한을 줄 수도 있다. (gcloud 명령으로도 될 것 같긴 하다)
구독 만드는 것도 구독 화면에서는 바로 안 되고, 토픽을 만들고 나서 거기에 대해 구독을 추가 메뉴를 선택하면 된다.


알림을 받은 후에 메일함 내용을 확인하는 절차는 대강의 흐름을 보면 이런 것 같다.
  1. https://developers.google.com/gmail/api/v1/reference/users/history/list 로 알림을 받은 실제 변경이 뭔지 목록으로 추려낸다.
    • https://developers.google.com/apis-explorer/#search/gmail.users.history.list/m/gmail/v1/gmail.users.history.list?userId=me&historyTypes=messageAdded&_h=2& 에서 gmail.users.history.list API를 실행해볼 수 있다.
    • historyId가 필수로 있어야 한다. gmail.users.messages.list 결과에서 하나 가져와보면 잘 동작한다.
  2. https://developers.google.com/gmail/api/v1/reference/users/messages/get 로 list에서 가져온 id의 실제 내용을 가져온다.
  3. https://developers.google.com/gmail/api/v1/reference/users/messages#resource 는 내용의 구성 설명인데, payload.body가 실제 본문이다.
  4. https://developers.google.com/gmail/api/v1/reference/users/messages/attachments#resource 는 payload.body의 설명인데, 그냥 본문이 들어가 있거나 multipart 메일인 경우에 별도로 가져올 수 있는 첨부의 id가 있다.

여기까지 문서를 검토해보니 귀찮은 절차들이 좀 있다. 누군가 구현해두지 않았을까?

인증은, 생각해보다는 간단했다. https://developers.google.com/gmail/api/auth/web-server 에서 안내하는 "Create credentials > Service account key" 부분을 보고, '서비스 계정 키' 종류를 하나 만들어서 json 파일로 받은 다음에 credentials.json라고 파일명을 바꿔서 샘플 코드에 먹여보니 잘 돌아간다.