2024-08-07 18:37:15 +00:00
import nextcord
from nextcord . ext import commands
from nextcord import TextInputStyle
2024-08-05 19:12:11 +00:00
from random import randint
import aiosqlite as sqlite3
import aiohttp
2024-08-11 18:06:21 +00:00
import traceback
2024-08-09 21:48:13 +00:00
import asyncio
2024-08-05 19:12:11 +00:00
from urllib . parse import urlparse
import os
2024-08-07 18:37:15 +00:00
class ApplicationView ( nextcord . ui . View ) :
2024-08-09 12:59:25 +00:00
def __init__ ( self , bot ) :
2024-08-07 18:37:15 +00:00
super ( ) . __init__ ( timeout = None )
self . bot = bot
@nextcord.ui.button (
label = " Approve " , style = nextcord . ButtonStyle . green , custom_id = " speechbubble:approve "
)
async def approve ( self , button : nextcord . ui . Button , interaction : nextcord . Interaction ) :
ogmsg = interaction . message . embeds
embed = ogmsg [ 0 ]
if interaction . user . id != int ( embed . fields [ 0 ] . value ) :
await interaction . response . send_message ( " you may not modify this speech bubble! " , ephemeral = True )
return
embed . add_field (
name = " Status " ,
value = " Approved " ,
inline = False ,
)
await self . bot . cur . execute ( f """
INSERT INTO userinfo VALUES
( { interaction . guild_id } , { int ( embed . fields [ 0 ] . value ) } , ' {embed.fields[1].value} ' , { int ( embed . fields [ 2 ] . value ) } )
""" )
await self . bot . db . commit ( )
await interaction . response . edit_message ( embed = embed , view = None )
return
@nextcord.ui.button (
label = " Deny " , style = nextcord . ButtonStyle . red , custom_id = " speechbubble:deny "
)
async def deny ( self , button : nextcord . ui . Button , interaction : nextcord . Interaction ) :
ogmsg = interaction . message . embeds
embed = ogmsg [ 0 ]
if interaction . user . id != int ( embed . fields [ 0 ] . value ) :
await interaction . response . send_message ( " you may not modify this speech bubble! " , ephemeral = True )
return
embed . add_field (
name = " Status " ,
value = " Denied " ,
inline = False ,
)
await interaction . response . edit_message ( embed = embed , view = None )
return
class ApplicationModal ( nextcord . ui . Modal ) :
2024-08-09 12:59:25 +00:00
def __init__ ( self , user , bot ) :
2024-08-05 19:12:11 +00:00
self . victim = user
2024-08-09 12:59:25 +00:00
self . bot = bot
2024-08-07 18:37:15 +00:00
super ( ) . __init__ (
f " create a speechbubble for { user . name } "
)
2024-08-05 19:12:11 +00:00
2024-08-07 18:37:15 +00:00
self . image = nextcord . ui . TextInput (
label = " link to image " ,
placeholder = " https://media.discordapp.net/goofyimg.png " ,
style = TextInputStyle . short ,
max_length = 400 ,
)
self . add_item ( self . image )
self . chance = nextcord . ui . TextInput (
label = " chance: a 1 in x chance " ,
placeholder = " 10 " ,
style = TextInputStyle . short ,
max_length = 5 ,
)
self . add_item ( self . chance )
async def callback ( self , interaction : nextcord . Interaction ) - > None :
embed = nextcord . Embed ( title = " New speech bubble! " , color = nextcord . Colour . green ( ) )
2024-08-05 19:12:11 +00:00
embed . add_field (
name = " User ID " ,
value = self . victim . id ,
inline = False ,
)
2024-08-07 18:37:15 +00:00
print ( self . image . value )
if urlparse ( self . image . value ) . netloc != ' media.discordapp.net ' and urlparse ( self . image . value ) . netloc != ' cdn.discordapp.com ' :
2024-08-11 17:42:11 +00:00
await interaction . send_message ( f " for security reasons, the bot only accepts images from media.discordapp.net or cdn.discordapp.com " , ephemeral = True )
2024-08-07 18:37:15 +00:00
return
async with aiohttp . ClientSession ( ) as session :
async with session . get ( self . image . value ) as response :
if ( response . status == 200 ) and ( response . headers [ ' content-type ' ] == " image/png " or response . headers [ ' content-type ' ] == " image/jpeg " or response . headers [ ' content-type ' ] == " image/jpg " ) :
pass
else :
await interaction . send ( f " you did not supply an image { response . status } { response . headers [ ' content-type ' ] } " , ephemeral = True )
2024-08-05 19:12:11 +00:00
return
2024-08-07 18:37:15 +00:00
if not self . chance . value . isdigit ( ) :
await interaction . send ( " you supplied words for a number " , ephemeral = True )
2024-08-05 19:12:11 +00:00
return
2024-08-07 18:37:15 +00:00
embed . add_field (
name = " Image " ,
value = self . image . value ,
inline = False ,
)
embed . add_field (
name = " Chance, a 1 in x chance " ,
value = self . chance . value ,
inline = False ,
)
2024-08-09 12:59:25 +00:00
await interaction . send ( f " <@ { self . victim . id } > { interaction . user . name } proposes the following speech bubble for you: " , embed = embed , view = ApplicationView ( self . bot ) )
2024-08-05 19:12:11 +00:00
2024-08-11 18:04:53 +00:00
async def on_error ( self , interaction : nextcord . Interaction , error : nextcord . DiscordException ) :
error = traceback . format_exception ( type ( error ) , error , error . __traceback__ )
strerror = " " . join ( error )
print ( strerror , file = sys . stderr )
message = f " ```py \n { strerror [ - 1800 : ] } \n ``` \n Contact <@ { self . bot . owner_id } > if the error persists "
try :
await interaction . send ( message , ephemeral = True )
except :
await interaction . followup . send ( message , ephemeral = True )
2024-08-05 19:12:11 +00:00
class speechbubble ( commands . Cog ) :
def __init__ ( self , bot : commands . Bot ) :
self . bot = bot
2024-08-10 19:57:19 +00:00
#errors if first loaded but is needed after
try :
self . bot . add_view ( ApplicationView ( self . bot ) )
except :
pass
2024-08-09 12:51:22 +00:00
2024-08-10 19:20:40 +00:00
@commands.Cog.listener ( ' on_ready ' )
async def bubbleready ( self ) :
self . bot . add_view ( ApplicationView ( self . bot ) )
2024-08-05 19:12:11 +00:00
@commands.Cog.listener ( ' on_message ' )
async def on_message ( self , message ) :
res = await self . bot . cur . execute ( f " SELECT imagelink, chance FROM userinfo WHERE serverid = { message . guild . id } AND userid = { message . author . id } ORDER BY RANDOM() LIMIT 1 " )
try :
imagelink , chance = await res . fetchone ( )
except TypeError :
return
if randint ( 1 , chance ) == 1 :
await message . channel . send ( imagelink )
2024-08-07 18:37:15 +00:00
@nextcord.slash_command (
2024-08-05 19:12:11 +00:00
name = " create " ,
description = " create a speech bubble for a user " ,
)
2024-08-07 18:37:15 +00:00
async def create ( self , interaction : nextcord . Interaction , victim : nextcord . Member = nextcord . SlashOption ( name = " victim " ) ) :
if interaction . user . id == victim . id :
await interaction . response . send_message ( " you may not assign yourself a speech bubble, try someone else! " , ephemeral = True )
2024-08-05 19:12:11 +00:00
return
2024-08-07 18:37:15 +00:00
await interaction . response . send_modal ( ApplicationModal ( victim , self . bot ) )
2024-08-05 19:12:11 +00:00
2024-08-07 18:37:15 +00:00
@nextcord.slash_command (
2024-08-05 19:12:11 +00:00
name = " removeme " ,
description = " Removes you from the database " ,
2024-08-07 18:37:15 +00:00
guild_ids = [ 732793772697583623 ] ,
2024-08-05 19:12:11 +00:00
)
2024-08-07 18:37:15 +00:00
async def removeme ( self , interaction : nextcord . Interaction , universal : str = nextcord . SlashOption ( choices = [ " yes " , " no " ] ) ) :
2024-08-05 19:12:11 +00:00
if universal == " yes " :
2024-08-07 18:37:15 +00:00
await self . bot . cur . execute ( f " DELETE FROM userinfo WHERE userid = { interaction . user . id } " )
2024-08-05 19:12:11 +00:00
elif universal == " no " :
2024-08-07 18:37:15 +00:00
await self . bot . cur . execute ( f " DELETE FROM userinfo WHERE userid = { interaction . user . id } AND serverid = { interaction . guild_id } " )
2024-08-05 19:12:11 +00:00
await self . bot . db . commit ( )
2024-08-07 18:37:15 +00:00
await interaction . response . send_message ( " Done! " , ephemeral = True )
2024-08-05 19:12:11 +00:00
def setup ( bot : commands . Bot ) :
bot . add_cog ( speechbubble ( bot ) )