cooldowns.Bot.meme()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
dl 0
loc 22
rs 9.8
c 0
b 0
f 0
cc 1
nop 1
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