feat: Implement Sponsors.
This commit is contained in:
7
data/migration/v13-v14/migration.sql
Normal file
7
data/migration/v13-v14/migration.sql
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
ALTER TABLE bot_config ADD COLUMN sponsor_prompt TEXT;
|
||||||
|
ALTER TABLE bot_config ADD COLUMN sponsor_message TEXT;
|
||||||
|
|
||||||
|
INSERT INTO VersionHistory (version, author) VALUES (14, 'v13-v14 migration');
|
||||||
|
COMMIT;
|
||||||
@@ -4,7 +4,7 @@ CREATE TABLE VersionHistory(
|
|||||||
time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
time TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
|
||||||
author TEXT
|
author TEXT
|
||||||
);
|
);
|
||||||
INSERT INTO VersionHistory (version, author) VALUES (13, 'Initial Creation');
|
INSERT INTO VersionHistory (version, author) VALUES (14, 'Initial Creation');
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION update_timestamp_column()
|
CREATE OR REPLACE FUNCTION update_timestamp_column()
|
||||||
@@ -17,17 +17,6 @@ $$ language 'plpgsql';
|
|||||||
-- }}}
|
-- }}}
|
||||||
|
|
||||||
-- App metadata {{{
|
-- App metadata {{{
|
||||||
CREATE TABLE AppData(
|
|
||||||
appid TEXT PRIMARY KEY,
|
|
||||||
last_study_badge_scan TIMESTAMP
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE AppConfig(
|
|
||||||
appid TEXT,
|
|
||||||
key TEXT,
|
|
||||||
value TEXT,
|
|
||||||
PRIMARY KEY(appid, key)
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE TABLE global_user_blacklist(
|
CREATE TABLE global_user_blacklist(
|
||||||
userid BIGINT PRIMARY KEY,
|
userid BIGINT PRIMARY KEY,
|
||||||
@@ -50,6 +39,8 @@ CREATE TABLE app_config(
|
|||||||
|
|
||||||
CREATE TABLE bot_config(
|
CREATE TABLE bot_config(
|
||||||
appname TEXT PRIMARY KEY REFERENCES app_config(appname) ON DELETE CASCADE,
|
appname TEXT PRIMARY KEY REFERENCES app_config(appname) ON DELETE CASCADE,
|
||||||
|
sponsor_prompt TEXT,
|
||||||
|
sponsor_message TEXT,
|
||||||
default_skin TEXT
|
default_skin TEXT
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
CONFIG_FILE = "config/bot.conf"
|
CONFIG_FILE = "config/bot.conf"
|
||||||
DATA_VERSION = 13
|
DATA_VERSION = 14
|
||||||
|
|
||||||
MAX_COINS = 2147483647 - 1
|
MAX_COINS = 2147483647 - 1
|
||||||
|
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ class CoreData(Registry, name="core"):
|
|||||||
------
|
------
|
||||||
CREATE TABLE bot_config(
|
CREATE TABLE bot_config(
|
||||||
appname TEXT PRIMARY KEY REFERENCES app_config(appname) ON DELETE CASCADE,
|
appname TEXT PRIMARY KEY REFERENCES app_config(appname) ON DELETE CASCADE,
|
||||||
|
sponsor_prompt TEXT,
|
||||||
|
sponsor_message TEXT,
|
||||||
default_skin TEXT
|
default_skin TEXT
|
||||||
);
|
);
|
||||||
"""
|
"""
|
||||||
@@ -54,6 +56,8 @@ class CoreData(Registry, name="core"):
|
|||||||
|
|
||||||
appname = String(primary=True)
|
appname = String(primary=True)
|
||||||
default_skin = String()
|
default_skin = String()
|
||||||
|
sponsor_prompt = String()
|
||||||
|
sponsor_message = String()
|
||||||
|
|
||||||
class Shard(RowModel):
|
class Shard(RowModel):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ active = [
|
|||||||
'.moderation',
|
'.moderation',
|
||||||
'.video_channels',
|
'.video_channels',
|
||||||
'.meta',
|
'.meta',
|
||||||
|
'.sponsors',
|
||||||
'.test',
|
'.test',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
10
src/modules/sponsors/__init__.py
Normal file
10
src/modules/sponsors/__init__.py
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import logging
|
||||||
|
from babel.translator import LocalBabel
|
||||||
|
|
||||||
|
babel = LocalBabel('sponsors')
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
async def setup(bot):
|
||||||
|
from .cog import SponsorCog
|
||||||
|
await bot.add_cog(SponsorCog(bot))
|
||||||
126
src/modules/sponsors/cog.py
Normal file
126
src/modules/sponsors/cog.py
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
from typing import Optional
|
||||||
|
import asyncio
|
||||||
|
|
||||||
|
import discord
|
||||||
|
from discord.ext import commands as cmds
|
||||||
|
import discord.app_commands as appcmds
|
||||||
|
|
||||||
|
from meta import LionCog, LionBot, LionContext
|
||||||
|
from wards import sys_admin_ward
|
||||||
|
|
||||||
|
from . import logger, babel
|
||||||
|
from .data import SponsorData
|
||||||
|
from .settings import SponsorSettings
|
||||||
|
from .settingui import SponsorUI
|
||||||
|
|
||||||
|
_p = babel._p
|
||||||
|
|
||||||
|
|
||||||
|
class SponsorCog(LionCog):
|
||||||
|
def __init__(self, bot: LionBot):
|
||||||
|
self.bot = bot
|
||||||
|
self.data: SponsorData = bot.db.load_registry(SponsorData())
|
||||||
|
self.settings = SponsorSettings
|
||||||
|
|
||||||
|
self.whitelisted = self.settings.Whitelist._cache
|
||||||
|
|
||||||
|
async def cog_load(self):
|
||||||
|
await self.data.init()
|
||||||
|
if (leo_setting_cog := self.bot.get_cog('LeoSettings')) is not None:
|
||||||
|
leo_setting_cog.bot_setting_groups.append(self.settings)
|
||||||
|
self.crossload_group(self.leo_group, leo_setting_cog.leo_group)
|
||||||
|
|
||||||
|
async def do_sponsor_prompt(self, interaction: discord.Interaction):
|
||||||
|
"""
|
||||||
|
Send the sponsor prompt as a followup to this interaction, if applicable.
|
||||||
|
"""
|
||||||
|
if not interaction.is_expired():
|
||||||
|
# TODO: caching
|
||||||
|
whitelist = (await self.settings.Whitelist.get(self.bot.appname)).value
|
||||||
|
if interaction.guild and interaction.guild.id in whitelist:
|
||||||
|
return
|
||||||
|
setting = await self.settings.SponsorPrompt.get(self.bot.appname)
|
||||||
|
value = setting.value
|
||||||
|
if value:
|
||||||
|
args = setting.value_to_args(self.bot.appname, value)
|
||||||
|
followup = interaction.followup
|
||||||
|
await followup.send(**args.send_args, ephemeral=True)
|
||||||
|
|
||||||
|
@cmds.hybrid_command(
|
||||||
|
name=_p('cmd:sponsors', "sponsors"),
|
||||||
|
description=_p(
|
||||||
|
'cmd:sponsors|desc',
|
||||||
|
"Check out our wonderful partners!"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
async def sponsor_cmd(self, ctx: LionContext):
|
||||||
|
"""
|
||||||
|
Display the sponsors message, if set.
|
||||||
|
"""
|
||||||
|
if ctx.interaction:
|
||||||
|
await ctx.interaction.response.defer(thinking=True, ephemeral=True)
|
||||||
|
|
||||||
|
sponsor = await self.settings.SponsorMessage.get(self.bot.appname)
|
||||||
|
value = sponsor.value
|
||||||
|
if value:
|
||||||
|
args = sponsor.value_to_args(self.bot.appname, value)
|
||||||
|
await ctx.reply(**args.send_args)
|
||||||
|
else:
|
||||||
|
await ctx.reply(
|
||||||
|
"Coming Soon!"
|
||||||
|
)
|
||||||
|
|
||||||
|
@LionCog.placeholder_group
|
||||||
|
@cmds.hybrid_group("leo", with_app_command=False)
|
||||||
|
async def leo_group(self, ctx: LionContext):
|
||||||
|
...
|
||||||
|
|
||||||
|
@leo_group.command(
|
||||||
|
name=_p(
|
||||||
|
'cmd:leo_sponsors', "sponsors"
|
||||||
|
),
|
||||||
|
description=_p(
|
||||||
|
'cmd:leo_sponsors|desc',
|
||||||
|
"Configure the sponsor text and whitelist."
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@appcmds.rename(
|
||||||
|
sponsor_prompt=SponsorSettings.SponsorPrompt._display_name,
|
||||||
|
sponsor_message=SponsorSettings.SponsorMessage._display_name,
|
||||||
|
)
|
||||||
|
@appcmds.describe(
|
||||||
|
sponsor_prompt=SponsorSettings.SponsorPrompt._desc,
|
||||||
|
sponsor_message=SponsorSettings.SponsorMessage._desc,
|
||||||
|
)
|
||||||
|
@sys_admin_ward
|
||||||
|
async def leo_sponsors_cmd(self, ctx: LionContext,
|
||||||
|
sponsor_prompt: Optional[discord.Attachment] = None,
|
||||||
|
sponsor_message: Optional[discord.Attachment] = None,
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Open the configuration UI for sponsors, and optionally set the prompt and message.
|
||||||
|
"""
|
||||||
|
if not ctx.interaction:
|
||||||
|
return
|
||||||
|
|
||||||
|
await ctx.interaction.response.defer(thinking=True)
|
||||||
|
modified = []
|
||||||
|
|
||||||
|
if sponsor_prompt is not None:
|
||||||
|
setting = self.settings.SponsorPrompt
|
||||||
|
content = await setting.download_attachment(sponsor_prompt)
|
||||||
|
instance = await setting.from_string(self.bot.appname, content)
|
||||||
|
modified.append(instance)
|
||||||
|
|
||||||
|
if sponsor_message is not None:
|
||||||
|
setting = self.settings.SponsorMessage
|
||||||
|
content = await setting.download_attachment(sponsor_message)
|
||||||
|
instance = await setting.from_string(self.bot.appname, content)
|
||||||
|
modified.append(instance)
|
||||||
|
|
||||||
|
for instance in modified:
|
||||||
|
await instance.write()
|
||||||
|
|
||||||
|
ui = SponsorUI(self.bot, self.bot.appname, ctx.channel.id)
|
||||||
|
await ui.run(ctx.interaction)
|
||||||
|
await ui.wait()
|
||||||
5
src/modules/sponsors/data.py
Normal file
5
src/modules/sponsors/data.py
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
from data import Registry, Table
|
||||||
|
|
||||||
|
|
||||||
|
class SponsorData(Registry):
|
||||||
|
sponsor_whitelist = Table('sponsor_guild_whitelist')
|
||||||
87
src/modules/sponsors/settings.py
Normal file
87
src/modules/sponsors/settings.py
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
from settings.data import ListData, ModelData
|
||||||
|
from settings.groups import SettingGroup
|
||||||
|
from settings.setting_types import GuildIDListSetting
|
||||||
|
|
||||||
|
from core.setting_types import MessageSetting
|
||||||
|
from core.data import CoreData
|
||||||
|
from wards import sys_admin_iward
|
||||||
|
from . import babel
|
||||||
|
from .data import SponsorData
|
||||||
|
|
||||||
|
_p = babel._p
|
||||||
|
|
||||||
|
|
||||||
|
class SponsorSettings(SettingGroup):
|
||||||
|
class Whitelist(ListData, GuildIDListSetting):
|
||||||
|
setting_id = 'sponsor_whitelist'
|
||||||
|
_write_ward = sys_admin_iward
|
||||||
|
|
||||||
|
_display_name = _p(
|
||||||
|
'botset:sponsor_whitelist', "sponsor_whitelist"
|
||||||
|
)
|
||||||
|
_desc = _p(
|
||||||
|
'botset:sponsor_whitelist|desc',
|
||||||
|
"List of guildids where the sponsor prompt is not shown."
|
||||||
|
)
|
||||||
|
_long_desc = _p(
|
||||||
|
'botset:sponsor_whitelist|long_desc',
|
||||||
|
"The sponsor prompt will not appear in the set guilds."
|
||||||
|
)
|
||||||
|
_accepts = _p(
|
||||||
|
'botset:sponsor_whitelist|accetps',
|
||||||
|
"Comma separated list of guildids."
|
||||||
|
)
|
||||||
|
|
||||||
|
_table_interface = SponsorData.sponsor_whitelist
|
||||||
|
_id_column = 'appid'
|
||||||
|
_data_column = 'guildid'
|
||||||
|
_order_column = 'guildid'
|
||||||
|
|
||||||
|
class SponsorPrompt(ModelData, MessageSetting):
|
||||||
|
setting_id = 'sponsor_prompt'
|
||||||
|
_set_cmd = 'leo sponsors'
|
||||||
|
_write_ward = sys_admin_iward
|
||||||
|
|
||||||
|
_display_name = _p(
|
||||||
|
'botset:sponsor_prompt', "sponsor_prompt"
|
||||||
|
)
|
||||||
|
_desc = _p(
|
||||||
|
'botset:sponsor_prompt|desc',
|
||||||
|
"Message to add underneath core commands."
|
||||||
|
)
|
||||||
|
_long_desc = _p(
|
||||||
|
'botset:sponsor_prompt|long_desc',
|
||||||
|
"Content of the message to send after core commands such as stats,"
|
||||||
|
" reminding users to check the sponsors command."
|
||||||
|
)
|
||||||
|
|
||||||
|
_model = CoreData.BotConfig
|
||||||
|
_column = CoreData.BotConfig.sponsor_prompt.name
|
||||||
|
|
||||||
|
async def editor_callback(self, editor_data):
|
||||||
|
self.value = editor_data
|
||||||
|
await self.write()
|
||||||
|
|
||||||
|
class SponsorMessage(ModelData, MessageSetting):
|
||||||
|
setting_id = 'sponsor_message'
|
||||||
|
_set_cmd = 'leo sponsors'
|
||||||
|
_write_ward = sys_admin_iward
|
||||||
|
|
||||||
|
_display_name = _p(
|
||||||
|
'botset:sponsor_message', "sponsor_message"
|
||||||
|
)
|
||||||
|
_desc = _p(
|
||||||
|
'botset:sponsor_message|desc',
|
||||||
|
"Message to send in response to /sponsors command."
|
||||||
|
)
|
||||||
|
_long_desc = _p(
|
||||||
|
'botset:sponsor_message|long_desc',
|
||||||
|
"Content of the message to send when a user runs the `/sponsors` command."
|
||||||
|
)
|
||||||
|
|
||||||
|
_model = CoreData.BotConfig
|
||||||
|
_column = CoreData.BotConfig.sponsor_message.name
|
||||||
|
|
||||||
|
async def editor_callback(self, editor_data):
|
||||||
|
self.value = editor_data
|
||||||
|
await self.write()
|
||||||
122
src/modules/sponsors/settingui.py
Normal file
122
src/modules/sponsors/settingui.py
Normal file
@@ -0,0 +1,122 @@
|
|||||||
|
import asyncio
|
||||||
|
|
||||||
|
import discord
|
||||||
|
from discord.ui.button import button, Button, ButtonStyle
|
||||||
|
|
||||||
|
from meta import LionBot
|
||||||
|
|
||||||
|
from utils.ui import ConfigUI
|
||||||
|
from utils.lib import MessageArgs
|
||||||
|
from utils.ui.msgeditor import MsgEditor
|
||||||
|
|
||||||
|
from .settings import SponsorSettings as Settings
|
||||||
|
from . import babel, logger
|
||||||
|
|
||||||
|
_p = babel._p
|
||||||
|
|
||||||
|
|
||||||
|
class SponsorUI(ConfigUI):
|
||||||
|
setting_classes = (
|
||||||
|
Settings.SponsorPrompt,
|
||||||
|
Settings.SponsorMessage,
|
||||||
|
Settings.Whitelist,
|
||||||
|
)
|
||||||
|
|
||||||
|
def __init__(self, bot: LionBot, appname: str, channelid: int, **kwargs):
|
||||||
|
self.settings = bot.get_cog('SponsorCog').settings
|
||||||
|
super().__init__(bot, appname, channelid, **kwargs)
|
||||||
|
|
||||||
|
# ----- UI Components -----
|
||||||
|
@button(
|
||||||
|
label="SPONSOR_PROMPT_BUTTON_PLACEHOLDER",
|
||||||
|
style=ButtonStyle.blurple
|
||||||
|
)
|
||||||
|
async def sponsor_prompt_button(self, press: discord.Interaction, pressed: Button):
|
||||||
|
await press.response.defer(thinking=True, ephemeral=True)
|
||||||
|
setting = self.get_instance(Settings.SponsorPrompt)
|
||||||
|
|
||||||
|
value = setting.value
|
||||||
|
if value is None:
|
||||||
|
value = {'content': "Empty"}
|
||||||
|
|
||||||
|
editor = MsgEditor(
|
||||||
|
self.bot,
|
||||||
|
value,
|
||||||
|
callback=setting.editor_callback,
|
||||||
|
callerid=press.user.id,
|
||||||
|
)
|
||||||
|
self._slaves.append(editor)
|
||||||
|
await editor.run(press)
|
||||||
|
|
||||||
|
async def sponsor_prompt_button_refresh(self):
|
||||||
|
button = self.sponsor_prompt_button
|
||||||
|
t = self.bot.translator.t
|
||||||
|
button.label = t(_p(
|
||||||
|
'ui:sponsors|button:sponsor_prompt|label',
|
||||||
|
"Sponsor Prompt"
|
||||||
|
))
|
||||||
|
|
||||||
|
@button(
|
||||||
|
label="SPONSOR_MESSAGE_BUTTON_PLACEHOLDER",
|
||||||
|
style=ButtonStyle.blurple
|
||||||
|
)
|
||||||
|
async def sponsor_message_button(self, press: discord.Interaction, pressed: Button):
|
||||||
|
await press.response.defer(thinking=True, ephemeral=True)
|
||||||
|
setting = self.get_instance(Settings.SponsorMessage)
|
||||||
|
|
||||||
|
value = setting.value
|
||||||
|
if value is None:
|
||||||
|
value = {'content': "Empty"}
|
||||||
|
|
||||||
|
editor = MsgEditor(
|
||||||
|
self.bot,
|
||||||
|
value,
|
||||||
|
callback=setting.editor_callback,
|
||||||
|
callerid=press.user.id,
|
||||||
|
)
|
||||||
|
self._slaves.append(editor)
|
||||||
|
await editor.run(press)
|
||||||
|
|
||||||
|
async def sponsor_message_button_refresh(self):
|
||||||
|
button = self.sponsor_message_button
|
||||||
|
t = self.bot.translator.t
|
||||||
|
button.label = t(_p(
|
||||||
|
'ui:sponsors|button:sponsor_message|label',
|
||||||
|
"Sponsor Message"
|
||||||
|
))
|
||||||
|
# ----- UI Flow -----
|
||||||
|
async def make_message(self) -> MessageArgs:
|
||||||
|
t = self.bot.translator.t
|
||||||
|
title = t(_p(
|
||||||
|
'ui:sponsors|embed|title',
|
||||||
|
"Leo Sponsor Panel"
|
||||||
|
))
|
||||||
|
embed = discord.Embed(
|
||||||
|
title=title,
|
||||||
|
colour=discord.Colour.orange()
|
||||||
|
)
|
||||||
|
for setting in self.instances:
|
||||||
|
embed.add_field(**setting.embed_field, inline=False)
|
||||||
|
|
||||||
|
return MessageArgs(embed=embed)
|
||||||
|
|
||||||
|
async def reload(self):
|
||||||
|
self.instances = [
|
||||||
|
await setting.get(self.bot.appname)
|
||||||
|
for setting in self.setting_classes
|
||||||
|
]
|
||||||
|
|
||||||
|
async def refresh_components(self):
|
||||||
|
to_refresh = (
|
||||||
|
self.edit_button_refresh(),
|
||||||
|
self.close_button_refresh(),
|
||||||
|
self.reset_button_refresh(),
|
||||||
|
self.sponsor_message_button_refresh(),
|
||||||
|
self.sponsor_prompt_button_refresh(),
|
||||||
|
)
|
||||||
|
await asyncio.gather(*to_refresh)
|
||||||
|
|
||||||
|
self.set_layout(
|
||||||
|
(self.sponsor_prompt_button, self.sponsor_message_button,
|
||||||
|
self.edit_button, self.reset_button, self.close_button)
|
||||||
|
)
|
||||||
@@ -55,6 +55,8 @@ class StatsCog(LionCog):
|
|||||||
await ctx.interaction.response.defer(thinking=True)
|
await ctx.interaction.response.defer(thinking=True)
|
||||||
ui = ProfileUI(self.bot, ctx.author, ctx.guild)
|
ui = ProfileUI(self.bot, ctx.author, ctx.guild)
|
||||||
await ui.run(ctx.interaction)
|
await ui.run(ctx.interaction)
|
||||||
|
if sponsors := self.bot.get_cog('SponsorCog'):
|
||||||
|
await sponsors.do_sponsor_prompt(ctx.interaction)
|
||||||
await ui.wait()
|
await ui.wait()
|
||||||
|
|
||||||
@cmds.hybrid_command(
|
@cmds.hybrid_command(
|
||||||
@@ -101,6 +103,9 @@ class StatsCog(LionCog):
|
|||||||
file = discord.File(profile_data, 'profile.png')
|
file = discord.File(profile_data, 'profile.png')
|
||||||
await ctx.reply(file=file)
|
await ctx.reply(file=file)
|
||||||
|
|
||||||
|
if sponsors := self.bot.get_cog('SponsorCog'):
|
||||||
|
await sponsors.do_sponsor_prompt(ctx.interaction)
|
||||||
|
|
||||||
@cmds.hybrid_command(
|
@cmds.hybrid_command(
|
||||||
name=_p('cmd:stats', "stats"),
|
name=_p('cmd:stats', "stats"),
|
||||||
description=_p(
|
description=_p(
|
||||||
@@ -116,6 +121,10 @@ class StatsCog(LionCog):
|
|||||||
await ctx.interaction.response.defer(thinking=True)
|
await ctx.interaction.response.defer(thinking=True)
|
||||||
ui = WeeklyMonthlyUI(self.bot, ctx.author, ctx.guild)
|
ui = WeeklyMonthlyUI(self.bot, ctx.author, ctx.guild)
|
||||||
await ui.run(ctx.interaction)
|
await ui.run(ctx.interaction)
|
||||||
|
|
||||||
|
if sponsors := self.bot.get_cog('SponsorCog'):
|
||||||
|
await sponsors.do_sponsor_prompt(ctx.interaction)
|
||||||
|
|
||||||
await ui.wait()
|
await ui.wait()
|
||||||
|
|
||||||
@cmds.hybrid_command(
|
@cmds.hybrid_command(
|
||||||
@@ -151,6 +160,10 @@ class StatsCog(LionCog):
|
|||||||
await ctx.interaction.response.defer(thinking=True)
|
await ctx.interaction.response.defer(thinking=True)
|
||||||
ui = LeaderboardUI(self.bot, ctx.author, ctx.guild)
|
ui = LeaderboardUI(self.bot, ctx.author, ctx.guild)
|
||||||
await ui.run(ctx.interaction)
|
await ui.run(ctx.interaction)
|
||||||
|
|
||||||
|
if sponsors := self.bot.get_cog('SponsorCog'):
|
||||||
|
await sponsors.do_sponsor_prompt(ctx.interaction)
|
||||||
|
|
||||||
await ui.wait()
|
await ui.wait()
|
||||||
|
|
||||||
@cmds.hybrid_command(
|
@cmds.hybrid_command(
|
||||||
|
|||||||
@@ -1381,7 +1381,7 @@ class StringListSetting(InteractiveSetting, ListSetting):
|
|||||||
_setting = StringSetting
|
_setting = StringSetting
|
||||||
|
|
||||||
|
|
||||||
class GuildIDListSetting(InteractiveSetting, ListSetting):
|
class GuildIDListSetting(ListSetting, InteractiveSetting):
|
||||||
"""
|
"""
|
||||||
List of guildids.
|
List of guildids.
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in New Issue
Block a user