This commit is contained in:
42
README.md
42
README.md
@ -2,25 +2,44 @@ Who is GarfBot?
|
|||||||
======
|
======
|
||||||

|

|
||||||
|
|
||||||
GarfBot is a discord bot that uses OpenAI's generative pre-trained models to produce text and images for your personal entertainment and companionship. There are a few ways you can interact with him on discord, either in a public server or by direct message:
|
GarfBot is a discord bot that uses OpenAI's generative pre-trained models to produce text and images for your personal entertainment and companionship.
|
||||||
|
<br>There are a few ways you can interact with him on discord, either in a public server or by direct message:
|
||||||
|
|
||||||
`hey garfield {prompt}`
|
`hey garfield {prompt}`
|
||||||
Responds with text.
|
<br>Responds with text.
|
||||||
|
|
||||||
`garfpic {prompt}`
|
`garfpic {prompt}`
|
||||||
Responds with an image.
|
<br>Responds with an image.
|
||||||
|
|
||||||
`garfping {target}`
|
`garfping {target}`
|
||||||
Responds with iputils-ping result from target.
|
<br>Responds with iputils-ping result from target.
|
||||||
|
|
||||||
`garfpic {target}`
|
`garfpic {target}`
|
||||||
Responds with dns lookup result from target.
|
<br>Responds with dns lookup result from target.
|
||||||
|
|
||||||
`garfhack {target}`
|
`garfhack {target}`
|
||||||
Responds with nmap scan result from target.
|
<br>Responds with nmap scan result from target.
|
||||||
|
|
||||||
`garfshop {item} {zip}`
|
`garfshop {item} {zip}`
|
||||||
Responds with 10 grocery {item}s from the nearest Kroger location, listed from least to most expensive.
|
<br>Responds with 10 grocery {item}s from the nearest Kroger location, listed from least to most expensive.
|
||||||
|
|
||||||
|
`garfwiki {query}`
|
||||||
|
<br>Garfbot looks up a wikipedia article and will summarize it for you.
|
||||||
|
|
||||||
|
`garfqr {text}`
|
||||||
|
<br>Create a QR code for any string up to 1000 characters.
|
||||||
|
|
||||||
|
`garfbot response {add} {trigger} {response}`
|
||||||
|
<br>Add a GarfBot auto response for your server. Use "quotes" if you like.
|
||||||
|
|
||||||
|
`garfbot response {remove} {trigger}`
|
||||||
|
<br>Remove a GarfBot auto response for your server.
|
||||||
|
|
||||||
|
`garfbot response {list}`
|
||||||
|
<br>List current GarfBot auto responses for your server.
|
||||||
|
|
||||||
|
`garfbot help`
|
||||||
|
<br>Show a list of these commands.
|
||||||
|
|
||||||
Installation
|
Installation
|
||||||
======
|
======
|
||||||
@ -38,7 +57,8 @@ GARFBOT_TOKEN = "Discord API token"
|
|||||||
OPENAI_TOKEN = "OpenAI API token"
|
OPENAI_TOKEN = "OpenAI API token"
|
||||||
```
|
```
|
||||||
|
|
||||||
I recommend building a docker image using the included DockerFile as a template. Run the container binding /usr/src/app to GarfBot's CWD:
|
I recommend building a docker image using the included DockerFile as a template.
|
||||||
|
<br>Run the container binding /usr/src/app to GarfBot's CWD:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
$ docker build -t garfbot .
|
$ docker build -t garfbot .
|
||||||
@ -53,7 +73,7 @@ If you prefer to install dependencies on you own host and run as a systemd servi
|
|||||||
$ sudo nano /etc/systemd/system/garfbot.service
|
$ sudo nano /etc/systemd/system/garfbot.service
|
||||||
```
|
```
|
||||||
|
|
||||||
Replace {user} with your username:
|
Replace $USER with your username:
|
||||||
|
|
||||||
```console
|
```console
|
||||||
[Unit]
|
[Unit]
|
||||||
@ -63,8 +83,8 @@ After=multi-user.target
|
|||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
Restart=always
|
Restart=always
|
||||||
User={user}
|
User=$USER
|
||||||
WorkingDirectory=/home/{user}/garfbot
|
WorkingDirectory=/home/$USER/garfbot
|
||||||
ExecStart=/usr/bin/python garfbot.py
|
ExecStart=/usr/bin/python garfbot.py
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
|
@ -38,7 +38,11 @@ class IPUtils:
|
|||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["ping", "-c", "4", target], capture_output=True, text=True
|
["ping", "-c", "4", target], capture_output=True, text=True
|
||||||
)
|
)
|
||||||
embed = discord.Embed(title=f"Ping result: {target}", color=0x4D4D4D, description=f"```{result.stdout}```")
|
embed = discord.Embed(
|
||||||
|
title=f"Ping result: {target}",
|
||||||
|
color=0x4D4D4D,
|
||||||
|
description=f"```{result.stdout}```",
|
||||||
|
)
|
||||||
await message.channel.send(embed=embed)
|
await message.channel.send(embed=embed)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await message.channel.send(f"`GarfBot Error: {str(e)}`")
|
await message.channel.send(f"`GarfBot Error: {str(e)}`")
|
||||||
@ -52,7 +56,11 @@ class IPUtils:
|
|||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["nslookup", target], capture_output=True, text=True
|
["nslookup", target], capture_output=True, text=True
|
||||||
)
|
)
|
||||||
embed = discord.Embed(title=f"NSLookup result: {target}", color=0x4D4D4D, description=f"```{result.stdout}```")
|
embed = discord.Embed(
|
||||||
|
title=f"NSLookup result: {target}",
|
||||||
|
color=0x4D4D4D,
|
||||||
|
description=f"```{result.stdout}```",
|
||||||
|
)
|
||||||
await message.channel.send(embed=embed)
|
await message.channel.send(embed=embed)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
await message.channel.send(f"`GarfBot Error: {str(e)}`")
|
await message.channel.send(f"`GarfBot Error: {str(e)}`")
|
||||||
@ -66,7 +74,11 @@ class IPUtils:
|
|||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
["nmap", "-Pn", "-O", "-v", target], capture_output=True, text=True
|
["nmap", "-Pn", "-O", "-v", target], capture_output=True, text=True
|
||||||
)
|
)
|
||||||
embed = discord.Embed(title=f"Nmap scan result: {target}", color=0x4D4D4D, description=f"```{result.stdout}```")
|
embed = discord.Embed(
|
||||||
|
title=f"Nmap scan result: {target}",
|
||||||
|
color=0x4D4D4D,
|
||||||
|
description=f"```{result.stdout}```",
|
||||||
|
)
|
||||||
embed.set_footer(text="https://nmap.org/")
|
embed.set_footer(text="https://nmap.org/")
|
||||||
await message.channel.send(embed=embed)
|
await message.channel.send(embed=embed)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -7,47 +7,47 @@ import re
|
|||||||
|
|
||||||
class GarfbotRespond:
|
class GarfbotRespond:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.guild_responses = {}
|
self.garfbot_responses = {}
|
||||||
self.responses_file = "responses.json"
|
self.responses_file = "responses.json"
|
||||||
|
|
||||||
def load_responses(self):
|
def load_responses(self):
|
||||||
if os.path.exists(self.responses_file):
|
if os.path.exists(self.responses_file):
|
||||||
try:
|
try:
|
||||||
with open(self.responses_file, "r", encoding="utf-8") as f:
|
with open(self.responses_file, "r", encoding="utf-8") as f:
|
||||||
self.guild_responses = json.load(f)
|
self.garfbot_responses = json.load(f)
|
||||||
self.guild_responses = {
|
self.garfbot_responses = {
|
||||||
int(k): v for k, v in self.guild_responses.items()
|
int(k): v for k, v in self.garfbot_responses.items()
|
||||||
}
|
}
|
||||||
total_responses = sum(
|
total_responses = sum(
|
||||||
len(responses) for responses in self.guild_responses.values()
|
len(responses) for responses in self.garfbot_responses.values()
|
||||||
)
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Loaded responses for {len(self.guild_responses)} server(s), ({total_responses} total responses)"
|
f"Loaded responses for {len(self.garfbot_responses)} server(s), ({total_responses} total responses)"
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info(f"Error loading responses: {e}")
|
logger.info(f"Error loading responses: {e}")
|
||||||
self.guild_responses = {}
|
self.garfbot_responses = {}
|
||||||
else:
|
else:
|
||||||
self.guild_responses = {}
|
self.garfbot_responses = {}
|
||||||
|
|
||||||
def save_responses(self):
|
def save_responses(self):
|
||||||
try:
|
try:
|
||||||
save_data = {str(k): v for k, v in self.guild_responses.items()}
|
save_data = {str(k): v for k, v in self.garfbot_responses.items()}
|
||||||
with open(self.responses_file, "w", encoding="utf-8") as f:
|
with open(self.responses_file, "w", encoding="utf-8") as f:
|
||||||
json.dump(save_data, f, indent=2, ensure_ascii=False)
|
json.dump(save_data, f, indent=2, ensure_ascii=False)
|
||||||
total_responses = sum(
|
total_responses = sum(
|
||||||
len(responses) for responses in self.guild_responses.values()
|
len(responses) for responses in self.garfbot_responses.values()
|
||||||
)
|
)
|
||||||
logger.info(
|
logger.info(
|
||||||
f"Saved responses for {len(self.guild_responses)} servers ({total_responses} total responses)"
|
f"Saved responses for {len(self.garfbot_responses)} servers ({total_responses} total responses)"
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.info(f"Error saving responses: {e}")
|
logger.info(f"Error saving responses: {e}")
|
||||||
|
|
||||||
def get_responses(self, guild_id):
|
def get_responses(self, guild_id):
|
||||||
if guild_id not in self.guild_responses:
|
if guild_id not in self.garfbot_responses:
|
||||||
self.guild_responses[guild_id] = {}
|
self.garfbot_responses[guild_id] = {}
|
||||||
return self.guild_responses[guild_id]
|
return self.garfbot_responses[guild_id]
|
||||||
|
|
||||||
async def garfbot_response(self, message, content):
|
async def garfbot_response(self, message, content):
|
||||||
guild_id = message.guild.id
|
guild_id = message.guild.id
|
||||||
@ -96,7 +96,7 @@ class GarfbotRespond:
|
|||||||
|
|
||||||
responses = self.get_responses(guild_id)
|
responses = self.get_responses(guild_id)
|
||||||
responses[trigger] = response_text
|
responses[trigger] = response_text
|
||||||
self.guild_responses[guild_id] = responses
|
self.garfbot_responses[guild_id] = responses
|
||||||
self.save_responses()
|
self.save_responses()
|
||||||
|
|
||||||
embed = discord.Embed(title="✅ Auto-response Added.", color=0x00FF00)
|
embed = discord.Embed(title="✅ Auto-response Added.", color=0x00FF00)
|
||||||
@ -112,7 +112,7 @@ class GarfbotRespond:
|
|||||||
if trigger in responses:
|
if trigger in responses:
|
||||||
removed_response = responses[trigger]
|
removed_response = responses[trigger]
|
||||||
del responses[trigger]
|
del responses[trigger]
|
||||||
self.guild_responses[guild_id] = responses
|
self.garfbot_responses[guild_id] = responses
|
||||||
self.save_responses()
|
self.save_responses()
|
||||||
|
|
||||||
embed = discord.Embed(title="✅ Auto-response Removed.", color=0xFF6B6B)
|
embed = discord.Embed(title="✅ Auto-response Removed.", color=0xFF6B6B)
|
||||||
@ -127,7 +127,7 @@ class GarfbotRespond:
|
|||||||
if key.lower() == trigger.lower():
|
if key.lower() == trigger.lower():
|
||||||
removed_response = responses[key]
|
removed_response = responses[key]
|
||||||
del responses[key]
|
del responses[key]
|
||||||
self.guild_responses[guild_id] = responses
|
self.garfbot_responses[guild_id] = responses
|
||||||
self.save_responses()
|
self.save_responses()
|
||||||
|
|
||||||
embed = discord.Embed(title="✅ Auto-response Removed.", color=0xFF6B6B)
|
embed = discord.Embed(title="✅ Auto-response Removed.", color=0xFF6B6B)
|
||||||
|
Reference in New Issue
Block a user