First commit

This commit is contained in:
Hash Borgir 2024-02-12 06:20:31 -07:00
commit 4e635b0042
17 changed files with 748 additions and 0 deletions

59
bot.py Executable file
View File

@ -0,0 +1,59 @@
#!/usr/bin/env python
import os
import logging
from dotenv import load_dotenv
import simplematrixbotlib as botlib
# Load environment variables from .env file
load_dotenv()
# Bot configuration settings
MATRIX_URL = os.getenv("MATRIX_URL")
MATRIX_USER = os.getenv("MATRIX_USER")
MATRIX_PASS = os.getenv("MATRIX_PASS")
ADMIN_USER = "@hashborgir:mozilla.org"
PREFIX = '!'
creds = botlib.Creds(MATRIX_URL, MATRIX_USER, MATRIX_PASS)
bot = botlib.Bot(creds)
# Setup logging
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO)
# Load plugins
PLUGINS_DIR = "plugins"
def load_plugins():
plugins = []
for plugin_file in os.listdir(PLUGINS_DIR):
if plugin_file.endswith(".py"):
plugin_name = os.path.splitext(plugin_file)[0]
try:
plugin_module = __import__(f"{PLUGINS_DIR}.{plugin_name}", fromlist=[""])
plugins.append(plugin_module)
logging.info(f"Loaded plugin: {plugin_name}")
except Exception as e:
logging.error(f"Error loading plugin {plugin_name}: {e}")
return plugins
plugins = load_plugins()
@bot.listener.on_message_event
async def handle_commands(room, message):
"""
Function to handle incoming command messages.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
for plugin in plugins:
await plugin.handle_command(room, message, bot, PREFIX)
bot.run()

326
hcbot.py Executable file
View File

@ -0,0 +1,326 @@
#!/usr/bin/env python
import subprocess
import sqlite3
import time
import os
import random
import socket
from urllib.parse import urlparse
import datetime
import simplematrixbotlib as botlib
import requests
from pytube import YouTube
import logging
import inspect
MATRIX_URL = "https://matrix.org"
MATRIX_USER = "@hcbot:matrix.org"
MATRIX_PASS = "W4iy$nt^qp~&$K~$w@@jEhnT"
creds = botlib.Creds(MATRIX_URL, MATRIX_USER, MATRIX_PASS)
bot = botlib.Bot(creds)
PREFIX = '!'
# Setup logging
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO)
# Database setup
conn = sqlite3.connect('karma.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS karma
(username TEXT PRIMARY KEY, points INTEGER)''')
conn.commit()
conn.close()
async def ping_proxy(proxy):
"""
Ping a proxy server to check its availability.
Args:
proxy (str): The proxy server address in the format 'ip:port'.
Returns:
float or str: The ping time in milliseconds if the proxy is up, or 'N/A' if it's down.
"""
ip, port = proxy.split(':')
start_time = time.time()
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(5)
result = sock.connect_ex((ip, int(port)))
if result == 0:
return round((time.time() - start_time) * 1000, 2)
except Exception as e:
logging.error(f"Error pinging proxy {proxy}: {e}")
return "N/A"
@bot.listener.on_message_event
async def commands(room, message):
"""
Command to display the list of available commands and their descriptions.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("commands"):
logging.info("Fetching commands documentation")
commands_message = """
**Available Commands:**
**!fortune**
Returns a random fortune message.
**!date**
Displays the current date and time.
**!proxy**
Retrieves and tests random SOCKS5 and HTTP proxies.
**!isup <domain/ip>**
Checks if the specified domain or IP address is reachable.
**!karma <user>**
Retrieves the karma points for the specified user.
**!karma <user> up**
Increases the karma points for the specified user by 1.
**!karma <user> down**
Decreases the karma points for the specified user by 1.
"""
await bot.api.send_markdown_message(room.room_id, commands_message)
logging.info("Sent commands documentation to the room")
@bot.listener.on_message_event
async def fortune(room, message):
"""
Command to get a random fortune.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("fortune"):
logging.info("Received !fortune command")
fortune_output = subprocess.run(['/usr/games/fortune'], capture_output=True).stdout.decode('UTF-8')
await bot.api.send_text_message(room.room_id, fortune_output)
logging.info("Sent fortune to the room")
@bot.listener.on_message_event
async def date(room, message):
"""
Command to get the current date and time.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("date"):
logging.info("Fetching current date and time")
current_datetime = datetime.datetime.now()
day_of_week = current_datetime.strftime("%A")
month = current_datetime.strftime("%B")
year = current_datetime.strftime("%Y")
time = current_datetime.strftime("%I:%M:%S %p")
date_message = f"Today is **{day_of_week}** of **{month}** in **{year}**. The time is **{time}**"
await bot.api.send_markdown_message(room.room_id, date_message)
logging.info("Sent current date and time to the room")
@bot.listener.on_message_event
async def proxy(room, message):
"""
Command to get random SOCKS5 and HTTP proxies.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("proxy"):
logging.info("Received !proxy command")
socks5_proxies = requests.get('https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/socks5.txt').text.splitlines()
http_proxies = requests.get('https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/http.txt').text.splitlines()
random_socks5_proxy = random.choice(socks5_proxies)
random_http_proxy = random.choice(http_proxies)
socks5_ping = await ping_proxy(random_socks5_proxy)
http_ping = await ping_proxy(random_http_proxy)
await bot.api.send_text_message(room.room_id, f"Random SOCKS5 Proxy: {random_socks5_proxy} - Ping time: {socks5_ping} ms")
await bot.api.send_text_message(room.room_id, f"Random HTTP Proxy: {random_http_proxy} - Ping time: {http_ping} ms")
logging.info("Sent proxies to the room")
@bot.listener.on_message_event
async def isup(room, message):
"""
Command to check if a website or server is up.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("isup"):
logging.info("Received !isup command")
args = match.args()
if len(args) != 1:
await bot.api.send_text_message(room.room_id, "Usage: !isup <ipv4/ipv6/domain>")
logging.info("Sent usage message to the room")
return
target = args[0]
try:
response = os.system(f"ping -c 1 {target}")
if response == 0:
await bot.api.send_text_message(room.room_id, f"{target} is up")
else:
await bot.api.send_text_message(room.room_id, f"{target} is down")
logging.info(f"Sent status of {target} to the room")
except Exception as e:
await bot.api.send_text_message(room.room_id, f"Error: {e}")
logging.error(f"Error occurred while checking {target}: {e}")
@bot.listener.on_message_event
async def karma(room, message):
"""
Command to manage karma points for users.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("karma"):
logging.info("Received !karma command")
args = match.args()
sender = str(message.sender)
if len(args) == 0:
# Query sender's own karma
conn = sqlite3.connect('karma.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS karma
(username TEXT PRIMARY KEY, points INTEGER)''')
c.execute('''INSERT OR IGNORE INTO karma (username, points) VALUES (?, ?)''', (sender, 0))
c.execute('''SELECT points FROM karma WHERE username = ?''', (sender,))
points = c.fetchone()[0]
conn.close()
await bot.api.send_text_message(room.room_id, f"{sender}'s karma points: {points}")
logging.info(f"Sent {sender}'s karma points ({points}) to the room")
elif len(args) == 1:
username = args[0]
if username == sender:
await bot.api.send_text_message(room.room_id, "You cannot modify your own karma.")
logging.info("Sent self-modification warning message to the room")
return
conn = sqlite3.connect('karma.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS karma
(username TEXT PRIMARY KEY, points INTEGER)''')
c.execute('''INSERT OR IGNORE INTO karma (username, points) VALUES (?, ?)''', (username, 0))
c.execute('''SELECT points FROM karma WHERE username = ?''', (username,))
points = c.fetchone()[0]
conn.close()
await bot.api.send_text_message(room.room_id, f"{username}'s karma points: {points}")
logging.info(f"Sent {username}'s karma points ({points}) to the room")
elif len(args) == 2:
username, action = args
if action not in ['up', 'down']:
await bot.api.send_text_message(room.room_id, "Invalid action. Use 'up' or 'down'.")
logging.info("Sent invalid action message to the room")
return
if username == sender:
await bot.api.send_text_message(room.room_id, "You cannot modify your own karma.")
logging.info("Sent self-modification warning message to the room")
return
conn = sqlite3.connect('karma.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS karma
(username TEXT PRIMARY KEY, points INTEGER)''')
if action == 'up':
c.execute('''UPDATE karma SET points = points + 1 WHERE username = ?''', (username,))
else:
c.execute('''UPDATE karma SET points = points - 1 WHERE username = ?''', (username,))
conn.commit()
c.execute('''SELECT points FROM karma WHERE username = ?''', (username,))
points = c.fetchone()[0]
conn.close()
await bot.api.send_text_message(room.room_id, f"{username}'s karma points: {points}")
logging.info(f"Sent {username}'s karma points ({points}) to the room")
else:
await bot.api.send_text_message(room.room_id, "Usage: !karma [username] [up/down]")
logging.info("Sent usage message to the room")
import re
@bot.listener.on_message_event
async def youtube(room, message):
"""
Command to fetch YouTube video information from links.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot)
if match.is_not_from_this_bot() and re.search(r'youtube\.com/watch\?v=', message.body):
logging.info("YouTube link detected")
video_id_match = re.search(r'youtube\.com/watch\?v=([^\s]+)', message.body)
if video_id_match:
video_id = video_id_match.group(1)
youtube_url = f"https://www.youtube.com/watch?v={video_id}"
logging.info(f"Fetching information for YouTube video: {youtube_url}")
try:
video = YouTube(youtube_url)
title = video.title
description = video.description
length = video.length
views = video.views
author = video.author
info_message = f"""Title: {title} | Length: {length} seconds | Views: {views} | Description: {description}"""
await bot.api.send_markdown_message(room.room_id, info_message)
logging.info("Sent YouTube video information to the room")
except Exception as e:
logging.error(f"Error fetching YouTube video information: {str(e)}")
await bot.api.send_text_message(room.room_id, "Error fetching YouTube video information.")
bot.run()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

45
plugins/commands.py Normal file
View File

@ -0,0 +1,45 @@
# plugins/commands.py
import logging
import simplematrixbotlib as botlib
async def handle_command(room, message, bot, PREFIX):
"""
Function to handle the !commands command.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("commands"):
logging.info("Fetching commands documentation")
commands_message = """
**Available Commands:**
**!fortune**
Returns a random fortune message.
**!date**
Displays the current date and time.
**!proxy**
Retrieves and tests random SOCKS5 and HTTP proxies.
**!isup <domain/ip>**
Checks if the specified domain or IP address is reachable.
**!karma <user>**
Retrieves the karma points for the specified user.
**!karma <user> up**
Increases the karma points for the specified user by 1.
**!karma <user> down**
Decreases the karma points for the specified user by 1.
"""
await bot.api.send_markdown_message(room.room_id, commands_message)
logging.info("Sent commands documentation to the room")

28
plugins/date.py Normal file
View File

@ -0,0 +1,28 @@
# plugins/date.py
import datetime
import logging
import simplematrixbotlib as botlib
async def handle_command(room, message, bot, PREFIX):
"""
Function to handle the !date command.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("date"):
logging.info("Fetching current date and time")
current_datetime = datetime.datetime.now()
day_of_week = current_datetime.strftime("%A")
month = current_datetime.strftime("%B")
year = current_datetime.strftime("%Y")
time = current_datetime.strftime("%I:%M:%S %p")
date_message = f"Today is **{day_of_week}** of **{month}** in **{year}**. The time is **{time}**"
await bot.api.send_markdown_message(room.room_id, date_message)
logging.info("Sent current date and time to the room")

23
plugins/fortune.py Normal file
View File

@ -0,0 +1,23 @@
# plugins/fortune.py
import subprocess
import logging
import simplematrixbotlib as botlib
async def handle_command(room, message, bot, PREFIX):
"""
Function to handle the !fortune command.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("fortune"):
logging.info("Received !fortune command")
fortune_output = subprocess.run(['/usr/games/fortune'], capture_output=True).stdout.decode('UTF-8')
await bot.api.send_text_message(room.room_id, fortune_output)
logging.info("Sent fortune to the room")

37
plugins/isup.py Normal file
View File

@ -0,0 +1,37 @@
# plugins/isup.py
import os
import logging
import simplematrixbotlib as botlib
async def handle_command(room, message, bot, PREFIX):
"""
Function to handle the !isup command.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("isup"):
logging.info("Received !isup command")
args = match.args()
if len(args) != 1:
await bot.api.send_text_message(room.room_id, "Usage: !isup <ipv4/ipv6/domain>")
logging.info("Sent usage message to the room")
return
target = args[0]
try:
response = os.system(f"ping -c 1 {target}")
if response == 0:
await bot.api.send_text_message(room.room_id, f"{target} is up")
else:
await bot.api.send_text_message(room.room_id, f"{target} is down")
logging.info(f"Sent status of {target} to the room")
except Exception as e:
await bot.api.send_text_message(room.room_id, f"Error: {e}")
logging.error(f"Error occurred while checking {target}: {e}")

85
plugins/karma.py Normal file
View File

@ -0,0 +1,85 @@
# plugins/karma.py
import sqlite3
import logging
import simplematrixbotlib as botlib
async def handle_command(room, message, bot, PREFIX):
"""
Function to handle the !karma command.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("karma"):
logging.info("Received !karma command")
args = match.args()
sender = str(message.sender)
if len(args) == 0:
# Query sender's own karma
conn = sqlite3.connect('karma.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS karma
(username TEXT PRIMARY KEY, points INTEGER)''')
c.execute('''INSERT OR IGNORE INTO karma (username, points) VALUES (?, ?)''', (sender, 0))
c.execute('''SELECT points FROM karma WHERE username = ?''', (sender,))
points = c.fetchone()[0]
conn.close()
await bot.api.send_text_message(room.room_id, f"{sender}'s karma points: {points}")
logging.info(f"Sent {sender}'s karma points ({points}) to the room")
elif len(args) == 1:
username = args[0]
if username == sender:
await bot.api.send_text_message(room.room_id, "You cannot modify your own karma.")
logging.info("Sent self-modification warning message to the room")
return
conn = sqlite3.connect('karma.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS karma
(username TEXT PRIMARY KEY, points INTEGER)''')
c.execute('''INSERT OR IGNORE INTO karma (username, points) VALUES (?, ?)''', (username, 0))
c.execute('''SELECT points FROM karma WHERE username = ?''', (username,))
points = c.fetchone()[0]
conn.close()
await bot.api.send_text_message(room.room_id, f"{username}'s karma points: {points}")
logging.info(f"Sent {username}'s karma points ({points}) to the room")
elif len(args) == 2:
username, action = args
if action not in ['up', 'down']:
await bot.api.send_text_message(room.room_id, "Invalid action. Use 'up' or 'down'.")
logging.info("Sent invalid action message to the room")
return
if username == sender:
await bot.api.send_text_message(room.room_id, "You cannot modify your own karma.")
logging.info("Sent self-modification warning message to the room")
return
conn = sqlite3.connect('karma.db')
c = conn.cursor()
c.execute('''CREATE TABLE IF NOT EXISTS karma
(username TEXT PRIMARY KEY, points INTEGER)''')
if action == 'up':
c.execute('''UPDATE karma SET points = points + 1 WHERE username = ?''', (username,))
else:
c.execute('''UPDATE karma SET points = points - 1 WHERE username = ?''', (username,))
conn.commit()
c.execute('''SELECT points FROM karma WHERE username = ?''', (username,))
points = c.fetchone()[0]
conn.close()
await bot.api.send_text_message(room.room_id, f"{username}'s karma points: {points}")
logging.info(f"Sent {username}'s karma points ({points}) to the room")
else:
await bot.api.send_text_message(room.room_id, "Usage: !karma [username] [up/down]")
logging.info("Sent usage message to the room")

103
plugins/proxy.py Normal file
View File

@ -0,0 +1,103 @@
# plugins/proxy.py
import os
import logging
import random
import requests
import socket
import asyncio
import time
import simplematrixbotlib as botlib
# Function to test SOCKS4 proxies
async def test_socks4_proxy(proxy):
try:
start_time = time.time()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
s.connect((proxy.split(':')[0], int(proxy.split(':')[1])))
latency = round((time.time() - start_time) * 1000, 2)
logging.info(f"Tested SOCKS4 proxy {proxy}. Latency: {latency} ms")
return True, latency
except Exception as e:
logging.error(f"Error testing SOCKS4 proxy {proxy}: {e}")
return False, None
# Function to test SOCKS5 proxies
async def test_socks5_proxy(proxy):
try:
start_time = time.time()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(5)
s.connect((proxy.split(':')[0], int(proxy.split(':')[1])))
latency = round((time.time() - start_time) * 1000, 2)
logging.info(f"Tested SOCKS5 proxy {proxy}. Latency: {latency} ms")
return True, latency
except Exception as e:
logging.error(f"Error testing SOCKS5 proxy {proxy}: {e}")
return False, None
# Function to test HTTP proxies
async def test_http_proxy(proxy):
local_ip = requests.get("https://api.ipify.org").text
try:
response = requests.get("https://api.ipify.org", proxies={"http": proxy}, timeout=5).text
if response.strip() != local_ip.strip():
logging.info(f"Tested anonymous HTTP proxy {proxy}")
return True
else:
logging.info(f"HTTP proxy {proxy} is not anonymous")
return False
except Exception as e:
logging.error(f"Error testing HTTP proxy {proxy}: {e}")
return False
async def handle_command(room, message, bot, PREFIX):
"""
Function to handle the !proxy command.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot, PREFIX)
if match.is_not_from_this_bot() and match.prefix() and match.command("proxy"):
logging.info("Received !proxy command")
try:
# Fetch SOCKS4 proxy
socks4_proxies = requests.get('https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/socks4.txt', timeout=5).text.splitlines()
random.shuffle(socks4_proxies)
for proxy in socks4_proxies:
is_working, latency = await test_socks4_proxy(proxy)
if is_working:
await bot.api.send_text_message(room.room_id, f"SOCKS4 Proxy: {proxy} - Latency: {latency} ms")
break
# Fetch SOCKS5 proxy
socks5_proxies = requests.get('https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/socks5.txt', timeout=5).text.splitlines()
random.shuffle(socks5_proxies)
for proxy in socks5_proxies:
is_working, latency = await test_socks5_proxy(proxy)
if is_working:
await bot.api.send_text_message(room.room_id, f"SOCKS5 Proxy: {proxy} - Latency: {latency} ms")
break
# Fetch HTTP proxy
http_proxies = requests.get('https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/http.txt', timeout=5).text.splitlines()
random.shuffle(http_proxies)
for proxy in http_proxies:
is_working = await test_http_proxy(proxy)
if is_working:
await bot.api.send_text_message(room.room_id, f"HTTP Proxy: {proxy}")
break
logging.info("Sent proxies to the room")
except asyncio.TimeoutError:
await bot.api.send_text_message(room.room_id, "Failed to fetch or test proxies. The operation timed out.")
logging.error("Proxy fetch and test operation timed out")
except Exception as e:
await bot.api.send_text_message(room.room_id, f"An error occurred: {e}")
logging.error(f"Error fetching or testing proxies: {e}")

39
plugins/youtube.py Normal file
View File

@ -0,0 +1,39 @@
# plugins/youtube.py
import re
import logging
from pytube import YouTube
import simplematrixbotlib as botlib
async def handle_command(room, message, bot, PREFIX):
"""
Function to handle YouTube video information from links.
Args:
room (Room): The Matrix room where the command was invoked.
message (RoomMessage): The message object containing the command.
Returns:
None
"""
match = botlib.MessageMatch(room, message, bot)
if match.is_not_from_this_bot() and re.search(r'youtube\.com/watch\?v=', message.body):
logging.info("YouTube link detected")
video_id_match = re.search(r'youtube\.com/watch\?v=([^\s]+)', message.body)
if video_id_match:
video_id = video_id_match.group(1)
youtube_url = f"https://www.youtube.com/watch?v={video_id}"
logging.info(f"Fetching information for YouTube video: {youtube_url}")
try:
video = YouTube(youtube_url)
title = video.title
description = video.description
length = video.length
views = video.views
author = video.author
info_message = f"""Title: {title} | Length: {length} seconds | Views: {views} | Description: {description}"""
await bot.api.send_markdown_message(room.room_id, info_message)
logging.info("Sent YouTube video information to the room")
except Exception as e:
logging.error(f"Error fetching YouTube video information: {str(e)}")
await bot.api.send_text_message(room.room_id, "Error fetching YouTube video information.")

3
requirements.txt Normal file
View File

@ -0,0 +1,3 @@
simplematrixbotlib
python-dotenv
pathlib