Moved to webhooks for discord and added discord

avatars if linked to matter most user id
This commit is contained in:
Jadowyne Ulve 2025-06-10 18:02:33 -05:00
parent 99d606f2a1
commit 28e2e4243c
7 changed files with 129 additions and 223 deletions

6
.gitignore vendored
View File

@ -1,2 +1,4 @@
generate_images/2025-06-08 150855867880-gen-PNG-ujZRQA.png generate_images/*
generate_images/test-gen-image.png
__pycache__/*

BIN
assets/images/owncast.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

View File

@ -31,7 +31,26 @@ def parse_links_from_mattermost(string):
DISCORD_BOT_URL = 'http://localhost:5001/post_message' DISCORD_BOT_URL = 'http://localhost:5001/post_message'
def send_mattermost_to_discord(post, channel_to, avatar_url=None): def getDiscordUserProfile(discord_user_id):
print("test")
bot_token = "MTMyNzcxNDM3MTEyMzgxMDMwNA.GwLjEd.quGP0FA5gHRe1xLyuYq-ANuJ5cRuRQ6dhJiojI"
guild_id = "954201387770736751"
headers = {'Authorization': f'Bot {bot_token}'}
discord_guild_endpoint = f"https://discord.com/api/v10/guilds/{guild_id}/members/{discord_user_id}"
response = requests.get(discord_guild_endpoint, headers=headers)
print(response)
if response.status_code == 200:
discord_user = response.json()
username = discord_user['nick']
if discord_user['avatar']:
avatar_url = f"https://cdn.discordapp.com/guilds/{guild_id}/users/{discord_user['user']['id']}/avatars/{discord_user['avatar']}.png"
else:
avatar_url = f"https://cdn.discordapp.com/avatars/{discord_user['user']['id']}/{discord_user['user']['avatar']}.png"
return True, username, avatar_url
else:
return False, "Unknown", ""
def send_mattermost_to_discord(post, webhook_url, avatar_url=""):
post_message = parse_links_from_mattermost(post['message']) post_message = parse_links_from_mattermost(post['message'])
@ -41,26 +60,15 @@ def send_mattermost_to_discord(post, channel_to, avatar_url=None):
else: else:
username = post['user']['nickname'] username = post['user']['nickname']
if avatar_url: payload = {
payload = { "content": post_message,
"message": post_message, "username": username,
"channel_to": channel_to, "avatar_url": avatar_url
"username": username, }
"avatar_url": avatar_url,
"discord_id": post['discord_id']
}
else:
payload = {
"message": post_message,
"channel_to": channel_to,
"username": username,
"avatar_url": None,
"discord_id": post['discord_id']
}
response = requests.post(DISCORD_BOT_URL, json=payload) response = requests.post(webhook_url, data=payload)
print("webhook response: ", response)
if response.status_code == 200: if response.status_code == 204:
print("Message sent successfully.") print("Message sent successfully.")
else: else:
print("Failed to send the message.") print("Failed to send the message.")
@ -82,34 +90,12 @@ def parse_links_from_discord(string):
return string return string
def send_discord_to_mattermost(message, channel_to): def send_discord_to_mattermost(message, channel_to):
bearer_token = "g9rpuzcpkpgyddozad6j5nui9r" channel_id = mattermostDriver.channels.get_channel_by_name_and_team_name(channel_to[1], channel_to[0])['id']
url = "http://chat.treehousefullofstars.com/api/v4/posts"
webhook_url = "https://chat.treehousefullofstars.com/hooks/qjxs466x1pr63y71bszze56x4c"
channel_id = mattermostDriver.channels.get_channel_by_name_and_team_name('Treehousefullofstars', channel_to)['id']
new_contents = "" new_contents = ""
count = 0 count = 0
file_ids = [] file_ids = []
"""if message.embeds:
print(message.embeds)
for embed in message.embeds:
new_contents += f"\n{embed.url}"
count += 1
file_url = embed.url
response = requests.get(file_url)
file_data = response.content
file_id = mattermostDriver.files.upload_file(
channel_id=channel_id,
files={'files': (embed.filename, file_data)}
)['file_infos'][0]['id']
file_ids.append(file_id)"""
if message.attachments: if message.attachments:
print(message.attachments)
for attachment in message.attachments: for attachment in message.attachments:
file_url = attachment.url file_url = attachment.url
@ -122,17 +108,6 @@ def send_discord_to_mattermost(message, channel_to):
)['file_infos'][0]['id'] )['file_infos'][0]['id']
file_ids.append(file_id) file_ids.append(file_id)
"""payload = {
"channel": channel_to,
"text": message.content,
"username": message.author.nick,
"icon_url": message.author.display_avatar.url,
"file_ids": file_ids
}
response = requests.post(webhook_url, json=payload)
print(response.content)"""
text = message.content text = message.content
if count>0: if count>0:
text += new_contents text += new_contents
@ -187,3 +162,30 @@ def send_misskey_to_mattermost(event, channel_id):
}, },
'message': note_content, 'message': note_content,
'file_ids': file_ids}) 'file_ids': file_ids})
owncast_webhook = "https://chat.treehousefullofstars.com/hooks/3o9tozzipi8e3rtkcns63pesfr"
def send_owncast_to_mattermost(event):
print(event)
data = event['eventData']
type = event['type']
post = False
text = ""
if type == "STREAM_STARTED":
text = f"Stream Starting... {data['streamTitle']}\n<http://184.83.153.182:5000/stream>"
post = True
elif type == "STREAM_STOPPED":
text = f"Stream Stopping..."
post = True
elif type == "STREAM_TITLE_UPDATED":
text = f"Stream title changed! We are now streaming... {data['streamTitle']}"
post = True
if post:
payload = {
"text": text,
"username": f"{data['name']} - Stream",
"icon_url": "http://192.168.1.67:8086/logo"
}
requests.post(owncast_webhook, json=payload)

View File

@ -70,13 +70,14 @@ async def on_ready():
channels = { channels = {
1125968295967850559: "our-comforter", #comforter 1125968295967850559: ("our-comforter", 'final-fantasy-14'), #comforter
954201387770736754: "lounge", #lounge 954201387770736754: ("lounge", 'final-fantasy-14'), #lounge
1119502004721557554: "town-square", # kweh 1119502004721557554: ("town-square", 'Treehousefullofstars'), # kweh
1367978276185964584: "misskey", #misskey 1367978276185964584: ("misskey", 'Treehousefullofstars'), #misskey
1167176429797113926: "photos-from-another-star", #photos-from-another-star 1167176429797113926: ("photos-from-another-star", 'final-fantasy-14'), #photos-from-another-star
1119508652844404816: "bulletin-board", #bulletin-board 1119508652844404816: ("bulletin-board", 'Treehousefullofstars'), #bulletin-board
955394194766192690: "photos-of-the-gang" #photos-of-the-gang 955394194766192690: ("photos-of-the-gang", 'final-fantasy-14'), #photos-of-the-gang
1381391455574167653: ("stream", 'Treehousefullofstars'),
} }
@client.event @client.event
@ -104,36 +105,6 @@ async def send_custom_message(channel: discord.TextChannel, message, username, u
await webhook.send(message, username=username, avatar_url=avatar_url) await webhook.send(message, username=username, avatar_url=avatar_url)
await webhook.delete() await webhook.delete()
# flask
app = flask.Flask(__name__)
@app.route('/post_message', methods=['POST'])
async def post_message():
data:dict = flask.request.json
message = data.get('message')
username = data.get('username', 'Unknown')
avatar_url = data.get('avatar_url', None)
user_id = data.get('discord_id', None)
print(data)
if message == "":
return flask.jsonify({'error': 'Message cannot be blank.'}), 400
channel = client.get_channel(data['channel_to'])
if channel:
client.loop.create_task(send_custom_message(channel, message, username, user_id, avatar_url))
#client.loop.create_task(channel.send(message))
return flask.jsonify({'status': 'Message sent successfully.'}), 200
else:
return flask.jsonify({'error': 'Channel not found.'}), 404
def run_flask_app():
app.run(port=5001)
# Run the Flask app in a separate thread
thread = Thread(target=run_flask_app)
thread.start()
token = "MTMyNzcxNDM3MTEyMzgxMDMwNA.GwLjEd.quGP0FA5gHRe1xLyuYq-ANuJ5cRuRQ6dhJiojI" token = "MTMyNzcxNDM3MTEyMzgxMDMwNA.GwLjEd.quGP0FA5gHRe1xLyuYq-ANuJ5cRuRQ6dhJiojI"
client.run(token) client.run(token)

View File

@ -3,15 +3,23 @@ from mattermostdriver import Driver
import bridges import bridges
channels = { channels = {
"ibfp3fskai8adgmynbfispz3se": 1125968295967850559, #comforter "zc69ns9jwpbn7c3wkxdf6x8nto": 1125968295967850559, #comforter
"rb43iupdy7rjbjwhg9w9c1mzjy": 954201387770736754, # lounge "ap61bgmm63f8irths1gk91zowh": 954201387770736754, # lounge
"s6muherhotfoircc1yzmwr5wty": 1119502004721557554, # kweh #"s6muherhotfoircc1yzmwr5wty": 1119502004721557554, # kweh
"fkcqa3qj83gu3bfikcu55sfwww": 1367978276185964584, #misskey "fkcqa3qj83gu3bfikcu55sfwww": 1367978276185964584 #misskey
"na4doo5f83ykbc45m9a5dn513a": 1167176429797113926, #photos-from-another-star #"na4doo5f83ykbc45m9a5dn513a": 1167176429797113926, #photos-from-another-star
"9ydcz9orepbtmedncb7idh43hr": 1119508652844404816, #bulletin-board #"9ydcz9orepbtmedncb7idh43hr": 1119508652844404816, #bulletin-board
"81qmzfzeeif7mmfhpy7hkxnjuc": 955394194766192690 #photos-of-the-gang #"81qmzfzeeif7mmfhpy7hkxnjuc": 955394194766192690, #photos-of-the-gang
#"u1ffegpqj3gg7yephh6rnso74o": 1381391455574167653 #stream
} }
webhooks = {
1125968295967850559: "https://discord.com/api/webhooks/1153490247905189909/pm_cDa8XqsTIlAsZY1uUFmSSvDZKjaI8u30mjFzmvHcMhMQFirQcWbI9rEee4OFmLNnu",
954201387770736754: "https://discord.com/api/webhooks/1127805939425235029/c4RvvRDUfDuE0-cvTzlPQPYbaTN6UdZzEPfLypOQCGSejax93Gh99E3_xgbCirrh4CqH"
}
post_webhooks_exemptions = ["u1ffegpqj3gg7yephh6rnso74o", "fkcqa3qj83gu3bfikcu55sfwww"]
users = { users = {
"f3nja8t9fpy73cxeh5ykzrozaw": 407247496008433675, "f3nja8t9fpy73cxeh5ykzrozaw": 407247496008433675,
"3byr3scix3f78xs5bpmgqzc6pc": 189202462442389514, "3byr3scix3f78xs5bpmgqzc6pc": 189202462442389514,
@ -36,23 +44,31 @@ async def event_handler(event):
if is_webhook != "true": if is_webhook != "true":
# add file syncing means you need to get the "file_ids" key from the post and then download them into blobs and pass those along # add file syncing means you need to get the "file_ids" key from the post and then download them into blobs and pass those along
# to the request as files, on the discord side those files would then get attached to the webhook. # to the request as files, on the discord side those files would then get attached to the webhook.
discord_channel_id = channels[post['channel_id']]
print(discord_channel_id)
user = mattermostDriver.users.get_user(user_id=post['user_id']) user = mattermostDriver.users.get_user(user_id=post['user_id'])
#print(user) #print(user)
post['user'] = user post['user'] = user
discord_id = None discord_id = None
print("user:", user) print("user:", user)
avatar_url = ""
if user['id'] in users.keys(): if user['id'] in users.keys():
discord_id = users[post['user']['id']] discord_user_id = users[post['user']['id']]
status, username, avatar_url = bridges.getDiscordUserProfile(discord_user_id)
post['user']['nickname'] = username
print(avatar_url)
post['discord_id'] = discord_id post['discord_id'] = discord_id
bridges.send_mattermost_to_discord(post, channel_to=channels[post['channel_id']]) print(webhooks[discord_channel_id])
elif post['channel_id'] == "fkcqa3qj83gu3bfikcu55sfwww" and is_webhook == "true": bridges.send_mattermost_to_discord(post, webhook_url=webhooks[discord_channel_id], avatar_url=avatar_url)
elif post['channel_id'] in post_webhooks_exemptions and is_webhook == "true":
print("exempt channel!")
username = post['props']['override_username'] username = post['props']['override_username']
avatar_url = post['props']['override_icon_url'] avatar_url = post['props']['override_icon_url']
user = {"nickname": username} user = {"nickname": username}
post['user'] = user post['user'] = user
post['discord_id'] = None post['discord_id'] = None
bridges.send_mattermost_to_discord(post, channel_to=channels[post['channel_id']], avatar_url=avatar_url) bridges.send_mattermost_to_discord(post, webhook_url=webhooks[discord_channel_id], avatar_url=avatar_url)
mattermostDriver = Driver({ mattermostDriver = Driver({
"url": "192.168.1.67", "url": "192.168.1.67",

12
owncast.app.py Normal file
View File

@ -0,0 +1,12 @@
import flask
import bridges
app = flask.Flask(__name__)
@app.route('/owncast_webhook', methods=['POST'])
async def post_message():
bridges.send_owncast_to_mattermost(flask.request.get_json())
return flask.Response(status=200)
app.run(host="0.0.0.0", port=5002, debug=True)

133
test.json
View File

@ -1,117 +1,20 @@
{ {
"type": "channel", "eventData": {
"body": { "id": "YiLYhFLNRz",
"id": "a79jhleyz47f00j9", "name": "Treehouse Full of Stars",
"type": "note", "status": {
"body": { "lastConnectTime": "2025-06-08T21:16:13Z",
"id": "a8qi6tndcsjw00uj", "lastDisconnectTime": null,
"createdAt": "2025-06-08T00:42:51.673Z", "versionNumber": "0.2.3",
"userId": "a78vufh1z47f000t", "streamTitle": "Messing around before Maps, test! tt",
"user": { "viewerCount": 0,
"id": "a78vufh1z47f000t", "overallMaxViewerCount": 5,
"name": "Gabriella Versi", "sessionMaxViewerCount": 0,
"username": "gabriella", "online": false
"host": null, },
"avatarUrl": "https://misskey.treehousefullofstars.com/proxy/avatar.webp?url=https%3A%2F%2Fmisskey.treehousefullofstars.com%2Ffiles%2F64e5e5cf-5d64-40f1-91ab-f7858f4b0e18&avatar=1", "streamTitle": "Messing around before Maps, test! tt",
"avatarBlurhash": "eOPZ7PRjpd%Mx]_Nxt?bs:xZ%gWCROWCM|%gWBRjofWXSPf5xtt7V@", "summary": "",
"avatarDecorations": [], "timestamp": "2025-06-08T21:16:13.781690442Z"
"isBot": false, },
"isCat": false, "type": "STREAM_STARTED"
"emojis": {},
"onlineStatus": "online",
"badgeRoles": [
{
"name": "Roots",
"iconUrl": null,
"displayOrder": 0
}
]
},
"text": null,
"cw": null,
"visibility": "public",
"localOnly": false,
"reactionAcceptance": null,
"renoteCount": 0,
"repliesCount": 0,
"reactionCount": 0,
"reactions": {},
"reactionEmojis": {},
"reactionAndUserPairCache": [],
"fileIds": [],
"files": [],
"replyId": null,
"renoteId": "a8ohrbj431al069k",
"clippedCount": 0,
"renote": {
"id": "a8ohrbj431al069k",
"createdAt": "2025-06-06T14:55:16.000Z",
"userId": "a7xcts4vcsjw00at",
"user": {
"id": "a7xcts4vcsjw00at",
"name": "Information Is Beautiful",
"username": "infobeautiful",
"host": "vis.social",
"avatarUrl": "https://misskey.treehousefullofstars.com/proxy/avatar.webp?url=https%3A%2F%2Fcdn.masto.host%2Fvissocial%2Faccounts%2Favatars%2F111%2F030%2F299%2F829%2F248%2F466%2Foriginal%2F0d4bfae30dce0763.png&avatar=1",
"avatarBlurhash": "e2CY]zxI9xx@=y$%juXSa{aeD,ou~UV|bayCj@ena#t7yCRowIxo01",
"avatarDecorations": [],
"isBot": false,
"isCat": false,
"instance": {
"name": "vis.social",
"softwareName": "mastodon",
"softwareVersion": "4.3.8",
"iconUrl": "https://vis.social/packs/media/icons/android-chrome-36x36-4c61fdb42936428af85afdbf8c6a45a8.png",
"faviconUrl": "https://vis.social/packs/media/icons/favicon-48x48-c1197e9664ee6476d2715a1c4293bf61.png",
"themeColor": "#181820"
},
"emojis": {},
"onlineStatus": "unknown"
},
"text": "Some interesting variations here...\n(by reddit user theworldmaps)",
"cw": null,
"visibility": "public",
"localOnly": false,
"reactionAcceptance": null,
"renoteCount": 1,
"repliesCount": 1,
"reactionCount": 0,
"reactions": {},
"reactionEmojis": {},
"reactionAndUserPairCache": [],
"emojis": {},
"fileIds": [
"a8ohrh7e31al069j"
],
"files": [
{
"id": "a8ohrh7e31al069j",
"createdAt": "2025-06-06T14:55:23.354Z",
"name": "b1743c8a716cf03a.png",
"type": "image/png",
"md5": "8fa3149c3db0e0d11e7b0b0007cabeeb",
"size": 0,
"isSensitive": false,
"blurhash": "eHQuZ@WdUE+^XoghOkXlw1oxLzNrmSr{t1vgQ;ogXOWZu2r;bwpaaM",
"properties": {
"width": 853,
"height": 1024
},
"url": "https://misskey.treehousefullofstars.com/files/webpublic-1225bfbb-9837-44b0-b0ac-1ed14fa1df92",
"thumbnailUrl": "https://misskey.treehousefullofstars.com/proxy/static.webp?url=https%3A%2F%2Fcdn.masto.host%2Fvissocial%2Fmedia_attachments%2Ffiles%2F114%2F636%2F994%2F245%2F080%2F080%2Foriginal%2Fb1743c8a716cf03a.png&static=1",
"comment": "A map of Europe showing the mean age of women at the birth of their first child, categorized by color from yellow (age 25) to purple (age 33). Examples include: Moldova with the youngest average age at 25.1, and Monaco with the highest at 32.5. Other notable countries: Spain at 31.6, Italy at 31.7, Germany at 29.9, and Finland at 29.9. The map includes small flags and labeled figures for precision. Data for the UK is from 2018, and other countries are from 2021 or 2022.",
"folderId": null,
"folder": null,
"userId": "a7xcts4vcsjw00at",
"user": null
}
],
"replyId": null,
"renoteId": null,
"uri": "https://vis.social/users/infobeautiful/statuses/114636994393755424",
"url": "https://vis.social/@infobeautiful/114636994393755424",
"clippedCount": 0
}
}
}
} }