Skip to content
This repository was archived by the owner on Aug 6, 2026. It is now read-only.
minpeter-labsPublic archive

About

[DEPRECATED]

Resources

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

Repository files navigation

kakao-agent

A minimal local webhook server for a Kakao i OpenBuilder chatbot "skill", exposed to the internet through a Cloudflare named tunnel.

Kakao  ──HTTPS──▶  https://kakao-agent-local.vhh.sh/webhook/kakao
                          │  (Cloudflare named tunnel: kakao-agent-local)
                          ▼
                   http://localhost:8788/webhook/kakao   (this server)

What it does

POST /webhook/kakao reads the user's message from userRequest.utterance, asks an LLM, and replies in Kakao's skill-response format:

{ "version": "2.0", "template": { "outputs": [ { "simpleText": { "text": "<reply>" } } ] } }

Kakao requires version: "2.0", Content-Type: application/json, and HTTP 200. The synchronous SLA is 5 seconds, which an LLM call easily blows past — so the server uses Kakao's Callback:

  1. When Callback is enabled on the block, Kakao includes userRequest.callbackUrl. The server immediately acks with { "version": "2.0", "useCallback": true } (inside the 5s SLA; no template — the waiting message is configured in OpenBuilder).
  2. It then runs the LLM and POSTs the final skill response to callbackUrl. That URL is valid up to 5 minutes and is single-use.
  3. With no callbackUrl (Callback off, or bot test) it answers synchronously, best-effort within 5s, falling back to a "couldn't answer in time" message.

Multiple bubbles

Kakao renders up to 3 outputs (말풍선) per response. The LLM is told to separate bubbles with a blank line; the server splits the reply on blank lines, keeps fenced code blocks intact, merges >3 chunks into 3 (length-balanced, order preserved), and overflows an over-long (>1000-char) bubble into spare slots before truncating.

Phases

  • Phase 1 (done): echo userRequest.utterance back.
  • Phase 2 (done): LLM reply via the Callback flow above, split into up to 3 bubbles. Falls back to echo: … if no AI_API_KEY is configured.

LLM config

Reads AI_API_KEY / AI_BASE_URL / AI_MODEL (falling back to OPENAI_*, then opengateway defaults). KAKAO_SYSTEM_PROMPT overrides only the persona — the bubble-splitting rules are always appended. See .env.example. An OpenAI-compatible /chat/completions endpoint is expected.

Run

pnpm install

# both server + tunnel together
pnpm dev

# or individually
pnpm dev:server   # tsx watch, localhost:8788
pnpm dev:tunnel   # cloudflared named tunnel

Local smoke test:

# Sync (no callbackUrl) — best-effort within 5s
curl -s localhost:8788/webhook/kakao \
  -H 'content-type: application/json' \
  -d '{"userRequest":{"utterance":"1+1은?"}}'
# {"version":"2.0","template":{"outputs":[{"simpleText":{"text":"1+1은 2입니다."}}]}}

# Callback — point callbackUrl at any local sink; the server acks immediately,
# then POSTs the LLM answer to that URL within ~5 min.
curl -s localhost:8788/webhook/kakao \
  -H 'content-type: application/json' \
  -d '{"userRequest":{"utterance":"길게 설명해줘","callbackUrl":"http://127.0.0.1:9911/cb"}}'
# {"version":"2.0","useCallback":true}

Tunnel

  • Tunnel name: kakao-agent-local
  • Hostname: kakao-agent-local.vhh.sh
  • Cloudflare account: the one that owns the vhh.sh zone
  • Config: cloudflared/config.yml (ingress → http://localhost:8788)

Created with:

cloudflared tunnel create kakao-agent-local
cloudflared tunnel route dns kakao-agent-local kakao-agent-local.vhh.sh

The credentials JSON lives at ~/.cloudflared/<tunnel-uuid>.json (git-ignored).

About

[DEPRECATED]

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages