mirror of
https://github.com/NovaOSS/nova-cord.git
synced 2024-11-25 19:03:57 +01:00
Added leaderboard thingy and goofy stuff
This commit is contained in:
parent
4441a9b612
commit
cce6cc5152
18
cord/autochat.py
Normal file
18
cord/autochat.py
Normal file
|
@ -0,0 +1,18 @@
|
|||
import random
|
||||
import embedder
|
||||
|
||||
async def process(message):
|
||||
if message.content == '/key':
|
||||
responses = [
|
||||
'https://media.tenor.com/t9f91LQWsM4AAAAS/breaking-bad-funny.gif',
|
||||
'NPC detected, command rejected.',
|
||||
'https://images-ext-1.discordapp.net/external/DXc3r4PyRR3m_4AzevpxWhfFtavdcMeDpZqFj3Ig4hc/https/media.tenor.com/b7swbvaVKhUAAAPo/seriously-laugh.mp4',
|
||||
'there👏is👏no👏/key👏command👏',
|
||||
'https://i.imgflip.com/7tuhc6.jpg'
|
||||
]
|
||||
|
||||
await message.reply(random.choice(responses))
|
||||
await message.channel.send('Jokes aside - the project is still under development. There\'s no **`/key`** command.')
|
||||
|
||||
if message.content.startswith('/') and ('commands' not in message.channel.name) and (not message.author.guild_permissions.manage_messages):
|
||||
await embedder.warn(message, 'Please only run commands in `/commands`.')
|
73
cord/bot.py
73
cord/bot.py
|
@ -1,13 +1,13 @@
|
|||
# This example requires the 'members' and 'message_content' privileged intents to function.
|
||||
|
||||
import os
|
||||
import asyncio
|
||||
import nextcord
|
||||
import requests
|
||||
|
||||
import keys
|
||||
import system
|
||||
import chatbot
|
||||
import embedder
|
||||
import autochat
|
||||
import community
|
||||
|
||||
from dotenv import load_dotenv
|
||||
from nextcord.ext import commands
|
||||
|
@ -17,7 +17,7 @@ load_dotenv()
|
|||
|
||||
bot = commands.Bot(
|
||||
intents=nextcord.Intents.all(),
|
||||
default_guild_ids=[int(guild_id) for guild_id in os.getenv('DISCORD_GUILD_IDS').split()]
|
||||
default_guild_ids=[int(guild_id) for guild_id in os.getenv('DISCORD_GUILD_IDS').split()] # so slash commands work
|
||||
)
|
||||
|
||||
@bot.event
|
||||
|
@ -27,6 +27,10 @@ async def on_ready():
|
|||
|
||||
@bot.event
|
||||
async def on_message(message):
|
||||
if message.author.bot: # block bots
|
||||
return
|
||||
|
||||
await autochat.process(message)
|
||||
await bot.process_commands(message)
|
||||
|
||||
@bot.slash_command(description='Chat with AI')
|
||||
|
@ -41,62 +45,17 @@ async def dm(interaction: nextcord.Interaction):
|
|||
await interaction.user.create_dm()
|
||||
await embedder.info(interaction.user.dm_channel, 'Hello!')
|
||||
except nextcord.Forbidden:
|
||||
await embedder.error(interaction, text='Please open this server\'s options, go to `Privacy Settings` and enable `Direct Messages` and `Message Requests`.')
|
||||
await embedder.error(interaction, text="""Please open this server\'s options,
|
||||
go to `Privacy Settings` and enable `Direct Messages` as well as `Message Requests`.""")
|
||||
else:
|
||||
await embedder.ok(interaction, 'Great, DMs are set up successfully!')
|
||||
|
||||
@bot.slash_command(description='Get your secret NovaAI API key.')
|
||||
async def key(interaction: nextcord.Interaction):
|
||||
try:
|
||||
resp = requests.post(
|
||||
url='https://nova-oss.com/api/tos-verification',
|
||||
timeout=5,
|
||||
headers={'Content-Type': 'application/json', 'Authorization': os.getenv('TOS_VERIFICATION_KEY')}
|
||||
).json()
|
||||
except Exception as exc:
|
||||
await embedder.error(interaction, """Sorry, the API server for the verification system is not functioning,
|
||||
which means you can\'t create a new key right now. Please report this issue to the staff!""")
|
||||
raise exc
|
||||
@bot.slash_command(description='Get your secret NovaAI API credentials.')
|
||||
async def credentials(interaction: nextcord.Interaction):
|
||||
return await system.get_credentials(interaction)
|
||||
|
||||
tos_code = resp['code']
|
||||
tos_emoji = resp['emoji']
|
||||
|
||||
tos_message = await embedder.warn(interaction, f"""# THIS IS JUST A DEMO!
|
||||
# THE KEY DOESN'T WORK!
|
||||
You have to read the privacy policy and terms of service first.
|
||||
In the latter, there is a hidden emoji which you'll have to send (NOT react!) in here.
|
||||
|
||||
https://nova-oss.com/legal/privacy
|
||||
https://nova-oss.com/legal/terms?verify={tos_code}
|
||||
|
||||
I know it's annoying, but it really helps combat spam bots and abuse.
|
||||
|
||||
This message will be deleted and your code will run out **after about 10 minutes**
|
||||
if you don't pass the verification, but **feel free to run this command again** at any time.
|
||||
""", ephemeral=True)
|
||||
|
||||
def check(message): return interaction.user.id == message.author.id and message.content == tos_emoji
|
||||
|
||||
try:
|
||||
answer = await bot.wait_for('message', timeout=666, check=check)
|
||||
except asyncio.TimeoutError:
|
||||
await tos_message.delete()
|
||||
requests.delete(
|
||||
url=f'https://nova-oss.com/api/tos-verification/{tos_code}',
|
||||
timeout=5,
|
||||
headers={'Content-Type': 'application/json', 'Authorization': os.getenv('TOS_VERIFICATION_KEY')}
|
||||
)
|
||||
|
||||
else:
|
||||
await answer.delete()
|
||||
api_key = await keys.create(interaction.user)
|
||||
await embedder.ok(interaction, f"""This is your **secret** API key. Don't paste it on untrusted websites, apps or programs.
|
||||
Store it securely using a `.env` file in the environment variables or use a secure password manager like *KeePass*, *ProtonPass* or *Bitwarden*.
|
||||
We reserve the right to __disable your API key at any time__ if you violate our terms of service.
|
||||
If you accept the terms of service and privacy policy, feel free to use the following API key:
|
||||
|
||||
## ||`{api_key}`||
|
||||
|
||||
""", ephemeral=True)
|
||||
@bot.slash_command(description='Leaderboard.')
|
||||
async def leaderboard(interaction: nextcord.Interaction):
|
||||
await community.leaderboard(interaction)
|
||||
|
||||
bot.run(os.getenv('DISCORD_TOKEN'))
|
||||
|
|
37
cord/community.py
Normal file
37
cord/community.py
Normal file
|
@ -0,0 +1,37 @@
|
|||
import asyncio
|
||||
import datetime
|
||||
|
||||
import embedder
|
||||
|
||||
async def process_channel(channel, scores):
|
||||
if channel.name in ['general', 'support', 'suggestions', 'showcase', 'team-discussion', 'prompts', 'research-resources']:
|
||||
after = datetime.datetime.now() - datetime.timedelta(days=7)
|
||||
|
||||
async for message in channel.history(limit=1000, after=after):
|
||||
if not '```' in message.content: # no code
|
||||
if not scores.get(message.author.id):
|
||||
scores[message.author.id] = 0
|
||||
|
||||
scores[message.author.id] += message.content.strip().count(' ')
|
||||
|
||||
async def leaderboard(interaction):
|
||||
msg = await interaction.send('Loading the leaderboard... Go grab a mug of bleach.. ||**[for legal reasons that a joke]**|| \nhttps://media.tenor.com/M67VmLlocdMAAAAS/spinning-seal.gif')
|
||||
|
||||
scores = {}
|
||||
|
||||
channels = interaction.guild.text_channels
|
||||
tasks = [process_channel(channel, scores) for channel in channels] # go fast like sonik by doing splitting it into tasks
|
||||
await asyncio.gather(*tasks)
|
||||
|
||||
board = dict(sorted(scores.items(), key=lambda x: x[1], reverse=True)[:10]) # sort dict by value and get only first 10
|
||||
|
||||
emojis = [':first_place:', ':second_place:', ':third_place:', ':four:', ':five:', ':six:', ':seven:', ':eight:', ':nine:', ':keycap_ten:']
|
||||
|
||||
text = 'Words (excluding code) typed in selected channels in the last 7 days with a limit of 1000 messages per channel:\n'
|
||||
place = 0
|
||||
|
||||
for user in list(board.keys()):
|
||||
text += f'{emojis[place]} {interaction.guild.get_member(user).mention} **{scores[user]}**\n'
|
||||
place += 1
|
||||
|
||||
await embedder.info(msg, title='Leaderboard (7 days)', text=text)
|
|
@ -1,5 +1,5 @@
|
|||
import nextcord
|
||||
import traceback
|
||||
import datetime
|
||||
|
||||
from typing import Union
|
||||
|
||||
|
@ -7,34 +7,59 @@ async def send(
|
|||
ctx,
|
||||
title: str,
|
||||
text: str,
|
||||
content: str = '',
|
||||
ephemeral: bool = False,
|
||||
color: nextcord.Color = nextcord.Color.blue()
|
||||
):
|
||||
edit = False
|
||||
|
||||
if isinstance(ctx, nextcord.PartialInteractionMessage):
|
||||
ctx = await ctx.fetch()
|
||||
edit = True
|
||||
|
||||
embed = nextcord.Embed(
|
||||
title=title,
|
||||
description=text,
|
||||
color=color
|
||||
)
|
||||
embed.set_footer(text='Powered by NovaAI', icon_url='https://i.ibb.co/LDyFcSh/fav-blurple.png')
|
||||
|
||||
time_difference = datetime.datetime.now(datetime.timezone.utc) - ctx.created_at
|
||||
milliseconds = int(time_difference.total_seconds() * 1000)
|
||||
|
||||
end = ''
|
||||
|
||||
if milliseconds > 10000: # https://youtu.be/-5wpm-gesOY
|
||||
end = f' in {milliseconds}ms'
|
||||
|
||||
embed.set_footer(text=f'Powered by NovaAI{end}', icon_url='https://i.ibb.co/LDyFcSh/fav-blurple.png')
|
||||
embed.set_author(name='NovaCord', url='https://nova-oss.com/novacord')
|
||||
|
||||
interaction_type = Union[nextcord.Interaction, nextcord.InteractionResponse]
|
||||
|
||||
# these checks are done so this function is easy as fuck to use
|
||||
|
||||
if edit:
|
||||
return await ctx.edit(embed=embed, content=content)
|
||||
|
||||
if isinstance(ctx, nextcord.Message):
|
||||
response = await ctx.reply(embed=embed)
|
||||
elif isinstance(ctx, Union[nextcord.Interaction, nextcord.InteractionResponse]):
|
||||
response = await ctx.send(embed=embed, ephemeral=ephemeral)
|
||||
response = await ctx.reply(embed=embed, content=content)
|
||||
|
||||
elif isinstance(ctx, interaction_type):
|
||||
response = await ctx.send(embed=embed, ephemeral=ephemeral, content=content)
|
||||
|
||||
else:
|
||||
response = await ctx.send(embed=embed)
|
||||
response = await ctx.send(embed=embed, content=content)
|
||||
|
||||
return response
|
||||
|
||||
async def ok(ctx, text: str, title: str='Success', *args, **kwargs):
|
||||
async def ok(ctx, text: str, title: str=':white_check_mark: Success', *args, **kwargs):
|
||||
return await send(ctx, title, text, color=nextcord.Color.green(), *args, **kwargs)
|
||||
|
||||
async def info(ctx, text: str, title: str='Information', *args, **kwargs):
|
||||
async def info(ctx, text: str, title: str=':information_source: Information', *args, **kwargs):
|
||||
return await send(ctx, title, text, color=nextcord.Color.blue(), *args, **kwargs)
|
||||
|
||||
async def warn(ctx, text: str, title: str='Warning', *args, **kwargs):
|
||||
async def warn(ctx, text: str, title: str=':warning: Warning', *args, **kwargs):
|
||||
return await send(ctx, title, text, color=nextcord.Color.orange(), *args, **kwargs)
|
||||
|
||||
async def error(ctx, text: str, title: str='Error - Command Failed', *args, **kwargs):
|
||||
async def error(ctx, text: str, title: str=':x: Error - Command Failed', *args, **kwargs):
|
||||
return await send(ctx, title, text, color=nextcord.Color.red(), *args, **kwargs)
|
||||
|
|
65
cord/system.py
Normal file
65
cord/system.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
import os
|
||||
import asyncio
|
||||
import requests
|
||||
|
||||
import keys
|
||||
import embedder
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
async def get_credentials(interaction):
|
||||
try:
|
||||
resp = requests.post(
|
||||
url='https://nova-oss.com/api/tos-verification',
|
||||
timeout=5,
|
||||
headers={'Content-Type': 'application/json', 'Authorization': os.getenv('TOS_VERIFICATION_KEY')}
|
||||
).json()
|
||||
except Exception as exc:
|
||||
await embedder.error(interaction, """Sorry, the API server for the verification system is not functioning,
|
||||
which means you can\'t create a new key right now. Please report this issue to the staff!""")
|
||||
raise exc
|
||||
|
||||
tos_code = resp['code']
|
||||
tos_emoji = resp['emoji']
|
||||
|
||||
tos_message = await embedder.warn(interaction, f"""# THIS IS JUST A DEMO/EXAMPLE!
|
||||
# THE KEY WON'T WORK!
|
||||
# THE SYSTEM ISN'T READY YET.
|
||||
# DON'T SAVE THE KEY!!!
|
||||
You have to read the privacy policy and terms of service first.
|
||||
In the latter, there is a hidden emoji which you'll have to send (NOT react!) in here.
|
||||
|
||||
https://nova-oss.com/legal/privacy
|
||||
https://nova-oss.com/legal/terms?verify={tos_code}
|
||||
|
||||
I know it's annoying, but it really helps combat spam bots and abuse.
|
||||
|
||||
This message will be deleted and your code will run out **after about 10 minutes**
|
||||
if you don't pass the verification, but **feel free to run this command again** at any time.
|
||||
""", ephemeral=True)
|
||||
|
||||
def check(message): return interaction.user.id == message.author.id and message.content == tos_emoji
|
||||
|
||||
try:
|
||||
answer = await interaction.client.wait_for('message', timeout=666, check=check)
|
||||
except asyncio.TimeoutError:
|
||||
await tos_message.delete()
|
||||
requests.delete(
|
||||
url=f'https://nova-oss.com/api/tos-verification/{tos_code}',
|
||||
timeout=5,
|
||||
headers={'Content-Type': 'application/json', 'Authorization': os.getenv('TOS_VERIFICATION_KEY')}
|
||||
)
|
||||
|
||||
else:
|
||||
await answer.delete()
|
||||
api_key = await keys.create(interaction.user)
|
||||
await embedder.ok(interaction, f"""This is your **secret** API key. Don't paste it on untrusted websites, apps or programs.
|
||||
Store it securely using a `.env` file in the environment variables or use a secure password manager like *KeePass*, *ProtonPass* or *Bitwarden*.
|
||||
We reserve the right to __disable your API key at any time__ if you violate our terms of service.
|
||||
If you accept the terms of service and privacy policy, feel free to use the following API key:
|
||||
|
||||
## ||`{api_key}`||
|
||||
|
||||
""", ephemeral=True)
|
Loading…
Reference in a new issue