Skip to content

Commit 575e4e3

Browse files
committed
docs: 2026-03-28-ai post
1 parent f958033 commit 575e4e3

File tree

6 files changed

+206
-0
lines changed

6 files changed

+206
-0
lines changed

_posts/ai/2026-03-28-ai.md

Lines changed: 206 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,206 @@
1+
---
2+
title: "AI로 사내 회의실 예약봇 만들기 — n8n부터 Chrome 확장까지"
3+
description: "매번 Wiki 페이지를 찾아 표를 병합하는 번거로움을 없애기 위해 만든 회의실 예약봇 개발기"
4+
date: 2026-03-28 +00:00:00
5+
permalink: /posts/2026-03-28-ai/
6+
mermaid: true
7+
categories: [Blogging,ai]
8+
---
9+
10+
## **왜 만들었는가**
11+
12+
사내에서는 직원들이 회의실을 잡을 때 Atlassian Confluence Wiki를 사용하여 예약을 하고 있습니다.
13+
14+
![스크린샷 2026-03-24 오전 11.36.28.png](AI%EB%A1%9C%20%EC%82%AC%EB%82%B4%20%ED%9A%8C%EC%9D%98%EC%8B%A4%20%EC%98%88%EC%95%BD%EB%B4%87%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20%E2%80%94%20n8n%EB%B6%80%ED%84%B0%20Chrome%20%ED%99%95%EC%9E%A5%EA%B9%8C%EC%A7%80/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2026-03-24_%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB_11.36.28.png)
15+
16+
회의실을 잡을 때마다 이번 주 Wiki 페이지를 찾아야 하고, 1시간을 예약한다면 표를 병합해야 한다는 번거로움이 있었습니다. 팀 업무상 회의가 많다 보니 이러한 문제를 해결하기 위해 사내 회의실 예약봇을 AI를 통해 만들기로 하였습니다.
17+
18+
### **주요 기능**
19+
20+
1. **팀 전체가 사용할 수 있어야 한다**
21+
- Wiki 계정(아이디/비밀번호)으로 로그인
22+
- 채팅 한 줄로 예약할 수 있는 간편한 UI
23+
2. **예약자명 자동 처리**
24+
- 예약 셀에 "부서명 (@사용자이름)" 형식으로 기록
25+
- 로그인한 계정으로 Confluence `@멘션` 자동 삽입
26+
3. **자연어 예약 / 조회**
27+
- "금요일 오후 2시 4회의실 예약해줘"처럼 말하면 됨
28+
- 예약뿐 아니라 "비어있어?"로 가용 여부 조회 가능
29+
4. **요일 생략 시 오늘 날짜 자동 인식**
30+
- "2시 4회의실" 입력만으로 오늘 날짜에 예약
31+
- 주말 입력 시 다음 주 월요일로 자동 처리
32+
5. **중복 예약 방지 및 만석 감지**
33+
- 이미 예약된 시간대에 요청 시 충돌 안내
34+
- 해당 요일 전체 만석일 경우 별도 안내
35+
6. **소요 시간 지정**
36+
- 기본 1시간 (2슬롯 rowspan), "30분", "2시간" 등 직접 지정 가능
37+
38+
### **사용한 Wiki API**
39+
40+
| **API** | **용도** |
41+
| --- | --- |
42+
| `GET /rest/api/content` | 이번 주 예약 페이지 검색 (`title``spaceKey` 파라미터) |
43+
| `GET /rest/api/user?username=` | 로그인 사용자 검증 및 Confluence userKey 조회 |
44+
| `PUT /rest/api/content/{pageId}` | 예약 완료 후 페이지 HTML 업데이트 |
45+
46+
---
47+
48+
## **과정**
49+
50+
처음에는 n8n을 활용해 챗봇을 만들려 했습니다. 사내에서 n8n을 통한 Wiki 페이지 생성과 자동화 효율성이 입증되면서, 팀 전체가 n8n 도입에 열광했기 때문입니다. 자연스럽게 첫 번째 프로토타입도 n8n으로 시작되었습니다.
51+
52+
하지만 n8n을 셀프 호스팅으로 운영하다 보니, 비개발자 팀원들이 이를 활용하려면 각자 환경을 구축하거나 복잡한 설정 과정을 거쳐야 하는 번거로움이 있었습니다. 도구가 오히려 업무의 짐이 되는 상황이었죠.
53+
54+
고민 끝에 결정한 해답은 **크롬 확장 프로그램**이었습니다. 우리 팀의 업무 환경을 관찰해 보니, 개발자와 비개발자 할 것 없이 업무의 90% 이상이 웹 브라우저 안에서 이루어지고 있었습니다. WEHAGO 메신저, 사내 Wiki, 각종 서비스까지 모두 크롬 탭 안에 있었죠.
55+
56+
별도의 설치나 학습 없이, 항상 켜져 있는 브라우저에서 아이콘 클릭 한 번으로 예약을 끝내는 경험. Wiki 계정만 있다면 누구나 즉시 사용할 수 있는 이 구조야말로 우리 팀의 업무 동선에 가장 자연스럽게 녹아드는 자동화라고 생각합니다.
57+
58+
### **1. n8n 챗봇 버전 (`Wiki 회의실 예약 챗봇`)**
59+
60+
첫 번째로 만든 건 순수 n8n 워크플로우 기반의 채팅봇입니다. n8n 내장 Chat Trigger UI로 대화하면 Gemini AI가 자연어를 파싱하고, Confluence REST API로 Wiki 페이지를 조회·수정합니다.
61+
62+
**워크플로우 구조**
63+
64+
![스크린샷 2026-03-28 오후 8.22.23.png](AI%EB%A1%9C%20%EC%82%AC%EB%82%B4%20%ED%9A%8C%EC%9D%98%EC%8B%A4%20%EC%98%88%EC%95%BD%EB%B4%87%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20%E2%80%94%20n8n%EB%B6%80%ED%84%B0%20Chrome%20%ED%99%95%EC%9E%A5%EA%B9%8C%EC%A7%80/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2026-03-28_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_8.22.23.png)
65+
66+
```
67+
[Chat Trigger]
68+
69+
[Gemini - 자연어 파싱]
70+
→ { room, day, time, action, meeting_name, duration_slots }
71+
72+
[Code - 이번 주 날짜 계산]
73+
74+
[HTTP - Wiki 페이지 검색]
75+
76+
[IF - 페이지 존재 여부]
77+
├─ 없음 → "이번 주 예약 페이지를 찾을 수 없습니다."
78+
└─ 있음 →
79+
[HTTP - 로그인 사용자 userKey 조회]
80+
81+
[Code - 테이블 파싱 & 가용성 확인]
82+
83+
[IF - book / check 분기]
84+
├─ check → 가용 여부 메시지 반환
85+
└─ book →
86+
[IF - 예약 가능 여부]
87+
├─ 불가 → 충돌 안내
88+
└─ 가능 →
89+
[Code - HTML rowspan 수정]
90+
91+
[HTTP - Wiki PUT 업데이트]
92+
93+
[Code - 완료 안내]
94+
```
95+
96+
핵심은 Wiki 테이블의 HTML을 직접 파싱하고 rowspan을 수동 계산하는 부분입니다. Confluence는 1시간 예약 시 첫 번째 셀에 `rowspan="2"`를 삽입하고 다음 행의 해당 `<td>`를 제거하는 방식으로 병합합니다. 단순히 셀을 교체하는 것이 아니라 rowspan 추적 맵을 유지하며 가상 컬럼 인덱스를 계산해야 했습니다.
97+
98+
### **2. 크롬 확장 프로그램 버전**
99+
100+
n8n 챗봇은 잘 동작했지만 **팀원들이 n8n을 설치해야 쓸 수 있다**는 문제가 있었습니다. 크롬 확장은 폴더 하나만 배포하면 되기 때문에 팀 전체가 설치 없이 바로 사용할 수 있습니다.
101+
102+
### **2.1 n8n Webhook 연동 크롬 확장 (`Wiki 회의실 예약 - Webhook`)**
103+
104+
역할을 명확히 나눈 구조입니다. **로그인과 인증은 크롬 확장이 직접** 처리하고, **자연어 파싱과 Wiki API 작업은 n8n Webhook이** 담당합니다.
105+
106+
**동작 흐름:**
107+
108+
```
109+
[크롬 확장]
110+
↓ 팝업 열림
111+
[내부망 체크] — wiki.사내.com:8080 HEAD 요청 (5초 타임아웃)
112+
├─ 실패 → "사내 내부망 사용자만 이용 가능합니다."
113+
└─ 성공 →
114+
[세션 확인]
115+
├─ 세션 없음 → [로그인 화면]
116+
│ ↓ ID / PW 입력
117+
│ Confluence API: GET /rest/api/user?username=
118+
│ → userKey, displayName 수신
119+
│ → authHeader(Base64 인코딩)를 세션에 저장 (평문 PW 미저장)
120+
└─ 세션 있음 → [채팅 화면]
121+
↓ 채팅 입력
122+
n8n Webhook POST /webhook/room-booking
123+
body: { chatInput, authHeader, userKey, defaultTitle }
124+
```
125+
126+
로그인 시 `btoa(id:pw)`로 만든 `authHeader`만 세션에 보관하고, n8n에 전달할 때도 이 값을 그대로 사용합니다. n8n은 받은 `authHeader`로 Confluence API를 직접 호출하기 때문에 n8n 서버에 계정 정보를 따로 등록할 필요가 없습니다.
127+
128+
**n8n이 하는 일 (Webhook 수신 후):**
129+
130+
![스크린샷 2026-03-28 오후 8.53.35.png](AI%EB%A1%9C%20%EC%82%AC%EB%82%B4%20%ED%9A%8C%EC%9D%98%EC%8B%A4%20%EC%98%88%EC%95%BD%EB%B4%87%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20%E2%80%94%20n8n%EB%B6%80%ED%84%B0%20Chrome%20%ED%99%95%EC%9E%A5%EA%B9%8C%EC%A7%80/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2026-03-28_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_8.53.35.png)
131+
132+
```
133+
[Webhook Trigger] — chatInput, authHeader, userKey, defaultTitle 수신
134+
135+
[Gemini - 자연어 파싱]
136+
→ { room, day, time, action, meeting_name, duration_slots }
137+
138+
[HTTP - Wiki 페이지 검색] ← Authorization: {authHeader}
139+
140+
[Code - 테이블 파싱 & 가용성 확인]
141+
142+
[IF - book / check 분기]
143+
├─ check → 가용 여부 메시지 반환
144+
└─ book →
145+
[Code - HTML rowspan 수정] ← userKey로 @멘션 생성
146+
147+
[HTTP - Wiki PUT 업데이트] ← Authorization: {authHeader}
148+
149+
[Respond to Webhook] — 완료 메시지 반환
150+
```
151+
152+
**챗봇 버전 대비 개선 사항:**
153+
154+
| **항목** | **챗봇 버전** | **Webhook 버전** |
155+
| --- | --- | --- |
156+
| 인증 | n8n에 하드코딩된 크레덴셜 | 로그인 사용자의 authHeader를 동적으로 전달 |
157+
| 멘션 | 고정 계정 | 로그인 사용자의 Confluence userKey |
158+
| 회의명 | `CoreDevCell` 고정 | 설정 화면에서 팀별 기본값 지정 가능 |
159+
| 만석 감지 | 미처리 | 해당 요일 전체 슬롯 순회 후 안내 |
160+
| n8n 설치 | 각자 설치 필요 | 팀 공용 서버 1대만 있으면 됨 |
161+
162+
설정 화면에서 n8n 서버 URL과 기본 회의명을 지정할 수 있어, 팀 서버로 전환할 때는 URL만 바꾸면 됩니다.
163+
164+
![스크린샷 2026-03-28 오후 8.47.01.png](AI%EB%A1%9C%20%EC%82%AC%EB%82%B4%20%ED%9A%8C%EC%9D%98%EC%8B%A4%20%EC%98%88%EC%95%BD%EB%B4%87%20%EB%A7%8C%EB%93%A4%EA%B8%B0%20%E2%80%94%20n8n%EB%B6%80%ED%84%B0%20Chrome%20%ED%99%95%EC%9E%A5%EA%B9%8C%EC%A7%80/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA_2026-03-28_%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE_8.47.01.png)
165+
166+
### **2.2 n8n 없이 Wiki API만으로 동작하는 최종 버전**
167+
168+
Webhook 연동 버전도 잘 동작했지만 팀 서버가 없는 환경에서는 n8n을 띄워야 한다는 의존성이 남아 있었습니다. 그래서 n8n 로직 전체를 Chrome Extension JavaScript로 이식한 **완전 독립 버전**을 만들었습니다.
169+
170+
**변경 포인트:**
171+
172+
- **`parser.js`** — Gemini AI 대신 규칙 기반 자연어 파싱으로 교체 요일·시간·회의실·회의명·소요시간을 정규식으로 추출하며, AI 호출 없이도 대부분의 입력을 처리
173+
- **`booking.js`** — n8n HTTP/Code 노드를 함수로 이식 `fetchPage()` → `checkAndBook()` → Confluence PUT 흐름을 직접 구현
174+
- **`popup.js`** — UI만 담당, n8n fetch 로직 제거
175+
176+
**아키텍처:**
177+
178+
```
179+
사용자 입력
180+
181+
parser.js: parseIntent(text) ← 규칙 기반 파싱
182+
↓ intent 객체
183+
booking.js: checkAndBook(...)
184+
├─ Confluence GET — 이번 주 페이지 조회
185+
├─ HTML 파싱 — rowspan 테이블 파싱
186+
├─ action=check → 가용 여부 반환
187+
└─ action=book
188+
├─ 만석 체크
189+
├─ 충돌 체크
190+
└─ HTML 수정 → Confluence PUT
191+
192+
popup.js: appendMessage('bot', message)
193+
```
194+
195+
**설치:**
196+
197+
1. `room-booking-extension-v2` 폴더를 받는다
198+
2. Chrome 주소창에 `chrome://extensions/` 입력
199+
3. **개발자 모드** 켜기 → **압축해제된 확장 프로그램을 로드합니다** 클릭
200+
4. 폴더 선택 → 완료
201+
202+
## **마치며**
203+
204+
처음에는 n8n의 강력한 워크플로우 기능으로 빠르게 프로토타입을 만들었고, 그 과정에서 Confluence HTML 파싱과 rowspan 처리라는 까다로운 문제를 풀었습니다. 그 로직을 검증한 뒤 Chrome Extension으로 이식하면서 팀원 누구나 설치 없이 사용할 수 있는 형태로 발전시켰습니다.
205+
206+
AI를 활용한 것은 **설계와 구현의 속도**였습니다. Confluence Wiki HTML 구조 분석, rowspan 알고리즘 설계, Chrome Extension 보안 설계까지 AI로 프로그래밍하면서 혼자서라면 시도도 못했던 작업을 하루 이틀 만에 완성할 수 있었습니다.

assets/img/ai/2026-03-28-ai-01.gif

16.6 MB
Loading

assets/img/ai/2026-03-28-ai-01.png

243 KB
Loading

assets/img/ai/2026-03-28-ai-02.png

261 KB
Loading

assets/img/ai/2026-03-28-ai-03.png

57 KB
Loading

assets/img/ai/2026-03-28-ai-04.png

146 KB
Loading

0 commit comments

Comments
 (0)