Repository navigation
handle*: add option to bridge polls with a provisioning API for fetching results - #1135
Conversation
|
All clear! No issues remaining. 🎉 4 issues already resolved
All required CI checks passed on
Select any unchecked box below to run or rerun that agent. Full resultsIndent Review Agent
|
| feat.DeleteChat = topicID == 0 | ||
| case ids.PeerTypeUser: | ||
| baseID += "+dm" | ||
| feat.Poll = event.CapLevelRejected |
There was a problem hiding this comment.
Hmm, telegram allows forwarding polls into DMs, I wonder if sending new ones is actually blocked or just hidden in the UI
| # Should polls be sent using unstable MSC3381 event types? Votes aren't bridged as events, | ||
| # clients fetch the current results with the poll results provisioning API instead. |
There was a problem hiding this comment.
The provisioning API detail is fairly irrelevant for people reading this
| # Should polls be sent using unstable MSC3381 event types? Votes aren't bridged as events, | |
| # clients fetch the current results with the poll results provisioning API instead. | |
| # Should polls be sent using unstable MSC3381 event types? | |
| # Bridging votes from Telegram is not supported. |
| "org.matrix.msc3381.poll.start": map[string]any{ | ||
| "kind": kind, | ||
| "max_selections": maxSelections, | ||
| "question": map[string]any{ | ||
| "org.matrix.msc1767.text": poll.Poll.Question.Text, | ||
| }, | ||
| "answers": msc3381Answers, | ||
| }, |
There was a problem hiding this comment.
There's a struct for this so it's nicer to use that
| "org.matrix.msc3381.poll.start": map[string]any{ | |
| "kind": kind, | |
| "max_selections": maxSelections, | |
| "question": map[string]any{ | |
| "org.matrix.msc1767.text": poll.Poll.Question.Text, | |
| }, | |
| "answers": msc3381Answers, | |
| }, | |
| "org.matrix.msc3381.poll.start": &event.PollStart{ | |
| Kind: kind, | |
| MaxSelections: maxSelections, | |
| Question: event.MSC1767Message{ | |
| Text: poll.Poll.Question.Text, | |
| }, | |
| Answers msc3381Answers, | |
| }, |
| poll := media.(*tg.MessageMediaPoll) | ||
| var textAnswers []string | ||
| var htmlAnswers strings.Builder | ||
| msc3381Answers := make([]map[string]any, 0, len(poll.Poll.Answers)) |
There was a problem hiding this comment.
| msc3381Answers := make([]map[string]any, 0, len(poll.Poll.Answers)) | |
| msc3381Answers := make([]event.PollOption, 0, len(poll.Poll.Answers)) |
| msc3381Answers = append(msc3381Answers, map[string]any{ | ||
| "id": pollAnswerID(nil, answer.Option), | ||
| "org.matrix.msc1767.text": text, | ||
| }) |
There was a problem hiding this comment.
| msc3381Answers = append(msc3381Answers, map[string]any{ | |
| "id": pollAnswerID(nil, answer.Option), | |
| "org.matrix.msc1767.text": text, | |
| }) | |
| msc3381Answers = append(msc3381Answers, event.PollOption{ | |
| ID: pollAnswerID(nil, answer.Option), | |
| Text: text, | |
| }) |
| "org.matrix.msc1767.message": []map[string]any{ | ||
| {"mimetype": "text/html", "body": part.Content.FormattedBody}, | ||
| {"mimetype": "text/plain", "body": part.Content.Body}, | ||
| }, |
There was a problem hiding this comment.
I think nothing actually reads this so let's leave it out
| "org.matrix.msc1767.message": []map[string]any{ | |
| {"mimetype": "text/html", "body": part.Content.FormattedBody}, | |
| {"mimetype": "text/plain", "body": part.Content.Body}, | |
| }, |
| "kind": kind, | ||
| "max_selections": maxSelections, | ||
| "question": map[string]any{ | ||
| "org.matrix.msc1767.text": poll.Poll.Question.Text, |
There was a problem hiding this comment.
I think both questions and answers on telegram polls can have formatting, which is probably worth bridging if it doesn't complicate this too much
(they can also have media, but that part is definitely complicated, so let's leave it out for now)
| func pollAnswerID(meta *PollMetadata, option []byte) string { | ||
| answerID := base64.RawURLEncoding.EncodeToString(option) | ||
| if meta != nil { | ||
| if mxID, ok := meta.MatrixAnswerIDs[answerID]; ok { | ||
| return mxID | ||
| } | ||
| } | ||
| return answerID | ||
| } | ||
|
|
||
| func pollOption(meta *PollMetadata, answerID string) ([]byte, error) { | ||
| for option, mxID := range meta.MatrixAnswerIDs { | ||
| if mxID == answerID { | ||
| return base64.RawURLEncoding.DecodeString(option) | ||
| } | ||
| } | ||
| return base64.RawURLEncoding.DecodeString(answerID) | ||
| } |
There was a problem hiding this comment.
should call these telegramToMatrixAnswerID and matrixToTelegramPollOption for a bit more clarity
|
@tulir - It's blocked server side, sending one to a user DM gave us MEDIA_INVALID. tdlib has the same check, forwards are allowed and so are bots and saved messages, so I opened up the capability for those two. |
With
extev_pollsenabled, Telegram polls are sent as MSC3381 polls and clients fetch the current results through the poll results provisioning API from mautrix/go#658, since votes aren't tied to a message and anonymous votes aren't visible at all. Polls and votes from Matrix are sent withsendMedia/sendVote.Tag
@indentto continue the conversation here.