Compare commits

..

No commits in common. "unstable" and "master" have entirely different histories.

2 changed files with 31 additions and 162 deletions

View file

@ -1,5 +0,0 @@
Foxtrot is a multipurpose bot intended to give images and facts about animals, memes, and more!
Foxtrot is open-sourced so people could help fix issues, and to stop people thinking we are doing malicious things with the bot.
Foxtrot also is not made to be self-hosted, but can be self-hosted if done correctly and changed a few things in the code and added your own bot's token in a token.json. Foxtrot is only really meant to be used for the official bot and test bots (to help with bugfixing and stability checking)

182
bot.py
View file

@ -3,7 +3,7 @@
import discord import discord
from discord import File, Streaming, Game, Activity, ActivityType, Status from discord import File, Streaming, Game, Activity, ActivityType, Status
from discord.ext import commands, tasks from discord.ext import commands, tasks
import io, aiohttp, asyncio, json, random, logging, requests, re import io, aiohttp, asyncio, json, random, logging, requests
foxmsgs = [ foxmsgs = [
@ -11,8 +11,6 @@ foxmsgs = [
'here fops', 'here fops',
'owo', 'owo',
'uwu', 'uwu',
'fox hugz u',
'fox fox fox',
'heres ur fox', 'heres ur fox',
] ]
@ -26,7 +24,7 @@ async def is_ginlang(ctx):
""" """
are you ginlang or the other dudes? are you ginlang or the other dudes?
""" """
if ctx.author.id in [287885666941927424, 160091312081731584, 894034804503351366, 296736767158255616, 831598877320413244]: if ctx.author.id in [287885666941927424, 894034804503351366, 296736767158255616, 831598877320413244]:
return True return True
else: else:
logchannel = await bot.fetch_channel(910622485916037150) logchannel = await bot.fetch_channel(910622485916037150)
@ -35,42 +33,17 @@ async def is_ginlang(ctx):
logging.basicConfig(level=logging.INFO) logging.basicConfig(level=logging.INFO)
intents = discord.Intents.default() bot = commands.Bot(command_prefix='gib ')
intents.members = True
bot = commands.Bot(command_prefix='gib ', intents = intents)
@bot.command(brief="gives you a fluffy fox") @bot.command(brief="gives you a fluffy fox")
async def fox(ctx): async def fox(ctx):
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.get('https://foxrudor.de/') as resp: async with session.get('https://foxrudor.de/') as resp:
file = File(io.BytesIO(await resp.read()),filename='fox.jpg') file = File(io.BytesIO(await resp.read()),filename='fox.jpg')
await ctx.message.delete()
await ctx.send(f"*Command executed by {ctx.author.name}#{ctx.author.discriminator}*")
try:
await ctx.send(random.choice(foxmsgs),file=file) await ctx.send(random.choice(foxmsgs),file=file)
except:
embed = discord.Embed(
title = "Command 'fox' failed",
description = "Received unexpected error, foxes occupied by ginlang, who is currently hugging them! 413 Payload too Large"
)
return await ctx.send(embed = embed)
@bot.command(brief="give someone a cuddle")
async def hug(ctx, *, name=None):
if not name:
return await ctx.send("Foxtrot hugs "+ctx.author.name.replace("@", "")+"! :3")
nameFixed = name.replace("@everyone", "everyone").replace("@here", "everyone here")
await ctx.send(ctx.author.name+f" hugs {nameFixed}! :3")
@bot.command(brief="gives the top.gg vote link")
async def vote(ctx):
await ctx.message.delete()
await ctx.author.send("Vote for Foxtrot on top.gg! <https://top.gg/bot/909103805264724038/vote>")
@bot.command(brief="cattttttttt") @bot.command(brief="cattttttttt")
async def cat(ctx): async def cat(ctx):
await ctx.send (f"*Command executed by {ctx.author.name}#{ctx.author.discriminator}*")
await ctx.message.delete()
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.get('https://some-random-api.ml/animal/cat') as resp: async with session.get('https://some-random-api.ml/animal/cat') as resp:
json = await resp.json() json = await resp.json()
@ -82,8 +55,6 @@ async def cat(ctx):
@bot.command(brief="gives you a fluffy panda") @bot.command(brief="gives you a fluffy panda")
async def panda(ctx): async def panda(ctx):
await ctx.send (f"*Command executed by {ctx.author.name}#{ctx.author.discriminator}*")
await ctx.message.delete()
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.get('https://some-random-api.ml/animal/panda') as resp: async with session.get('https://some-random-api.ml/animal/panda') as resp:
json = await resp.json() json = await resp.json()
@ -96,8 +67,6 @@ async def panda(ctx):
@bot.command(brief="omg koala") @bot.command(brief="omg koala")
async def koala(ctx): async def koala(ctx):
await ctx.send(f"*Command executed by {ctx.author.name}#{ctx.author.discriminator}*")
await ctx.message.delete()
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.get('https://some-random-api.ml/animal/koala') as resp: async with session.get('https://some-random-api.ml/animal/koala') as resp:
json = await resp.json() json = await resp.json()
@ -107,16 +76,9 @@ async def koala(ctx):
await ctx.send(json["fact"]) await ctx.send(json["fact"])
await ctx.send(json["image"]) await ctx.send(json["image"])
@bot.command(hidden=True)
@commands.check(is_ginlang)
async def restart(ctx):
await ctx.send("shutting down. beep boop.")
await exit()
@bot.command(brief="bin eaters") @bot.command(brief="bin eaters")
async def raccoon(ctx): async def raccoon(ctx):
await ctx.send(f"*Command executed by {ctx.author.name}#{ctx.author.discriminator}*")
await ctx.message.delete()
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.get('https://some-random-api.ml/animal/raccoon') as resp: async with session.get('https://some-random-api.ml/animal/raccoon') as resp:
json = await resp.json() json = await resp.json()
@ -126,6 +88,11 @@ async def raccoon(ctx):
await ctx.send(json["fact"]) await ctx.send(json["fact"])
await ctx.send(json["image"]) await ctx.send(json["image"])
@bot.command(hidden=True)
@commands.check(is_ginlang)
async def restart(ctx):
await ctx.send("shutting down, beep boop.")
exit()
@bot.command(hidden=True) @bot.command(hidden=True)
@ -136,23 +103,16 @@ async def activity(ctx, atype, *, aname):
if atype not in atypes: if atype not in atypes:
await ctx.send("invalid activity type. the valid types are "+' '.join(atypes.keys())) await ctx.send("invalid activity type. the valid types are "+' '.join(atypes.keys()))
return return
await bot.change_presence(activity=Activity(name=(aname + f" ¦ {str(getAllUsers())} users"), type=atypes[atype], url="https://www.youtube.com/watch?v=1xBO4pUAs4M")) await bot.change_presence(activity=Activity(name=(aname + f" ¦ {str(getAllUsers())} users"), type=atypes[atype], url="https://twitch.tv/xginlang"))
await ctx.send('Success!') await ctx.send('Success!')
@bot.command(brief="gives bot invite link") @bot.command(brief="gives bot invite link")
async def invite(ctx): async def invite(ctx):
await ctx.message.delete() await ctx.send("Add this bot to your server: https://discord.com/oauth2/authorize?client_id=909103805264724038&permissions=274878203904&scope=bot")
try:
await ctx.author.send("""Add this bot to your server: <https://discord.com/api/oauth2/authorize?client_id=909103805264724038&permissions=274878032896&scope=bot%20applications.commands>
You can also join our official Discord server at <https://discord.gg/VrnJFVfSJR>!""")
except:
await ctx.send(f"<@{ctx.author.id}>. I could not DM you!")
@bot.command(brief="gives information about a minecraft user") @bot.command(brief="gives information about a minecraft user")
async def mc(ctx, *, name = None): async def mc(ctx, *, name = None):
await ctx.message.delete()
await ctx.send(f"*Command executed by {ctx.author.name}#{ctx.author.discriminator}*")
if not name: if not name:
embed = discord.Embed( embed = discord.Embed(
title = "No Minecraft user given!", title = "No Minecraft user given!",
@ -179,44 +139,37 @@ async def mc(ctx, *, name = None):
@bot.command(brief="gives credits") @bot.command(brief="gives credits")
async def credits(ctx): async def credits(ctx):
await ctx.message.delete() await ctx.send("""API endpoints used in this bot are taken from:
try:
await ctx.author.send("""API endpoints used in this bot are taken from:
https://foxrudor.de/ https://foxrudor.de/
https://some-random-api.ml https://some-random-api.ml
https://shitfest.net https://shitfest.net
""") """)
except:
await ctx.send(f"<@{ctx.author.id}>. I could not DM you!")
@bot.command(brief="shows contributors to Foxtrot")
async def contributors(ctx):
await ctx.send("""Contributors to the Foxtrot bot are:
Helixu#1111
xfnw#1113
<https://cat.casa/~julia/> (shitfest memes API)
TFTWPhoenix#9240 (I dont know, hes cool I guess.)
remi#9948 (also pretty cool ig)
Foxtrot is open source! Find the code at <https://code.cat.casa/Helixu/Foxtrot>
""")
@bot.command(brief="random meme") @bot.command(brief="random meme")
async def meme(ctx): async def meme(ctx):
await ctx.message.delete()
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.get('https://api.shitfest.net/v2/random.php') as resp: async with session.get('https://shitfest.net/api/random.php') as resp:
json = await resp.json() json = await resp.json()
await ctx.send(f"""*Command executed by {ctx.author.name}#{ctx.author.discriminator}* await ctx.send(json["url"])
""""https://shitfest.net/"""+json["name"])
@bot.command(brief='Kitsune Discord server invite', aliases=["support"])
async def server(ctx):
await ctx.message.delete()
try:
await ctx.author.send("""The official discord server for Foxtrot is discord.gg/mDBfnysAqd
Our server contains everything we do and work on.""")
except:
await ctx.send(f"<@{ctx.author.id}>. I could not DM you!")
@bot.command(brief='makes things gay') @bot.command(brief='makes things gay')
async def gay(ctx, url = None): async def gay(ctx, member: discord.Member=None):
await ctx.message.delete() member = member or ctx.author
await ctx.send(f"*Command executed by {ctx.author.name}#{ctx.author.discriminator}*")
await ctx.trigger_typing() await ctx.trigger_typing()
async with aiohttp.ClientSession() as session: async with aiohttp.ClientSession() as session:
async with session.get( async with session.get(
f'https://some-random-api.ml/canvas/gay?avatar={url}' f'https://some-random-api.ml/canvas/gay?avatar={member.avatar_url_as(format="png")}'
) as af: ) as af:
if 300 > af.status >= 200 : if 300 > af.status >= 200 :
fp = io.BytesIO(await af.read()) fp = io.BytesIO(await af.read())
@ -228,93 +181,14 @@ async def gay(ctx, url = None):
embed.set_image(url="attachment://gay.png") embed.set_image(url="attachment://gay.png")
await ctx.send(embed=embed, file=file) await ctx.send(embed=embed, file=file)
else: else:
await ctx.send("""An unexpected error happened, Steve.. I told you this already! await ctx.send("An unexpected error happened, Steve.. I told you this already!")
Are you sure that the image URL you sent is correct? Image attachments currently do not work!""")
@bot.command(brief='where the wetters go')
async def jail(ctx, member: discord.Member=None):
await ctx.message.delete()
await ctx.send(f"*Command executed by {ctx.author.name}#{ctx.author.discriminator}*")
await ctx.trigger_typing()
async with aiohttp.ClientSession() as session:
async with session.get(
f'https://some-random-api.ml/canvas/jail?avatar={member.avatar_url_as(format="png", size=1024)}'
) as af:
if 300 > af.status >= 200 :
fp = io.BytesIO(await af.read())
file = discord.File(fp, "amongus.png")
embed = discord.Embed(
title="dont drop the soap!",
color=0xf1f1f1,
)
embed.set_image(url="attachment://amongus.png")
await ctx.send(embed=embed, file=file)
else:
await ctx.send("""An unexpected error happened, Steve.. I told you this already!
Are you sure that the user's name is correct?""")
@bot.command(brief='similar to esmBot blurple, but with 104% more fox')
async def blurple(ctx, url = None):
await ctx.message.delete()
await ctx.send(f"*Command executed by {ctx.author.name}#{ctx.author.discriminator}*")
await ctx.trigger_typing()
async with aiohttp.ClientSession() as session:
async with session.get(
f'https://some-random-api.ml/canvas/blurple?avatar={url}'
) as af:
if 300 > af.status >= 200 :
fp = io.BytesIO(await af.read())
file = discord.File(fp, "amongus.png")
embed = discord.Embed(
title="amogus?",
color=0xf1f1f1,
)
embed.set_image(url="attachment://amongus.png")
await ctx.send(embed=embed, file=file)
else:
await ctx.send("""An unexpected error happened, Steve.. I told you this already!
Are you sure that the image URL you sent is correct? Image attachments currently do not work!""")
@bot.command(brief="get a user's profile picture")
async def pfp(ctx, *, person=None):
if person is None:
person = ctx.message.author
else:
try:
person = await ctx.guild.fetch_member(
re.sub(
r"[<>!@]",
"",
person,
)
)
except (discord.NotFound, discord.HTTPException):
found = None
for member in ctx.guild.members:
if (
person.lower() in member.name.lower()
or person.lower() in member.display_name.lower()
):
if found is None:
found = member
else:
await ctx.send(
"oh nOwO, that was not specific enough, try `@mention`ing them."
)
return
if found is None:
await ctx.send(
"sowwy i could not find that user, try `@mention`ing them."
)
return
person = found
await ctx.send(f"**{person.display_name}**'s pfp: {person.avatar_url}")
@bot.event @bot.event
async def on_ready(): async def on_ready():
await asyncio.sleep(1) # someone on stackoverflow said discord does not like if you are speedy await asyncio.sleep(1) # someone on stackoverflow said discord does not like if you are speedy
await bot.change_presence(activity=Streaming(name=f"Dev Mode ¦ {str(getAllUsers())} users", url="https://www.youtube.com/watch?v=1xBO4pUAs4M")) await bot.change_presence(activity=Streaming(name=f"Dev Mode ¦ {str(getAllUsers())} users", url="https://twitch.tv/xginlang"))
with open('token.json', 'r') as file: with open('token.json', 'r') as file:
# this breaks if you are on windows # this breaks if you are on windows