import misskey import websockets import json import asyncio import requests from io import BytesIO MISSKEY_INSTANCE = "misskey.treehousefullofstars.com" MISSKEY_TOKEN = "JSvVuz1eS2BGq6MagdQC9m109gOllwcO" msk = misskey.Misskey(address=MISSKEY_INSTANCE, i=MISSKEY_TOKEN) MY_ID = msk.i()['id'] WS_URL=f"wss://{MISSKEY_INSTANCE}/streaming" channels = ['localTimeline', 'globalTimeline' 'hybridTimeline', 'main'] discord_webhook = "https://discord.com/api/webhooks/1367836441098326107/fqDmUGd-u2sWXF9ymuAgArHPnmTCU70_pFaqagqFww9cd07ujjQ4S1s8KvVuc1O1xIHX" async def handleMentions(message: str, mentions): for mention in mentions: user, discord = await getUserProfile(mention) if user and discord: misskey_mention_tag = f"@{user['username']}" discord_mention_tag = f"<@{discord['user']['id']}>" message = message.replace(misskey_mention_tag, discord_mention_tag) return message async def getUserProfile(userID): api_endpoint = f"https://{MISSKEY_INSTANCE}/api/users/show" bot_token = "MTMyNzcxNDM3MTEyMzgxMDMwNA.GwLjEd.quGP0FA5gHRe1xLyuYq-ANuJ5cRuRQ6dhJiojI" guild_id = "954201387770736751" params = { "i": MISSKEY_TOKEN, "userId": userID } response = requests.post(api_endpoint, json=params) user_profile = None discord_user = None if response.status_code == 200: user_profile = response.json() else: return user_profile, discord_user discord_id = None if user_profile != {}: for field in user_profile.get('fields', []): if field['name'] == "Discord": discord_id = field['value'] discord_user = {} if discord_id: headers = {'Authorization': f'Bot {bot_token}'} discord_guild_endpoint = f"https://discord.com/api/v10/guilds/{guild_id}/members/{discord_id}" response = requests.get(discord_guild_endpoint, headers=headers) if response.status_code == 200: discord_user = response.json() else: return user_profile, discord_user with open('user.json', 'w+') as file: file.write(json.dumps({'user': user_profile, 'discord': discord_user}, indent=5)) return user_profile, discord_user async def handle_message(websocket, message): data = json.loads(message) with open('test.json', 'w+') as file: file.write(json.dumps(data, indent=5)) headers={ 'Content-type':'application/json', 'Accept':'application/json' } response = requests.post("http://127.0.0.1:5000/misskey-connect", json=data, headers=headers) print(response) guild_id = "954201387770736751" user_id = data['body']['body']['userId'] user, discord = await getUserProfile(userID=user_id) with open('user.json', 'w+') as file: file.write(json.dumps({'user': user, 'discord': discord}, indent=5)) if data['body']['type'] == "note": print("note") if data['body']['body']['renoteId']: files = data['body']['body']['renote'].get('files', None) else: files = data['body']['body'].get('files', None) passed_files = {} if files != []: for i, file in enumerate(files): response = requests.get(file['url']) file_data = BytesIO(response.content) filename = file['name'] passed_files[f"file{i}"] = (filename, file_data, file['type']) if data['body']['body']['renoteId']: renote_user = data['body']['body']['renote']['user'].get('name', 'unknown') renote_username = data['body']['body']['renote']['user'].get('username', 'unknown') renote_user_host = data['body']['body']['renote']['user'].get('hose', 'unknown') note_content = f"*Renoted {renote_user} (@{renote_username}@{renote_user_host})*\n{data['body']['body']['renote']['text']}" else: note_content = data['body']['body'].get('text', 'No text in note') username = data['body']['body']['user'].get('name', 'Misskey Bot') avatar_url = data['body']['body']['user'].get('avatarUrl', None) if discord: username = discord['nick'] if discord['avatar']: avatar_url = f"https://cdn.discordapp.com/guilds/{guild_id}/users/{discord['user']['id']}/avatars/{discord['avatar']}.png" else: avatar_url = f"https://cdn.discordapp.com/avatars/{discord['user']['id']}/{discord['user']['avatar']}.png" note_content = await handleMentions(note_content, data['body']['body'].get('mentions', [])) print(note_content, username, avatar_url) if passed_files != {}: await send_to_discord(note_content, username=username, avatar_url=avatar_url, files=passed_files) else: await send_to_discord(note_content, username=username, avatar_url=avatar_url) async def send_to_discord(message, username="Misskey Bot", avatar_url=None, embeds=None, files=None): content = f"{message}" payload = { "content": content, "username": username, "avatar_url": avatar_url } if embeds: payload['embeds'] = embeds print(payload) if files: response = requests.post(discord_webhook, data=payload, files=files) else: response = requests.post(discord_webhook, json=payload) if response.status_code != 204: print(f"Failed to send message to Discord: {response.status_code} {response.text}") async def connect_and_listen(): while True: try: print("Connecting to WebSocket...") async with websockets.connect(WS_URL) as websocket: print("Connected to WebSocket") # Subscribe to the channels for channel in channels: subscription_request = { "type": "connect", "body": { "channel": channel, "id": MY_ID, "access_token": MISSKEY_TOKEN } } await websocket.send(json.dumps(subscription_request)) print(f"Sent subscription request for {channel} channel with ID: {MY_ID}") response = await websocket.recv() print(f"Received response for {channel} channel: {response}") await handle_message(websocket, response) # Listen for messages #while True: # async for message in websocket: # await handle_message(websocket, message) except websockets.exceptions.ConnectionClosedError as e: print(f"Connection closed unexpectedly: {e}") await asyncio.sleep(5) # Wait for 5 seconds before retrying except Exception as e: print(f"An error occurred: {e}") await asyncio.sleep(5) # Wait for 5 seconds before retrying # Run the client if __name__ == "__main__": asyncio.run(connect_and_listen())