Update app.py
Browse files
app.py
CHANGED
@@ -1,30 +1,43 @@
|
|
1 |
# img_bot.py
|
2 |
import discord, os, io, asyncio, logging, requests, replicate, subprocess
|
3 |
|
4 |
-
# ──
|
5 |
-
TOKEN = os.getenv("DISCORD_TOKEN") #
|
6 |
-
CHANNEL_ID = int(os.getenv("DISCORD_CHANNEL_ID")) #
|
7 |
-
REPL_TOKEN = (os.getenv("OPENAI_API_KEY") or "").strip() # Replicate 토큰(
|
8 |
-
# ───────────────────────────────────────────────────────────────
|
9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
MODEL = (
|
11 |
"bytedance/sdxl-lightning-4step:"
|
12 |
"6f7a773af6fc3e8de9d5a3c00be77c17308914bf67772726aff83496ba1e3bbe"
|
13 |
)
|
14 |
|
|
|
15 |
logging.basicConfig(
|
16 |
level=logging.INFO,
|
17 |
format="%(asctime)s [%(levelname)s] %(message)s",
|
18 |
handlers=[logging.StreamHandler()]
|
19 |
)
|
20 |
|
|
|
21 |
intents = discord.Intents.default()
|
22 |
-
intents.message_content = True #
|
23 |
|
24 |
class ImageBot(discord.Client):
|
25 |
async def on_ready(self):
|
26 |
logging.info(f"Logged in as {self.user} (id={self.user.id})")
|
27 |
-
# web.py
|
28 |
try:
|
29 |
subprocess.Popen(["python", "web.py"])
|
30 |
logging.info("web.py server has been started.")
|
@@ -32,7 +45,7 @@ class ImageBot(discord.Client):
|
|
32 |
logging.warning(f"web.py 실행 실패: {e}")
|
33 |
|
34 |
async def on_message(self, message: discord.Message):
|
35 |
-
#
|
36 |
if message.author.id == self.user.id or message.channel.id != CHANNEL_ID:
|
37 |
return
|
38 |
|
@@ -42,18 +55,20 @@ class ImageBot(discord.Client):
|
|
42 |
|
43 |
await message.channel.typing()
|
44 |
|
45 |
-
# Replicate 호출
|
46 |
def run_replicate():
|
47 |
return list(replicate.run(MODEL, input={"prompt": prompt}))
|
48 |
|
49 |
try:
|
50 |
-
|
51 |
-
|
|
|
52 |
except Exception as e:
|
53 |
logging.error(f"Replicate error: {e}")
|
54 |
await message.reply("⚠️ 이미지 생성 실패!")
|
55 |
return
|
56 |
|
|
|
57 |
files = []
|
58 |
for idx, item in enumerate(images):
|
59 |
try:
|
@@ -62,10 +77,12 @@ class ImageBot(discord.Client):
|
|
62 |
except Exception as e:
|
63 |
logging.warning(f"[IMG {idx}] 처리 실패: {e}")
|
64 |
|
65 |
-
await message.reply(
|
66 |
-
|
|
|
|
|
67 |
|
|
|
68 |
if __name__ == "__main__":
|
69 |
-
#
|
70 |
-
replicate.Client(api_token=REPL_TOKEN)
|
71 |
ImageBot(intents=intents).run(TOKEN)
|
|
|
1 |
# img_bot.py
|
2 |
import discord, os, io, asyncio, logging, requests, replicate, subprocess
|
3 |
|
4 |
+
# ── 환경 변수 ────────────────────────────────────────────────
|
5 |
+
TOKEN = os.getenv("DISCORD_TOKEN") # Discord 봇 토큰
|
6 |
+
CHANNEL_ID = int(os.getenv("DISCORD_CHANNEL_ID")) # 감시할 채널 ID
|
7 |
+
REPL_TOKEN = (os.getenv("OPENAI_API_KEY") or "").strip() # Replicate 토큰(동일 변수 사용)
|
|
|
8 |
|
9 |
+
if not TOKEN or not CHANNEL_ID:
|
10 |
+
raise RuntimeError("DISCORD_TOKEN 과 DISCORD_CHANNEL_ID 환경 변수를 모두 지정하세요.")
|
11 |
+
|
12 |
+
if not REPL_TOKEN:
|
13 |
+
raise RuntimeError(
|
14 |
+
"OPENAI_API_KEY 환경 변수에 Replicate Personal Access Token 값을 넣어주세요."
|
15 |
+
)
|
16 |
+
|
17 |
+
# Replicate 라이브러리가 참조하도록 토큰 주입
|
18 |
+
os.environ["REPLICATE_API_TOKEN"] = REPL_TOKEN
|
19 |
+
|
20 |
+
# ── 모델 ────────────────────────────────────────────────────
|
21 |
MODEL = (
|
22 |
"bytedance/sdxl-lightning-4step:"
|
23 |
"6f7a773af6fc3e8de9d5a3c00be77c17308914bf67772726aff83496ba1e3bbe"
|
24 |
)
|
25 |
|
26 |
+
# ── 로깅 ────────────────────────────────────────────────────
|
27 |
logging.basicConfig(
|
28 |
level=logging.INFO,
|
29 |
format="%(asctime)s [%(levelname)s] %(message)s",
|
30 |
handlers=[logging.StreamHandler()]
|
31 |
)
|
32 |
|
33 |
+
# ── Discord 설정 ────────────────────────────────────────────
|
34 |
intents = discord.Intents.default()
|
35 |
+
intents.message_content = True # 메시지 콘텐츠 읽기
|
36 |
|
37 |
class ImageBot(discord.Client):
|
38 |
async def on_ready(self):
|
39 |
logging.info(f"Logged in as {self.user} (id={self.user.id})")
|
40 |
+
# web.py 병렬 실행
|
41 |
try:
|
42 |
subprocess.Popen(["python", "web.py"])
|
43 |
logging.info("web.py server has been started.")
|
|
|
45 |
logging.warning(f"web.py 실행 실패: {e}")
|
46 |
|
47 |
async def on_message(self, message: discord.Message):
|
48 |
+
# 봇 자신의 메시지 혹은 대상 아닌 채널 → 무시
|
49 |
if message.author.id == self.user.id or message.channel.id != CHANNEL_ID:
|
50 |
return
|
51 |
|
|
|
55 |
|
56 |
await message.channel.typing()
|
57 |
|
58 |
+
# ── Replicate 호출 ──────────────────────────────────
|
59 |
def run_replicate():
|
60 |
return list(replicate.run(MODEL, input={"prompt": prompt}))
|
61 |
|
62 |
try:
|
63 |
+
images = await asyncio.get_running_loop().run_in_executor(
|
64 |
+
None, run_replicate
|
65 |
+
)
|
66 |
except Exception as e:
|
67 |
logging.error(f"Replicate error: {e}")
|
68 |
await message.reply("⚠️ 이미지 생성 실패!")
|
69 |
return
|
70 |
|
71 |
+
# ── 이미지 Discord 전송 ─────────────────────────────
|
72 |
files = []
|
73 |
for idx, item in enumerate(images):
|
74 |
try:
|
|
|
77 |
except Exception as e:
|
78 |
logging.warning(f"[IMG {idx}] 처리 실패: {e}")
|
79 |
|
80 |
+
await message.reply(
|
81 |
+
files=files if files else None,
|
82 |
+
content=None if files else "⚠️ 이미지를 전송할 수 없습니다."
|
83 |
+
)
|
84 |
|
85 |
+
# ── 실행 ────────────────────────────────────────────────────
|
86 |
if __name__ == "__main__":
|
87 |
+
replicate.Client(api_token=REPL_TOKEN) # 인증
|
|
|
88 |
ImageBot(intents=intents).run(TOKEN)
|