뉴스레터 피드백, 잘 관리되고 있나요?
우리 회사는 주식·경제 관련 뉴스레터를 매주 화, 목 아침마다 발송하고 있다.
이번 글은 뉴스레터를 운영하면서 독자들의 '피드백'을 놓치지 않고 잘 체크하는 법에 대한 이야기라, 뉴스레터 고도화에 대한 이야기는 다음 기회에 할 예정이다.
우리 팀은 투자자들에게 중요한 정보를 빠르고 정확하게 전달하기 위해 끊임없이 노력하고 있다. '어떻게 하면 부족한 점을 더 개선할 수 있을까?', '어떤 주제를 독자들이 좋아할까?', '제목을 어떻게 지어야 많은 사람들이 궁금해할까?'와 같은 고민을 한다.
그렇게 때문에 독자들의 직접적인 의견을 들을 수 있는 피드백을 수집하여 분석, 반영하는 것을 가장 중요하게 생각하고 있다.
우리 팀은 피드백 수집 툴로 '구글 시트'를 활용하고 있는데, 메일로 알람을 설정할 수 있지만 많은 업무 메일들에 섞여 놓치는 경우가 발생하기도 하고 아직 초기 프로덕트라 피드백이 그리 많지 않아 매일 찾아가서 트래킹 하기가 번거롭다고 느껴졌다.
그래서 어떻게 하면 피드백이 왔을 때 놓치지 않고, 매번 불필요하게 구글시트를 켜보는 일을 줄일 수 있을까?를 고민하다가 팀즈 봇을 만들어보기로 했다.
큰 도움을 준(거의 다 떠먹여 주신) 개발자 동료 준형 님께 감사 인사를 드리며, 내가 배운 것들을 정리해보려고 한다.
웹훅은 쉽게 말해 특정 이벤트가 발생했을 때 다른 서비스나 응용프로그램으로 알림을 보내는 기능이다. 이번 같은 경우에는 구글 시트에 '설문 제출'이라는 이벤트가 발생하면 팀즈에 그 내용을 쏘는(알림을 보내는) 기능을 구현한 것이다.
크게 웹훅은 Incoming Webhook과 Outgoing Webhook이 있는데
- Incoming Webhook: 외부 서비스에서 특정 이벤트가 발생했을 때 내부 서비스(팀즈)에서 확인하는 기능
- Outgoing Webhook: 내부 서비스(팀즈)에서 메시지를 작성해 외부 서비스에 데이터를 요청하는 기능
비개발자 입장에서는 이 정도로만 이해해도 충분한 것 같다.
사내에서 실제로 활용하는 팀즈이기 때문에 캡처가 조심스럽다.
내가 Incoming Webhook을 팀즈에 설치할 때 도움받았던 몇 가지 문서를 첨부해본다.
1. 공식문서: microsoft 공식 문서
2. 상세한 step by step이 궁금하다면? 전봉근 님 포스팅
https://bkjeon1614.github.io/blog/teams-web-hook-api-example
위의 내용을 차근차근 따라 하면 웹훅 url 뽑는데 까지는 큰 어려움이 없을 것이다.
혹시나 안된다면 댓글 부탁드립니다!
① 위의 포스팅을 참고하여 팀즈에 incoming 웹훅 설치 후 채널 url 생성하기
② 실시간 알람을 받을 google sheet를 켜서 확장 프로그램 → App Script 클릭
③ 편집기에 함수를 선언한다.
function sendLetter() {
var teamsUrl="여기에 teams webhook url 넣어주세요";
try {
const spreadsheet = SpreadsheetApp.openById("여기에 googlesheetid를 넣어주세요");
const sheet = spreadsheet.getSheetByName("여기에 시트 이름을 넣어주세요");
var range = sheet.getRange("A:C");
var answers = []
for (i = 1; i <= 4; i++) {
answers[i] = range.getCell(sheet.getLastRow(), i).getValue()
}
} catch (err) {
// TODO (developer) - Handle exception
Logger.log('Failed with error %s', err.message);
}
var questions = [null, "이번 알파레터가 도움이 되셨나요?", "좋았던 점은 무엇인가요?","알파레터가 다뤄줬으면 하는 이슈가 있나요?"]
var text = ""
for (i = 1; i <= 4; i++) {
text += "**"+ questions[i] + "** \n" + answers[i] + " \n \n"
}
Logger.log(text)
var title = "피드백이 도착했습니다";
var card = {
"@context": "https://schema.org/extensions",
"@type": "MessageCard",
"themeColor": "D01411",
"title": title,
"text": text,
"potentialAction": [
{ "@type": "OpenUri",
"name": "바로가기",
"targets": [
{ "os": "default", "uri": "https://docs.google.com/spreadsheets/d/1ejbuMeuaa7U_VXRHwhkatYMjP9Cc4tKI8W8kf47c4rQ/edit#gid=0" }
]
}
]
};
payload = JSON.stringify(card);
var option = {
"contentType": "application/json",
"method": "post",
"payload": payload
};
UrlFetchApp.fetch(teamsUrl, option);
}
④ 트리거를 만든다.
sendLetter는 ③번에서 작성한 함수 이름이다. 함수를 작성하지 않으면 트리거 설정이 안 되니 함수를 먼저 작성하자!
나는 양식 제출할 때마다 알림 받는 것으로 했고, 실패 시 즉시 알림을 주도록 설정했다.
⑤ 디버깅하면서 잘 들어오는지 확인한다.
Logger.log(text)
⑥ 문제없다면 팀즈에서 실시간으로 확인 가능!
구글 시트 설문 제출 내용을 팀즈에서 받아볼 수 있는 방법 - Incoming Webhook에 대해 알아봤습니다. 도움이 되었길 바라며 이상한 점이 있거나 궁금한 점이 있다면 댓글 주세요!
※제가 작성한 건 극히 일부의 얕은 지식이니, 더 자세한 건 함수 별로 구글링 하는 걸 추천드립니다!
1) 6번째 줄 코드의 openById 뒤에는 구글 시트 ID를 넣어준다.
~/d/해당 부분입니다/edit#gid=0
2) 8번째 줄 코드의 getSheetByName("sheet1") ← 시트 이름 쓰기
3) 9번째 줄 코드의 getRange("A:C") ← 불러올 시트의 범위 쓰기
4) for 함수 쓰기
5) 23번째 줄: 두 개의 array를 한 result로 묶어서 내보내는 방법
6) 28번째 줄~ 43번째 줄 팀즈는 card 형식으로만 webhook을 받기 때문에 card 형식을 꼭 먼저 선언해줘야 한다.
7) 39번째 줄 url은 구글시트 url이다.
8) 45번째 줄의 payload는 JSON 형태로 선언해줘야 한다. + card도 미리 선언해두기!
9) 마지막 줄의 UrlFechApp 함수는 해당 스크립트를 팀즈로 보내는 역할을 한다.