Compare commits

...

7 Commits

Author SHA1 Message Date
80c5f1bc04 update readme 2024-03-16 12:06:05 +01:00
3296ac762e update readme 2024-03-16 12:05:21 +01:00
5c8d544814 add template cog 2024-03-16 12:00:37 +01:00
4f2aa85356 update basic bot, add cog functionality 2024-03-16 11:50:01 +01:00
80e139e8cb add config samle 2024-03-16 11:43:16 +01:00
e4d0bd8248 add requirement list 2024-03-16 11:42:09 +01:00
25320254ce update gitignore 2024-03-16 11:41:57 +01:00
10 changed files with 297 additions and 62 deletions

165
.gitignore vendored
View File

@@ -1,3 +1,166 @@
# ---> Python
tmp/
*.tmp
.vscode/
# Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/
bot.conf *.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log *.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

3
.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "bot/cogs/cog-template"]
path = bot/cogs/cog-template
url = https://git.ao-it.net/templatecity/bot-discord-cog

View File

@@ -1,6 +1,23 @@
# Template: Discord Bot # Template: Discord Bot
## Howto ## Howto
### get token
1. Go to: https://discord.com/developers/applications 1. Go to: https://discord.com/developers/applications
2. Create a new Aplication 2. Create a new Aplication
3. In the Application go to Bot, add them and copy the token 3. In the Application go to Bot, add them and copy the token
4. Add the token in bot.conf 4. Add the token in bot.conf
### add cogs
1. add cog to `./bot/cogs` with main file `cog.py` (sub dir is allowed)
2. optional use submodule like: https://git.ao-it.net/templatecity/bot-discord-cog
```bash
git submodule add $URL ./bot/cogs/myCog/
```
### run bot
```bash
python3 main.py
```
or
```bash
./main.py
```

View File

@@ -1,5 +1,6 @@
{ {
"token": "your-token", "token": "your-token-here",
"prefix": "$",
"name": "Template Bot", "name": "Template Bot",
"description": "Template for a Discord Bot", "description": "Template for a Discord Bot",
"author": "Template" "author": "Template"

View File

@@ -1 +1 @@
from .client import client from .bot import DiscordBot

104
bot/bot.py Normal file
View File

@@ -0,0 +1,104 @@
#!/usr/bin/env python3
from discord.ext import commands, tasks
from discord import Intents
import glob
import logging
import json
class DiscordBot(commands.Bot):
__AUTHOR__ = 'anima'
__VERSION__ = '1.0.0'
def __init__(self, *, intents: Intents = Intents().all(), **options: tasks.Any) -> None:
# lod config file
with open("bot.conf", 'r') as f:
self.botConfig = json.load(f)
# setup logging
self.log = logging.getLogger(__name__)
self._set_loglevel()
logHandler = logging.FileHandler('DiscordBot.log')
logHandler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s - %(name)s : %(message)s'))
self.log.addHandler(logHandler)
# init bot with prefix, intents and commands
super().__init__(command_prefix=self.botConfig['prefix'], intents=intents, **options)
self.add_commands()
def _set_loglevel(self, level: str = 'info'):
"""
allow to change log level external of class
"""
match level:
case 'info':
self.log.setLevel(logging.INFO)
case 'warn':
self.log.setLevel(logging.WARNING)
case 'error':
self.log.setLevel(logging.ERROR)
case 'crit':
self.log.setLevel(logging.CRITICAL)
case 'debug':
self.log.setLevel(logging.DEBUG)
def run(self, token: str = None, *, reconnect: bool = True) -> None:
# load token from config file if none given
if token == None:
token = self.botConfig['token']
return super().run(token, reconnect=reconnect)
async def on_ready(self) -> None:
self.log.info(f'Bot starts as {self.user}')
print(f'Bot starts as {self.user}')
# initate cogs to extend functions
await self.load_cogs()
self.fetch_guilds()
for guild in self.guilds:
self.log.info(f'Connect to Server {guild.name} (id: {guild.id})')
print(f'Connect to Server {guild.name} (id: {guild.id})')
# start background loops
self.mainloop.start()
async def load_cogs(self, reload: bool = False) -> None:
# fetch all cog.py files and add these to bot
for cogFile in glob.glob('**/cogs/**/cog.py', recursive=True):
cogPath = cogFile[:-3].replace('/', '.')
if reload:
self.log.info(f'Try reload cog from: {cogPath}')
await self.reload_extension(cogPath)
else:
self.log.info(f'Try load cog from: {cogPath}')
await self.load_extension(cogPath)
self.log.debug(f'Cogs loaded: {self.extensions}')
for cog in self.extensions.keys():
print(f'Cog loaded: {cog}')
def add_commands(self):
@self.command(name="relmods", pass_context=True)
@commands.has_role('@admin')
async def reload_cogs(ctx) -> None:
"""
allow on the fily reload of cogs
"""
await self.load_cogs(reload=True)
cogs = ''
for cog in self.extensions.keys():
cogs += '' + cog.split('.')[-1] + '\n'
await ctx.send(f'Reload Modules ... \n{cogs}')
@tasks.loop(minutes=1)
async def mainloop(self):
await self.wait_until_ready()
self.log.debug('Run mainloop')
def main():
bot = DiscordBot()
bot._set_loglevel('debug')
bot.run()
if __name__ == "__main__":
main()

View File

@@ -1,17 +0,0 @@
import discord
from discord import app_commands
guild_id = '283156308465811456'
class client(discord.Client):
def __init__(self, intents=discord.Intents.default()):
super().__init__(intents=intents)
self.synced = False #we use this so the bot doesn't sync commands more than once
self.tree = tree = app_commands.CommandTree(self)
async def on_ready(self):
await self.wait_until_ready()
if not self.synced: #check if slash commands have been synced
await self.tree.sync(guild = discord.Object(id=guild_id)) #guild specific: leave blank if global (global registration can take 1-24 hours)
self.synced = True
print(f"We have logged in as {self.user}.")

1
bot/cogs/cog-template Submodule

Submodule bot/cogs/cog-template added at 1d93a050ab

46
main.py Normal file → Executable file
View File

@@ -1,43 +1,5 @@
""" #!/usr/bin/env python3
version 2.0.0 from bot import DiscordBot
author 4nima, oce
description template for discord bot
requirements
- discord
- flask (for keep_alive)
"""
## Imports bot = DiscordBot()
import json bot.run()
import logging as log
import discord
from bot import client
#from lib.keep_alive import keep_alive
intents = discord.Intents.default()
intents.message_content = True
guild_id = '283156308465811456'
bot = client(intents)
## Vars
### Load and set Bot Config
with open("bot.conf", 'r') as f:
BOTDATA = json.load(f)
### Set logging options
log.basicConfig(
filename="bot.log",
level=log.DEBUG,
format='%(asctime)s - %(process)d-%(levelname)s: %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# run
# bot defination
@bot.tree.command(guild = discord.Object(id=guild_id), name = 'tester', description='testing') #guild specific slash command
async def slash2(interaction: discord.Interaction):
await interaction.response.send_message(f"I am working! I was made with Discord.py!", ephemeral = True)
bot.run(BOTDATA['token'])

1
requirements.txt Normal file
View File

@@ -0,0 +1 @@
discord