Skip to content

Instantly share code, notes, and snippets.

@plowsof
Created June 14, 2024 19:36
Show Gist options
  • Save plowsof/fe60bdc161056046cff2ac01d933c656 to your computer and use it in GitHub Desktop.
Save plowsof/fe60bdc161056046cff2ac01d933c656 to your computer and use it in GitHub Desktop.
messages users on matrix.org homerver once if the bot sees them send a message,
import asyncio
import logging
from nio import (
AsyncClient, RoomMessageText, RoomCreateResponse, RoomCreateError,
LoginResponse, RoomPreset, RoomVisibility
)
import aiosqlite
from datetime import datetime
# Set up logging
#logging.basicConfig(level=logging.DEBUG)
class MatrixBot:
def __init__(self, homeserver, user_id, password, target_rooms):
self.client = AsyncClient(homeserver, user_id)
self.password = password
self.target_rooms = target_rooms
self.join_timestamps = {} # Dictionary to hold join timestamps for each room
async def process_message(self, room_id, event):
user_id = event.sender
timestamp = event.server_timestamp
# Process only messages sent after the bot joined the room
if timestamp > self.join_timestamps[room_id]:
logging.debug(f"Message from {user_id} in room {room_id}: {event.body}")
if "matrix.org" in user_id:
async with aiosqlite.connect('users.db') as db:
async with db.execute("SELECT 1 FROM messaged_users WHERE user_id=?", (user_id,)) as cursor:
result = await cursor.fetchone()
if result is None:
logging.info(f"User {user_id} has not been messaged before. Sending private message.")
try:
response = await self.client.room_create(
visibility=RoomVisibility.private,
invite=[user_id],
preset=RoomPreset.public_chat,
topic="This is a public, unencrypted room.",
)
#logging.debug(f"Room create response: {response}")
#logging.debug(f"Room create response type: {type(response)}")
if isinstance(response, RoomCreateResponse):
dm_room_id = response.room_id
logging.info(f"Direct message room created: {dm_room_id}")
await self.client.room_send(
room_id=dm_room_id,
message_type="m.room.message",
content={
"msgtype": "m.text",
"body": "🚨 **Attention:** We noticed that you are using the `matrix.org` homeserver. Unfortunately, this server is currently experiencing severe delays when sending and receiving messages to others. You have two options:\n\n1. **Continue Using `matrix.org`:** Accept the delays and the lack of perceived activity. You can follow the ongoing conversations on https://libera.monerologs.net/.\n\n2. **Register on Another Homeserver:** You can create an account on a different homeserver such as Monero Social. We have a helpful guide on how to set up a Monero Social account at https://web.getmonero.org/resources/user-guides/join-monero-matrix.html.\n\nThank you for your understanding. πŸ™",
"format": "org.matrix.custom.html",
"formatted_body": """
🚨 <strong>Attention:</strong> We noticed that you are using the <code>matrix.org</code> homeserver. Unfortunately, this server is currently experiencing severe delays when sending and receiving messages to others. You have two options:<br><br>
1. <strong>Continue Using <code>matrix.org</code>:</strong> Accept the delays and the lack of perceived activity. You can follow the ongoing conversations on <a href="https://libera.monerologs.net/">https://libera.monerologs.net/</a>.<br><br>
2. <strong>Register on Another Homeserver:</strong> You can create an account on a different homeserver such as Monero Social. We have a helpful guide on how to set up a Monero Social account at <a href="https://web.getmonero.org/resources/user-guides/join-monero-matrix.html">https://web.getmonero.org/resources/user-guides/join-monero-matrix.html</a>.<br><br>
Thank you for your understanding. πŸ™πŸˆοΈπŸ§‘β€πŸ’»
"""
}
)
await db.execute("INSERT INTO messaged_users (user_id) VALUES (?)", (user_id,))
await db.commit()
logging.info(f"Message sent to {user_id} in room {dm_room_id}.")
elif isinstance(response, RoomCreateError):
logging.error(f"Failed to create room: {response.message}")
else:
logging.error(f"Unexpected response type: {type(response)} - {response}")
except Exception as e:
logging.error(f"Error creating or sending message: {e}")
async def message_callback(self, room, event):
if isinstance(event, RoomMessageText) and room.room_id in self.target_rooms:
await self.process_message(room.room_id, event)
async def join_rooms(self):
for room_id in self.target_rooms:
logging.info(f"Joining target room: {room_id}")
join_response = await self.client.join(room_id)
if join_response:
logging.info(f"Joined room: {room_id}")
# Save the timestamp of when the bot joined the room
self.join_timestamps[room_id] = datetime.now().timestamp() * 1000 # convert to milliseconds
else:
logging.error(f"Failed to join room: {room_id}")
async def run(self):
try:
logging.info("Logging in")
login_response = await self.client.login(self.password)
if isinstance(login_response, LoginResponse):
logging.info("Logged in successfully")
else:
logging.error(f"Failed to log in: {login_response}")
return
await self.join_rooms()
self.client.add_event_callback(self.message_callback, RoomMessageText)
logging.info("Starting sync loop")
await self.client.sync_forever(timeout=30000)
except Exception as e:
logging.error(f"Error in main run loop: {e}")
async def setup_database():
async with aiosqlite.connect('users.db') as db:
await db.execute('''
CREATE TABLE IF NOT EXISTS messaged_users (user_id TEXT PRIMARY KEY)
''')
await db.commit()
async def main():
await setup_database()
# Configuration
HOMESERVER = "https://matrix.org"
USER_ID = "@nvmitsmatrixdotorg:matrix.org"
PASSWORD = "hunter2"
TARGET_ROOMS = ["!eBgZCVRnRRkKchiYzS:monero.social", "!WzzKmkfUkXPHFERgvm:matrix.org", "!LmpzSzbSMKFmPbCpHe:monero.social", "!cSwJDzxRuWndmFUZTd:haveno.network"]
bot = MatrixBot(HOMESERVER, USER_ID, PASSWORD, TARGET_ROOMS)
await bot.run()
asyncio.run(main())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment