[n8n] AI Agent의 구글 캘린더에서 빠르게 Get event 하기

소개

  • 구글 캘린더를 도구로 쓰는 Calendar Agent 를 만들기 (X)

    • 만들 수는 있는데 실제로 쾌적한 느낌이 들지 않음.

    • 문제상황 : 캘린더 2개이상 사용하는 나로서는 느려서 답답하다. 구글 캘린더 호출이 많으면 호출 한도에 걸리지 않을까? 등

여러 장치가있는 모바일 앱의 다이어그램

  • 구글 캘린더 Get events를 정해진 시간간격마다 긁어와서 Sheet에 저장. 일정을 물어보면 Sheet정보를 통해서 답변해주는 AI Agent 만들기 (O)

프로세스의 흐름을 보여주는 다이어그램

진행 방법

  • Google Credential 적용

    Google 계정에 Google 계정을 추가하는 방법을 보여주는 화면
    • 가장 지루하고 힘든 작업이었다..

    • 사실 프로세스를 정확히는 모르겠다.

    • 중간에 Secret 를 잃어버려서 재발급하고 난리도 아니었음..

    • 다행인 점은 sheet, calendar, docs 모두 동일한 Client ID와 Secret를 사용한다는 점..?

솔직히 지쳤다. 그래도 한 번만 하면 되니까!

  • Cached Calendar 설정하기

    다양한 유형의 데이터를 보여주는 스프레드 시트의 스크린 샷
    • Sheet를 준비한다 (Header를 제외하고 200행을 삭제)

    • 캘린더1에서 4주간의 일정을 가져온다

    • Sheet에 Append한다

    • 캘린더2에서 4주간의 일정을 가져온다

    • Sheet에 Append한다

가장 챌린지 했던 것 :

  • 구글캘린더의 반복일정(ex. 매주 월요일 10시 팀 회의) = id, iCalUID 등이 아예 동일하다. 그래서 시작시간과 종료시간 말고는 구분할수 있는 방법이 없음.

  • Main Workflow 짜기

    • Basic LLM chain 노드를 구성

      • 목적: "이번주 일정 알려줘", "다음주 일정 뭐야?", "내일 일정뭐임?" 등의 메시지에 대응해서 필요한 날짜 구간을 파악해야함

      • Structured Output parser를 활용해서 JSON으로 고정된 응답 도출

JSON 출력 파서 -JSON 출력 파서 -JSON 출력 파서 -JSON
  • 그 다음부터는 일사천리다

    • Sheet로 저장된 Cashed Calendar를 불러온다

    • Filter node를 활용해서 start-date와 end-date 사이에 있는 행만 남긴다

    • Edit field node를 활용해서 필요없는 열을 날리고 필요한 열만 남긴다.

    • 요리가 준비되었다.

  • Code node (JavaScript)를 활용해서, 각 일정에 대해서 [시간~시간: 일정내용]의 형태로 줄글로 만들었다.

const result = items.map(item => {
  const json = item.json;

  // 날짜 우선순위: dateTime → date → '날짜 없음'
  const start = json["start-dateTime"] || json["start-date"] || "날짜 없음";
  const end = json["end-dateTime"] || json["end-date"] || "";

  const title = json["summary"] || "제목 없음";

  // 시간 범위 문자열 구성
  let dateText = start;
  if (end && end !== start) {
    dateText += ` ~ ${end}`;
  }

  return `• ${dateText}: ${title}`;
}).join("\n");

return [{ json: { summary: result } }];

  • AI Agent 노드에서 해당 결과물 (summary)를 받아서 주어진 형태로 출력한다.

다양한 옵션이있는 화면의 스크린 샷

당신은 캘린더 요약 비서를 맡고 있습니다.

다음은 사용자의 캘린더 일정입니다. 이 일정을 아래의 **출력 형식**에 맞춰 간결하게 요약해 주세요.  
형식을 정확히 지키고, 날짜별로 정렬하여 출력해 주세요.

## ✅ 출력 형식 예시
- 2025년 07월 10일 (목)
    - 하루종일: 프로젝트 회의
    - 14:00 ~ 15:30: GPT 워크숍 참석
- 2025년 07월 11일 (금)
    - 09:00 ~ 10:00: 팀 미팅
    - 13:00 ~ 14:00: 클라이언트 상담

## ✅ 출력 규칙
- 날짜 오름차순 정렬
- 하루종일 일정은 “하루종일:”로 시작
- 시간 있는 일정은 “hh:mm ~ hh:mm: 제목” 형식
- 요일은 반드시 괄호 안에 한글로 표기 (예: (목))
- 날짜가 없는 일정은 제외
- 출력은 위의 형식을 **그대로 유지**

## 🕒 현재 시각
{{ $now }}

## 📅 일정 데이터
{{ $('Code2').item.json.summary }}

가장 챌린지 했던 점:

1. 채팅으로 받았던 chatInput을 마지막 노드인 AI Agent에 expression 형태로 집어넣어도 계속 빨간불이 뜨면서 렉이 걸렸다. 너무 화가 났다. 분명히 되야하는데 안되니까..
{{$('message').item}} 등 JSON 표현식이 아예 작동안했다.

-> 앞쪽에 Edit field노드를 통해서 처음에 받은 chatInput을 불러와서, 그것으로 AI Agent에 넣을수 있어서 해결 완료. 즉 {{$json.chatInput}} 로 해결했다.

  1. 분명히 sheet에 저장해놓아서 처리방법이 일방향이어서 속도가 굉장히 빨랐다! 😀
    그런데 chatmodel에서 20초씩 잡아먹으니까 너무 짜증이 났다.

-> 실행당시 openai 서버의 문제로 늦었던 것이었다. 아침에 다시해보니 4초, 4초. 총 10초정도 걸린다.

결과와 배운 점

  • AI Agent에 tool로 붙여놓은 구글캘린더 Get many events에서는 다소 느리고, 많은 토큰을 잡아먹는다. 반면, 이번에 개발한 Get event만 하는 로직이 더욱 빠르고 저렴하였다.

o4-mini-high 붙인 AI Agents + Google calendar Tool : 56초 / 10259토큰

My workflow (chatgpt-3.5-turbo) : 10.9초 / 3300토큰

  • 앤트로픽의 Barry Zhang이 말했다. 모든것을 위한 Agent를 만들지 말라고.
    나는 앞으로도 더 구체적인 Agent 모델을 만들어 보겠다. 결국엔 그것들끼리 만나는 날이 올 것이다.

  • MCP 를 쓴다면 얼마나 더 편리해질까? 궁금하다.

  • 선배님들의 과감한 코멘트 부탁드립니다!

도움 받은 글 (옵션)

👉 이 게시글도 읽어보세요