mx_extract_media_events() builds a fixed record per event (R/messages.R:219-233):
out[[length(out) + 1L]] <- list(room_id = rid, ..., body =, filename =,
msgtype =, ts =, url =, mime =, size =, sha256 =, encrypted =,
file =, mentions =, relates_to =)
Every other key in content is dropped. That includes the two that identify a deliberate voice message:
org.matrix.msc3245.voice (an empty object, present as a marker)
org.matrix.msc1767.audio ({duration, waveform})
Without them a consumer can only gate on msgtype == "m.audio", which does not distinguish a voice message someone recorded from an arbitrary audio file someone attached. For a bot that transcribes audio, that is the difference between answering a voice message and transcribing every mp3 dropped in a room.
Both markers are standard on the Element/FluffyChat send path, so this is the normal shape of the event rather than an edge case.
Suggestion
Either carry the two keys explicitly, or add a content field passing the original through so consumers can read whatever they need without this function having to anticipate it. The passthrough seems better: MSCs land regularly and a fixed list needs editing every time one matters.
While you are in there
Two notes, both about $ on lists rather than about this issue:
ev$content$file (:215, :231) partial-matches filename when file is absent, which I gather is what #24 fixes -- flagging only so the passthrough change does not reintroduce it elsewhere in the same function. Every read here uses $: content$url, content$body, content$msgtype, content$info$mimetype.
The same bug shape bit a different cornball package this week, where spec$devices partial-matched devices_require_complete_userspace and admission ended up iterating a logical instead of a device list. It is worth [[ throughout on any list whose keys come off the wire, since a prefix collision only appears once a caller sends the longer key.
mx_extract_media_events()builds a fixed record per event (R/messages.R:219-233):Every other key in
contentis dropped. That includes the two that identify a deliberate voice message:org.matrix.msc3245.voice(an empty object, present as a marker)org.matrix.msc1767.audio({duration, waveform})Without them a consumer can only gate on
msgtype == "m.audio", which does not distinguish a voice message someone recorded from an arbitrary audio file someone attached. For a bot that transcribes audio, that is the difference between answering a voice message and transcribing every mp3 dropped in a room.Both markers are standard on the Element/FluffyChat send path, so this is the normal shape of the event rather than an edge case.
Suggestion
Either carry the two keys explicitly, or add a
contentfield passing the original through so consumers can read whatever they need without this function having to anticipate it. The passthrough seems better: MSCs land regularly and a fixed list needs editing every time one matters.While you are in there
Two notes, both about
$on lists rather than about this issue:ev$content$file(:215,:231) partial-matchesfilenamewhenfileis absent, which I gather is what #24 fixes -- flagging only so the passthrough change does not reintroduce it elsewhere in the same function. Every read here uses$:content$url,content$body,content$msgtype,content$info$mimetype.The same bug shape bit a different cornball package this week, where
spec$devicespartial-matcheddevices_require_complete_userspaceand admission ended up iterating a logical instead of a device list. It is worth[[throughout on any list whose keys come off the wire, since a prefix collision only appears once a caller sends the longer key.