![[AI 가계부] AI와 상담하며 가족 전용 가계부 시스템을 만들어 보았다 ④ ~LINE Bot과 LIFF로 일상에서 사용할 수 있는 형태로 대표 이미지](https://static.zenn.studio/user-upload/fd1f5b4acca9-20260731.jpg)
[AI 가계부] AI와 상담하며 가족 전용 가계부 시스템을 만들어 보았다 ④ ~LINE Bot과 LIFF로 일상에서 사용할 수 있는 형태로
요약
Gemini API와 LINE Bot, Cloud Functions를 연동하여 스마트폰에서 영수증 이미지를 보내면 자동으로 가계부에 등록되는 시스템 구축 과정을 설명합니다. 로컬 PC 환경에서 클라우드 기반의 자동화 환경으로 전환하는 방법을 다룹니다.
핵심 포인트
- LINE Messaging API와 Webhook을 활용한 메시지 수신 자동화
- 로컬 Python 실행 환경을 Google Cloud Functions로 이식
- 스마트폰을 통한 간편한 영수증 입력 인터페이스 구현
- Gemini API를 이용한 영수증 데이터 분석 및 스프레드시트 저장
서론
지난 기사에서는 Gemini API를 이용한 영수증 분석과, 분석 결과를 Spreadsheet(스프레드시트)에 저장하는 메커니즘에 대해 소개했습니다.
이전 시점의 구성
하지만 이 상태로는 아직,
- PC를 부팅한다
- 영수증 이미지를 폴더에 넣는다
- Python을 실행한다
라는 작업이 필요했습니다.
기술 검증으로서는 충분하지만, 가계부로서 지속적으로 사용하기에는 다소 번거로움이 있습니다.
그래서 다음 목표로,
"스마트폰에서 LINE으로 영수증 이미지를 보내는 것만으로 가계부에 등록할 수 있는"
상태를 목표로 했습니다.
목표하는 구성
점점 비엔지니어(Non-engineer) 분들에게는 이해하기 어려워지고 있을지도 모르겠습니다만, 양해 부탁드립니다.
여기서 수행하고 있는 것은,
- 입력 방법을 PC상의 폴더 배치에서 LINE Bot 경유로 변경
- Python 처리 실행 환경을 로컬 PC에서 Cloud Functions로 이행
의 크게 두 가지 점입니다.
이 이행은 단순히 Python 코드를 Cloud Functions로 복사하는 것만으로는 작동하지 않기 때문에, LINE Bot 측의 준비와 Python 코드의 수정을 병행하여 진행할 필요가 있었습니다.
1. LINE Bot 준비
LINE Bot은 LINE 상에서 사용자와 자동으로 주고받는 프로그램입니다.
매장의 공식 LINE 등에서 사용되는 그것입니다.
이용을 위해서는 공식 계정이 필요하지만 개인이라도 무료로 생성할 수 있습니다.
LINE Bot으로는
- 메시지에 대한 자동 답장
- 이미지나 파일 수신
- 외부 서비스와의 연동
등을 수행할 수 있습니다.
이번에는 LINE Bot 중에서도 외부 프로그램과 연동할 수 있는 Messaging API를 이용했습니다.
Messaging API를 통해서는 사용자가 LINE으로 전송한 메시지를 외부 프로그램으로 통지하고, 처리 결과를 LINE으로 돌려줄 수 있습니다.
이번에는 이 메커니즘을 이용하여 영수증 이미지를 받아 AI 분석 처리로 전달하고 있습니다.
Webhook 사용하기
Messaging API에서는 사용자가 메시지를 전송했을 때, LINE Platform에서 외부 프로그램으로 통지를 보내는 메커니즘인 Webhook을 이용합니다.
Webhook이란 어떤 서비스에서 이벤트가 발생했을 때, 다른 서비스로 자동 통지하는 메커니즘입니다.
지금까지는 수동으로 Python을 실행하여 처리해 왔지만, Webhook을 사용함으로써 다음과 같이 자동화하는 것이 가능합니다.
사용자가 LINE으로 이미지 전송
↓
LINE Bot이 Webhook 통지
↓
처리가 기동
흐름을 이미지로 나타내면 다음과 같습니다.
※ 엄밀하지는 않으며, 다소 이해하기 쉽게 표현했습니다.
LINE Bot 측 설정에서 발행할 수 있는 Access Token을 처리 측에, Cloud Functions에서 발행되는 URL을 LINE 측에 각각 연결함으로써 서로 연동할 수 있게 되는 메커니즘입니다.
LINE Bot 측에는 Messaging API 항목에 Webhook URL을 기재하는 칸이 있으므로, 거기에 Cloud Functions에서 발행된 URL을 붙여넣으면 OK입니다.
세부적인 설정 방법에 대해서는 이 기사에서 생략하겠습니다.
설정 화면에는 비슷한 문구가 많아 다소 복잡할 수 있지만, AI와 상담하며 설정하면 가능할 것이라 생각합니다.
2. Cloud Functions로 Python 처리 이식하기
Webhook 자체는 Cloud Functions가 아니더라도 이용할 수 있지만, 그러기 위해서는 상시 통지를 받을 수 있는 실행 환경이 필요합니다.
집에 서버가 있거나 사용하지 않는 PC를 24시간 가동할 수 있는 경우에는 그것들을 활용해도 좋겠지만, 비엔지니어이면서 그런 분들은 그리 많지 않을 것이라 생각합니다.
그래서 여러 번 등장하고 있는 Google Cloud Functions를 이용하고 있습니다.
Cloud Functions는 위 그림에도 있듯이 특정 이벤트를 계기로 코드를 실행할 수 있는 서버리스(Serverless) 서비스입니다.
코드 변경
Webhook을 받는 입구 생성하기
먼저 로컬 코드에서의 변경점으로서 Webhook을 받는 HTTP 엔트리 포인트(Entry point)를 준비해야 합니다.
예를 들어,
@functions_framework.http
def main_entry_point(request):
signature = request.headers.get("X-Line-Signature")
...
와 같은 함수를 Webhook URL의 수신부로 준비하여, LINE으로부터 통지된 이벤트를 처리합니다.
이미지 메시지의 경우, 다음과 같은 이벤트 핸들러 (Event handler)가 호출됩니다.
@handler.add(MessageEvent, message=ImageMessageContent)
def handle_image_message(event):
LINE API에 액세스하기 위한 Token 설정
Webhook 통지에는,
・ 사용자 ID (User ID)
・ 메시지 ID (Message ID)
・ 메시지 종류 (Message type)
등의 정보가 포함되지만, 이미지 데이터 자체는 포함되어 있지 않습니다.
따라서 위 그림 ④에 있는 것처럼 이미지를 가져오는 요청을 LINE에 보냄으로써 이미지를 취득해야 합니다.
이때, 인증 정보로서 필요하게 되는 것이 Channel Access Token입니다.
Channel Access Token은 LINE Developers 측에서 발행하며, 발행한 Token은 Cloud Functions에 설정합니다.
이 Token은 코드에 직접 기재하는 것은 바람직하지 않으므로 (유출될 리스크가 있음), 환경 변수 (Environment variable)로 등록합니다.
이번에는 LINE_CHANNEL_ACCESS_TOKEN과 같은 형태로 Cloud Functions에 등록하고, Python 측에서는 환경 변수로부터 가져옵니다.
LINE 이미지 취득
Webhook으로 취득한 Message ID를 사용하여 LINE API를 호출하고, 이미지 데이터를 취득하는 처리를 수행합니다.
LINE_CHANNEL_ACCESS_TOKEN = os.environ.get("LINE_CHANNEL_ACCESS_TOKEN")
line_config = Configuration(access_token=LINE_CHANNEL_ACCESS_TOKEN)
with ApiClient(line_config) as api_client:
...
이렇게 함으로써, LINE으로 보낸 이미지를 Python이 취득하여 Gemini에게 전달하는 흐름을 만들고 있습니다.
처리 상황을 LINE으로 통지하기
영수증 해석은 수 초 정도의 시간이 걸리기 때문에, 이미지를 받은 후 즉시 처리 시작 메시지를 반환하도록 했습니다.
messaging_api.push_message(
PushMessageRequest(
to=chat_id,
...
이를 통해 사용자는 이미지 전송 후 처리가 시작되었음을 확인할 수 있습니다.
그 후, Gemini에 의한 해석과 Spreadsheet로의 등록이 완료되면, 결과를 Flex Message로서 회신합니다.
reply_message_obj = FlexMessage(
alt_text="🎉 영수증 해석이 완료되었습니다!",
contents=FlexContainer.from_dict(flex_content)
...
Cloud Functions로 배포하기
코드 수정이 완료되면, Cloud Functions로 배포합니다.
배포하면 Cloud Functions 측에서 Webhook을 받기 위한 HTTPS URL이 발행됩니다.
앞서 기재했듯이, 이 URL을 LINE Developers의 Messaging API 설정에 있는 Webhook URL에 등록합니다.
이를 통해,
LINE으로 이미지 전송
↓
LINE Bot이 Webhook 통지
↓
Cloud Functions 기동
↓
Python 처리 실행
이라는 연동이 완성됩니다.
이로써 목표했던 "스마트폰에서 LINE으로 영수증 이미지를 보내는 것만으로 가계부에 등록할 수 있는" 흐름을 실현할 수 있었습니다.
3. LIFF를 통한 Human-in-the-loop 도입
첫 번째 기사에서도 썼듯이, AI에 의한 해석 결과에는 오인식이나 카테고리 분류 오류가 발생하기 때문에, 인간에 의한 확인인 Human-in-the-loop를 거쳐야 합니다.
이번 경우에는 LINE 내에서 웹 앱을 동작시킬 수 있는 LIFF (LINE Front-end Framework)를 이용하여, 해석 결과를 확인 및 수정할 수 있는 화면을 작성했습니다.
화면 이미지는 다음과 같습니다.

LIFF 확인 화면: 직관적으로 조작할 수 있는 것을 의식하고 있습니다
LIFF는 LIFF 공식 계정에서 설정할 수 있는 리치 메뉴(Rich Menu)나 URL 등을 통해 실행할 수 있습니다. 이번에는 가계부를 바로 열 수 있도록 리치 메뉴에서 실행할 수 있게 하고, 해석 완료 메시지에도 URL을 포함하도록 했습니다.
LIFF를 추가함으로써, 해석 결과는 다음과 같은 흐름으로 확인 및 등록됩니다.
LIFF 도입에서는 주로 다음의 3가지를 구현했습니다.
- GAS (Google Apps Script) Web 앱을 통한 확인 화면 제공
- 임시 저장 데이터를 가져오는 API 추가
- 수정 후 데이터를 명세(Detail)로 등록하는 처리 추가
지금까지 Gemini의 출력 결과는 명세 시트에 직접 추가해 왔으나, 새롭게 Spreadsheet에 임시 저장용 시트를 생성하여 일단 저장하도록 변경했습니다.
사용자가 LIFF 화면을 열면 임시 저장 시트의 내용이 표시되며, 화면상에서 확인 및 수정이 가능하도록 되어 있습니다.
작업이 완료되어 등록을 누르면,
・ 명세 데이터로 등록
・ 임시 저장 시트 삭제
가 수행됩니다.
LIFF 측 설정으로는,
・ LINE Developers에서 LIFF 앱을 생성하기
・ Endpoint URL에 GAS의 Web 앱 URL을 설정하기
와 같은 작업이 필요합니다. 이 부분도 AI와 상담하며 진행하는 것이 이해하기 쉬울 것이라 생각되므로, 여기서는 생략하겠습니다.
GAS Web 앱 작성
LIFF 자체는 화면을 가지고 있지 않기 때문에, 표시할 웹 페이지를 준비해야 합니다.
이번에는 GAS를 Web 앱으로 공개하고, 그 URL을 LIFF의 Endpoint URL로 설정했습니다.
GAS 측에서는 doGet()을 입구로 하여 HTML을 반환합니다.
function doGet(e) {
const template = HtmlService.createTemplateFromFile('index_view');
return template.evaluate()
...
index_view가 html 파일이며, 여기에 확인 사양을 기재하고 있습니다.
수정 후 데이터 등록
확인 및 수정 후의 데이터는 LIFF에서 GAS로 JSON 형식으로 전송됩니다.
GAS 측에서는 doPost()로 데이터를 받아 명세 데이터로 등록합니다.
function doPost(e) {
const postData = JSON.parse(e.postData.contents);
const items = postData.items;
...
등록 완료 후에는 실수로 중복 등록되지 않도록 임시 저장 시트의 내용을 삭제합니다.
이를 통해 가계부 시스템에 인간이 확인하는 플로우를 구축할 수 있었습니다.
이 시점에서의 시스템 구성은 다음과 같습니다.
4. Looker Studio를 통한 가계부 데이터 시각화
주요 기능으로는 아마 마지막이 되겠지만, 축적된 명세 데이터를 확인하기 쉽게 하기 위해
Google의 BI 도구인 Looker Studio를 이용했습니다. Looker Studio에서는 Spreadsheet 등의 데이터 소스와 연결하여, 집계 결과를 대시보드 형식으로 표시할 수 있습니다.
집계 시트에서도 시각화를 하고 있지만, Spreadsheet는 아무래도 스마트폰에서는 보기 어렵다는 과제가 있었습니다. LINE을 이번 메커니즘의 메인으로 삼는다면 Looker Studio와 같이 스마트폰에서도 보기 편한 환경을 갖추는 것이 바람직하다고 생각합니다.

Looker Studio로 작성한 서머리(Summary) 이미지
어떻게 시각화할지는 개인의 취향에 달려 있지만, 이번에는 총계의 카테고리 비율과 기간별 집계, 등록 내용을 볼 수 있도록 했습니다. 집계 기간은 연 단위/월 단위로 나눌 수 있게 하거나, 금액의 합계를 낼지 해당 기간의 비율을 낼지를 전환할 수 있도록 했습니다.
5. AI 가계부 시스템 완성
지금까지의 구현을 통해 다음과 같은 흐름이 완성되었습니다.
구성으로는 다음과 같습니다.
자동화와 사람에 의한 확인을 결합함으로써, 번거로움을 줄이는 것과 신뢰성을 양립한 메커니즘을 만들 수 있었던 것이 아닐까 생각합니다.
요약
이번 기사에서는 AI를 이용한 영수증 해석부터 시작한 가계부 시스템을, 지속적으로 이용할 수 있는 사용하기 편한 형태로 발전시켜 나가는 과정을 소개했습니다.
PC 상에서 자동으로 처리할 수 있는 것만으로도 유용하겠지만, 역시 일상에서 사용할 기회가 많은 앱을 메인 창구로 설정함으로써 편의성이 높아졌다고 생각합니다.
전체적인 소개는 이상입니다만, 다음 회차에서는 마지막으로 부대 기능이나 고안한 점, 개선점, 직접 만들어 본 소감 등 여러 가지 이야기를 잡다하게 적어볼 수 있으면 좋겠습니다. 괜찮으시다면 마지막까지 함께해 주세요.
※ 이 기사도 ChatGPT가 초안을 작성해 주었습니다.
이하는 일본어 기사를 수작업으로 영어로 옮긴 후, ChatGPT가 수정한 영문입니다.
English Summary
This article introduces how I evolved my AI-powered household budget system from a simple receipt analysis tool into a practical daily-use application.
I implemented LINE Bot, Cloud Functions, LIFF, GAS, and Looker Studio to automate receipt input, provide a confirmation interface, and visualize household spending data.
Through this development, I built a system that combines AI automation with human verification for more reliable household budget management.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기