생일 축하 슬랙 앱 만들기

May 20, 2023

Birthday notification in slack

    아래는 제 블로그의 서치 콘솔입니다.

    Search console

    대부분의 분들이 저의 Slack과 Google Docs로 연차관리 자동화하기를 보고 찾아오셨습니다. :)
    코드 없이 슬랙과 스프레드시트만으로 자동화를 할 수 있다는 것이 매력적이었던 것 같습니다. 그래서 이번에는 글또 8기에서 생일 축하 알림을 슬랙으로 보내는 앱을 만든 경험을 공유하고자 합니다.

    이미 BirthdayBot이 존재하지만, 30명 이상이 넘어가는 경우 인당 1.59 달러에 해당하는 돈을 내야했기 때문에 스프레드시트의 앱스크립트 기능슬랙 인커밍웹훅을 사용해서 직접 만들어보기로 했습니다.

    Gukbob

    이미지 출처: 국밥계산기

    슬랙 인커밍웹훅은 슬랙에서 제공하는 기능으로, HTTP request를 통해 슬랙 채널에 메시지를 보낼 수 있습니다.

    1. Add to Slack 버튼을 눌러서 슬랙 워크스페이스에 앱을 추가합니다.
    Add to slack
    1. 메세지를 남기길 원하는 채널을 선택한 후 Add Incoming WebHooks integration을 클릭합니다.
    Add to slack
    1. Webhook URL을 복사합니다.
    Add to slack

    스프레드시트 앱스크립트는 구글에서 제공하는 기능으로, 구글 스프레드시트에서 자바스크립트를 사용할 수 있게 해줍니다.
    그리고 트리거를 이용해서 해당 함수를 정해진 시각에 실행할 수 있습니다.

    1. 구글 스프레드시트를 만듭니다. 예시는 다음과 같습니다.

    2. Extensions > Apps Script(확장 프로그램 > Apps Script)를 클릭합니다.

    Apps script
    1. Code.gs를 클릭한 뒤, 다음과 같은 함수를 넣어줍니다.
    // 본인의 스프레드시트 아이디를 넣어주세요.
    // 스프레드시트 아이디는 스프레드시트 링크에서 https://docs.google.com/spreadsheets/d/1jaTNcl86cIGxyWuzdXXjy82ADrVLOxYPIfcgUKFmkhk/edit#gid=0
    // d/부터 다음 /까지가 구글스프레드 시트의 id값입니다.
    const spreadsheetId = "1jaTNcl86cIGxyWuzdXXjy82ADrVLOxYPIfcgUKFmkhk";
    
    // 발급받은 Webhook URL을 넣어주세요.
    const webhookURL = "https://hooks.slack.com/services/......";
    
    const range = SpreadsheetApp.openById(spreadsheetId).getRange("생일!A1:B"); 
    
    function isValidDate(d) {
      if ( Object.prototype.toString.call(d) !== "[object Date]" )
        return false;
      return !isNaN(d.getTime());
    }
    
    function getBirthdayMap() {
      const birthdayMap = {}
    
      const rowNum = range.getNumRows();
      for(let i = 2; i <= rowNum; i++) {
        const nameCell = range.getCell(i, 1);
        if(nameCell.isBlank()) {
          break;
        }
    
        const date = range.getCell(i, 2).getValue();
    
        if(isValidDate(date)) {
          const dateKey = date.toLocaleDateString(undefined, {
            month: "2-digit",
            day: "2-digit",
          });
    
          if(birthdayMap[dateKey]) {
            birthdayMap[dateKey].push(i)
          } else {
            birthdayMap[dateKey] = [i, ]
          }
        }
      }
    
      return birthdayMap;
    }
    
    function sendMessageToSlack(today, birthdayMembers) {
      const todayDateKey = Utilities.formatDate(today, "KST", "yyyy-MM-dd");
    
      let text = "";
    
      if(birthdayMembers)
        text = birthdayMembers.reduce((acc, rowNum) => acc + "@" + range.getCell(rowNum, 1).getValue().toString() + " ", "");
      // 생일이 아닐 경우 출력할 메세지를 입력합니다.
      else
        text = "오늘 생일인 사람이 존재하지 않습니다. :)";
    
      // 여기에서 전송될 메세지 양식을 바꿔줄 수 있습니다.
      // 아래 링크에서처럼 다양한 포맷을 통해 메세지를 전송해줄 수 있습니다.
      // https://api.slack.com/messaging/webhooks#advanced_message_formatting
      const message = {
        "attachments":[
            {
              "color":"#2eb886",
              "fields":[
                  {
                    "title":`생일 축하드려요. 🥳 (${todayDateKey})`,
                    "value":`${text}\n\n🙌`,
                    "short":false
                  }
              ]
            }
        ]
      }
    
      var options = {
        'method' : 'post',
        'contentType': 'application/json',
        // Convert the JavaScript object to a JSON string.
        'payload' : JSON.stringify(message)
      };
    
      UrlFetchApp.fetch(webhookURL, options);
    }
    
    function sendBirthdayMessage() {
      const birthdayMap = getBirthdayMap();
    
      const today = new Date();
    
      const todayDateKey = Utilities.formatDate(today, "KST", "MM/dd");
    
      const birthdayMembers = birthdayMap[todayDateKey];
    
      sendMessageToSlack(today, birthdayMembers);
    }
    
    1. Save Project를 클릭한 뒤, 왼쪽 Nav Bar에서 Triggers를 클릭합니다.
    trigger
    1. Add Trigger를 클릭한 뒤, 아래와 같이 설정합니다.
    trigger

    Select time of day 설정을 바꿔서 언제 메세지를 보낼지 설정할 수 있습니다.

    1. Save를 클릭합니다.

    Save를 클릭하면 권한을 승인하기 위한 로그인 화면이 뜹니다.

    verification-error

    로그인을 하면 위와 같은 에러가 뜰텐데, 당황하지 않고 Advanced > Go to ExampleOfSendBirthdayMessage (unsafe)를 클릭합니다. 그러면 권한 제공 승인을 진행할 수 있습니다. :)

    이제 매일 트리거에 설정한 시간에 슬랙으로 생일 축하 메세지가 전송됩니다. 🥳

    잘전송되는지 확인하고 싶다면, 왼쪽 Nav Bar에서 Editor를 클릭한 뒤, Run을 클릭하면 됩니다.

    run

    Voila!

    message
    1. (Optional) 슬랙 메세지를 보낼 때, 슬랙 봇의 이름을 바꾸고 싶다면, 인커밍 웹훅 (설정 페이지)[https://chavodev.slack.com/apps/A0F7XDUAZ-incoming-webhooks?tab=settings&next_id=0] 으로 가서 Customize NameCustomize Icon을 바꿔주면 됩니다.
    configuration

    이번 포스팅에서는 구글 스프레드시트와 슬랙을 이용해서 생일 축하 메세지를 자동으로 보내는 방법을 알아봤습니다.
    생각보다 간단하게 구현할 수 있었는데, 해당 아이디어를 바탕으로 또다른 원하는 자동화를 구현할 수 있을 것 같습니다.

    이번 포스팅이 도움이 되셨다면, 좋아요와 댓글 부탁드립니다. 🙏 읽어주셔서 감사합니다~!