nobilis/src/backend/kick/emotes.rs knows exactly one source of emotes: https://files.kick.com/emotes/... (:81). There is no 7TV, no BTTV and no
FrankerFaceZ.
On Kick that is most of the emotes actually in use. Channels install a 7TV set and the
chat then talks in it, so a busy channel reads here as a column of bare words where
every other viewer sees pictures - and the words are not even the right words, since a
7TV emote's name is chosen to be typed, not read.
Of everything left on Kick this is the one that changes what the client looks like in
ordinary use, rather than adding something at the edges. The lookup is per-channel and
cacheable, and the existing emote pipeline already turns a token into a picture.
`nobilis/src/backend/kick/emotes.rs` knows exactly one source of emotes:
`https://files.kick.com/emotes/...` (`:81`). There is no 7TV, no BTTV and no
FrankerFaceZ.
On Kick that is most of the emotes actually in use. Channels install a 7TV set and the
chat then talks in it, so a busy channel reads here as a column of bare words where
every other viewer sees pictures - and the words are not even the right words, since a
7TV emote's name is chosen to be typed, not read.
Of everything left on Kick this is the one that changes what the client looks like in
ordinary use, rather than adding something at the edges. The lookup is per-channel and
cacheable, and the existing emote pipeline already turns a token into a picture.
The issue was wrong to name three providers. Checked rather than assumed: api.betterttv.net/3/cached/users/kick/<id> answers 404 where the same path with twitch answers 200, and FrankerFaceZ has no Kick route at all. Both are Twitch
products that never followed Kick. This is 7TV only.
The part that would have failed silently: 7TV keys its sets by Kick's user id,
not the channel id, and those are different numbers — xqc is user 676 and channel
668, and asking with 668 answers 404 rather than an empty set. moho stored only the
channel id, so user_id had to be captured first. Without that this would have
shipped looking like a client where no channel has any emotes. Verified live: 676
returns 965 emotes, 668 returns 404.
Global set first, the channel's own on top, so a channel overriding a global name
gets its own picture. Best-effort and quiet — most channels have no 7TV set and
answer 404, which is ordinary rather than a failure.
Substitution is whole-word and case-sensitive, because 7TV names collide with
ordinary English constantly (a channel with an emote called "ok" would otherwise turn
half the conversation into pictures). Whitespace is the boundary rather than \b,
since names routinely contain digits and underscores. Lookups go through hasOwnProperty.call — without it a message containing "toString" or "constructor"
would find a function on the prototype and put it in the page. All of that checked: GAMBAx and xGAMBA untouched, gamba is not GAMBA, adjacent emotes both draw.
554 tests green. Note #205, which will fold these into the picker.
Finished — https://git.salastil.com/Salastil/nobilis/commit/5d408bd, https://git.salastil.com/Salastil/moho/commit/b636c33
**The issue was wrong to name three providers.** Checked rather than assumed:
`api.betterttv.net/3/cached/users/kick/<id>` answers 404 where the same path with
`twitch` answers 200, and FrankerFaceZ has no Kick route at all. Both are Twitch
products that never followed Kick. This is 7TV only.
**The part that would have failed silently:** 7TV keys its sets by Kick's *user* id,
not the channel id, and those are different numbers — xqc is user 676 and channel
668, and asking with 668 answers 404 rather than an empty set. moho stored only the
channel id, so `user_id` had to be captured first. Without that this would have
shipped looking like a client where no channel has any emotes. Verified live: 676
returns 965 emotes, 668 returns 404.
Global set first, the channel's own on top, so a channel overriding a global name
gets its own picture. Best-effort and quiet — most channels have no 7TV set and
answer 404, which is ordinary rather than a failure.
Substitution is whole-word and case-sensitive, because 7TV names collide with
ordinary English constantly (a channel with an emote called "ok" would otherwise turn
half the conversation into pictures). Whitespace is the boundary rather than `\b`,
since names routinely contain digits and underscores. Lookups go through
`hasOwnProperty.call` — without it a message containing "toString" or "constructor"
would find a function on the prototype and put it in the page. All of that checked:
`GAMBAx` and `xGAMBA` untouched, `gamba` is not `GAMBA`, adjacent emotes both draw.
554 tests green. Note #205, which will fold these into the picker.
7TV on Kick is a browser extension, not a Kick feature. Kick's own chat shows the
bare word, so this was drawing pictures where every viewer without that extension sees
text, and offering those words in the picker where sending one posts something most of
the channel reads as a word.
That is worse than not having it. A client that renders more than the service does is
not being generous — it is showing a different conversation from the one everybody else
is in, and only this client's reader is confused about which.
Removed: the module, the per-channel fetch, the word map, the kickWordEmotes event,
the formatter substitution, and user_id on the Kick channel, which was captured only
because 7TV keyed on it. Kick's own [emote:id:name] is untouched — those render in
Kick and were never in question.
Closing as won't implement rather than reopening: the feature worked, it just should
not exist.
Reverted — https://git.salastil.com/Salastil/nobilis/commit/7e15621, https://git.salastil.com/Salastil/moho/commit/5819345
7TV on Kick is a **browser extension, not a Kick feature**. Kick's own chat shows the
bare word, so this was drawing pictures where every viewer without that extension sees
text, and offering those words in the picker where sending one posts something most of
the channel reads as a word.
That is worse than not having it. A client that renders more than the service does is
not being generous — it is showing a different conversation from the one everybody else
is in, and only this client's reader is confused about which.
Removed: the module, the per-channel fetch, the word map, the `kickWordEmotes` event,
the formatter substitution, and `user_id` on the Kick channel, which was captured only
because 7TV keyed on it. Kick's own `[emote:id:name]` is untouched — those render in
Kick and were never in question.
Closing as won't implement rather than reopening: the feature worked, it just should
not exist.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
nobilis/src/backend/kick/emotes.rsknows exactly one source of emotes:https://files.kick.com/emotes/...(:81). There is no 7TV, no BTTV and noFrankerFaceZ.
On Kick that is most of the emotes actually in use. Channels install a 7TV set and the
chat then talks in it, so a busy channel reads here as a column of bare words where
every other viewer sees pictures - and the words are not even the right words, since a
7TV emote's name is chosen to be typed, not read.
Of everything left on Kick this is the one that changes what the client looks like in
ordinary use, rather than adding something at the edges. The lookup is per-channel and
cacheable, and the existing emote pipeline already turns a token into a picture.
Finished — https://git.salastil.com/Salastil/nobilis/commit/5d408bd, https://git.salastil.com/Salastil/moho/commit/b636c33
The issue was wrong to name three providers. Checked rather than assumed:
api.betterttv.net/3/cached/users/kick/<id>answers 404 where the same path withtwitchanswers 200, and FrankerFaceZ has no Kick route at all. Both are Twitchproducts that never followed Kick. This is 7TV only.
The part that would have failed silently: 7TV keys its sets by Kick's user id,
not the channel id, and those are different numbers — xqc is user 676 and channel
668, and asking with 668 answers 404 rather than an empty set. moho stored only the
channel id, so
user_idhad to be captured first. Without that this would haveshipped looking like a client where no channel has any emotes. Verified live: 676
returns 965 emotes, 668 returns 404.
Global set first, the channel's own on top, so a channel overriding a global name
gets its own picture. Best-effort and quiet — most channels have no 7TV set and
answer 404, which is ordinary rather than a failure.
Substitution is whole-word and case-sensitive, because 7TV names collide with
ordinary English constantly (a channel with an emote called "ok" would otherwise turn
half the conversation into pictures). Whitespace is the boundary rather than
\b,since names routinely contain digits and underscores. Lookups go through
hasOwnProperty.call— without it a message containing "toString" or "constructor"would find a function on the prototype and put it in the page. All of that checked:
GAMBAxandxGAMBAuntouched,gambais notGAMBA, adjacent emotes both draw.554 tests green. Note #205, which will fold these into the picker.
Reverted — https://git.salastil.com/Salastil/nobilis/commit/7e15621, https://git.salastil.com/Salastil/moho/commit/5819345
7TV on Kick is a browser extension, not a Kick feature. Kick's own chat shows the
bare word, so this was drawing pictures where every viewer without that extension sees
text, and offering those words in the picker where sending one posts something most of
the channel reads as a word.
That is worse than not having it. A client that renders more than the service does is
not being generous — it is showing a different conversation from the one everybody else
is in, and only this client's reader is confused about which.
Removed: the module, the per-channel fetch, the word map, the
kickWordEmotesevent,the formatter substitution, and
user_idon the Kick channel, which was captured onlybecause 7TV keyed on it. Kick's own
[emote:id:name]is untouched — those render inKick and were never in question.
Closing as won't implement rather than reopening: the feature worked, it just should
not exist.