This repository has been archived by the owner on Dec 4, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
discordbot.py
130 lines (102 loc) · 3.74 KB
/
discordbot.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
from os import getenv
from traceback import TracebackException
import discord
from discord.ext import commands
from mogirin import (
TicketAlreadyCollected,
TicketCollector,
TicketNumberNotFound,
find_ticket_number,
)
MOGIRI_CHANNEL_ID = int(getenv("MOGIRI_CHANNEL_ID"))
ATTENDEE_ROLE_ID = int(getenv("ATTENDEE_ROLE_ID"))
bot = commands.Bot(command_prefix="/")
collector = TicketCollector(getenv("SPREADSHEET_ID"))
class NeedToNotifyMonitors(Exception):
def __init__(self, message):
self.message = message
@bot.event
async def on_command_error(ctx, error):
original_error = getattr(error, "original", error)
error_message = "".join(
TracebackException.from_exception(original_error).format()
)
await ctx.send(error_message)
async def greet(channel_id=int(getenv("LOGGING_CHANNEL_ID"))):
channel = bot.get_channel(channel_id)
await channel.send("[INFO] もぎりん、起動しました")
async def notify(
message,
channel_id=int(getenv("LOGGING_CHANNEL_ID")),
guild_id=int(getenv("GUILD_ID")),
role_id=int(getenv("STAFF_ROLE_ID")),
):
channel = bot.get_channel(channel_id)
guild = bot.get_guild(guild_id)
staff_role = guild.get_role(role_id)
await channel.send(f"{staff_role.mention} {message}")
@bot.event
async def on_ready():
await greet()
@bot.command()
async def ping(ctx):
await ctx.send("pong")
async def collect_ticket(
ticket_number: str, member: discord.Member, role: discord.Role
) -> str:
try:
await collector.collect(ticket_number, member, role)
except TicketNumberNotFound:
return (
f"LookupError: Couldn't find your number {ticket_number!r}.\n"
"If the number is correct, try again in a few hours "
"(Sorry, there is a lag in synchronizing participant information)."
)
except TicketAlreadyCollected:
message = (
f"RuntimeError: the ticket {ticket_number!r} is already used.\n"
"If the number is correct, please contact staff "
"with `@2021-staff` mention."
)
raise NeedToNotifyMonitors(message)
else:
return "Accepted! Welcome to PyCon JP 2021 venue!"
@bot.event
async def on_message(message):
if message.channel.id != MOGIRI_CHANNEL_ID:
# もぎり用テキストチャンネル以外のmessageには反応しない
return
if message.author.bot:
# botからのmessageには反応しない (Issue #8)
return
if bot.user not in message.mentions:
# @mogirin メンションがないmessageには反応しない
return
attendee_role = message.guild.get_role(ATTENDEE_ROLE_ID)
if attendee_role in message.author.roles:
# すでにattendeeロールが付いているユーザからのmessageには反応しない
return
ticket_number = find_ticket_number(message.clean_content)
needs_to_notify = False
if ticket_number is None:
reply_message = (
f"ValueError: ticket number is not included in your message.\n"
"Please input numeric ticket number like `@mogirin 1234567`."
)
else:
try:
reply_message = await collect_ticket(
ticket_number, message.author, attendee_role
)
except NeedToNotifyMonitors as ex:
needs_to_notify = True
reply_message = ex.message
await message.channel.send(f"{message.author.mention} {reply_message}")
if needs_to_notify:
monitor_message = (
f"「{message.author.display_name}」氏のもぎりに以下のエラーを送出しました\n"
f"{reply_message}"
)
await notify(monitor_message)
token = getenv("DISCORD_BOT_TOKEN")
bot.run(token)