I built a Twitch chat integration system using multiple tutorials and documentation sources. The connection works fine, and I can read messages from the chat, but I’m encountering two specific problems.
The first issue is that all usernames come through as lowercase, even though the actual Twitch usernames contain uppercase letters. I need to display the names with their correct capitalization.
Next, I’m unable to determine user roles like moderators, subscribers, or VIPs. While this isn’t as urgent, it would be nice to have.
My primary focus is fixing the username capitalization. Has anyone experienced this before? Is there a method to retrieve the correctly formatted usernames from the IRC connection?
using System;
using System.IO;
using System.Net.Sockets;
using UnityEngine;
public class StreamChatHandler : MonoBehaviour
{
public static StreamChatHandler instance;
public ChatCredentials credentials = new();
public event Action<string, string> OnMessageReceived;
public event Action<string> OnConnectionSuccess;
public event Action OnDisconnected;
public event Action<string> OnAuthFailed;
public bool isConnected = false;
private TcpClient chatClient;
private StreamReader inputStream;
private StreamWriter outputStream;
private const string SERVER_URL = "irc.chat.twitch.tv";
private const int SERVER_PORT = 6667;
private float heartbeatTimer = 0;
private string credentialsFile = "chatauth.json";
private void Awake()
{
DontDestroyOnLoad(gameObject);
instance = this;
credentialsFile = Application.persistentDataPath + "/chatauth.json";
LoadCredentials();
}
public void SetupConnection(string username, string token, string channelName)
{
credentials.Username = username;
credentials.AuthToken = token;
credentials.ChannelName = channelName;
}
public void EstablishConnection()
{
CloseConnection();
chatClient = new TcpClient(SERVER_URL, SERVER_PORT);
inputStream = new StreamReader(chatClient.GetStream());
outputStream = new StreamWriter(chatClient.GetStream());
credentials.Username = credentials.Username.ToLower();
credentials.ChannelName = credentials.ChannelName.ToLower();
outputStream.WriteLine("PASS " + credentials.AuthToken);
outputStream.WriteLine("NICK " + credentials.Username);
outputStream.WriteLine($"USER {credentials.Username} 8 * :{credentials.Username}");
outputStream.WriteLine("JOIN #" + credentials.ChannelName);
outputStream.Flush();
}
private void Update()
{
if (chatClient == null) return;
if (!chatClient.Connected && isConnected)
{
EstablishConnection();
}
heartbeatTimer += Time.deltaTime;
if (heartbeatTimer > 45)
{
outputStream.WriteLine("PING " + SERVER_URL);
outputStream.Flush();
heartbeatTimer = 0;
}
if (chatClient.Available > 0)
{
string rawMessage = inputStream.ReadLine();
if (rawMessage.Contains("PRIVMSG"))
{
int nameEnd = rawMessage.IndexOf("!");
string sender = rawMessage[1..nameEnd];
int contentStart = rawMessage.IndexOf(":", 1);
string content = rawMessage[(contentStart + 1)..];
OnMessageReceived?.Invoke(sender, content);
}
else if (rawMessage.Contains(":Welcome, GLHF!"))
{
SaveCredentials();
isConnected = true;
OnConnectionSuccess?.Invoke(credentials.Username);
}
}
}
}