initial polls support (not exactly working)

This commit is contained in:
Ellie Algase
2026-01-25 14:33:09 +13:00
committed by Cadence Ember
parent 2496f4c3b0
commit e565342ac8
16 changed files with 749 additions and 14 deletions
+64
View File
@@ -203,6 +203,46 @@ async function attachmentToEvent(mentions, attachment) {
}
}
/** @param {DiscordTypes.APIPoll} poll */
async function pollToEvent(poll) {
let fallbackText = poll.question.text
if (poll.allow_multiselect) {
var maxSelections = poll.answers.length;
} else {
var maxSelections = 1;
}
let answers = poll.answers.map(answer=>{
let matrixText = answer.poll_media.text
if (answer.poll_media.emoji) {
if (answer.poll_media.emoji.id) {
// Custom emoji. It seems like no Matrix client allows custom emoji in poll answers, so leaving this unimplemented.
} else {
matrixText = "[" + answer.poll_media.emoji.name + "] " + matrixText
}
}
let matrixAnswer = {
id: answer.answer_id.toString(),
"org.matrix.msc1767.text": matrixText
}
fallbackText = fallbackText + "\n" + answer.answer_id.toString() + ". " + matrixText
return matrixAnswer;
})
return {
$type: "org.matrix.msc3381.poll.start",
"org.matrix.msc3381.poll.start": {
question: {
"org.matrix.msc1767.text": poll.question.text,
body: poll.question.text,
msgtype: "m.text"
},
kind: "org.matrix.msc3381.poll.disclosed", // Discord always lets you see results, so keeping this consistent with that.
max_selections: maxSelections,
answers: answers
},
"org.matrix.msc1767.text": fallbackText
}
}
/**
* @param {DiscordTypes.APIMessage} message
* @param {DiscordTypes.APIGuild} guild
@@ -226,6 +266,20 @@ async function messageToEvent(message, guild, options = {}, di) {
return []
}
if (message.type === DiscordTypes.MessageType.PollResult) {
const event_id = select("event_message", "event_id", {message_id: message.message_reference?.message_id}).pluck().get()
return [{
$type: "org.matrix.msc3381.poll.end",
"m.relates_to": {
rel_type: "m.reference",
event_id
},
"org.matrix.msc3381.poll.end": {},
body: "This poll has ended.",
msgtype: "m.text"
}]
}
if (message.type === DiscordTypes.MessageType.ThreadStarterMessage) {
// This is the message that appears at the top of a thread when the thread was based off an existing message.
// It's just a message reference, no content.
@@ -702,6 +756,12 @@ async function messageToEvent(message, guild, options = {}, di) {
}
}
// Then polls
if (message.poll) {
const pollEvent = await pollToEvent(message.poll)
events.push(pollEvent)
}
// Then embeds
const urlPreviewEnabled = select("guild_space", "url_preview", {guild_id: guild?.id}).pluck().get() ?? 1
for (const embed of message.embeds || []) {
@@ -713,6 +773,10 @@ async function messageToEvent(message, guild, options = {}, di) {
continue // Matrix's own URL previews are fine for images.
}
if (embed.type === "poll_result") {
// The code here is only for the message to be bridged to Matrix. Dealing with the Discord-side updates is in actions/poll-close.js.
}
if (embed.url?.startsWith("https://discord.com/")) {
continue // If discord creates an embed preview for a discord channel link, don't copy that embed
}