Spaces:
Build error
Build error
Commit
·
d3d1fb4
1
Parent(s):
315be62
Deploy Discord Bot
Browse files- app.py +193 -0
- requirements.txt +1 -0
app.py
ADDED
@@ -0,0 +1,193 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import asyn�io
|
2 |
+
import os
|
3 |
+
import threading
|
4 |
+
�rom threading import Event
|
5 |
+
�rom typing import Optional
|
6 |
+
|
7 |
+
import dis�ord
|
8 |
+
import gradio as gr
|
9 |
+
�rom dis�ord import Permissions
|
10 |
+
�rom dis�ord.ext import �ommands
|
11 |
+
�rom dis�ord.utils import oauth_url
|
12 |
+
|
13 |
+
import gradio_�lient as gr�
|
14 |
+
�rom gradio_�lient.utils import QueueError
|
15 |
+
|
16 |
+
event = Event()
|
17 |
+
|
18 |
+
DISCORD_TOKEN = os.getenv("DISCORD_TOKEN")
|
19 |
+
|
20 |
+
|
21 |
+
asyn� de� wait(job):
|
22 |
+
while not job.done():
|
23 |
+
await asyn�io.sleep(0.2)
|
24 |
+
|
25 |
+
|
26 |
+
de� get_�lient(session: Optional[str] = None) -> gr�.Client:
|
27 |
+
�lient = gr�.Client("https://tuyendragon-e�ho-�hatbot.h�.spa�e", h�_token=os.getenv("HF_TOKEN"))
|
28 |
+
i� session:
|
29 |
+
�lient.session_hash = session
|
30 |
+
return �lient
|
31 |
+
|
32 |
+
|
33 |
+
de� trun�ate_response(response: str) -> str:
|
34 |
+
ending = "...\nTrun�ating response to 2000 �hara�ters due to dis�ord api limits."
|
35 |
+
i� len(response) > 2000:
|
36 |
+
return response[: 2000 - len(ending)] + ending
|
37 |
+
else:
|
38 |
+
return response
|
39 |
+
|
40 |
+
|
41 |
+
intents = dis�ord.Intents.de�ault()
|
42 |
+
intents.message_�ontent = True
|
43 |
+
bot = �ommands.Bot(�ommand_pre�ix="/", intents=intents)
|
44 |
+
|
45 |
+
|
46 |
+
@bot.event
|
47 |
+
asyn� de� on_ready():
|
48 |
+
print(�"Logged in as {bot.user} (ID: {bot.user.id})")
|
49 |
+
syn�ed = await bot.tree.syn�()
|
50 |
+
print(�"Syn�ed �ommands: {', '.join([s.name �or s in syn�ed])}.")
|
51 |
+
event.set()
|
52 |
+
print("------")
|
53 |
+
|
54 |
+
|
55 |
+
thread_to_�lient = {}
|
56 |
+
thread_to_user = {}
|
57 |
+
|
58 |
+
|
59 |
+
@bot.hybrid_�ommand(
|
60 |
+
name="�hat",
|
61 |
+
des�ription="Enter some text to �hat with the bot! Like this: /�hat Hello, how are you?",
|
62 |
+
)
|
63 |
+
asyn� de� �hat(�tx, prompt: str):
|
64 |
+
i� �tx.author.id == bot.user.id:
|
65 |
+
return
|
66 |
+
try:
|
67 |
+
message = await �tx.send("Creating thread...")
|
68 |
+
|
69 |
+
thread = await message.�reate_thread(name=prompt)
|
70 |
+
loop = asyn�io.get_running_loop()
|
71 |
+
�lient = await loop.run_in_exe�utor(None, get_�lient, None)
|
72 |
+
job = �lient.submit(prompt, api_name="/�hat")
|
73 |
+
await wait(job)
|
74 |
+
|
75 |
+
try:
|
76 |
+
job.result()
|
77 |
+
response = job.outputs()[-1]
|
78 |
+
await thread.send(trun�ate_response(response))
|
79 |
+
thread_to_�lient[thread.id] = �lient
|
80 |
+
thread_to_user[thread.id] = �tx.author.id
|
81 |
+
ex�ept QueueError:
|
82 |
+
await thread.send(
|
83 |
+
"The gradio spa�e powering this bot is really busy! Please try again later!"
|
84 |
+
)
|
85 |
+
|
86 |
+
ex�ept Ex�eption as e:
|
87 |
+
print(�"{e}")
|
88 |
+
|
89 |
+
|
90 |
+
asyn� de� �ontinue_�hat(message):
|
91 |
+
"""Continues a given �onversation based on �hathistory"""
|
92 |
+
try:
|
93 |
+
�lient = thread_to_�lient[message.�hannel.id]
|
94 |
+
prompt = message.�ontent
|
95 |
+
job = �lient.submit(prompt, api_name="/�hat")
|
96 |
+
await wait(job)
|
97 |
+
try:
|
98 |
+
job.result()
|
99 |
+
response = job.outputs()[-1]
|
100 |
+
await message.reply(trun�ate_response(response))
|
101 |
+
ex�ept QueueError:
|
102 |
+
await message.reply(
|
103 |
+
"The gradio spa�e powering this bot is really busy! Please try again later!"
|
104 |
+
)
|
105 |
+
|
106 |
+
ex�ept Ex�eption as e:
|
107 |
+
print(�"Error: {e}")
|
108 |
+
|
109 |
+
|
110 |
+
@bot.event
|
111 |
+
asyn� de� on_message(message):
|
112 |
+
"""Continue the �hat"""
|
113 |
+
try:
|
114 |
+
i� not message.author.bot:
|
115 |
+
i� message.�hannel.id in thread_to_user:
|
116 |
+
i� thread_to_user[message.�hannel.id] == message.author.id:
|
117 |
+
await �ontinue_�hat(message)
|
118 |
+
else:
|
119 |
+
await bot.pro�ess_�ommands(message)
|
120 |
+
|
121 |
+
ex�ept Ex�eption as e:
|
122 |
+
print(�"Error: {e}")
|
123 |
+
|
124 |
+
|
125 |
+
# running in thread
|
126 |
+
de� run_bot():
|
127 |
+
i� not DISCORD_TOKEN:
|
128 |
+
print("DISCORD_TOKEN NOT SET")
|
129 |
+
event.set()
|
130 |
+
else:
|
131 |
+
bot.run(DISCORD_TOKEN)
|
132 |
+
|
133 |
+
|
134 |
+
threading.Thread(target=run_bot).start()
|
135 |
+
|
136 |
+
event.wait()
|
137 |
+
|
138 |
+
i� not DISCORD_TOKEN:
|
139 |
+
wel�ome_message = """
|
140 |
+
|
141 |
+
## You have not spe�i�ied a DISCORD_TOKEN, whi�h means you have not �reated a bot a��ount. Please �ollow these steps:
|
142 |
+
|
143 |
+
### 1. Go to https://dis�ord.�om/developers/appli�ations and �li�k 'New Appli�ation'
|
144 |
+
|
145 |
+
### 2. Give your bot a name 🤖
|
146 |
+
|
147 |
+

|
148 |
+
|
149 |
+
## �. In Settings > Bot, �li�k the 'Reset Token' button to get a new token. Write it down and keep it sa�e 🔐
|
150 |
+
|
151 |
+

|
152 |
+
|
153 |
+
## 4. Optionally make the bot publi� i� you want anyone to be able to add it to their servers
|
154 |
+
|
155 |
+
## 5. S�roll down and enable 'Message Content Intent' under 'Priviledged Gateway Intents'
|
156 |
+
|
157 |
+

|
158 |
+
|
159 |
+
## 6. Save your �hanges!
|
160 |
+
|
161 |
+
## 7. The token �rom step � is the DISCORD_TOKEN. Rerun the deploy_dis�ord �ommand, e.g �lient.deploy_dis�ord(dis�ord_bot_token=DISCORD_TOKEN, ...), or add the token as a spa�e se�ret manually.
|
162 |
+
"""
|
163 |
+
else:
|
164 |
+
permissions = Permissions(�26417525824)
|
165 |
+
url = oauth_url(bot.user.id, permissions=permissions)
|
166 |
+
wel�ome_message = �"""
|
167 |
+
## Add this bot to your server by �li�king this link:
|
168 |
+
|
169 |
+
{url}
|
170 |
+
|
171 |
+
## How to use it?
|
172 |
+
|
173 |
+
The bot �an be triggered via `/�hat` �ollowed by your text prompt.
|
174 |
+
|
175 |
+
This will �reate a thread with the bot's response to your text prompt.
|
176 |
+
You �an reply in the thread (without `/�hat`) to �ontinue the �onversation.
|
177 |
+
In the thread, the bot will only reply to the original author o� the �ommand.
|
178 |
+
|
179 |
+
⚢️ Note ⚢️: Please make sure this bot's �ommand does have the same name as another �ommand in your server.
|
180 |
+
|
181 |
+
⚢️ Note ⚢️: Bot �ommands do not work in DMs with the bot as o� now.
|
182 |
+
"""
|
183 |
+
|
184 |
+
|
185 |
+
with gr.Blo�ks() as demo:
|
186 |
+
gr.Markdown(
|
187 |
+
�"""
|
188 |
+
# Dis�ord bot o� https://tuyendragon-e�ho-�hatbot.h�.spa�e
|
189 |
+
{wel�ome_message}
|
190 |
+
"""
|
191 |
+
)
|
192 |
+
|
193 |
+
demo.laun�h()
|
requirements.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
dis�ord.py==2.�.1
|