|
10 | 10 | TOKEN = os.getenv('DISCORD_BOT_TOKEN') |
11 | 11 |
|
12 | 12 | intents = disnake.Intents.default() |
13 | | -intents.message_content = True # Enable message content intent |
14 | | -intents.members = True # Enable members intent |
| 13 | +intents.message_content = True |
| 14 | +intents.members = True |
15 | 15 |
|
16 | 16 | bot = commands.Bot(command_prefix='!', intents=intents) |
17 | | -current_order = None |
18 | | -allowed_channel_name = "food-order" |
19 | | -allowed_channel_name = "food-order" |
20 | | -order_message = None |
21 | | -last_order_backup = None # Backup variable for the last order |
| 17 | + |
| 18 | +# Support multiple channels |
| 19 | +orders = {} # {channel_id: current_order} |
| 20 | +order_messages = {} # {channel_id: order_message} |
| 21 | +last_order_backups = {} # {channel_id: last_order_backup} |
| 22 | +final_order_messages = {} # {channel_id: final_order_message} |
22 | 23 |
|
23 | 24 | @bot.event |
24 | 25 | async def on_ready(): |
25 | 26 | print(f'Logged in as {bot.user}') |
26 | 27 | print("Bot is ready.") |
27 | | - channel = disnake.utils.get(bot.get_all_channels(), name=allowed_channel_name) |
28 | | - if channel: |
29 | | - print(f"Channel '{allowed_channel_name}' found.") |
30 | | - await clear_and_initialize_channel(channel) |
31 | | - else: |
32 | | - print(f"Channel '{allowed_channel_name}' not found.") |
| 28 | + for channel in bot.get_all_channels(): |
| 29 | + if channel.name.startswith("food-order"): |
| 30 | + print(f"Channel '{channel.name}' found.") |
| 31 | + await clear_and_initialize_channel(channel) |
33 | 32 |
|
34 | 33 | def is_allowed_channel(interaction): |
35 | | - return interaction.channel.name == allowed_channel_name |
| 34 | + return interaction.channel.name.startswith("food-order") |
36 | 35 |
|
37 | 36 | async def clear_and_initialize_channel(channel): |
38 | | - global order_message |
| 37 | + channel_id = channel.id |
39 | 38 | async for message in channel.history(limit=100): |
40 | 39 | await message.delete() |
41 | | - order_message = await channel.send("No active order.") |
| 40 | + order_messages[channel_id] = await channel.send("No active order.") |
42 | 41 |
|
43 | 42 | @bot.event |
44 | 43 | async def on_message(message): |
45 | | - if isinstance(message.channel, disnake.TextChannel) and message.channel.name == allowed_channel_name and current_order is not None: |
| 44 | + channel_id = message.channel.id |
| 45 | + if (isinstance(message.channel, disnake.TextChannel) |
| 46 | + and message.channel.name.startswith("food-order") |
| 47 | + and channel_id in orders): |
46 | 48 | if message.author == bot.user: |
47 | 49 | return |
48 | 50 | await message.delete() |
49 | 51 |
|
50 | 52 | @bot.slash_command(name="startorder", description="Start a new food order") |
51 | 53 | async def start_order(interaction: disnake.ApplicationCommandInteraction, place: str, time: str): |
52 | 54 | if not is_allowed_channel(interaction): |
53 | | - await interaction.response.send_message(f'This command can only be used in the #{allowed_channel_name} channel.', ephemeral=True) |
| 55 | + await interaction.response.send_message("This command can only be used in a food-order channel.", ephemeral=True) |
54 | 56 | return |
55 | 57 |
|
56 | | - global current_order |
57 | | - global order_message |
| 58 | + channel_id = interaction.channel.id |
58 | 59 |
|
59 | | - if current_order is not None: |
60 | | - await interaction.user.send('An order is already in progress.') |
61 | | - await interaction.response.send_message('An order is already in progress.', ephemeral=True) |
| 60 | + if channel_id in orders: |
| 61 | + await interaction.user.send("An order is already in progress.") |
| 62 | + await interaction.response.send_message("An order is already in progress.", ephemeral=True) |
62 | 63 | return |
63 | 64 |
|
64 | | - channel = interaction.channel |
65 | | - async for message in channel.history(limit=100): |
66 | | - if message != order_message: |
| 65 | + async for message in interaction.channel.history(limit=100): |
| 66 | + if channel_id in order_messages and message.id != order_messages[channel_id].id: |
67 | 67 | await message.delete() |
68 | 68 |
|
69 | 69 | cet_tz = pytz.timezone("Europe/Copenhagen") |
70 | | - start_time = datetime.now(pytz.utc).astimezone(cet_tz).strftime("%Y-%m-%d %H:%M:%S") # Get current time |
71 | | - |
72 | | - current_order = { |
73 | | - 'starter': interaction.user.id, |
74 | | - 'username': interaction.user.name, |
75 | | - 'place': place, |
76 | | - 'time': time, |
77 | | - 'start_time': start_time, # Store start time |
| 70 | + start_time = datetime.now(pytz.utc).astimezone(cet_tz).strftime("%Y-%m-%d %H:%M:%S") |
| 71 | + |
| 72 | + orders[channel_id] = { |
| 73 | + 'starter': interaction.user.id, |
| 74 | + 'username': interaction.user.name, |
| 75 | + 'place': place, |
| 76 | + 'time': time, |
| 77 | + 'start_time': start_time, |
78 | 78 | 'items': {} |
79 | 79 | } |
80 | 80 |
|
81 | | - await update_order_message(interaction) |
82 | | - await interaction.response.send_message('Order started!', ephemeral=True) |
| 81 | + await update_order_message(interaction, force_new=True) |
| 82 | + await interaction.response.send_message("Order started!", ephemeral=True) |
| 83 | + |
| 84 | +async def update_order_message(interaction, force_new=False): |
| 85 | + channel_id = interaction.channel.id |
83 | 86 |
|
84 | | -async def update_order_message(interaction): |
85 | | - global order_message |
86 | | - channel = interaction.channel |
87 | | - if current_order is None: |
| 87 | + if force_new and channel_id in order_messages: |
| 88 | + try: |
| 89 | + await order_messages[channel_id].delete() |
| 90 | + except disnake.NotFound: |
| 91 | + pass |
| 92 | + order_messages[channel_id] = None |
| 93 | + |
| 94 | + order = orders.get(channel_id) |
| 95 | + if not order: |
88 | 96 | content = "No active order." |
89 | 97 | else: |
90 | | - order_list = [f'{interaction.guild.get_member(user_id).mention}: {", ".join(user_orders)}' for user_id, user_orders in current_order['items'].items()] |
91 | | - content = (f'Order in progress by {current_order["username"]}\n \n' |
92 | | - f'From: {current_order["place"]} \nOrder before: {current_order["time"]}\n' |
93 | | - f'Started at: {current_order["start_time"]} \n \n' # Add start time to the message |
94 | | - 'Use "/addorder [order]" to order your food.\n' f'Current orders: \n' + '\n'.join(order_list)) |
95 | | - |
96 | | - if order_message is None: |
97 | | - order_message = await channel.send(content) |
| 98 | + order_list = [ |
| 99 | + f'{interaction.guild.get_member(uid).mention}: {", ".join(items)}' |
| 100 | + for uid, items in order['items'].items() |
| 101 | + ] |
| 102 | + content = (f'Order in progress by {order["username"]}\n\n' |
| 103 | + f'From: {order["place"]} \nOrder before: {order["time"]}\n' |
| 104 | + f'Started at: {order["start_time"]}\n\n' |
| 105 | + 'Use "/addorder [order]" to order your food.\n' + |
| 106 | + ('Current orders:\n' + '\n'.join(order_list) if order_list else "No orders yet.")) |
| 107 | + |
| 108 | + if channel_id not in order_messages or order_messages[channel_id] is None: |
| 109 | + order_messages[channel_id] = await interaction.channel.send(content) |
98 | 110 | else: |
99 | | - await order_message.edit(content=content) |
| 111 | + await order_messages[channel_id].edit(content=content) |
100 | 112 |
|
101 | | -@bot.slash_command(name="addorder", description="Add an item to the current order (will overwrite any previous order)") |
| 113 | +@bot.slash_command(name="addorder", description="Add an item to the current order (overwrites previous)") |
102 | 114 | async def add_order(interaction: disnake.ApplicationCommandInteraction, order: str): |
103 | 115 | if not is_allowed_channel(interaction): |
104 | | - await interaction.response.send_message(f'This command can only be used in the #{allowed_channel_name} channel.', ephemeral=True) |
| 116 | + await interaction.response.send_message("This command can only be used in a food-order channel.", ephemeral=True) |
105 | 117 | return |
106 | 118 |
|
107 | | - global current_order |
108 | | - if current_order is None: |
109 | | - await interaction.user.send('No active order. Start an order using /startorder.') |
110 | | - await interaction.response.send_message('No active order. Start an order using /startorder.', ephemeral=True) |
| 119 | + channel_id = interaction.channel.id |
| 120 | + current_order = orders.get(channel_id) |
| 121 | + if not current_order: |
| 122 | + await interaction.user.send("No active order. Start an order using /startorder.") |
| 123 | + await interaction.response.send_message("No active order.", ephemeral=True) |
111 | 124 | return |
112 | 125 |
|
113 | 126 | current_order['items'][interaction.user.id] = [order] |
114 | | - |
115 | 127 | await update_order_message(interaction) |
116 | | - await interaction.response.send_message('Your order has been updated!', ephemeral=True) |
117 | | - |
118 | | -final_order_message = None # Variable to store the finalized order message |
| 128 | + await interaction.response.send_message("Your order has been updated!", ephemeral=True) |
119 | 129 |
|
120 | 130 | @bot.slash_command(name="endorder", description="Finalize the current order") |
121 | 131 | async def finalize_order(interaction: disnake.ApplicationCommandInteraction, mobilepay: str = None): |
122 | 132 | if not is_allowed_channel(interaction): |
123 | | - await interaction.response.send_message(f'This command can only be used in the #{allowed_channel_name} channel.', ephemeral=True) |
| 133 | + await interaction.response.send_message("This command can only be used in a food-order channel.", ephemeral=True) |
124 | 134 | return |
125 | | - |
126 | | - global current_order, last_order_backup, final_order_message |
127 | | - if current_order is None: |
128 | | - await interaction.user.send('No active order to finalize.') |
129 | | - await interaction.response.send_message('No active order to finalize.', ephemeral=True) |
| 135 | + |
| 136 | + channel_id = interaction.channel.id |
| 137 | + current_order = orders.get(channel_id) |
| 138 | + if not current_order: |
| 139 | + await interaction.user.send("No active order to finalize.") |
| 140 | + await interaction.response.send_message("No active order to finalize.", ephemeral=True) |
130 | 141 | return |
131 | | - |
132 | | - # Backup the current order before finalizing |
133 | | - last_order_backup = current_order.copy() |
134 | 142 |
|
135 | | - # Prepare the final order list message with mentions |
| 143 | + last_order_backups[channel_id] = current_order.copy() |
| 144 | + |
136 | 145 | order_list = [] |
137 | 146 | for user_id, user_orders in current_order['items'].items(): |
138 | 147 | member = interaction.guild.get_member(user_id) |
139 | 148 | if member: |
140 | 149 | order_list.append(f'{member.mention}: {", ".join(user_orders)}') |
141 | 150 | else: |
142 | 151 | order_list.append(f'Unknown User ({user_id}): {", ".join(user_orders)}') |
143 | | - |
144 | | - # Construct the final message |
| 152 | + |
145 | 153 | order_list_message = "The following order has been ended:\n" + '\n'.join(order_list) |
146 | | - |
147 | | - # Add MobilePay details if provided |
148 | 154 | if mobilepay: |
149 | | - order_list_message += f"\n\nPlease MobilePay to following number: {mobilepay}" |
| 155 | + order_list_message += f"\n\nPlease MobilePay to the following number: {mobilepay}" |
150 | 156 |
|
151 | | - # Send the final order list to the channel and save the message reference |
152 | | - final_order_message = await interaction.channel.send(order_list_message) |
153 | | - |
154 | | - # Send the finalized order as a DM to the user ending the order |
155 | | - await interaction.user.send("Order finalized:\n" + order_list_message) |
| 157 | + final_order_messages[channel_id] = await interaction.channel.send(order_list_message) |
| 158 | + await interaction.user.send( |
| 159 | + f"Order finalized for **{current_order['place']}**:\n\n" |
| 160 | + f"{order_list_message}\n\n" |
| 161 | + "If you ended it by mistake, you can use `/restoreorder` to restore the last order." |
| 162 | +) |
156 | 163 |
|
157 | | - # Clear the current order |
158 | | - current_order = None |
159 | | - await update_order_message(interaction) |
160 | | - await interaction.response.send_message('Order finalized!', ephemeral=True) |
161 | 164 |
|
| 165 | + del orders[channel_id] |
| 166 | + await update_order_message(interaction) |
| 167 | + await interaction.response.send_message("Order finalized!", ephemeral=True) |
162 | 168 |
|
163 | | -@bot.slash_command(name="restoreorder", description="Restore the last ended order if it was ended by mistake") |
| 169 | +@bot.slash_command(name="restoreorder", description="Restore the last ended order") |
164 | 170 | async def restore_order(interaction: disnake.ApplicationCommandInteraction): |
165 | 171 | if not is_allowed_channel(interaction): |
166 | | - await interaction.response.send_message(f'This command can only be used in the #{allowed_channel_name} channel.', ephemeral=True) |
| 172 | + await interaction.response.send_message("This command can only be used in a food-order channel.", ephemeral=True) |
167 | 173 | return |
168 | | - |
169 | | - global current_order, last_order_backup, final_order_message |
170 | | - if current_order is not None: |
171 | | - await interaction.response.send_message("An order is already in progress, cannot restore another order.", ephemeral=True) |
| 174 | + |
| 175 | + channel_id = interaction.channel.id |
| 176 | + if channel_id in orders: |
| 177 | + await interaction.response.send_message("An order is already in progress.", ephemeral=True) |
172 | 178 | return |
173 | | - |
174 | | - if last_order_backup is None: |
| 179 | + |
| 180 | + if channel_id not in last_order_backups: |
175 | 181 | await interaction.response.send_message("No order available to restore.", ephemeral=True) |
176 | 182 | return |
177 | 183 |
|
178 | | - # Remove the finalized order message if it exists |
179 | | - if final_order_message: |
180 | | - await final_order_message.delete() |
181 | | - final_order_message = None # Reset the reference |
| 184 | + if final_order_messages.get(channel_id): |
| 185 | + await final_order_messages[channel_id].delete() |
| 186 | + final_order_messages[channel_id] = None |
182 | 187 |
|
183 | | - # Restore the last backup |
184 | | - current_order = last_order_backup |
| 188 | + orders[channel_id] = last_order_backups[channel_id] |
185 | 189 | await update_order_message(interaction) |
186 | 190 | await interaction.response.send_message("The previous order has been restored.", ephemeral=True) |
187 | 191 |
|
188 | 192 | @bot.slash_command(name="clearorder", description="Remove your order from the current order") |
189 | 193 | async def clear_order(interaction: disnake.ApplicationCommandInteraction): |
190 | | - print("clear_order command defined") |
191 | 194 | if not is_allowed_channel(interaction): |
192 | | - await interaction.response.send_message(f'This command can only be used in the #{allowed_channel_name} channel.', ephemeral=True) |
| 195 | + await interaction.response.send_message("This command can only be used in a food-order channel.", ephemeral=True) |
193 | 196 | return |
194 | | - |
195 | | - global current_order |
196 | | - if current_order is None: |
197 | | - await interaction.user.send('No active order to modify.') |
198 | | - await interaction.response.send_message('No active order to modify.', ephemeral=True) |
| 197 | + |
| 198 | + channel_id = interaction.channel.id |
| 199 | + current_order = orders.get(channel_id) |
| 200 | + if not current_order: |
| 201 | + await interaction.user.send("No active order to modify.") |
| 202 | + await interaction.response.send_message("No active order to modify.", ephemeral=True) |
199 | 203 | return |
200 | | - |
| 204 | + |
201 | 205 | if interaction.user.id not in current_order['items']: |
202 | | - await interaction.user.send('You have no items in the current order.') |
203 | | - await interaction.response.send_message('You have no items in the current order.', ephemeral=True) |
| 206 | + await interaction.user.send("You have no items in the current order.") |
| 207 | + await interaction.response.send_message("You have no items in the current order.", ephemeral=True) |
204 | 208 | return |
205 | | - |
| 209 | + |
206 | 210 | del current_order['items'][interaction.user.id] |
207 | 211 | await update_order_message(interaction) |
208 | | - |
209 | | - await interaction.response.send_message('Your order has been removed!', ephemeral=True) |
210 | | - print("clear_order command processed") |
| 212 | + await interaction.response.send_message("Your order has been removed!", ephemeral=True) |
211 | 213 |
|
212 | 214 | @bot.slash_command(name="help", description="Shows a list of available commands") |
213 | 215 | async def help_command(interaction: disnake.ApplicationCommandInteraction): |
214 | | - print("help command defined") |
215 | 216 | help_text = ( |
216 | 217 | "Hello\n" |
217 | | - "My name is FoodBot, i help you organize a food order, to use me see my commands below:\n \n" |
218 | | - "/startorder [place] [time] - Starts a new food order\n \n" |
219 | | - "/addorder [order] - Add an item to the current order\n \n" |
220 | | - "/endorder - Finalize the current order\n \n" |
221 | | - "/clearorder - Remove your order from the current order\n \n" |
222 | | - "/Restoreorder - Restores the last ended order, if it was ended by mistake\n \n" |
223 | | - "/help - Show this help message\n \n" |
| 218 | + "My name is FoodBot, I help you organize a food order.\n\n" |
| 219 | + "/startorder [place] [time] - Starts a new food order\n" |
| 220 | + "/addorder [order] - Add an item to the current order\n" |
| 221 | + "/endorder - Finalize the current order\n" |
| 222 | + "/clearorder - Remove your order from the current order\n" |
| 223 | + "/restoreorder - Restore the last ended order if ended by mistake\n" |
| 224 | + "/help - Show this help message" |
224 | 225 | ) |
225 | | - # Use ephemeral response for the help message to avoid confusion |
226 | | - await interaction.response.send_message('A list of commands has been sent to your DMs!', ephemeral=True) |
227 | | - await interaction.user.send(help_text) # Send the help text to the user's DM |
228 | | - print("help command processed") |
229 | | - |
| 226 | + await interaction.response.send_message("A list of commands has been sent to your DMs!", ephemeral=True) |
| 227 | + await interaction.user.send(help_text) |
230 | 228 |
|
231 | 229 | bot.run(TOKEN) |
0 commit comments