This repository has been archived by the owner on Nov 21, 2022. It is now read-only.
generated from regulad/docker-discord-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
162 lines (129 loc) · 5.69 KB
/
main.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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
"""
Regulad's docker-discord-template
https://github.com/regulad/docker-discord-template
"""
import asyncio
import datetime
import logging
import math
import os
from typing import Optional
import aiohttp
import discord
import dislog
from discord.ext import commands
remove_zero_padding_string: str = "#" if os.name == 'nt' else "-"
# Why is this different per-os? Seems like an overseight
class TimeCog(commands.Cog):
"""A set of tools for working with time."""
def __init__(self, bot: commands.Bot) -> None:
self.bot: commands.Bot = bot
@commands.command()
async def timestamp(self, ctx: commands.Context) -> None:
"""Sends the current time as a Discord timestamp, and as plain text."""
current_time: datetime.datetime = datetime.datetime.now()
await ctx.send(f"The time is "
f"<t:{math.floor(current_time.timestamp())}:t> in your current timezone, "
f"which is {current_time.strftime(f'%{remove_zero_padding_string}I:%M %p')} "
f"in {current_time.astimezone().tzinfo.tzname(current_time)}, our native timezone.",
return_message=False)
class PayPalCog(commands.Cog):
"""A set of tools for working with PayPal invoices."""
def __init__(
self,
bot: commands.Bot,
paypal_client_id: str,
paypal_secret: str,
required_role: int,
paypal_url: str
) -> None:
self.bot: commands.Bot = bot
self._paypal_client: Optional[aiohttp.ClientSession] = None
self._token_client: Optional[aiohttp.ClientSession] = None
self._token_type: Optional[str] = None
self._token: Optional[str] = None
self._expiry: Optional[datetime.datetime] = None
self._paypal_client_id: str = paypal_client_id
self._paypal_secret: str = paypal_secret
self._required_role: int = required_role
self._paypal_url: str = paypal_url
async def refresh_token(self) -> None:
if self._token_client is None:
self._token_client = aiohttp.ClientSession(
headers={
"Accept": "application/json",
"Accept-Language": "en_US",
},
auth=aiohttp.BasicAuth(self._paypal_client_id, self._paypal_secret)
)
async with self._token_client.post(f"{self._paypal_url}/v1/oauth2/token",
data="grant_type=client_credentials") as request:
return_json: dict = await request.json()
self._expiry = datetime.datetime.utcnow() + datetime.timedelta(seconds=return_json["expires_in"])
self._token_type = return_json["token_type"]
self._token = return_json["access_token"]
async def cog_check(self, ctx: commands.Context) -> bool:
role: discord.Role = ctx.guild.get_role(self._required_role)
permissible: bool = role in ctx.author.roles
if permissible:
return permissible
else:
raise commands.MissingPermissions
def cog_unload(self) -> None:
if self._token_client is not None:
self.bot.loop.run_until_complete(self._token_client.close())
if self._paypal_client is not None:
self.bot.loop.run_until_complete(self._paypal_client.close())
async def cog_before_invoke(self, ctx: commands.Context) -> None:
if self._expiry is None or datetime.datetime.utcnow() > self._expiry:
await self.refresh_token()
if self._paypal_client is None:
self._paypal_client = aiohttp.ClientSession()
@commands.command()
async def invoice(
self,
ctx: commands.Context,
amount: int = commands.Option(description="The amount of money, USD, that is owed."),
) -> None:
"""Creates an invoice for the specified amount and sends it."""
await ctx.defer(ephemeral=True)
await ctx.send("This command is not yet implemented.", ephemeral=True)
if __name__ == "__main__":
debug: bool = os.environ.get("DEBUG") is not None
# Setup logging
logging.basicConfig(
level=logging.DEBUG if debug else logging.INFO, format="%(asctime)s:%(levelname)s:%(name)s: %(message)s"
)
if os.environ.get("LOGGING_WEBHOOK") is not None:
logging.root.addHandler(dislog.DiscordWebhookHandler(os.environ.get("LOGGING_WEBHOOK")))
# Initialize everything
role_id: int = int(os.environ["FREELANCE_ROLE"])
guild_id: int = int(os.environ["MAIN_GUILD"])
loop: asyncio.AbstractEventLoop = asyncio.get_event_loop_policy().new_event_loop()
bot: commands.Bot = commands.Bot(
max_messages=None, # Slim this bitch RIGHT down! We are never using messages.
command_prefix=".", # We don't use this.
description=None,
intents=discord.Intents(guilds=True),
slash_command_guilds=[guild_id] if debug else None,
message_commands=False,
slash_commands=True,
help_command=None,
loop=loop,
activity=discord.Game("Serious business.")
)
bot.add_cog(TimeCog(bot)) # No prereq's for this
maybe_paypal_secret: Optional[str] = os.environ.get("PAYPAL_SECRET")
maybe_paypal_client_id: Optional[str] = os.environ.get("PAYPAL_CLIENT_ID")
if maybe_paypal_secret is not None and maybe_paypal_client_id is not None:
bot.add_cog(
PayPalCog(
bot,
maybe_paypal_client_id,
maybe_paypal_secret,
role_id,
"https://api-m.paypal.com" if not debug else "https://api-m.sandbox.paypal.com"
),
)
# Get running!
bot.run(os.environ["DISCORD_TOKEN"])