Skip to content

About

An all-in-one Discord bot built in Python with server utilities, automation, and AI-assisted features for community management.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Latest commit

ย 

History

468 Commits

Folders and files

Repository files navigation

Discord All-in-One Bot

Discord ์„œ๋ฒ„ ์šด์˜, AI ๋ณด์กฐ, ์Œ์•… ์žฌ์ƒ, ๊ฒŒ์ž„/๋„๋ฐ•, ์ผ์ •, ์™ธ๋ถ€ ์•Œ๋ฆผ์„ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌํ•˜๋Š” Python ๊ธฐ๋ฐ˜ Discord ๋ด‡์ž…๋‹ˆ๋‹ค.

์ด ์ €์žฅ์†Œ๋Š” ๋ด‡ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ, Docker ์‹คํ–‰ ์ž์‚ฐ, Jenkins ์˜ˆ์‹œ ํŒŒ์ดํ”„๋ผ์ธ, DB ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ•จ๊ป˜ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๊ณต์œ  Jenkins ์ปจํŠธ๋กค๋Ÿฌ๋‚˜ ์™ธ๋ถ€ ๋Ÿฐํƒ€์ž„ ์ธํ”„๋ผ๋Š” ์ด ์ €์žฅ์†Œ ๋ฒ”์œ„๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค.

ํ•ต์‹ฌ ์š”์•ฝ

  • discord.py ๊ธฐ๋ฐ˜ slash command/package cog ๊ตฌ์กฐ
  • OpenAI Responses API ๊ธฐ๋ฐ˜ ์งˆ๋ฌธ, ๊ฒ€์ƒ‰, ์š”์•ฝ, ๋ฒˆ์—ญ, ํ•ด์„, ์„ค๋ช…, ์Œ์‹ ์ถ”์ฒœ, ๊ณต์ง€ ์š”์•ฝ
  • YouTube ์˜์ƒ ์š”์•ฝ, ๋Œ“๊ธ€ ์š”์•ฝ, ๋ผ์ด๋ธŒ/์—…๋กœ๋“œ/WebSub/์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œ๋ฌผ ์•Œ๋ฆผ
  • ์Œ์•… ์žฌ์ƒ, ๋Œ€๊ธฐ์—ด, ๋ฐ˜๋ณต, ์…”ํ”Œ, ์ฆ๊ฒจ์ฐพ๊ธฐ, ํŒจ๋„ UI
  • MySQL ๊ธฐ๋ฐ˜ ๊ธธ๋“œ ์„ค์ •, ๋„๋ฐ• ์ž”์•ก, ์˜ˆ์•ฝ ๋ฉ”์‹œ์ง€, YouTube ๊ตฌ๋…, DDAY, ๊ธฐ๋Šฅ ์ƒํƒœ ์ €์žฅ
  • aiohttp.web ๊ธฐ๋ฐ˜ ์ƒํƒœ/์™ธ๋ถ€ ์ฝœ๋ฐฑ API
  • Docker Compose ๋ฐฐํฌ์™€ Jenkins ๊ฒ€์ฆ/๋งˆ์ด๊ทธ๋ ˆ์ด์…˜/๋ฐฐํฌ ๋‹จ๊ณ„

๊ธฐ์ˆ  ์Šคํƒ

  • Runtime: Python 3.11
  • Discord: discord.py, discord.py[voice], discord-ext-voice-recv
  • HTTP/DB: aiohttp, aiomysql
  • AI: OpenAI Responses API, hosted prompt payload
  • ์Œ์„ฑ/๋ฏธ๋””์–ด: faster-whisper, pyttsx3, yt-dlp, ffmpeg
  • ์™ธ๋ถ€ API: YouTube Data API, Riot API, ํ•œ๊ตญ์€ํ–‰ ECOS
  • ํ…Œ์ŠคํŠธ: unittest, compileall
  • ๋ฐฐํฌ: Docker, Docker Compose, Jenkins Pipeline

ํ”„๋กœ์ ํŠธ ๊ตฌ์กฐ

.
โ”œโ”€โ”€ bot.py                    # Bot ์ƒ์„ฑ, Cog ์ž๋™ ๋กœ๋“œ, ๋ฉ”์‹œ์ง€ ์บ์‹œ, startup ์ดˆ๊ธฐํ™”
โ”œโ”€โ”€ api/                      # OpenAI, Riot, ECOS API adapter
โ”œโ”€โ”€ cogs/                     # Slash command์™€ background/API cog
โ”œโ”€โ”€ common/                   # ๊ณตํ†ต OpenAI prompt payload helper
โ”œโ”€โ”€ func/                     # YouTube ์š”์•ฝ/๋ฏธ๋””์–ด ์ฒ˜๋ฆฌ์™€ 1557 ๊ฐ์ง€ ๊ธฐ๋Šฅ
โ”œโ”€โ”€ util/                     # DB, guild/message/music/youtube/maplestory/loop helper
โ”œโ”€โ”€ scripts/migrate_db.py     # MySQL schema migration entrypoint
โ”œโ”€โ”€ test/                     # unittest ๊ธฐ๋ฐ˜ ํšŒ๊ท€ ํ…Œ์ŠคํŠธ
โ”œโ”€โ”€ Dockerfile*               # runtime/dependency image
โ”œโ”€โ”€ docker-compose.yml        # local/deploy compose service
โ””โ”€โ”€ Jenkinsfile               # checkout, verify, migrate, deploy ์˜ˆ์‹œ pipeline

์•„ํ‚คํ…์ฒ˜

Entry Point

bot.py๊ฐ€ commands.Bot์„ ์ƒ์„ฑํ•˜๊ณ  cogs/ ์•„๋ž˜์˜ ๋‹จ์ผ ํŒŒ์ผ cog์™€ package cog๋ฅผ ์ž๋™์œผ๋กœ ๋ฐœ๊ฒฌํ•ด ๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค. cogs.status_api๋Š” ํ•„์ˆ˜ cog๋กœ ์ทจ๊ธ‰๋˜์–ด ๋กœ๋“œ ์‹คํŒจ ์‹œ startup์ด ์ค‘๋‹จ๋ฉ๋‹ˆ๋‹ค.

bot.py๋Š” ๋‹ค์Œ ์ „์—ญ ์ƒํƒœ๋„ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • DISCORD_CLIENT.USER_MESSAGES: ๊ธธ๋“œ๋ณ„ ์ตœ๊ทผ ๋ฉ”์‹œ์ง€ ์บ์‹œ. AI ์งˆ๋ฌธ๊ณผ ์š”์•ฝ ์ปจํ…์ŠคํŠธ๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋Œ€ํ™” ์š”์•ฝ์€ ์ตœ๊ทผ ์ด๋ฏธ์ง€ ์ตœ๋Œ€ 4์žฅ๋„ ํ•จ๊ป˜ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, ํ•ด์„๊ณผ ์„ค๋ช…์€ ์„ ํƒ ๋ฉ”์‹œ์ง€ ๊ธฐ์ค€ ์ฑ„๋„ ๊ธฐ๋ก์„ ์ง์ ‘ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค.
  • DISCORD_CLIENT.PARTY_LIST: -ํŒŒํ‹ฐ๋กœ ๋๋‚˜๋Š” Discord ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ๊ธธ๋“œ๋ณ„๋กœ ์ถ”์ ํ•ฉ๋‹ˆ๋‹ค.

Cog Layout

ํ˜„์žฌ ์ฃผ์š” ๊ธฐ๋Šฅ์€ package cog ํ˜•ํƒœ์ธ cogs/<name>/__init__.py์— ์œ„์น˜ํ•ฉ๋‹ˆ๋‹ค. ๋ณต์žกํ•œ ๊ธฐ๋Šฅ์€ ํ•ด๋‹น cog๊ฐ€ command surface๋งŒ ๋‹ด๋‹นํ•˜๊ณ  ์„ธ๋ถ€ ๋กœ์ง์€ util/, func/, ํ•˜์œ„ ๋ชจ๋“ˆ๋กœ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

๋Œ€ํ‘œ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • cogs/gambling/: ๋„๋ฐ• ๋ช…๋ น surface, ์ž”์•ก/๊ฒŒ์ž„ ๋กœ์ง์€ ํ•˜์œ„ ํŒŒ์ผ๋กœ ๋ถ„๋ฆฌ
  • cogs/music/: ์Œ์•… ๋ช…๋ น surface, queue/playback/source/view helper๋Š” util/music/
  • cogs/youtube_subscriptions/: YouTube ๊ตฌ๋… ๋ช…๋ น surface, ์ƒํƒœ/์•Œ๋ฆผ/WebSub helper๋Š” util/youtube/
  • cogs/maplestory/: MapleStory ๋ช…๋ น surface, fetch/parser/sender/state๋Š” util/maplestory/
  • cogs/loop/: background task orchestration, ์„ธ๋ถ€ runner๋Š” util/loop/, util/youtube/, util/maplestory/, util/codex_resets/, util/earthquake/

๋ช…๋ น์–ด

๊ธฐ๋ณธ/๊ด€๋ฆฌ

๋ช…๋ น์–ด ์„ค๋ช…
/๋„์›€ ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ๋„์›€๋ง UI
/๊ธฐ๊ฐ€์ฑ„๋“œ ๊ธฐ๊ฐ€์ฑ„๋“œ ์ด๋ฏธ์ง€ ์ „์†ก
/ํ•‘ ๋ด‡ latency ํ™•์ธ
/clean ๊ด€๋ฆฌ์ž ์ „์šฉ ์ตœ๊ทผ ๋ฉ”์‹œ์ง€ ์ •๋ฆฌ
/์ฑ„๋„์„ค์ • ๊ธฐ๋…์ผ, ๋„๋ฐ•, ์Œ์•…, ์œ ํŠœ๋ธŒ, ๋ฉ”์ดํ”Œ๊ณต์ง€, ๋กœ์•„๊ณต์ง€, ์ฝ”๋ฑ์Šค๋ฆฌ์…‹, ์ง€์ง„์•Œ๋ฆผ ์ฑ„๋„ ์ง€์ •/ํ•ด์ œ
/์ฑ„๋„์„ค์ •ํ™•์ธ ํ˜„์žฌ ๊ธธ๋“œ์˜ ๊ธฐ๋Šฅ๋ณ„ ์ฑ„๋„ ์„ค์ • ํ™•์ธ

๊ธฐ๋…์ผ/DDAY/์ผ์ •

๋ช…๋ น์–ด ์„ค๋ช…
/๊ธฐ๋…์ผ์—…๋ฐ์ดํŠธ ์˜ค๋Š˜ ๊ธฐ๋…์ผ/์‚ฌ๊ฑด ๊ณต์ง€๋ฅผ ์ˆ˜๋™ ๊ฐฑ์‹ 
/dday์ถ”๊ฐ€ ์„œ๋ฒ„ DDAY ์ถ”๊ฐ€
/dday์‚ญ์ œ DDAY ๋ชฉ๋ก์—์„œ ์„ ํƒ ์‚ญ์ œ
/dday๋ชฉ๋ก ์„œ๋ฒ„ DDAY ๋ชฉ๋ก ์กฐํšŒ
/์˜ˆ์•ฝ ์ผ๋ฐ˜ ์ง€์ • ์‹œ๊ฐ์— ๋ฉ”์‹œ์ง€ ์˜ˆ์•ฝ
/์˜ˆ์•ฝ ๋ฐ˜๋ณต ๋งค์‹œ๊ฐ„/๋งค์ผ/๋งค์ฃผ/๋งค๋‹ฌ ๋ฐ˜๋ณต ๋ฉ”์‹œ์ง€ ์˜ˆ์•ฝ
/์˜ˆ์•ฝ ๋ฆฌ์ŠคํŠธ ์˜ˆ์•ฝ ๋ชฉ๋ก ์กฐํšŒ ๋ฐ ์‚ญ์ œ

AI

๋ช…๋ น์–ด/์•ก์…˜ ์„ค๋ช…
/์งˆ๋ฌธ ์ตœ๊ทผ ๋Œ€ํ™” ๋ฌธ๋งฅ์„ ๋ฐ˜์˜ํ•˜๋Š” ํ…์ŠคํŠธ/์ด๋ฏธ์ง€ ์งˆ๋ฌธ
/์‹ ์ด์‹œ์—ฌ ํ…์ŠคํŠธ์™€ ์ด๋ฏธ์ง€ ๊ธฐ๋ฐ˜ ์งˆ๋ฌธ
/๊ฒ€์ƒ‰ ํ…์ŠคํŠธ์™€ ์„ ํƒ ์ด๋ฏธ์ง€ ๋‹จ์„œ๋ฅผ ์ด์šฉํ•œ ์›น ๊ฒ€์ƒ‰
/๋Œ€ํ™”์š”์•ฝ ์ตœ๊ทผ ์ฑ„ํŒ…๊ณผ ์ตœ๊ทผ ์ด๋ฏธ์ง€ ์ตœ๋Œ€ 4์žฅ ์š”์•ฝ
/๋ฒˆ์—ญ ์ž…๋ ฅ ํ…์ŠคํŠธ/์ด๋ฏธ์ง€ ๋˜๋Š” ์ตœ๊ทผ ๋ฉ”์‹œ์ง€ ๋ฒˆ์—ญ
/ํ•ด์„ ์ž…๋ ฅ ํ…์ŠคํŠธ/์ด๋ฏธ์ง€ ๋˜๋Š” ์ตœ๊ทผ ๋ฉ”์‹œ์ง€์™€ ๊ฐ€๊นŒ์šด ์ฃผ๋ณ€ ์ด๋ฏธ์ง€ ์ตœ๋Œ€ 4์žฅ์˜ ์ˆ˜์น˜, ๊ณ„์‚ฐ, ๋ฐˆ ํ›„๋ณด ๊ฒ€์ƒ‰ ํ•ด์„
/์„ค๋ช… ์ž…๋ ฅ ํ…์ŠคํŠธ/์ด๋ฏธ์ง€ ๋˜๋Š” ์ตœ๊ทผ ๋ฉ”์‹œ์ง€์™€ ๊ฐ€๊นŒ์šด ์ฃผ๋ณ€ ์ด๋ฏธ์ง€ ์ตœ๋Œ€ 4์žฅ ์„ค๋ช…
/๋ญ๋จน์ง€ ์ €์žฅ ํ”„๋กฌํ”„ํŠธ์™€ gpt-6-luna๋กœ ์„ธ๊ณ„ ์Œ์‹ ๋ฉ”๋‰ด ํ•˜๋‚˜ ์ถ”์ฒœ, ์Œ์‹ ๋ฌธํ™”๊ถŒ ์ˆœํ™˜๊ณผ ์ตœ๊ทผ 20๊ฐœ ๋ฉ”๋‰ด ๋ฐ˜๋ณต ๋ฐฉ์ง€ (์žฌ์‹œ์ž‘ ์‹œ ์ดˆ๊ธฐํ™”)
์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด ๋ฉ”์‹œ์ง€ ๋ฒˆ์—ญ ์„ ํƒ ๋ฉ”์‹œ์ง€ ๋ฒˆ์—ญ
์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด ๋ฉ”์‹œ์ง€ ํ•ด์„ ์„ ํƒ ๋ฉ”์‹œ์ง€ ํ•ด์„
์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด ๋ฉ”์‹œ์ง€ ์„ค๋ช… ์„ ํƒ ๋ฉ”์‹œ์ง€ ์„ค๋ช…

OpenAI ํ˜ธ์ถœ์€ api/chatGPT.py์—์„œ ๊ฐ์‹ธ๋ฉฐ, hosted prompt payload๋Š” common/openai_prompt.py์˜ helper๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. OpenAI SDK ์˜ˆ์™ธ๋Š” OpenAIModelError๋กœ ๋งคํ•‘ํ•ด ์‚ฌ์šฉ์ž์—๊ฒŒ ์•ˆ์ „ํ•œ ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

์Œ์„ฑ ๋Œ€ํ™”

๋ช…๋ น์–ด ์„ค๋ช…
/๋Œ€ํ™” ์Œ์„ฑ ์ฑ„๋„์— ์ฐธ์—ฌํ•ด ์‹ค์‹œ๊ฐ„ ์Œ์„ฑ ๋Œ€ํ™” ์‹œ์ž‘
/๋Œ€ํ™”์ข…๋ฃŒ ์Œ์„ฑ ๋Œ€ํ™” ์ข…๋ฃŒ ๋ฐ ํ‡ด์žฅ

์Œ์„ฑ ์ฒ˜๋ฆฌ๋Š” discord-ext-voice-recv Opus sink์—์„œ Discord DAVE payload๋ฅผ ๋จผ์ € ํ•ด๋…ํ•œ ๋’ค ์‚ฌ์šฉ์ž๋ณ„ Opus decoder๋กœ PCM์„ ๋งŒ๋“ค๊ณ , silence detection, faster-whisper STT, pyttsx3 TTS ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์†์ƒ๋œ ์Œ์„ฑ frame์€ ํ•ด๋‹น ์‚ฌ์šฉ์ž decoder์—์„œ๋งŒ ํ๊ธฐํ•˜๋ฏ€๋กœ ์ „์ฒด ์ˆ˜์‹  loop๋ฅผ ์ค‘๋‹จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Windows ๋กœ์ปฌ ์‹คํ–‰์—์„œ๋Š” bin/ ๋˜๋Š” PATH์˜ ffmpeg๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. STT๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ tiny ๋ชจ๋ธ์„ CPU int8๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. CUDA ๋ชจ๋ธ์€ GPU ๋Ÿฐํƒ€์ž„์„ ์‹ค์ œ๋กœ ์ค€๋น„ํ•œ ํ™˜๊ฒฝ์—์„œ๋งŒ VOICE_CHAT_WHISPER_DEVICE=cuda์™€ ๋ชจ๋ธ ๋ฐ ์—ฐ์‚ฐ ํ˜•์‹์„ ๋ช…์‹œํ•ด ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

YouTube

๋ช…๋ น์–ด/๊ธฐ๋Šฅ ์„ค๋ช…
/์š”์•ฝ ์ตœ๊ทผ ๋ฉ”์‹œ์ง€์˜ YouTube ๋งํฌ 10๊ฐœ๋ฅผ ์„ ํƒํ•ด ์˜์ƒ/๋Œ“๊ธ€/๊ฒŒ์‹œ๋ฌผ ์š”์•ฝ
์ปจํ…์ŠคํŠธ ๋ฉ”๋‰ด ์œ ํŠœ๋ธŒ ์š”์•ฝ ์„ ํƒ ๋ฉ”์‹œ์ง€์˜ YouTube ๋งํฌ ์š”์•ฝ
/์œ ํŠœ๋ธŒ๊ตฌ๋… ์ถ”๊ฐ€ ์ฑ„๋„ URL, ID, @handle, ๊ฒ€์ƒ‰์–ด๋กœ ๊ตฌ๋… ์ถ”๊ฐ€
/์œ ํŠœ๋ธŒ๊ตฌ๋… ์•Œ๋ฆผ์„ค์ • ๊ตฌ๋…๋ณ„ ๋ผ์ด๋ธŒ/์˜์ƒ/์ปค๋ฎค๋‹ˆํ‹ฐ ์•Œ๋ฆผ on/off
/์œ ํŠœ๋ธŒ๊ตฌ๋… ์‚ญ์ œ ๊ตฌ๋… ๋ชฉ๋ก์—์„œ ์„ ํƒ ์‚ญ์ œ
/์œ ํŠœ๋ธŒ๊ตฌ๋… ๋ชฉ๋ก ์„œ๋ฒ„์˜ YouTube ๊ตฌ๋… ๋ชฉ๋ก ํ™•์ธ

YouTube ์š”์•ฝ์€ ์ž๋ง‰์„ ์šฐ์„  ์‚ฌ์šฉํ•˜๊ณ , ํ•„์š” ์‹œ ์˜ค๋””์˜ค๋ฅผ MP3๋กœ ๋ณ€ํ™˜ํ•ด STT ํ›„ ์š”์•ฝํ•ฉ๋‹ˆ๋‹ค. ๋Œ“๊ธ€์€ ์ตœ๋Œ€ 40๊ฐœ๋ฅผ ์š”์•ฝํ•ฉ๋‹ˆ๋‹ค. ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œ๋ฌผ์€ direct post URL๊ณผ channel posts page๋ฅผ ํŒŒ์‹ฑํ•ฉ๋‹ˆ๋‹ค.

YouTube ์•Œ๋ฆผ์€ ๋‹ค์Œ ๊ฒฝ๋กœ๋ฅผ ์กฐํ•ฉํ•ฉ๋‹ˆ๋‹ค.

  • WebSub Atom callback ์ˆ˜์‹ 
  • YouTube Data API videos.list๋กœ live/upcoming/upload/shorts ๋ถ„๋ฅ˜
  • Atom feed fallback polling
  • ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œ๋ฌผ 10๋ถ„ polling
  • WebSub ๊ตฌ๋… 12์‹œ๊ฐ„ ์ฃผ๊ธฐ ๊ฐฑ์‹ 

MapleStory

๋ช…๋ น์–ด/๊ธฐ๋Šฅ ์„ค๋ช…
/์ฌ๋ฐ์ด๋ฉ”์ดํ”Œ ์ง„ํ–‰ ์ค‘์ธ ์ŠคํŽ˜์…œ ์ฌ๋ฐ์ด ๋ฉ”์ดํ”Œ ์ด๋ฒคํŠธ ์ด๋ฏธ์ง€ ์กฐํšŒ
/๋ฉ”์ดํ”Œ๊ณต์ง€๊ตฌ๋… ํ˜„์žฌ ์ฑ„๋„์— ๋ฉ”์ดํ”Œ์Šคํ† ๋ฆฌ ๊ณต์ง€ ์•Œ๋ฆผ ๊ตฌ๋…/ํ•ด์ œ

๋กœ์ŠคํŠธ์•„ํฌ

๋ช…๋ น์–ด ์„ค๋ช…
/๋กœ์•„๊ณต์ง€๊ตฌ๋… [์ƒํƒœ] ๊ด€๋ฆฌ์ž๊ฐ€ ํ˜„์žฌ ์ฑ„๋„์— ๋กœ์ŠคํŠธ์•„ํฌ ๊ณต์ง€ ์•Œ๋ฆผ์„ ๊ตฌ๋…/ํ•ด์ œ
  • /์ฑ„๋„์„ค์ • ๊ธฐ๋Šฅ:๋กœ์•„๊ณต์ง€์—์„œ๋„ ๊ฐ™์€ ์•Œ๋ฆผ ์ฑ„๋„์„ ์ง€์ •ํ•˜๊ฑฐ๋‚˜ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. /์ฑ„๋„์„ค์ •ํ™•์ธ์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๊ณต์‹ ๊ณต์ง€ ๋ชฉ๋ก์„ 3๋ถ„๋งˆ๋‹ค ํ™•์ธํ•˜๋ฉฐ, ์ œ๋ชฉ๊ณผ ๋ณธ๋ฌธ ๋ณ€๊ฒฝ๋„ ๊ฐ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ์ตœ์ดˆ ๊ตฌ๋…๊ณผ ์ฑ„๋„ ๋ณ€๊ฒฝ ์‹œ ๊ธฐ์กด ๊ณต์ง€๋Š” ๊ธฐ์ค€ ์ƒํƒœ๋กœ ์ €์žฅํ•˜๋ฉฐ ๊ณผ๊ฑฐ ๊ธ€์„ ์ „์†กํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋ฉ”์ดํ”Œ ๊ณต์ง€์™€ ๊ฐ™์€ 3~4์ค„ AI ์š”์•ฝ ์ž„๋ฒ ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ, ์š”์•ฝ ์‹คํŒจ ์‹œ ์›๋ฌธ ๊ธฐ๋ฐ˜ ์š”์•ฝ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋ฏธ ์ „์†กํ•œ ๊ธ€์ด ์ˆ˜์ •๋˜๋ฉด ๊ธฐ์กด ๋ฉ”์‹œ์ง€๋ฅผ ๊ฐฑ์‹ ํ•ฉ๋‹ˆ๋‹ค. ๋™์ผ ๊ธ€์˜ ์ ๊ฒ€ ์—ฐ์žฅ๊ณผ ์™„๋ฃŒ ์ฒ˜๋ฆฌ๋Š” ๋ฉ”์ดํ”Œ ๊ณต์ง€ ์ „์†ก ๋กœ์ง์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.
  • ์ˆ˜์ง‘๊ณผ ๊ตฌ๋… ์ƒํƒœ๋Š” util/lostark/notices.py์—์„œ ๊ด€๋ฆฌํ•˜๋ฉฐ DB์˜ lostarkNoticeState์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

๊ณต์ง€ ์•Œ๋ฆผ์€ 3๋ถ„๋งˆ๋‹ค ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ ์ ๊ฒ€ ๊ณต์ง€๋Š” ์ƒˆ ๋ฉ”์‹œ์ง€๋กœ ๋ณด๋‚ด๊ณ , ์ผ๋ฐ˜ ์ˆ˜์ •์€ ๊ธฐ์กด ๋ฉ”์‹œ์ง€๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ์—ฐ์žฅ ๊ณต์ง€๋Š” ๋ณ„๋„ ๋ฉ”์‹œ์ง€๋กœ ์•Œ๋ฆฌ๊ณ , ์ ๊ฒ€ ์™„๋ฃŒ ๊ณต์ง€๊ฐ€ ๋‚˜์˜ค๋ฉด ์ด์ „ ์ ๊ฒ€ ๊ด€๋ จ ๋ฉ”์‹œ์ง€๋ฅผ ์ •๋ฆฌํ•œ ๋’ค ์™„๋ฃŒ ๊ณต์ง€๋ฅผ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

Codex ๋ฆฌ์…‹

๋ช…๋ น์–ด/๊ธฐ๋Šฅ ์„ค๋ช…
/์ฝ”๋ฑ์Šค๋ฆฌ์…‹์•Œ๋ฆผ ํ˜„์žฌ ์ฑ„๋„์— Codex ์‚ฌ์šฉ๋Ÿ‰ ๋ฆฌ์…‹ ์•Œ๋ฆผ ์„ค์ •/ํ•ด์ œ

codex-resets.com์ด ์ œ๊ณตํ•˜๋Š” ๊ณต๊ฐœ API์˜ /api/v1/resets๋ฅผ 3๋ถ„๋งˆ๋‹ค ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ตœ์‹  100๊ฑด ์ค‘ ์ƒˆ ์ผ๋ฐ˜ ๋ฆฌ์…‹๊ณผ ์ ๋ฆฝํ˜• ๋ฆฌ์…‹์„ ์•Œ๋ฆฌ๋ฉฐ, X ๊ฒŒ์‹œ๋ฌผ ์—†์ด ๊ด€์ธก๋œ ๋ฆฌ์…‹๋„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์ • ๋ฆฌ์…‹๊ณผ ๋ฆฌ์…‹ ๊ฐ€๋Šฅ์„ฑ ์˜ˆ์ธก์€ ์•Œ๋ฆผ ๋Œ€์ƒ์—์„œ ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค. ์ด ์‚ฌ์ดํŠธ๋Š” OpenAI ๊ณต์‹ ์„œ๋น„์Šค๊ฐ€ ์•„๋‹Œ ๋น„๊ณต์‹ ์ถ”์ ๊ธฐ์ž…๋‹ˆ๋‹ค.

์‹ค์‹œ๊ฐ„ ์ง€์ง„ ์•Œ๋ฆผ

๋ช…๋ น์–ด/๊ธฐ๋Šฅ ์„ค๋ช…
/์ง€์ง„์•Œ๋ฆผ ํ˜„์žฌ ์ฑ„๋„์— ์ผ๋ณธ M5.9 ์ด์ƒ, ํ•œ๊ตญ M5.0 ์ด์ƒ, ๊ธฐํƒ€ ๊ตญ๊ฐ€ M6.5 ์ด์ƒ ์ง€์ง„ ์•Œ๋ฆผ ์„ค์ •/ํ•ด์ œ
/์ฑ„๋„์„ค์ • ๊ธฐ๋Šฅ:์ง€์ง„์•Œ๋ฆผ ์ง€์ •ํ•œ ์ฑ„๋„์— ์ง€์ง„ ์•Œ๋ฆผ ์„ค์ •/ํ•ด์ œ

/์ง€์ง„์•Œ๋ฆผ ์ƒํƒœ:true๋กœ ์‹คํ–‰ํ•œ ํ˜„์žฌ ์ฑ„๋„์ด๋‚˜ /์ฑ„๋„์„ค์ • ๊ธฐ๋Šฅ:์ง€์ง„์•Œ๋ฆผ ์ฑ„๋„:#์•Œ๋ฆผ์ฑ„๋„๋กœ ์ง€์ •ํ•œ ์ฑ„๋„์— ์•Œ๋ฆผ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๋‘ ๋ช…๋ น์–ด๋Š” ๊ฐ™์€ earthquake_alert ์„ค์ •์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋Œ€์ƒ ์ •๋ณด ์ถœ์ฒ˜ Discord ์ „์†ก ๊ธฐ์ค€ @everyone ๊ธฐ์ค€
์ผ๋ณธ Wolfx JMA ๊ธด๊ธ‰์ง€์ง„์†๋ณด M5.9 ์ด์ƒ M7.0 ์ด์ƒ
ํ•œ๊ตญ ๋ฐ ํ•œ๋ฐ˜๋„ ์ธ์ ‘ ํ•ด์—ญ EMSC/CSEM M5.0 ์ด์ƒ M5.5 ์ด์ƒ
์ผ๋ณธ๊ณผ ํ•œ๊ตญ์„ ์ œ์™ธํ•œ ๊ตญ๊ฐ€ EMSC/CSEM M6.5 ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Œ

์ผ๋ณธ์€ Wolfx์˜ JMA ๊ธด๊ธ‰์ง€์ง„์†๋ณด WebSocket์— ์ƒ์‹œ ์—ฐ๊ฒฐํ•ด ์ผ๋ณธ ๊ธฐ์ƒ์ฒญ์ด ๋ฐœํ‘œํ•œ M5.9 ์ด์ƒ ์˜ˆ๋ณด์™€ ๊ฒฝ๋ณด๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ์ง„์›์ง€์™€ ์˜ˆ์ƒ ์ง€์—ญ์˜ ์ผ๋ณธ์–ด๋Š” ๋ณ„๋„ ํ‚ค๊ฐ€ ํ•„์š” ์—†๋Š” Google ๋ฒˆ์—ญ์œผ๋กœ ๋ณ€ํ™˜ํ•ด ์ผ๋ณธ์–ด(ํ•œ๊ตญ์–ด) ํ˜•์‹์œผ๋กœ ํ‘œ์‹œํ•˜๋ฉฐ, ๋ฒˆ์—ญ ์š”์ฒญ์ด ์‹คํŒจํ•˜๋ฉด ์›๋ฌธ์œผ๋กœ ์•Œ๋ฆผ์„ ๊ณ„์† ๋ณด๋ƒ…๋‹ˆ๋‹ค. ๊ฐ™์€ ์ง€์ง„์˜ ํ›„์†๋ณด์™€ ์ตœ์ข…๋ณด๋Š” ๊ธฐ์กด Discord ๋ฉ”์‹œ์ง€์™€ ์ง€๋„ ์œ„์น˜๋ฅผ ์ˆ˜์ •ํ•˜๋ฉฐ ์ทจ์†Œ๋ณด๋„ ๋ฐ˜์˜ํ•ฉ๋‹ˆ๋‹ค. ํ›ˆ๋ จ๋ณด์™€ 2๋ถ„ ์ด์ƒ ์ง€๋‚œ ์ดˆ๊ธฐ ์Šค๋ƒ…์ƒท์€ ์•Œ๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ผ๋ณธ ์™ธ ์ „ ์„ธ๊ณ„๋Š” EMSC/CSEM Standing Order WebSocket์— ์ƒ์‹œ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. ํ•œ๊ตญ์€ ์ง€์—ญ๋ช…๊ณผ ํ•œ๋ฐ˜๋„ ์ขŒํ‘œ ๋ฒ”์œ„๋กœ ํŒ๋ณ„ํ•ด M5.0 ์ด์ƒ๋ถ€ํ„ฐ, ๊ทธ ๋ฐ–์˜ ๊ตญ๊ฐ€๋Š” M6.5 ์ด์ƒ๋ถ€ํ„ฐ ๊ทผ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. EMSC์˜ unid์™€ ๊ฐฑ์‹  ์‹œ๊ฐ์œผ๋กœ ์‹ ๊ทœ, ์ˆ˜์ •, ์‚ญ์ œ ์ •๋ณด๋ฅผ ๊ฐ™์€ Discord ๋ฉ”์‹œ์ง€์— ๋ฐ˜์˜ํ•˜๋ฉฐ ์ผ๋ณธ ์ง€์—ญ์€ JMA ์•Œ๋ฆผ๊ณผ์˜ ์ค‘๋ณต์„ ๋ง‰๊ธฐ ์œ„ํ•ด ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค. ์—ฐ๊ฒฐ์ด ๋Š๊ฒผ๋‹ค๊ฐ€ ๋ณต๊ตฌ๋˜๋ฉด ์ตœ๊ทผ 10๋ถ„ ๋™์•ˆ ๊ฐฑ์‹ ๋œ M5.0 ์ด์ƒ ์ž๋ฃŒ๋ฅผ ์กฐํšŒํ•œ ๋’ค ์ง€์—ญ๋ณ„ ๊ธฐ์ค€์„ ์ ์šฉํ•ด ๋ˆ„๋ฝ์„ ๋ณด์™„ํ•˜์ง€๋งŒ ์ตœ์ดˆ ์‹คํ–‰ ๋•Œ ๊ณผ๊ฑฐ ์ง€์ง„์€ ์žฌ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. EMSC๋Š” ์กฐ๊ธฐ๊ฒฝ๋ณด๊ฐ€ ์•„๋‹ˆ๋ผ ๊ด€์ธก ํ›„ ์ž๋™ ๋ถ„์„๋˜๋Š” ์˜ˆ๋น„ ์ •๋ณด์ด๋ฉฐ ์›์ž๋ฃŒ ๊ธฐ๊ด€๊ณผ EMSC/CSEM์„ ์ž„๋ฒ ๋“œ ํ•˜๋‹จ์— ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

@everyone์€ ์ผ๋ณธ ์ง€์ง„ M7.0 ์ด์ƒ๊ณผ ํ•œ๊ตญ ์ง€์ง„ M5.5 ์ด์ƒ์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ์ง€์ง„์—์„œ๋Š” ํ•œ ๋ฒˆ๋งŒ ๋ฉ˜์…˜ํ•˜๋ฉฐ, ์ผ๋ฐ˜ ์•Œ๋ฆผ์„ ๋ณด๋‚ธ ๋’ค ํ›„์† ์ •๋ณด์—์„œ ์ฒ˜์Œ ๋ฉ˜์…˜ ๊ธฐ์ค€ ์ด์ƒ์œผ๋กœ ์ƒํ–ฅ๋˜๋ฉด ๋ฉ˜์…˜์ด ํฌํ•จ๋œ ์ƒˆ ๋ฉ”์‹œ์ง€๋กœ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๋ฐ–์˜ ๊ตญ๊ฐ€์—์„œ ๋ฐœ์ƒํ•œ EMSC ์ง€์ง„์€ ๊ทœ๋ชจ์™€ ๊ด€๊ณ„์—†์ด ๋ฉ˜์…˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฉ˜์…˜์„ ๋ณด๋‚ด๋ ค๋ฉด ๋ด‡์— ๋Œ€์ƒ ์ฑ„๋„์˜ @everyone, @here, ๋ชจ๋“  ์—ญํ•  ๋ฉ˜์…˜ ๊ถŒํ•œ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Discord ์ž„๋ฒ ๋“œ๋Š” ๋‘ ์†Œ์Šค ๋ชจ๋‘ ๊ทœ๋ชจ, ๊นŠ์ด, ์ตœ๋Œ€ ์˜ˆ์ƒ ์ง„๋„์™€ ๋ฐœํ‘œ ๋‹จ๊ณ„, ๋ฐœํ‘œ ์‹œ๊ฐ, ๋ฐœ์ƒ ์ถ”์ • ์‹œ๊ฐ์„ ๊ฐ๊ฐ 3์—ด ํ–‰์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. EMSC๋Š” ์˜ˆ์ƒ ์ง„๋„๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š์•„ ์ œ๊ณต ์•ˆ ํ•จ์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์ถ”์ • ์ง„์›์€ OpenStreetMap ์ง€๋„ ์ด๋ฏธ์ง€์™€ ํฌ๊ฒŒ ๋ณด๊ธฐ ๋งํฌ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์™ผ์ชฝ ํ…Œ๋‘๋ฆฌ๋Š” ๊ทœ๋ชจ M3.0 ์ด์ƒ ์ดˆ๋ก, M4.0 ์ด์ƒ ๋…ธ๋ž‘, M5.0 ์ด์ƒ ์ฃผํ™ฉ, M6.0 ์ด์ƒ ๋นจ๊ฐ•์ด๋ฉฐ ์ทจ์†Œ ๋˜๋Š” ์‚ญ์ œ ์ •๋ณด์™€ ๊ทœ๋ชจ ๋ฏธ์ƒ์€ ํšŒ์ƒ‰์ž…๋‹ˆ๋‹ค.

Wolfx๋Š” ์ผ๋ณธ ๊ธฐ์ƒ์ฒญ๊ณผ ๊ด€๊ณ„์—†๋Š” ๋น„๊ณต์‹ ์ค‘๊ณ„ ์„œ๋น„์Šค์ด๋ฉฐ EMSC/CSEM์€ ์—ฌ๋Ÿฌ ๊ด€์ธก๊ธฐ๊ด€์˜ ์ž๋ฃŒ๋ฅผ ์ˆ˜์ง‘ํ•˜๋Š” ๋น„์ •๋ถ€ ๋น„์˜๋ฆฌ ๊ธฐ๊ด€์ž…๋‹ˆ๋‹ค. EMSC ์ž๋ฃŒ๋Š” ์ด์šฉ ์กฐ๊ฑด์— ๋”ฐ๋ผ ์ถœ์ฒ˜๋ฅผ ํ‘œ์‹œํ•˜๋ฉฐ ์ƒ์—…์  ์‚ฌ์šฉ ์ „ ๋ณ„๋„ ํ—ˆ๊ฐ€ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์†๋ณด์˜ ๊ทœ๋ชจ, ์ง„์›, ์˜ˆ์ƒ ์ง„๋„๋Š” ํ›„์† ์ •๋ณด์—์„œ ๋ฐ”๋€Œ๊ฑฐ๋‚˜ ์ทจ์†Œ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ˜„์ง€ ๊ณต์‹ ์žฌ๋‚œ ์•Œ๋ฆผ์„ ์šฐ์„  ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฒŒ์ž„/๋žญํฌ/ํˆฌํ‘œ

๋ช…๋ น์–ด ์„ค๋ช…
/๋‚ด์ „ ๊ฐ™์€ ์Œ์„ฑ๋ฐฉ์—์„œ ๋ฒ„ํŠผ์œผ๋กœ 10๋ช…์„ ๋ชจ์ง‘ํ•œ ๋’ค LoL ๋‚ด์ „ ํŒ€/ํฌ์ง€์…˜ ์ž๋™ ๋ฐฐ์ •
/์†”๋žญ Riot ID ๊ธฐ๋ฐ˜ ์†”๋กœ ๋žญํฌ ์กฐํšŒ
/์ž๋žญ Riot ID ๊ธฐ๋ฐ˜ ์ž์œ  ๋žญํฌ ์กฐํšŒ
/์ผ์ผ๋žญํฌ ์ž์ • ์†”๋žญ ์กฐํšŒ ๋Œ€์ƒ ํ™•์ธ
/์ผ์ผ๋žญํฌ๋ณ€๊ฒฝ ์ž์ • ์†”๋žญ ์กฐํšŒ ๋Œ€์ƒ ๋ณ€๊ฒฝ
/์ผ์ผ๋žญํฌ๋ฃจํ”„ ์ž์ • ๋žญํฌ ๋ฃจํ”„ on/off
/ํˆฌํ‘œ ์ฝค๋งˆ ๊ตฌ๋ถ„ ํ•ญ๋ชฉ๊ณผ ์ฐธ์—ฌ ์ธ์›์œผ๋กœ ๋ฒ„ํŠผ ํˆฌํ‘œ ์ง„ํ–‰

/๋‚ด์ „์€ ๋ช…๋ น์„ ์‹คํ–‰ํ•œ ์‚ฌ์šฉ์ž๊ฐ€ ์ฐธ๊ฐ€ ์ค‘์ธ ์Œ์„ฑ๋ฐฉ์„ ๊ธฐ์ค€์œผ๋กœ 10๋ถ„ ๋™์•ˆ ๋ชจ์ง‘ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ์Œ์„ฑ๋ฐฉ์˜ ์‚ฌ์šฉ์ž๋งŒ ์ฐธ๊ฐ€ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ฐธ๊ฐ€์ž๊ฐ€ ์Œ์„ฑ๋ฐฉ์„ ๋‚˜๊ฐ€๋ฉด ๋ช…๋‹จ์—์„œ ์ž๋™์œผ๋กœ ์ œ์™ธ๋ฉ๋‹ˆ๋‹ค. 10๋ช…์ด ๋ชจ์ด๋ฉด ์ฐธ๊ฐ€ ์ˆœ์„œ์™€ ๊ด€๊ณ„์—†์ด ๋ ˆ๋“œํŒ€๊ณผ ๋ธ”๋ฃจํŒ€์˜ 5๊ฐœ ํฌ์ง€์…˜์„ ๋ฌด์ž‘์œ„๋กœ ๋ฐฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ์ง‘์ž์™€ ์„œ๋ฒ„ ๊ด€๋ฆฌ์ž๋Š” ์™„๋ฃŒ ์ „์— ๋ชจ์ง‘์„ ์ทจ์†Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋„๋ฐ•

๋„๋ฐ• ๋ช…๋ น์€ /์ฑ„๋„์„ค์ • ๊ธฐ๋Šฅ:๋„๋ฐ•์œผ๋กœ ์ง€์ •ํ•œ ์ฑ„๋„์—์„œ๋งŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ช…๋ น์–ด ์„ค๋ช…
/๋ฟŒ๋ฆฌ๊ธฐ ์ง€์ • ๊ธˆ์•ก์„ ์ง€์ • ์ธ์›์—๊ฒŒ ์„ ์ฐฉ์ˆœ ๋žœ๋ค ๋ถ„๋ฐฐ
/๋ˆ์ค˜ ํ•˜๋ฃจ 1ํšŒ 10,000์› ์ง€๊ธ‰
/์ž”์•ก ๋ณด์œ  ๊ธˆ์•ก ํ™•์ธ
/์ˆœ์œ„ ๊ธธ๋“œ ๋‚ด ๋ณด์œ  ๊ธˆ์•ก ์ˆœ์œ„
/์†ก๊ธˆ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์—๊ฒŒ ์†ก๊ธˆ
/๊ฐ€์œ„๋ฐ”์œ„๋ณด ์Šน๋ฆฌ 2๋ฐฐ, ๋ฌด์Šน๋ถ€ ์ ˆ๋ฐ˜, ํŒจ๋ฐฐ ์†์‹ค
/๋„๋ฐ• 30-70% ๋žœ๋ค ํ™•๋ฅ , ์„ฑ๊ณต ์‹œ 2๋ฐฐ
/์ฆ‰์„๋ณต๊ถŒ 300์› ๋ณต๊ถŒ ๊ตฌ๋งค
/์‚ฌ๋‹ค๋ฆฌ 3๊ฐœ ์‚ฌ๋‹ค๋ฆฌ ์ค‘ 1๊ฐœ ๋‹น์ฒจ ์„ ํƒ
/์Šฌ๋กฏ 3๊ฐœ ์Šฌ๋กฏ ์ผ์น˜ ์‹œ ๋ฐฐ๋‹น
/๋ธ”๋ž™์žญ Hit/Stand/Double, ๋ธ”๋ž™์žญ 1.5๋ฐฐ ์ถ”๊ฐ€ ๋ฐฐ๋‹น

์Œ์•…

์Œ์•… ๋ช…๋ น์€ /์ฑ„๋„์„ค์ • ๊ธฐ๋Šฅ:์Œ์•…์œผ๋กœ ์ฑ„๋„์„ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ช…๋ น์–ด ์„ค๋ช…
/์Œ์•… ์žฌ์ƒ ์ƒํƒœ์™€ ๋ฒ„ํŠผ ํŒจ๋„ ํ‘œ์‹œ
/์žฌ์ƒ YouTube URL ๋˜๋Š” ๊ฒ€์ƒ‰์–ด ์žฌ์ƒ
/์ผ์‹œ์ •์ง€ ํ˜„์žฌ ๊ณก ์ผ์‹œ์ •์ง€
/๋‹ค์‹œ์žฌ์ƒ ์ผ์‹œ์ •์ง€๋œ ๊ณก ์žฌ๊ฐœ
/์ •์ง€ ์žฌ์ƒ ์ •์ง€ ๋ฐ ์Œ์„ฑ ์ฑ„๋„ ํ‡ด์žฅ
/์Šคํ‚ต ํ˜„์žฌ ๊ณก ๊ฑด๋„ˆ๋›ฐ๊ธฐ
/๋Œ€๊ธฐ์—ด ํ˜„์žฌ ๋Œ€๊ธฐ์—ด ์กฐํšŒ
/๊ตฌ๊ฐ„์ด๋™ ์žฌ์ƒ ์œ„์น˜ ์ด๋™
/๋ฐ˜๋ณต ๋ฐ˜๋ณต ๋ชจ๋“œ on/off
/๋Œ€๊ธฐ์—ด์‚ญ์ œ ์ง€์ • ๋ฒˆํ˜ธ์˜ ๋Œ€๊ธฐ์—ด ํ•ญ๋ชฉ ์‚ญ์ œ
/๋Œ€๊ธฐ์—ด๋น„์šฐ๊ธฐ ๋Œ€๊ธฐ์—ด ์ „์ฒด ๋น„์šฐ๊ธฐ
/๋Œ€๊ธฐ์—ด์ด๋™ ๋Œ€๊ธฐ์—ด ์ˆœ์„œ ๋ณ€๊ฒฝ
/์…”ํ”Œ ๋Œ€๊ธฐ์—ด ๋ฌด์ž‘์œ„ ์„ž๊ธฐ

ํŒŒํ‹ฐ

๋ช…๋ น์–ด ์„ค๋ช…
/ํŒŒํ‹ฐ ํ˜„์žฌ ์ƒ์„ฑ๋œ ํŒŒํ‹ฐ ๋ชฉ๋ก ์กฐํšŒ
/ํŒŒํ‹ฐ์ƒ์„ฑ ๋น„๊ณต๊ฐœ ์นดํ…Œ๊ณ ๋ฆฌ/ํ…์ŠคํŠธ/์Œ์„ฑ ์ฑ„๋„ ์ƒ์„ฑ
/ํŒŒํ‹ฐ์ดˆ๋Œ€ ํŒŒํ‹ฐ์™€ ์œ ์ €๋ฅผ ์„ ํƒํ•ด ์ดˆ๋Œ€
/ํŒŒํ‹ฐ์ฐธ๊ฐ€ ํŒŒํ‹ฐ ์ฐธ๊ฐ€
/ํŒŒํ‹ฐ์› ํŒŒํ‹ฐ ๋ฉค๋ฒ„ ๋ชฉ๋ก ์กฐํšŒ
/ํŒŒํ‹ฐํƒˆํ‡ด ํŒŒํ‹ฐ ๊ถŒํ•œ ํ•ด์ œ
/ํŒŒํ‹ฐํ•ด์ œ ํŒŒํ‹ฐ ์‚ญ์ œ

๊ฒฝ์ œ ์ง€ํ‘œ

๋ช…๋ น์–ด ์„ค๋ช…
/ํ™˜์œจ ํ•œ๊ตญ์€ํ–‰ ECOS ๊ธฐ์ค€ ์ตœ์‹  ํ™˜์œจ๊ณผ ๊ธฐ๋ณธ 30์ผ ๊ทธ๋ž˜ํ”„, ์ตœ๋Œ€ 365์ผ
/์™ธํ™˜๋ณด์œ ์•ก ํ•œ๊ตญ์€ํ–‰ ECOS ๊ธฐ์ค€ ์ตœ์‹  ์™ธํ™˜๋ณด์œ ์•ก๊ณผ ๊ธฐ๋ณธ 12๊ฐœ์›” ๊ทธ๋ž˜ํ”„, ์ตœ๋Œ€ 60๊ฐœ์›”

๋ฉ”์‹œ์ง€ listener ๊ธฐ๋Šฅ

  • ๋‹จ์ผ ์ปค์Šคํ…€ ์ด๋ชจ์ง€ ์ž…๋ ฅ ์‹œ ์›๋ณธ ํฌ๊ธฐ ์ด๋ฏธ์ง€ ์ถœ๋ ฅ
  • ์ผ๋ฐ˜ ๋ฉ”์‹œ์ง€๋ฅผ USER_MESSAGES์— ์บ์‹œํ•ด AI ์ปจํ…์ŠคํŠธ๋กœ ์‚ฌ์šฉ
  • ๋ฉ”์‹œ์ง€ ๋‚ด YouTube ๋งํฌ ๊ฐ์ง€ ํ›„ ์š”์•ฝ UI ์ œ๊ณต
  • ํŠน์ • ์ฑ„๋„์˜ 1557 ๊ฐ์ง€ ๋ฐ ์ฃผ๊ฐ„ ๋ฆฌํฌํŠธ ์ง‘๊ณ„

๋ฐฑ๊ทธ๋ผ์šด๋“œ ์ž‘์—…

์ฃผ๊ธฐ ์ž‘์—…
60์ดˆ Discord presence ๊ฐฑ์‹ 
๋งค์ผ 00:00 KST ์ตœ๊ทผ ๋ฉ”์‹œ์ง€ ์žฌ๋กœ๋”ฉ, ๊ธฐ๋…์ผ/DDAY/์ฌ๋ฐ์ด๋ฉ”์ดํ”Œ refresh
๋งค์ผ 00:01 KST ์ฃผ๊ฐ„ 1557 ๋ฆฌํฌํŠธ ์กฐ๊ฑด ํ™•์ธ
60์ดˆ YouTube WebSub/Atom feed ํ›„๋ณด ํ™•์ธ
10๋ถ„ YouTube ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ฒŒ์‹œ๋ฌผ polling
3๋ถ„ MapleStory ๊ณต์ง€ polling
3๋ถ„ ๋กœ์ŠคํŠธ์•„ํฌ ๊ณต์ง€ polling
12์‹œ๊ฐ„ YouTube WebSub ๊ตฌ๋… ๊ฐฑ์‹ 
30์ดˆ ์˜ˆ์•ฝ ๋ฉ”์‹œ์ง€ ๋ฐœ์†ก ํ™•์ธ

HTTP API

cogs/status_api๊ฐ€ aiohttp.web ์„œ๋ฒ„๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ํฌํŠธ๋Š” 1557์ด๋ฉฐ API_PORT๋กœ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Method Path ์„ค๋ช…
GET / ๊ฐ„๋‹จํ•œ ์ƒํƒœ ๋ฌธ์ž์—ด
GET /health bot readiness, latency, uptime, guild/user/message count, schema version
POST /celebration/update ๊ธฐ๋…์ผ ๊ณต์ง€ ์ˆ˜๋™ ๊ฐฑ์‹ 
GET /youtube/websub YouTube WebSub challenge ๊ฒ€์ฆ
POST /youtube/websub YouTube Atom notification ์ˆ˜์‹ 

/celebration/update๋Š” X-API-Key: <CELEBRATION_UPDATE_API_KEY> ํ—ค๋”๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. JSON body ๋˜๋Š” query string์œผ๋กœ guild_id๋ฅผ ๋„˜๊ธฐ๋ฉด ํŠน์ • ๊ธธ๋“œ๋งŒ ๊ฐฑ์‹ ํ•˜๊ณ , ์ƒ๋žตํ•˜๋ฉด ๊ธฐ๋…์ผ ์ฑ„๋„์ด ์„ค์ •๋œ ๋ชจ๋“  ๊ธธ๋“œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

WebSub callback์€ YOUTUBE_WEBSUB_VERIFY_TOKEN์„ query์˜ token ๋˜๋Š” hub.verify_token์œผ๋กœ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ๋ฐฐํฌ ๋Ÿฐํƒ€์ž„์—์„œ๋Š” ์ด ๊ฐ’์ด ํ•„์ˆ˜์ž…๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ

MySQL์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•ฑ์€ ์‹œ์ž‘ ์‹œ schema version๋งŒ ํ™•์ธํ•˜๊ณ , ์‹ค์ œ DDL ์ ์šฉ์€ scripts/migrate_db.py์—์„œ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ํ…Œ์ด๋ธ”:

  • guild, discord_user
  • channel_settings
  • setting_data
  • gambling_balances
  • scheduled_messages
  • panel_messages
  • music_favorites
  • counter_1557
  • youtube_subscriptions
  • dday_events
  • special_days
  • schema_migrations

๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹คํ–‰:

python -m scripts.migrate_db

ํ™˜๊ฒฝ ๋ณ€์ˆ˜

.env๋Š” ๋กœ์ปฌ ์‹คํ–‰์šฉ, .env.deploy๋Š” ๋ฐฐํฌ ์‹คํ–‰์šฉ์ž…๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค secret ํŒŒ์ผ์ด๋ฉฐ Git์— ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ ์„ค์ •ํ•  ๋•Œ๋Š” .env.example์„ ๋ณต์‚ฌํ•ด ์‹ค์ œ ๊ฐ’์„ ์ฑ„์›๋‹ˆ๋‹ค.

ํ•„์ˆ˜/์ฃผ์š” ๊ฐ’:

DISCORD_TOKEN=...
OPENAI_KEY=...
GOOGLE_API_KEY=...
RIOT_KEY=...
ECOS_API_KEY=...

SONPANNO_GUILD_ID=...
SSAFY_GUILD_ID=...

DB_HOST=localhost:3306
DB_DATABASE=...
DB_USERNAME=...
DB_PASSWORD=...

API_PORT=1557
CELEBRATION_UPDATE_API_KEY=...

VOICE_CHAT_WHISPER_DEVICE=cpu
VOICE_CHAT_WHISPER_MODEL=tiny
VOICE_CHAT_WHISPER_COMPUTE_TYPE=int8
TZ=Asia/Seoul

YOUTUBE_WEBSUB_CALLBACK_URL=https://example.com/youtube/websub
YOUTUBE_WEBSUB_VERIFY_TOKEN=...

Docker ๋ฐฐํฌ์—์„œ MySQL์ด ํ˜ธ์ŠคํŠธ loopback์— ๋ฐ”์ธ๋”ฉ๋˜์–ด ์žˆ์œผ๋ฉด DB_HOST=host.docker.internal:3306์ฒ˜๋Ÿผ Docker host gateway๋ฅผ ๊ฐ€๋ฆฌ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋กœ์ปฌ ์‹คํ–‰

Python 3.11 ๊ธฐ์ค€์œผ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

pip install -r requirements.txt
python -m scripts.migrate_db
python bot.py

Windows์—์„œ๋Š” ์•„๋ž˜ ์Šคํฌ๋ฆฝํŠธ๋„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

.\_launchBot.ps1

๋˜๋Š”:

_launchBot.bat

pip_install.txt๋Š” legacy/manual ์„ค์น˜ ๋ฉ”๋ชจ์ด๋ฉฐ, ๊ธฐ๋ณธ dependency entrypoint๋Š” requirements.txt์ž…๋‹ˆ๋‹ค.

Docker ์‹คํ–‰

docker build -f Dockerfile.deps -t bot-discord-bot-deps:latest .
docker compose --env-file .env up -d --build
docker compose --env-file .env ps

Compose๋Š” 127.0.0.1:1557:1557๋กœ Status API๋ฅผ ๋…ธ์ถœํ•˜๊ณ , ์ปจํ…Œ์ด๋„ˆ์—์„œ ํ˜ธ์ŠคํŠธ DB ์ ‘๊ทผ์„ ์œ„ํ•ด host.docker.internal host gateway๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. Whisper ๋‹ค์šด๋กœ๋“œ๋Š” whisper-model-cache named volume์— ๋ณด์กด๋˜๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ปจํ…Œ์ด๋„ˆ ๊ต์ฒด ๋•Œ ๊ฐ™์€ ๋ชจ๋ธ์„ ๋‹ค์‹œ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Docker json-file ๋กœ๊ทธ๋Š” ๊ธฐ๋ณธ 10MB ํŒŒ์ผ 3๊ฐœ๋กœ ํšŒ์ „ํ•˜๋ฉฐ BOT_LOG_MAX_SIZE์™€ BOT_LOG_MAX_FILES๋กœ ์กฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒ€์ฆ

์ฝ”๋“œ ๋ณ€๊ฒฝ ํ›„ ๊ธฐ๋ณธ ๊ฒ€์ฆ:

python -m compileall -q bot.py api cogs common func util test
python -m unittest discover -s test

test/๋Š” importable package๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ focused test๋„ discovery mode๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

python -m unittest discover -s test -p "test_scheduler.py"

Docker/Jenkins์™€ ๋งž์ถฐ DB migration๊นŒ์ง€ ํ™•์ธํ•  ๋•Œ:

python -m scripts.migrate_db
python -m compileall -q bot.py api cogs common func util test
python -m unittest discover -s test

๋ฐฐํฌ

Jenkinsfile์€ ์˜ˆ์‹œ pipeline์œผ๋กœ ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  1. Checkout
  2. .env.deploy ๋ณต์› ๋ฐ Docker ํ™˜๊ฒฝ ํ™•์ธ
  3. dependency image ๊ธฐ๋ฐ˜ compileall/unittest ๊ฒ€์ฆ
  4. DB migration ์‹คํ–‰
  5. scripts/jenkins_deploy.sh๋กœ Docker Compose ๋ฐฐํฌ
  6. ๋ฐฐํฌ ๋กœ๊ทธ์™€ ์ƒํƒœ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋ณด๊ด€

Jenkins ๋ฐฐํฌ๋Š” Secret text credential discordbot-env์—์„œ .env.deploy ๋‚ด์šฉ์„ ๋ณต์›ํ•˜๋„๋ก ๊ตฌ์„ฑ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฐํฌ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ๋ณ€๊ฒฝํ–ˆ๋‹ค๋ฉด ์ €์žฅ์†Œ diff๋งŒ์œผ๋กœ๋Š” ๋ฐฐํฌ ๊ฐ’์ด ๋ฐ”๋€Œ์ง€ ์•Š์œผ๋ฏ€๋กœ Jenkins credential์˜ Secret text payload๋„ ๊ฐ™์€ ๋‚ด์šฉ์œผ๋กœ ๊ฐฑ์‹ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฐฐํฌ ์Šคํฌ๋ฆฝํŠธ ์ง์ ‘ ์‹คํ–‰ ์˜ˆ:

ENV_FILE=.env.deploy ./scripts/jenkins_deploy.sh auto
ENV_FILE=.env.deploy ./scripts/jenkins_deploy.sh restart
ENV_FILE=.env.deploy ./scripts/jenkins_deploy.sh force

๊ฐœ๋ฐœ ๊ทœ์น™

  • I/O, HTTP, DB ์ž‘์—…์€ async ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • HTTP client๋Š” aiohttp๋ฅผ ์šฐ์„  ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๊ธธ๋“œ๋ณ„ ์ฑ„๋„ ์„ค์ •์€ util/guild/channel_settings.py helper๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • ๊ธฐ๋Šฅ ์ƒํƒœ๋Š” setting_data ๋˜๋Š” ์ „์šฉ ํ…Œ์ด๋ธ”์— ์ €์žฅํ•˜๊ณ  ๋กœ์ปฌ JSON ํŒŒ์ผ์„ ์ƒˆ๋กœ ๋งŒ๋“ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๊ฒฝ๋กœ ์ฒ˜๋ฆฌ๋Š” pathlib ๋˜๋Š” bot.py์˜ BASE_DIR ๊ธฐ๋ฐ˜์œผ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์ด๋Š” ์‹คํŒจ๋Š” Discord ๋ฉ”์‹œ์ง€๋กœ ์•ˆ์ „ํ•˜๊ฒŒ ์•ˆ๋‚ดํ•˜๊ณ , ๋‚ด๋ถ€ ์˜ˆ์™ธ๋Š” traceback๊ณผ ํ•จ๊ป˜ ๋กœ๊ทธ์— ๋‚จ๊น๋‹ˆ๋‹ค.
  • .env, .env.deploy, ๋‚ด๋ถ€ URL, ๋กœ์ปฌ ์ ˆ๋Œ€ ๊ฒฝ๋กœ, private ์šด์˜ ์„ธ๋ถ€์‚ฌํ•ญ์€ ์ปค๋ฐ‹ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

About

An all-in-one Discord bot built in Python with server utilities, automation, and AI-assisted features for community management.

Topics

Resources

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages