Blog Archive

레이블이 인 게시물을 표시합니다. 모든 게시물 표시
레이블이 인 게시물을 표시합니다. 모든 게시물 표시

2023-10-25

Airtable 자동화 예시: 내일 이벤트를 영업일 하루 전에 자동으로 안내

요즘 많은 노코드 툴들이 그러하듯이, 에어테이블(Airtable)에도 강력한 자동화(automations) 기능이 있습니다. 즉, 여러 앱들간의 프로세스를 엮어주는 재피어(Zapier)메이크(Make) 등을 쓰지 않아도, 상당한 수준의 워크플로우 자동화를 구축할 수 있습니다. 저의 개인적인 경험으로는 재피어나 메이크는 트리거(trigger)나 액션(action)을 정의할 때, 앱 내부의 동작을 세부적으로 정의하는 데에는 좀 한계가 있었습니다.

오늘은 아주 초보적인 자동화를 예시로 소개합니다. 예전에 다루었던 행사 운영 관리 베이스에 간단한 자동화를 얹어보겠습니다. 행사 운영 관리 베이스에는 매일 이벤트(교육, 행사, 모임 등)가 있고, 이벤트에는 담당 강사가 있습니다. 강사는 별도의 테이블에 연결된 Linked records 필드이고, 강사 이메일은 Lookup 필드입니다.

강사들은 조직 내부 구성원이 아니므로, 이벤트를 까먹지 않고 준비하도록 별도의 안내를 보내려고 합니다. 10일 전 안내, 3일 전 안내, 하루 전 안내 등 필요한 시기에 안내를 메일이나 문자로 보내주면 좋겠지요. 이번 예시에서는 하루 전에 자동 안내 메일을 보내봅니다.

자동화할 작업 정의 및 시작하기

무엇을 자동화할 것인지 명확히 하는 게 좋겠죠. 날마다 있는 행사에서 일일이 안내 메일을 보내기 어려우니, 정확히 하루 전에 행사 담당 강사에게 자동으로 행사 안내 메일을 보내기로 합니다. 에어테이블에서 자동화 시작은, 화면 왼쪽 위에 베이스 이름 옆에 [Automations]를 누르면 시작합니다. 참고로, [Data]는 기본적으로 테이블과 컬럼을 만들고, 데이터를 추가하는 곳이고, [Interfaces]는 데이터 시각화 툴입니다.

Airtable 화면 위쪽에 Automations를 선택하면 자동화 정의를 시작합니다.
에어테이블 화면의 왼쪽 위에, 베이스 이름 옆에서, Automations를 선택해서 자동화 화면으로 들어갑니다.

트리거(trigger) 설정

가장 간단한 자동화는 트리거 하나와 액션 하나로 구성됩니다.

트리거는 자동화를 일으키는 조건입니다. "만약 행사가 다음 날 있으면, 안내 메일을 보내라!"라는 자동화에서, "만약 행사가 다음 날 있으면"이라는 것이 바로 트리거입니다.

에어테이블 트리거 유형(trigger type)은 주로 다음과 같은 것들이 있습니다.(물론 그 밖에 외부 앱과 직접 연동되는 트리거도 있습니다.)

When record matches conditions
레코드의 데이터 값이 특정 조건을 만족할 때
When a form is submitted
사용자자 양식(form)에 값을 제출할 때
When record created
새로운 레코드가 생성될 때
When record updated
기존 레코드 값이 변경될 때
When record enters view
특정 뷰를 기준으로 레코드가 생성될 때(정확히는, 조건에 맞는 레코드가 들어올 때)
At scheduled time
특정 시간이 되면
When webhook recieved
(외부 앱에서) 웹훅 이벤트를 받을 때
When a button is clicked
버튼(필드)이 눌릴 때
Airtable의 Trigger 종류
에어테이블에서 자동화 시발점인 트리거의 종류

우리는 제일 첫 번째 트리거를 사용합니다. 행사 운영 관리 베이스에서는 영업일 기준으로 {시작일} 필드의 날짜를 검사하는 수식을 이미 만들어 놓았습니다. 따라서 조금 더 구체적으로 트리거를 다음과 같이 정의할 수 있습니다. {영업일 기준}의 값이 "다음날"이면, 뭔가 액션을 취해라. 간단하죠? 아래 그림과 같이 트리거 유형, 테이블, 조건(conditions)를 차례로 설정해주면 됩니다.

트리거 설정: 트리거 유형, 테이블, 조건을 설정한다.
트리거 유형에서 레코드가 특정 조건에 맞을 때를 선택하고, 테이블은 "일정" 테이블을, 조건은 {영업일 기준} 필드값이 "다음날"인 경우로 설정했다.

액션(actions) 설정

트리거 조건을 만족하면, 무엇을 시킬 것인가가 바로 액션이죠. 우리는 강사에게 메일을 보냅니다. 다음과 같은 액션 유형(action type) 중에 Send email을 고르면 됩니다.

Send email
메일을 보낸다.
Create record
새로운 레코드를 생성(추가)한다.
Update record
기존 레코드 값을 변경한다.
Find records
(조건에 맞는) 레코드를 찾아낸다.
Run script
스크립트를 실행한다.
Airtable 자동화 액션의 유형
에어테이블 자동화에서 액션의 유형

이 밖에도, 에어테이블에서 직접 슬랙이나 마이크로소프트 팀즈에 메시지를 보낸다든지, 구글 캘린더, 구글 시트, 지라 등에 내용을 추가하는 등의 액션 유형도 있습니다.

메일을 보내기로 했으니까, 수신자, 주제, 메일 내용과 같은 필수값들을 설정해주면 됩니다. 물론 데이터베이스에서 특정 필드를 변수로 포함시킬 수 있습니다. 특정 필드값을 변수로 사용하기 위해서는 파란색 ⊞ 버튼을 누르고, Insert value from field 목록에서 원하는 필드명을 고르면 됩니다.

액션에 대한 레이블(label)은 "강사 안내 메일"로 설명을 넣어줍니다.

수신자에는 {강사 메일}이라는 이메일 주소값 필드를 넣어줍니다.

메일 제목은 아래와 같이 작성했습니다.

다음 날({시작일}) {이벤트} 안내
액션에서 액션 레이블, 메일 수신자, 메일 제목을 설정합니다.
액션 설정: 액션의 제목을 넣어주고, 이어서, 메일 수신자, 메일 제목을 넣습니다.

메일 내용에는 간단히 아래와 같이 세 개의 필드를 포함시켰습니다.

{강사}님, 안녕하세요?
{시작일}에 {이벤트}이/가 시작되어요. 
미리 준비하시고, 당일날 늦지 않게 와주세요. 
감사합니다.
메일 내용 설정 화면
메일 내용 설정 화면

테스트 및 미리 보기

이제 트리거와 액션을 만들었으니, [Generate a preview] 버튼을 눌러 메일 모양이 어떻게 나올지 확인해봅니다. 또는 [View results] 버튼을 눌러 자동화 실행 결과가 성공적인지 확인해봅니다.

액션 결과 미리보기
액션 결과 미리 보기

활성화(activate)

마지막으로 방금 만든 자동화가 아직 비활성화(inactive) 상태이므로, 활성화(active) 상태로 바꿔줍니다.

지금까지 정의한 자동화를 active 상태로 바꿔준다.
지금까지 정의한 자동화를 활성 상태(active)로 바꿔준다.

이제 다 되었습니다. 앞으로는 운영자들이 일일이 사전 안내를 하지 않아도, 담당 강사에게 하루 전 메일이 자동으로 나갑니다. 물론 이 예시에서는 극단적으로 간단한 조건들을 사용했지만, 보다 복잡한 조건, 복합 트리거, 복합 액션, 조건부 분기 액션을 만드는 것도 크게 어렵지 않습니다.

다음 기회에는 메일 말고, 문자나 카카오톡 메시지를 자동으로 보내는 것을 살펴보겠습니다.

2023-10-19

SQL과 연관지어본 Airtable: linked records, lookup, count, rollup 필드

에어테이블(Airtable)은 기본적으로 관계형 데이터베이스입니다. 요즘에는 비정형 데이터와 빅데이터가 부상하면서 NoSQL 데이터베이스도 많이 쓰이지만, 여전히 관계형 데이터베이스는 매우 중요합니다. 에어테이블을 사용하기 위해 데이터베이스의 개념이나 질의 언어인 SQL을 알 필요는 전혀 없습니다. 그러나, 기존에 SQL을 조금이라도 써왔던 분들은, SQL과 연관시켜서 에어테이블의 주요 개념들을 좀 더 쉽게 이해할 수 있을 것입니다.

에어테이블에서 한 개의 데이터베이스를 베이스(base)라고 부릅니다. 그리고 베이스 안에는 여러 개의 테이블(table)을 담을 수 있습니다. 다시 테이블은 여러 개의 다른 방식으로 표현된 뷰(view)를 가질 수 있습니다. 이 때 기본적으로 테이블과 테이블이 관계를 맺으면(에어테이블에서 link to라고 표현함. SQL에서 말하는 join), 현재의 테이블에 관계 맺어진 다른 테이블의 값을 불러오거나(lookup), 가져와서 요약 정리하거나(rollup), 갯수를 셀 수(count) 있습니다. 이 글에서는, 관계형 데이터베이스를 설명하려는 것은 아니므로, 간단히 에어테이블에서 이런 것들이 어떤 필드로 표현되는지, 그것을 SQL로 표현하면 어떻게 대응되는지만 살펴봅니다.

어떤 예제로 설명을 해야 하나 고민하다가, 그냥 제가 개인적으로 사용하고 있는 독서 목록이라는 베이스를 사용하기로 했습니다. 읽은 책들을 정리하기 위한 베이스의 구조는 아주 간단합니다. 책 목록과 작가 목록 두 개의 테이블로 되어 있고, 책의 저자가 작가의 이름과 연결(link)되어 있습니다. 책 목록에 같은 작가가 쓴 책이 여러 권 있을 때, 작가 이름을 매번 새롭게 치는 것이 아니고, 작가 테이블에서 불러온다는 것입니다.

예시 (데이터)베이스

예전부터 공개된 독서 카드(특정 뷰)

에어테이블에서는 미리 테이블 안에 linked records 필드 (또는 link to 필드), lookup 필드, count 필드, rollup 필드를 만들어놓게 되므로, 컬럼(필드) 수가 다소 많아지게 됩니다. 그래서, 필요 없는 컬럼은 숨기기하면서 목적에 맞는 여러 개의 뷰(view)를 만들면 됩니다.

실제로는 아래 두 개의 테이블명과 필드명으로 한글을 사용했습니다. 다만, 일반적인 데이터베이스에서 한글을 테이블과 필드 이름으로 사용하는 데에는 제약이 따르므로, 여기 예시에서는 편의상 영문으로 합니다.

Books 테이블 구조
필드명필드 유형비고
Book_titleSingle line textPrimary field
AuthorLinked records저자 테이블과 연결
RatingRating1점~5점
About_authorLookup저자 테이블에서 인물소개 값을 참조

Authors 테이블 구조
필드명필드 유형비고
Author_nameSingle line textPrimary field
DescriptionLong text저자에 대한 소개글
BooksLinked records해당 저자가 쓴 책 목록. 책 테이블과 연결
N_of_booksCount이 작가의 책이 책 테이블에 몇 개 있는지 셈
Average_ratingRollup이 작가가 쓴 책의 평균 별점 계산

Linked records 필드

Airtable의 확장 프로그램인 Base schema를 이용해 독서 목록이라는 베이스의 스키마를 시각적으로 표현한 그림. 두 테이블 사이에 Linked records 필드만 보여주도록 설정한 경우
에어테이블 확장 프로그램인 Base schema를 이용해 독서 목록이라는 베이스의 스키마를 시각적으로 표현한 그림. 두 테이블 사이에 Linked records 필드만 보여주도록 설정한 경우

Linked records 필드는 두 개의 테이블을 연결하는 것입니다. Books 테이블에서 저자는, Authors 테이블에 있는 저자명과 연결됩니다. 에어테이블에서는 한 테이블에서 Link to 필드를 만들면, 자동으로 다른 테이블에도 Link to 필드가 생깁니다. 다시 말해, Books 테이블의 저자를 Authors 테이블의 저자명과 연결하면, 거꾸로 Authors 테이블에는 Books 테이블의 책이름과 연결되는 Link to 필드가 자동 생성되어, 해당 저자가 쓴 책 목록이 모두 표시됩니다. Books 테이블에서는 글쓴이가 보여지는 방식을 SQL로 표현하면 다음과 같이 되겠지요.

SELECT b.book_title, a.author
FROM books b
INNER JOIN authors a ON b.author = a.author_name;

Lookup 필드

Lookup 필드는 연결된 다른 테이블에서 특정 필드 값을 조회해서 가져오는 것입니다. Books 테이블에서는 매번 저자의 인물 소개가 들어가지 않지만, Authors 테이블에서 Description의 값을 조회해서 보여주는 방식입니다.

SELECT b.book_title, b.author, a.description AS about_author
FROM books b
INNER JOIN authors a ON b.author = a.author_name;

Count 필드

에어테이블에서 Count라는 유형의 필드는 실제 SQL에서 count 함수를 쓰는 것과 비슷합니다. 아래 쿼리는 저자별로 Books 테이블에 몇 권의 책이 있는지 세어서 보여줍니다.

SELECT a.author_name, COUNT(*) AS n_of_books
FROM books b INNER JOIN authors a 
ON b.author = a.author_name
GROUP BY a.author_name;

Rollup 필드

에어테이블의 Rollup 필드는 연결된 다른 테이블의 특정 필드를 요약해서 보여줄 때 사용합니다. 위에서 저자별로 여러 권의 책이 있고, 각 책들의 별점이 있는데, 저자별로 모든 책들의 별점의 평균을 보여주기 위해 Authors 테이블에 Rollup 필드를 넣었습니다. Rollup 필드는 평균 외에도, 합계, 갯수, 최대값, 최소값, 문자열 함수, 논리 함수 등 여러 가지를 사용해서 요약할 수 있습니다.

에어테이블의 평균별점 필드의 수식은 다음과 같이 정의됩니다. 별점이 있는 경우, 있는 레코드만 모아서 평균을 보여달라는 것이죠.

IF(values, AVERAGE(values))

SQL에서 저자와 저자별 별점 평균을 보여주려면 다음과 같이 하면 되겠죠. (소수 첫째 자리까지만)

SELECT a.author_name, ROUND(AVG(b.rating), 1) AS average_rating
FROM books b
INNER JOIN authors a ON b.author = a.author_name
GROUP BY a.author_name;

제가 겪은 실무에서는, 단순하게 lookup, rollup, count를 쓰기보다는 조건부(conditional) 필드를 사실 더 많이 쓰게 됩니다. 에어테이블에서는 상당히 직관적으로 코딩 없이 조건부 lookup, rollup, count를 사용할 수 있고, 그것에 따라 여러 개의 뷰를 만들 수 있습니다. 그리고 각각의 뷰에서 할 수 있는 일을 제한해놓습니다. 그러면, 데이터베이스나 프로그래밍에 대한 지식이 거의 없어도, 상당히 복잡한 업무 처리를 이것만으로 구현하게 됩니다.

2023-09-29

Airtable 팁: 2024년 공휴일을 반영한 영업일 기준 전날, 다음날 계산식

에어테이블(Airtable)은 관계형 데이터베이스를 기반으로 매우 쉽고, 매우 강력한 노코드 앱 개발 환경을 제공합니다. 스프레드시트와 유사하지만, 훨씬 다재다능하며, 워크플로우(workflow), 자동화, 데이터 시각화나 비즈니스 인텔리전스(BI)를 쉽게 구축할 수 있으며, 데스크톱 또는 모바일 앱 또는 웹을 쉽게 만들 수도 있습니다. 앞으로 Airtable과 관련한 다양한 이야기와 팁을 하나씩 정리해보겠습니다.

두 날짜의 차이 판단하여 이름 붙이기

Airtable에서 {시작일}이라는 필드가 있다고 했을 때, 그 시작일이 현재를 기준으로 다음날인지, 전날인지, 아니면 이틀 후인지 등은 DATETIME_DIFF 함수를 통해 쉽게 파악할 수 있습니다.

SWITCH(     
	DATETIME_DIFF({시작일}, NOW(), 'days'), 
	2, '모레',
	1, '내일',
	0, '오늘',
	-1, '어제',
	-2, '그제' )
이런 식입니다. 그런데, 이 수식에는 몇 가지 문제가 있습니다. 

첫째, 시간대가 반영되지 않았습니다. 우리 나라는 표준 시간(UTC, Universal Time Coordinated)보다 9시간 빠르므로, 위와 같이 하면, 9시간의 오차가 계속 나게 됩니다. 즉, 필드 값이 어제 오후 3시가 넘어가면, 위의 수식에서는 그냥 '오늘'이라는 값을 리턴해버립니다.

둘째, 영업일(working days, business days)이 반영되지 않았습니다. 실제 Airtable을 비즈니스 현장에서 쓸 때에는 영업일을 기준으로 날짜 계산이 필요한 경우가 많습니다. 예를 들어, 예정 일정 하루 전에 반드시 (자동 또는 수동으로) 이메일/문자 알림을 보내거나, 고객에게 전화를 걸어야 하는 업무가 있다고 가정해보겠습니다. 다음 주 월요일이 교육 시작일인데, 오늘은 전주 금요일입니다. 그러면 오늘은 그냥 날짜 상으로는 3일 전이지만, 영업일 기준으로는 하루 전입니다. 그래서 오늘 반드시 고객에게 전화를 걸어야 합니다. 

2024년 9월 달력. 영업일 기준 다음날과 캘린더 기준 내일이 완전히 다른 경우
2024년 9월 달력. 영업일 기준 다음날과 캘린더 기준 내일이 완전히 다른 경우


    
영업일을 반영하려면, 주말인 토요일, 일요일을 일단 계산에서 제외해야 합니다. 그래도 문제가 있습니다. 주말은 아니지만, 공휴일, 소위 말하는 빨간 날을 제외해야 제대로 된 영업일 기준의 날짜 계산을 해줍니다. 그냥 수동으로 업무를 처리할 때에는, 그 정도는 사람이 감안해서 미리미리 처리해주면 되겠지만, 모든 것이 자동으로 처리되는 대량의 데이터 시스템에서는, 이런 계산을 대충 하게 되면 큰일 납니다.

시간대, 영업일을 고려한 날짜 차이 계산식

따라서 다음과 같이 보완을 해줍니다.

첫째, 시간대를 반영해서, Airtable 현재 시스템 시간에 DATEADD 함수를 이용해 9시간을 더합니다.
DATEADD(NOW(), 9, 'hours')
둘째, 구해진 시간을 한국 시간대로  설정해줍니다. SET_TIMEZONE 함수는 첫 번째 파라미터의 시간을 두 번째 파라미터에서 표시한 시간대로 표시해 시간값을 리턴해줍니다. 시간대별 표시자(identifier) 목록을 참고하십시오. (Airtable 필드 형식(Formatting) 설정에서 시간대를 바꿔주는 옵션이 있습니다만, 이것은 손대지 않는다고 가정합니다.) 추가로, 편의상 DATESTR 함수를 써서 일정 표시를 ISO 8601 날짜 표현방식에 따라, YYYY-MM-DD로 바꿔주겠습니다.

DATESTR(SET_TIMEZONE(DATEADD(NOW(), 9, 'hours'), 'Asia/Seoul'))


셋째, 이렇게 구한 현재 날짜/시간과 {시작일} 필드값을 비교해야 합니다. 그런데, 위에서 썼던 DATETIME_DIFF 함수를 쓰면, 주말이나 공휴일을 고려하지 않고, 날짜 차이를 계산합니다. 약간 주의할 점은, 시작일과 끝일을 모두 포함하여 계산하니, 양수인 경우 +1이, 음수인 경우 -1을 더한 값이 나옵니다.WORKDAY_DIFF라는 영업일 계산 함수를 써서, 일단 주말을 고려하여 날짜 차이를 계산합니다.

WORKDAY_DIFF(
  	DATESTR(SET_TIMEZONE(DATEADD(NOW(), 9, 'hours'), 'Asia/Seoul')),
    {시작일}
)

이렇게 하면, 시작일에서 현재일 사이에 영업일이 며칠 있는지 계산해줍니다. 그 값이 마이너스이면, 시작일이 이미 지났다는 뜻이고, 양수이면 시작일이 미래라는 뜻입니다. 결과가 0이면 영업일이 하나도 없으니, 시작일과 현재일이 모두 휴일이라는 뜻입니다. 1 또는 -1이면 시작일이나 현재일 둘 중의 하나가 영업일이라는 뜻입니다.

넷째, WORKDAY_DIFF 함수에서 세 번째 파라미터에 주말이 아닌 공휴일을 추가합니다. 2024년 기준 대한민국 공휴일을 참조하여, 마지막으로 공휴일 목록을 하나의 문자열로 묶어서 넣습니다. 

WORKDAY_DIFF(
	DATESTR(SET_TIMEZONE(DATEADD(NOW(), 9, 'hours'), 'Asia/Seoul')),
    {시작일}, 
    '2023-01-23, 2023-01-24, 2023-03-01, 2023-05-05, 2023-06-06, 2023-08-15, 2023-09-28, 2023-09-29, 2023-10-02, 2023-10-03, 2023-10-09, 2023-12-25, 2024-01-01, 2024-02-09, 2024-03-01, 2024-05-15, 2024-06-06, 2024-08-15, 2024-09-16, 2024-09-17, 2024-09-18, 2024-10-03, 2024-10-09, 2024-12-25'
)

다섯째, 다시 SWITCH 조건문에서 위의 값을 검사하여, 전전날, 전날, 오늘, 다음날, 담담날을 표시해주도록 합니다.

SWITCH(
	WORKDAY_DIFF(DATESTR(SET_TIMEZONE(DATEADD(NOW(), 9, 'hours'), 'Asia/Seoul')), {시작일}, '2023-01-23, 2023-01-24, 2023-03-01, 2023-05-05, 2023-06-06, 2023-08-15, 2023-09-28, 2023-09-29, 2023-10-02, 2023-10-03, 2023-10-09, 2023-12-25, 2024-01-01, 2024-02-09, 2024-03-01, 2024-05-15, 2024-06-06, 2024-08-15, 2024-09-16, 2024-09-17, 2024-09-18, 2024-10-03, 2024-10-09, 2024-12-25'),
	-3,'전전날',
	-2,'전날',
    -1,'(지난)오늘',
    0, '휴일',
	1,'(올)오늘',
	2,'다음날',
	3,'담담날'
)

실제 베이스 예시: 행사 운영 관리


아래에 예시로 만들어놓은 '행사운영관리'라는 베이스를 살펴보십시오. {시작일}이 오늘인지, 전날인지, 다음 날인지 판단하여 {영업일 기준}이라는 필드에서 결과를 보여줍니다. 시작일 하루 전에는 '사전 안내'를 반드시 해야 하고, 당일은 '현장 진행'을 해야 하고, 하루가 지나면 '해피콜'을 반드시 해야 한다고 합시다. 그런 업무를 체크리스트로 만들어놓고, 전날 일정, 오늘 일정, 다음날 일정 등만 따로 볼 수 있는 뷰(View)를 만들어놓으면, 누락이 없는 업무 관리 시스템이 됩니다. 또 거기에 전날, 오늘, 다음날 해야 하는 일들을 자동화(automation)로 걸어놓으면, 업무 담당자의 반복적인 업무가 획기적으로 줄어들겠죠? 이런 이야기는 다음 기회에...