ryanwinchester / tmi.ex

Twitch Messaging Interface for Elixir.
Apache License 2.0
44 stars 7 forks source link

Handle message, "=" in reply content breaks tags #24

Closed emek7 closed 4 months ago

emek7 commented 5 months ago

In TMI.parse_tags/1, when the message being replied to has the equal sign in it, the Enum.map(&String.split(&1, "=")) part splits the value of "reply-parent-msg-body" into multiple strings. This results in the next |> Enum.into(%{}, &List.to_tuple/1) failing.

str =  "@badge-info=;badges=broadcaster/1;client-nonce=1234;color=#1E90FF;display-name=user;emotes=;first-msg=0;flags=;id=824e7420;mod=0;reply-parent-display-name=user;reply-parent-msg-body=sdlkhdsjlkg\\s=\\sasfjhkgashjfg\\s=\\ssjafhsa;reply-parent-msg-id=212979af;reply-parent-user-id=1234;reply-parent-user-login=user;reply-thread-parent-display-name=user;reply-thread-parent-msg-id=56f74d32;reply-thread-parent-user-id=1234;reply-thread-parent-user-login=user;returning-chatter=0;room-id=1234;subscriber=0;tmi-sent-ts=1714826411987;turbo=0;user-id=1234;user-type="
tags = str |> String.split(";") |> Enum.map(&String.split(&1, "="))
[
  ["@badge-info", ""],
  ["badges", "broadcaster/1"],
  ["client-nonce", "1234"],
  ["color", "#1E90FF"],
  ["display-name", "user"],
  ["emotes", ""],
  ["first-msg", "0"],
  ["flags", ""],
  ["id", "824e7420"],
  ["mod", "0"],
  ["reply-parent-display-name", "user"],
  ["reply-parent-msg-body", "sdlkhdsjlkg\\s", "\\sasfjhkgashjfg\\s",
   "\\ssjafhsa"],
  ["reply-parent-msg-id", "212979af"],
  ["reply-parent-user-id", "1234"],
  ["reply-parent-user-login", "user"],
  ["reply-thread-parent-display-name", "user"],
  ["reply-thread-parent-msg-id", "56f74d32"],
  ["reply-thread-parent-user-id", "1234"],
  ["reply-thread-parent-user-login", "user"],
  ["returning-chatter", "0"],
  ["room-id", "1234"],
  ["subscriber", "0"],
  ["tmi-sent-ts", "1714826411987"],
  ["turbo", "0"],
  ["user-id", "1234"],
  ["user-type", ""]
]

Ugly fix i did.

def parse_tags(tags) do
    tags = tags
    |> String.split(";")
    |> Enum.map(&String.split(&1, "="))
    replyitem = Enum.find(tags, fn x -> Enum.at(x, 0) == "reply-parent-msg-body" end)
    tags = Enum.map(tags, fn x -> if Enum.at(x, 0) == "reply-parent-msg-body" && length(x) > 2 do 
      [a | b] = x
      [a | [Enum.join(b, "=")]]
    else
      x
    end end)
    tags = tags
    |> Enum.into(%{}, &List.to_tuple/1)
    tags
  end
ryanwinchester commented 5 months ago

Thanks. I think I solved this in the v1 branch that I was working on here: https://github.com/ryanwinchester/tmi.ex/blob/v1/lib/tmi/chat/tags.ex#L47-L57

it uses :binary.split/2 which is the same in this case as String.split(&1, "=", parts: 2)

I'm working on some rewrites for the api, eventsub, and chat right now in separate libraries that will be dependencies of this this library hopefully in the next few months.

i'll see if i can merge the fix in v1 to main soon

ryanwinchester commented 4 months ago

Should be fixed in b7ecee5 and released in v0.7.0 let me know if you have any other issues with it and I can re-open