Home > Back-end >  Twitch Integrations - Getting chatter's roles and name with capital letters
Twitch Integrations - Getting chatter's roles and name with capital letters

Time:05-14

I have a class created through a few different sources to connect, stay connected, read, and interact with a selected Twitch channel, but there seems to be no information as to how to do certain things.

One of the issues is that the names of the chatters are always in all lowercase characters. The other issue is that there doesnt seem to be any information of users. Ie are they a mod, subscriber, VIP?

While the roles parts arent that high priority for me, I want for the names to be properly capitalized.

Is there any trick that can do this?

using System;
using System.IO;
using System.Net.Sockets;
using UnityEngine;

public class TwitchConnect : MonoBehaviour
{
    public static TwitchConnect instance;

    public TwitchAccountData TwitchSettings = new();

    public event Action<string, string> OnChatMessage;
    public event Action<string> OnLoggedIn;
    public event Action OnLoggedOut;
    public event Action<string> OnInvalidLogin;

    public bool loggedIn = false;

    private TcpClient Twitch;
    private StreamReader Reader;
    private StreamWriter Writer;

    //private const string URL = "irc.chat.twitch.tv";
    private const string URL = "irc.twitch.tv";
    private const int PORT = 6667;

    private float PingCounter = 0;

    private string saveTwitchPath = "twitchauth.json";

    private void Awake()
    {
        DontDestroyOnLoad(gameObject);

        instance = this;

        saveTwitchPath = Application.persistentDataPath   "/twitchauth.json";

        LoadAccount();
    }

    public void UpdateAccount(string nUser, string nOAuth, string nChannel)
    {
        TwitchSettings.User = nUser;
        TwitchSettings.OAuth = nOAuth;
        TwitchSettings.Channel = nChannel;
    }

    public void ConnectToTwitch()
    {
        DisconnectFromTwitch();

        Twitch = new TcpClient(URL, PORT);
        Reader = new StreamReader(Twitch.GetStream());
        Writer = new StreamWriter(Twitch.GetStream());

        TwitchSettings.User = TwitchSettings.User.ToLower();
        TwitchSettings.Channel = TwitchSettings.Channel.ToLower();

        Writer.WriteLine("PASS "   TwitchSettings.OAuth);
        Writer.WriteLine("NICK "   TwitchSettings.User);
        Writer.WriteLine($"USER {TwitchSettings.User} 8 * :{TwitchSettings.User}");
        Writer.WriteLine("JOIN #"   TwitchSettings.Channel);
        Writer.Flush();//initiate connection
    }

    public void DisconnectFromTwitch()
    {
        loggedIn = false;
        PingCounter = 0;

        Twitch?.Dispose();
        Reader?.Dispose();
        Writer?.Dispose();

        Twitch = null;
        Reader = null;
        Writer = null;

        OnLoggedOut?.Invoke();
    }

    public void SaveAccount()
    {
        string jsonTwitch = JsonUtility.ToJson(TwitchSettings, true);
        File.WriteAllText(saveTwitchPath, jsonTwitch, System.Text.Encoding.Unicode);

        Debug.LogWarning("Twitch account settings saved!");
    }

    public void LoadAccount()
    {
        //twitch saved account settings - user, oauth, channel
        if (File.Exists(saveTwitchPath))
        {
            string jsonSettings = File.ReadAllText(saveTwitchPath, System.Text.Encoding.Unicode);
            JsonUtility.FromJsonOverwrite(jsonSettings, TwitchSettings);

            Debug.LogWarning("Twitch account loaded, logging in...");

            ConnectToTwitch();
        }
    }

    public void SendIrcMessage(string message)
    {
        Writer.WriteLine(message);
        Writer.Flush();
    }

    public void SendChatMessage(string message)
    {
        Writer.WriteLine($":{TwitchSettings.User}!{TwitchSettings.User}@{TwitchSettings.User}.tmi.twitch.tv PRIVMSG #{TwitchSettings.Channel} :{message}");
        Writer.Flush();
    }

    private void Update()
    {
        if (Twitch == null) return;

        if (!Twitch.Connected && loggedIn)
        {
            ConnectToTwitch();
        }

        PingCounter  = Time.deltaTime;
        if (PingCounter > 50)
        {
            Writer.WriteLine("PING "   URL);
            Writer.Flush();
            PingCounter = 0;
        }
        
        if (Twitch.Available > 0)
        {
            string message = Reader.ReadLine();
#if UNITY_EDITOR
            Debug.Log(message);//DEBUG
#endif

            if (message.Contains("PRIVMSG"))
            {
                int splitPoint = message.IndexOf("!");
                string chatter = message[1..splitPoint];//get chatter name

                splitPoint = message.IndexOf(":", 1);
                string msg = message[(splitPoint   1)..];//get message only

                OnChatMessage?.Invoke(chatter, msg);
            }
            else if (message.Contains(":Welcome, GLHF!"))//successful login
            {
                SaveAccount();

                loggedIn = true;
                OnLoggedIn?.Invoke(TwitchSettings.User);
            }
            else if (message.Contains(":Invalid NICK"))
            {
                OnInvalidLogin?.Invoke("Invalid NICK");
            }
            else if (message.Contains(":Improperly formatted auth"))
            {
                OnInvalidLogin?.Invoke("Improperly formatted auth");
            }
        }
    }

    private void OnDestroy()
    {
        DisconnectFromTwitch();
    }
}

CodePudding user response:

For TMI - Twitch Messaging Interface to get DisplayName and Role information you need to enable some IRCv3 capabilities then updates your parser to extract the data.

Before PASS you should send

CAP REQ :twitch.tv/commands twitch.tv/tags

So,

Writer.WriteLine("PASS "   TwitchSettings.OAuth);

becomes

Writer.WriteLine("CAP REQ :twitch.tv/commands twitch.tv/tags");
Writer.WriteLine("PASS "   TwitchSettings.OAuth);

To enable additional data - https://dev.twitch.tv/docs/irc/capabilities

This will then add additioanl data to PRIVMSGs sent by Twitch.

These are commonly referered to as IRCv3 Tags.

This is an example from the documentations

@badge-info=;badges=broadcaster/1;client-nonce=28e05b1c83f1e916ca1710c44b014515;color=#0000FF;display-name=foofoo;emotes=62835:0-10;first-msg=0;flags=;id=f80a19d6-e35a-4273-82d0-cd87f614e767;mod=0;room-id=713936733;subscriber=0;tmi-sent-ts=1642696567751;turbo=0;user-id=713936733;user-type= :[email protected] PRIVMSG #bar :bleedPurple

https://dev.twitch.tv/docs/irc/send-receive-messages#receiving-chat-messages

This user:

  • sent the message bleedpurple in the channel bar
  • has the display-name of foofoo this will be the Capitislation of the user if any is set by the user
  • has the badges of broadcaster (version 1 of said badge)

So for VIP or moderator you would monitor for the badges of vip or moderator and so on for whatever roles you are looking for.

Further reading is on https://dev.twitch.tv/docs/irc/tags#privmsg-tags

Some badge examples:

Comma-separated list of chat badges in the form, <badge>/<version>. For example, admin/1. There are many possible badge values, but here are few:
admin
bits
broadcaster
moderator
subscriber
staff
turbo

You would normally poke the badges API (channel or global) for available badges nad versions of those badges.

But the salient role based badges are in this non exhuastive list.

  • Related