1
|
|
|
from random import randint |
2
|
|
|
from typing import Tuple |
3
|
|
|
|
4
|
|
|
from aiohttp import ClientSession |
5
|
|
|
|
6
|
|
|
from pincer import Client, command |
7
|
|
|
from pincer.exceptions import CommandCooldownError |
8
|
|
|
from pincer.objects import Embed, MessageContext, Message, InteractionFlags |
9
|
|
|
from pincer.utils import MISSING |
10
|
|
|
|
11
|
|
|
|
12
|
|
|
# Create our base bot client, if you want to you can use an init an |
13
|
|
|
# super call it. But that isn't required for this example. |
14
|
|
|
|
15
|
|
|
|
16
|
|
|
class Bot(Client): |
17
|
|
|
# Our url from where we'll get our juicy memes! |
18
|
|
|
MEME_URL = "https://some-random-api.ml/meme" |
19
|
|
|
|
20
|
|
|
@staticmethod |
21
|
|
|
def random_color(): |
22
|
|
|
""" |
23
|
|
|
Generate a valid random Discord color! |
24
|
|
|
""" |
25
|
|
|
return randint(0, 16581375) |
26
|
|
|
|
27
|
|
|
async def get_meme(self) -> Tuple[str, str]: |
28
|
|
|
""" |
29
|
|
|
Get a random meme from our configured MEME_URL! |
30
|
|
|
""" |
31
|
|
|
# Standard aiohttp session setup: |
32
|
|
|
async with ClientSession() as session: |
33
|
|
|
# Send our HTTP get request! |
34
|
|
|
async with session.get(self.MEME_URL) as response: |
35
|
|
|
# To extract the data we need to have the json as a dict! |
36
|
|
|
data = await response.json() |
37
|
|
|
|
38
|
|
|
# If the json was malformed, make sure we have backup values! |
39
|
|
|
caption = data.get("caption", "Oops, something went wrong!") |
40
|
|
|
image = data.get("image", MISSING) |
41
|
|
|
|
42
|
|
|
# Return it as a tuple so we can easily extract the two |
43
|
|
|
# values in our method which called this! |
44
|
|
|
return caption, image |
45
|
|
|
|
46
|
|
|
@Client.event |
47
|
|
|
async def on_ready(self): |
48
|
|
|
# Our client has successfully started, lets let ourself know that! |
49
|
|
|
print("Successfully created discord client on", self.bot) |
50
|
|
|
|
51
|
|
|
@command( |
52
|
|
|
# We don't want to send too many requests to our `MEME_URL` so |
53
|
|
|
# lets use cooldowns! |
54
|
|
|
# Only allow one request |
55
|
|
|
cooldown=1, |
56
|
|
|
# For every three seconds |
57
|
|
|
cooldown_scale=3, |
58
|
|
|
# And just to make things more clear for our user on what this |
59
|
|
|
# command does, lets define a description! |
60
|
|
|
description="Get a random meme!", |
61
|
|
|
) |
62
|
|
|
async def meme(self): |
63
|
|
|
# Fetch our caption and image from our `MEME_URL`. |
64
|
|
|
caption, image = await self.get_meme() |
65
|
|
|
|
66
|
|
|
# Respond with an embed which contains the meme and caption! |
67
|
|
|
return ( |
68
|
|
|
Embed(caption, color=self.random_color()) |
69
|
|
|
.set_image(image) |
70
|
|
|
.set_footer( |
71
|
|
|
"Provided by some-random-api.ml", |
72
|
|
|
"https://i.some-random-api.ml/logo.png", |
73
|
|
|
) |
74
|
|
|
) |
75
|
|
|
|
76
|
|
|
@Client.event |
77
|
|
|
async def on_command_error(self, ctx: MessageContext, error: Exception): |
78
|
|
|
# OH NO, something went wrong while executing our command. |
79
|
|
|
# Don't worry tho, it might be our user whom is trespassing our |
80
|
|
|
# set cooldown. Lets check if the error is a cooldown error, |
81
|
|
|
if isinstance(error, CommandCooldownError): |
82
|
|
|
# Yeah, the user got rate limited by our cooldown. |
83
|
|
|
# Lets let them know in a private embed message! |
84
|
|
|
return Message( |
85
|
|
|
embeds=[ |
86
|
|
|
Embed( |
87
|
|
|
title="Oops...", |
88
|
|
|
description=f"The `{ctx.command.app.name}` command can " |
89
|
|
|
f"only be used `{ctx.command.cooldown}` time*(s)* every" |
90
|
|
|
f" `{ctx.command.cooldown_scale}` second*(s)*!", |
91
|
|
|
color=self.random_color(), |
92
|
|
|
) |
93
|
|
|
], |
94
|
|
|
flags=InteractionFlags.EPHEMERAL, |
95
|
|
|
) |
96
|
|
|
|
97
|
|
|
# Oh no, it wasn't a cooldown error. Lets throw it! |
98
|
|
|
raise error |
99
|
|
|
|
100
|
|
|
|
101
|
|
|
if __name__ == "__main__": |
102
|
|
|
# Of course we have to run our client, you can replace the |
103
|
|
|
# XXXYOURBOTTOKENHEREXXX with your token, or dynamically get it |
104
|
|
|
# through a dotenv/env. |
105
|
|
|
Bot("XXXYOURBOTTOKENHEREXXX").run() |
106
|
|
|
|