LINE 설정
Hermes 에이전트를 공식 LINE Messaging API를 통해 LINE 봇으로 실행합니다. 어댑터는 plugins/platforms/line/ 아래의 번들된 플랫폼 플러그인으로 존재하며 — 핵심 수정은 필요 없고, 다른 플랫폼처럼 활성화하기만 하면 됩니다.
LINE은 일본, 대만, 태국에서 가장 많이 사용되는 메신저 앱입니다. 사용자가 그곳에 있다면, 이 방법으로 여러분에게 접근합니다.
봇의 응답 방식
| 컨텍스트 | 행동 |
|---|---|
1:1 채팅 (U ID) | 모든 메시지에 응답 |
그룹 채팅 (C ID) | 그룹이 허용 목록에 있을 때 응답합니다 |
다중 사용자 방 (R ID) | 방이 허용 목록에 있을 때 응답합니다 |
수신 텍스트, 이미지, 오디오, 비디오, 파일, 스티커, 위치가 모두 처리됩니다. 발신 텍스트는 무료 응답 토큰을 먼저 사용(단일 사용, 약 60초 유효)하며, 토큰이 만료되면 계량형 Push API로 대체됩니다.
단계 1: LINE 메시징 API 채널 생성
- LINE Developers Console로 이동하세요.
- 프로바이더를 생성한 후, 그 아래에 메시징 API 채널을 만듭니다.
- 채널의 기본 설정탭에서채널 비밀을 복사하세요.
- Messaging API탭에서 아래로 스크롤하여**채널 액세스 토큰(장기)**을 찾고 발급을 클릭합니다. 토큰을 복사합니다.
- 메시징 API탭에서자동응답 메시지와 인사말 메시지도 비활성화하여 봇의 응답과 충돌하지 않도록 하세요.
2단계: 웹훅 포트 노출
LINE은 공개 HTTPS를 통해 웹후크를 전달합니다. 기본 포트는 8646이며, 필요 시 LINE_PORT로 변경할 수 있습니다.
# Cloudflare Tunnel (recommended for production — fixed hostname)
cloudflared tunnel --url http://localhost:8646
# ngrok (good for dev)
ngrok http 8646
# devtunnel
devtunnel create hermes-line --allow-anonymous
devtunnel port create hermes-line -p 8646 --protocol https
devtunnel host hermes-line
``https://...` URL을 복사하세요 — 아래에서 웹훅 URL로 설정할 것입니다. **테스트하는 동안 터널을 계속 실행하세요.** 운영 환경에서는 웹훅 URL이 재시작 시 변경되지 않도록 고정된 Cloudflare 명명 터널을 설정하세요.
---
## 3단계: Hermes 구성 \{#step-3-configure-hermes}
`~/.hermes/.env`에 추가:
```env
LINE_CHANNEL_ACCESS_TOKEN=YOUR_LONG_LIVED_TOKEN
LINE_CHANNEL_SECRET=YOUR_CHANNEL_SECRET
# Allowlist — at least one of these (or LINE_ALLOW_ALL_USERS=true for dev)
LINE_ALLOWED_USERS=U1234567890abcdef... # comma-separated U-prefixed IDs
LINE_ALLOWED_GROUPS=C1234567890abcdef... # optional group IDs
LINE_ALLOWED_ROOMS=R1234567890abcdef... # optional room IDs
# Required for image / audio / video sends — the public HTTPS base URL
# the tunnel resolves to. Without it, send_image/voice/video will refuse.
LINE_PUBLIC_URL=https://my-tunnel.example.com
그런 다음 ~/.hermes/config.yaml에서:
gateway:
platforms:
line:
enabled: true
그걸로 충분합니다 — gateway/config.py의 번들 플러그인 스캔이 자동으로 plugins/platforms/line/를 감지합니다. Platform.LINE 열거형 편집도, _create_adapter 등록도 필요 없습니다.
4단계: 웹훅 URL 설정
다시 LINE 콘솔로 돌아가서:
- 채널을 열고 → Messaging API 탭으로 이동하세요.
- 웹훅 설정 → 웹훅 URL에서
https://<your-tunnel>/line/webhook를 붙여넣으세요 (/line/webhook경로를 참고하세요 — 어댑터가 해당 경로를 청취합니다). - 확인을 클릭하세요. LINE이 URL에 핑을 보내면, 200이 보여야 합니다.
- 웹훅 사용을 켬으로 전환하세요.
5단계: 게이트웨이를 실행하세요
hermes gateway
에이전트 로그에 다음과 같이 표시됩니다:
LINE: webhook listening on 0.0.0.0:8646/line/webhook (public: https://my-tunnel.example.com)
LINE 앱에서 봇을 친구로 추가하세요(채널의 Messaging API 탭에 있는 QR 코드를 스캔)하고 메시지를 보내세요.
느린 LLM 응답
LINE의 응답 토큰은 단일 사용이며, 수신 이벤트 후 약 60초 후에 만료됩니다. 느린 LLM은 제시간에 응답할 수 없으며, 이는 일반적으로 유료 푸시 API 호출을 강제하게 됩니다.
LLM이 여전히 LINE_SLOW_RESPONSE_THRESHOLD초(기본값 45) 이상 실행 중일 때, 어댑터는 템플릿 버튼 버블을 보내기 위해 원래 응답 토큰을 사용합니다:
🤔 아직 생각 중입니다. 준비되면 답을 가져오려면 아래를 누르세요.
[ 답변 받기 ]
사용자는 편할 때 답변 받기를 탭합니다 — 해당 포스트백은 새로운 답변 토큰을 전달하며, 어댑터는 이를 사용하여 캐시된 답변(여전히 무료)을 전송합니다.
상태 기계: PENDING → READY → DELIVERED, 취소된 실행에 대해서는 ERROR 추가 (/stop 후에 고아 PENDING은 "실행이 완료되기 전에 중단되었습니다."로 해결되어 지속적인 버튼이 반복되지 않음).
포스트백 버튼을 비활성화하고 항상 푸시-폴백을 사용하려면:
LINE_SLOW_RESPONSE_THRESHOLD=0
포스트백 흐름이 안정적으로 작동하려면, 임계값 전에 응답 토큰을 소비할 대화를 억제하십시오:
# ~/.hermes/config.yaml
display:
interim_assistant_messages: false
platforms:
line:
tool_progress: off
크론 / 알림 전달
LINE_HOME_CHANNEL=Uxxxxxxxxxxxxxxxxxxxx # default delivery target
``deliver: line`가 있는 크론 작업은 `LINE_HOME_CHANNEL`로 라우팅됩니다. 어댑터는 독립 실행형 푸시 전용 송신기를 제공하므로 크론이 게이트웨이와 별도의 프로세스에서 실행되더라도 크론 작업이 작동합니다.
---
## 환경 변수 참조 \{#step-3-configure-hermes}
| 변수 | 필수 | 기본값 | 설명 |
|---|---|---|---|
| `LINE_CHANNEL_ACCESS_TOKEN` | 예 | — | 장수 채널 액세스 토큰 |
| `LINE_CHANNEL_SECRET` | 예 | — | 채널 시크릿 (HMAC-SHA256 웹훅 검증) |
| `LINE_HOST` | no | `0.0.0.0` | 웹훅 바인드 호스트 |
| `LINE_PORT` | no | `8646` | 웹훅 바인드 포트 |
| `LINE_PUBLIC_URL` | 미디어용 | — | 공용 HTTPS 기본 URL; 이미지/음성/동영상 전송에 필요 |
| `LINE_ALLOWED_USERS` | 중 하나 | — | 쉼표로 구분된 사용자 ID (U로 시작) |
| `LINE_ALLOWED_GROUPS` | ~중 하나 | — | 쉼표로 구분된 그룹 ID(C로 시작) |
| `LINE_ALLOWED_ROOMS` | 중 하나 | — | 쉼표로 구분된 방 ID (R로 시작) |
| `LINE_ALLOW_ALL_USERS` | 개발 전용 | `false` | 허용 목록 전체 건너뛰기 |
| `LINE_HOME_CHANNEL` | no | — | 기본 크론 / 알림 전송 대상 |
| `LINE_SLOW_RESPONSE_THRESHOLD` | no | `45` | 포스트백 버튼이 실행되기 직전 (`0` = 비활성화됨) |
| `LINE_PENDING_TEXT` | no | 🤔 아직 생각 중… | 게시 버튼 옆에 표시되는 버블 텍스트 |
| `LINE_BUTTON_LABEL` | no | 답을 얻다 | 버튼 레이블 |
| `LINE_DELIVERED_TEXT` | no | 이미 답장함 ✅ | 이미 전달된 버튼을 다시 탭할 때 응답 |
| `LINE_INTERRUPTED_TEXT` | no | 실행이 완료되기 전에 중단되었습니다. | _`/stop`_ 고아 버튼이 눌렸을 때 응답 |
---
## 문제 해결 \{#step-4-set-the-webhook-url}
**웹훅 검증에서 '잘못된 서명(invalid signature)'입니다.** `Channel secret`가 잘못 복사되었거나, 터널이 요청 본문을 변경했습니다. 먼저 `curl -i https://<tunnel>/line/webhook/health`로 확인하세요 — 그러면 `{"status":"ok","platform":"line"}`가 반환되어야 합니다.
**봇은 그룹에서 아무 것도 받지 않습니다.** `LINE_ALLOWED_GROUPS`에 `C...` 그룹 ID가 포함되어 있는지 확인하세요. 그룹 ID를 찾으려면 테스트 메시지를 보내고 `~/.hermes/logs/gateway.log`에서 `LINE: rejecting unauthorized source`을 검색하세요 — 거부된 소스 사전에 ID가 있습니다.
**`send_image`가 'LINE_PUBLIC_URL must be set' 오류로 실패합니다.** LINE의 메시징 API는 바이너리 업로드를 허용하지 않습니다 — 이미지, 오디오, 비디오는 HTTPS URL을 통해 접근 가능해야 합니다. `LINE_PUBLIC_URL`을 터널의 공개 호스트명으로 설정하면 어댑터가 `/line/media/<token>/<filename>`에서 파일을 자동으로 제공할 것입니다.
**포스트백 버튼이 전혀 나타나지 않습니다.** LLM이 `LINE_SLOW_RESPONSE_THRESHOLD`보다 빠르게 응답했거나, 다른 버블(도구 진행, 스트리밍)이 먼저 응답 토큰을 사용했을 수 있습니다. '느린 LLM 응답' 아래의 억제 블록을 참조하세요.
**"다른 프로필에서 이미 사용 중입니다."** 동일한 채널 액세스 토큰이 다른 실행 중인 Hermes 프로필에 연결되어 있습니다. 다른 게이트웨이를 중지하거나 별도의 채널을 사용하세요.
---
## 제한 사항 \{#step-5-run-the-gateway}
* **청크당 단일 말풍선.** 각 LINE 텍스트 말풍선은 5000자로 제한되며, 한 Reply/Push 호출당 최대 5개의 말풍선이 전송됩니다. 더 긴 응답은 줄임표(...)로 잘립니다.
* **원본 메시지 편집 금지.** LINE에는 메시지 편집 API가 없습니다 — 스트리밍 응답은 항상 새로운 버블을 보내며 이전 메시지를 편집하지 않습니다.
* **마크다운 렌더링 없음.** 굵게(`**`), 기울임(`*`), 코드 블록, 및 제목은 문자 그대로 렌더링됩니다. 어댑터는 전송 전에 이를 제거합니다; URL은 유지됩니다 (`[label](url)`가 `label (url)`으로 변경됨).
* **로딩 표시기는 DM 전용입니다.** LINE은 그룹 및 채팅방에 대한 채팅/로딩 API를 허용하지 않으므로, 입력 표시기는 1:1 채팅에서만 표시됩니다.