189 lines
7.0 KiB
Python
189 lines
7.0 KiB
Python
|
|
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()) |