Connecting to Twitch Chat in Swift

It shouldn’t have been too difficult to connect to Twitch’s IRC Chat for my channel using Swift. Turns out it wasn’t as straightforward as doing it in Unity.

I found this four-year-old IRC client demo next. I pulled it down and stuck its two main files into my project’s Lib folder.

sgoodwin/IRC files in my project sgoodwin/IRC files in my project

I wouldn’t usually copy code into a project like this but it’s a stale repo so I’m unlikely to miss any bug fixes or be submitting any pull requests any time soon).

Modification 1: Add password to IRCUser

I changed the IRCUser struct to look like this by deleting the initialiser (structs get member-wise init automatically) and then adding a password field.

public struct IRCUser {
    public let username: String
    public let realName: String
    public let nick: String
    public let password: String
}

See this commit.

Modification 2: Send PASS message

Now in IRCServer's init function I added one line to use the user’s password:

public required init(hostname: String, port: Int, user: IRCUser, session: URLSession) {
    self.session = session

    task = session.streamTask(withHostName: hostname, port: port)
    task.resume()
    read()

    // NEW LINE:    
    send("PASS \(user.password)")
    //
    send("USER \(user.username) 0 * :\(user.realName)")
    send("NICK \(user.nick)")
}

Here’s that commit.

I’ve forked the repo so you can see my changes here.

Getting a “Password”

Go to the Twitch Chat OAuth Password Generator to create a password.

TwitchChat implementation

//  TwitchChat.swift
//  Created by Michael Forrest on 09/06/2021.
import Foundation
class TwitchChat: IRCServerDelegate, IRCChannelDelegate{
    let session = URLSession(configuration: .default)
    let user = IRCUser(
        // Use your own details here:
        username: "MichaelForrest",
        realName: "Michael Forrest",
        nick: "MichaelForrest",
        password: "oauth:12345fdgd32932423042340024" // not my real one!
    )
    let server: IRCServer
    let channel: IRCChannel

    init(){
        server = IRCServer(
            hostname: "irc.chat.twitch.tv",
            port: 6667,
            user: user,
            session: session
        )
        // Join the channel you want. This seems to be case-sensitive.
        channel = server.join("michaelforrest")

        server.delegate = self
        channel.delegate = self

        // Send a message:        
        channel.send("Hello from bot!")

    }
    func didRecieveMessage(_ server: IRCServer, message: String) {
        print("Server message:", message)
    }
    func didRecieveMessage(_ channel: IRCChannel, message: String) {
        print("Channel message:", message)

    }
}

That should do it!

Now if you create a TwitchChat instance in your project, you should be able to see your chat messages.

Any comments? Use my Twitter below.

And don’t for get to follow me on Twitch!

(I also tried NozeIO’s package but failed)

When I first searched I found NozeIO/swift-nio-irc-client. I didn’t know what swift-nio was (but I guess I should have; it’s an Apple thing and one of the few packages included in Apple’s Swift Packages Collection!). There’s not so much as an example on the swift-nio-irc-client page, but when I found Noze’s reference app I was able to make some progress.

Ultimately this was a non-starter as the client implementation seems incomplete.