forked from IPD/Foxtrot
Compare commits
58 commits
Author | SHA1 | Date | |
---|---|---|---|
c8b851038e | |||
3b3f34d96d | |||
a14bd192d3 | |||
d5aa241ba0 | |||
f6a54c5cca | |||
f86208020d | |||
69c083c396 | |||
6a7e2675fa | |||
7a7d1aaae9 | |||
cd02848012 | |||
3bd38c42d3 | |||
94976fb929 | |||
22347815cb | |||
1fac729e83 | |||
739cc1afb1 | |||
fae97f40ca | |||
d860f2ce6a | |||
76d49a4597 | |||
610be72b7a | |||
1f54938ec4 | |||
5c6a48537a | |||
58528f657a | |||
f48a9e0bf2 | |||
b8d76b7440 | |||
027dc4c07c | |||
fb4880a411 | |||
8c24ad8818 | |||
f9e1d89c11 | |||
d81226b80a | |||
743be56057 | |||
b92fa8f7a6 | |||
b5539d5326 | |||
30370500b3 | |||
b752e87129 | |||
3ee887744e | |||
3e8e197eed | |||
2288581903 | |||
3b11c6e4f2 | |||
90370ea280 | |||
49a4c10d0d | |||
ae31406805 | |||
8ce21fad0e | |||
cd9b99fe1d | |||
0515773f68 | |||
e438fd6d9b | |||
4f4d83bae4 | |||
88875887c2 | |||
5290d8c28a | |||
f7068305bb | |||
620eff1782 | |||
ce174cefa1 | |||
e79a2b3d0f | |||
93fcf25d67 | |||
65b316926f | |||
3648e3c6ca | |||
45d0a2406e | |||
c652d76d89 | |||
1290e21e35 |
2 changed files with 162 additions and 31 deletions
|
@ -0,0 +1,5 @@
|
||||||
|
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)
|
188
bot.py
188
bot.py
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
|
|
||||||
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
|
import io, aiohttp, asyncio, json, random, logging, requests, re
|
||||||
|
|
||||||
|
|
||||||
foxmsgs = [
|
foxmsgs = [
|
||||||
|
@ -11,6 +11,8 @@ foxmsgs = [
|
||||||
'here fops',
|
'here fops',
|
||||||
'owo',
|
'owo',
|
||||||
'uwu',
|
'uwu',
|
||||||
|
'fox hugz u',
|
||||||
|
'fox fox fox',
|
||||||
'heres ur fox',
|
'heres ur fox',
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -24,7 +26,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, 894034804503351366, 296736767158255616, 831598877320413244]:
|
if ctx.author.id in [287885666941927424, 160091312081731584, 894034804503351366, 296736767158255616, 831598877320413244]:
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
logchannel = await bot.fetch_channel(910622485916037150)
|
logchannel = await bot.fetch_channel(910622485916037150)
|
||||||
|
@ -33,17 +35,42 @@ async def is_ginlang(ctx):
|
||||||
|
|
||||||
logging.basicConfig(level=logging.INFO)
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
bot = commands.Bot(command_prefix='gib ')
|
intents = discord.Intents.default()
|
||||||
|
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.send(random.choice(foxmsgs),file=file)
|
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)
|
||||||
|
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()
|
||||||
|
@ -55,6 +82,8 @@ 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()
|
||||||
|
@ -67,6 +96,8 @@ 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()
|
||||||
|
@ -76,9 +107,16 @@ 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()
|
||||||
|
@ -88,11 +126,6 @@ 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)
|
||||||
|
@ -103,16 +136,23 @@ 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://twitch.tv/xginlang"))
|
await bot.change_presence(activity=Activity(name=(aname + f" ¦ {str(getAllUsers())} users"), type=atypes[atype], url="https://www.youtube.com/watch?v=1xBO4pUAs4M"))
|
||||||
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.send("Add this bot to your server: https://discord.com/oauth2/authorize?client_id=909103805264724038&permissions=274878203904&scope=bot")
|
await ctx.message.delete()
|
||||||
|
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!",
|
||||||
|
@ -139,37 +179,44 @@ 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.send("""API endpoints used in this bot are taken from:
|
await ctx.message.delete()
|
||||||
|
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://shitfest.net/api/random.php') as resp:
|
async with session.get('https://api.shitfest.net/v2/random.php') as resp:
|
||||||
json = await resp.json()
|
json = await resp.json()
|
||||||
await ctx.send(json["url"])
|
await ctx.send(f"""*Command executed by {ctx.author.name}#{ctx.author.discriminator}*
|
||||||
|
""""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, member: discord.Member=None):
|
async def gay(ctx, url = None):
|
||||||
member = member or ctx.author
|
await ctx.message.delete()
|
||||||
|
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={member.avatar_url_as(format="png")}'
|
f'https://some-random-api.ml/canvas/gay?avatar={url}'
|
||||||
) 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())
|
||||||
|
@ -181,14 +228,93 @@ async def gay(ctx, member: discord.Member=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://twitch.tv/xginlang"))
|
await bot.change_presence(activity=Streaming(name=f"Dev Mode ¦ {str(getAllUsers())} users", url="https://www.youtube.com/watch?v=1xBO4pUAs4M"))
|
||||||
|
|
||||||
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
|
||||||
|
|
Loading…
Reference in a new issue