From 11e1c8f7bb704176561c519a2b36f4a9331d9a12 Mon Sep 17 00:00:00 2001 From: AoshiW Date: Sun, 27 Jul 2025 13:02:35 +0200 Subject: [PATCH 1/3] init example and README --- README.md | 75 ++++++++++++++++++- TwitchLib.Client.Example/Program.cs | 37 +++++++++ .../TwitchLib.Client.Example.csproj | 18 +++++ TwitchLib.Client.sln | 10 ++- 4 files changed, 137 insertions(+), 3 deletions(-) create mode 100644 TwitchLib.Client.Example/Program.cs create mode 100644 TwitchLib.Client.Example/TwitchLib.Client.Example.csproj diff --git a/README.md b/README.md index ba9c95a2..03559c7a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,77 @@ # TwitchLib.Client Client component of TwitchLib. -For a general overview and example, refer to https://github.com/TwitchLib/TwitchLib/blob/master/README.md +## Installation + +| NuGet | | [![TwitchLib.Client][1]][2] | +| :--------------- | ----: | :---------------------------------------------------------------- | +| Package Manager | `PM>` | `Install-Package TwitchLib.Client -Version 4.0.1` | +| .NET CLI | `>` | `dotnet add package TwitchLib.Client --version 4.0.1` | +| PackageReference | | `` | +| Paket CLI | `>` | `paket add TwitchLib.Client --version 4.0.1` | + +[1]: https://img.shields.io/nuget/v/TwitchLib.Client.svg?label=TwitchLib.Client +[2]: https://www.nuget.org/packages/TwitchLib.Client + +## Breaking Changes in Version 4.0.1 + +Version 4.0.1 contains breaking changes. +- Methods are now asynchronous. (The return value changed from `void` to `Task` and gains `Async` suffix) +- Events are now asynchronous (return value changed from `void` to `Task`) + +TODO +- OnLog=> ILoggerFactory +- suffix Event => EventArgs +- command identifiers + +## Minimal Setup +Step 1: Create a new Console project + +Step 2: Install the `TwitchLib.Client` NuGet package. (See above on how to do that) + +Step 2.5: (Optional) Install the [`Microsoft.Extensions.Logging.Console`](https://www.nuget.org/packages/Microsoft.Extensions.Logging.Console) NuGet package (or some other compatible logging provider) to see logs. + +Step 3: Add the following code to your `Program.cs` file: +```cs +using Microsoft.Extensions.Logging; +using TwitchLib.Client; +using TwitchLib.Client.Events; +using TwitchLib.Client.Models; + +// Optional logger +var loggerFactory = LoggerFactory.Create(c => c + .AddConsole() +// .SetMinimumLevel(LogLevel.Trace) // uncomment to view raw messages received from twitch +); + +var credentials = new ConnectionCredentials(); // anonymous user, add Username and OAuth token to get the ability to send messages +var client = new TwitchClient(loggerFactory: loggerFactory); + +client.Initialize(credentials); +client.OnConnected += Client_OnConnected; +client.OnJoinedChannel += Client_OnJoinedChannel; +client.OnMessageReceived += Client_OnMessageReceived; + +await client.ConnectAsync(); +await Task.Delay(Timeout.Infinite); + + +async Task Client_OnConnected(object? sender, OnConnectedEventArgs e) +{ + await client.JoinChannelAsync("channel_name"); // replace with the channel you want to join +} + +async Task Client_OnJoinedChannel(object? sender, OnJoinedChannelArgs e) +{ + Console.WriteLine($"Connected to {e.Channel}"); + await client.SendMessageAsync(e.Channel, "Hey guys! I am a bot connected via TwitchLib!"); +} + +async Task Client_OnMessageReceived(object? sender, OnMessageReceivedArgs e) +{ + Console.WriteLine($"{e.ChatMessage.Username}#{e.ChatMessage.Channel}: {e.ChatMessage.Message}"); +} +``` +Step 4: Change the `channel_name` in the `Client_OnConnected` method to the name of the channel you want to join and run the application. + +More complete examples can be found in the [TwitchLib.Client.Example](/TwitchLib.Client.Example/) diff --git a/TwitchLib.Client.Example/Program.cs b/TwitchLib.Client.Example/Program.cs new file mode 100644 index 00000000..afc1a904 --- /dev/null +++ b/TwitchLib.Client.Example/Program.cs @@ -0,0 +1,37 @@ +using Microsoft.Extensions.Logging; +using TwitchLib.Client; +using TwitchLib.Client.Events; +using TwitchLib.Client.Models; + +var loggerFactory = LoggerFactory.Create(c => c + .AddConsole() + //.SetMinimumLevel(LogLevel.Trace) // uncomment to view raw messages received from twitch +); + +var credentials = new ConnectionCredentials(); // anonymous user, add Username and OAuth token to get the ability to send messages +var client = new TwitchClient(loggerFactory: loggerFactory); + +client.Initialize(credentials); +client.OnConnected += Client_OnConnected; +client.OnJoinedChannel += Client_OnJoinedChannel; +client.OnMessageReceived += Client_OnMessageReceived; + +await client.ConnectAsync(); +await Task.Delay(Timeout.Infinite); + + +async Task Client_OnConnected(object? sender, OnConnectedEventArgs e) +{ + await client.JoinChannelAsync("channel_name"); // replace with the channel you want to join +} + +async Task Client_OnJoinedChannel(object? sender, OnJoinedChannelArgs e) +{ + Console.WriteLine($"Connected to {e.Channel}"); + await client.SendMessageAsync(e.Channel, "Hey guys! I am a bot connected via TwitchLib!"); +} + +async Task Client_OnMessageReceived(object? sender, OnMessageReceivedArgs e) +{ + Console.WriteLine($"{e.ChatMessage.Username}#{e.ChatMessage.Channel}: {e.ChatMessage.Message}"); +} diff --git a/TwitchLib.Client.Example/TwitchLib.Client.Example.csproj b/TwitchLib.Client.Example/TwitchLib.Client.Example.csproj new file mode 100644 index 00000000..cd9e3f95 --- /dev/null +++ b/TwitchLib.Client.Example/TwitchLib.Client.Example.csproj @@ -0,0 +1,18 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + diff --git a/TwitchLib.Client.sln b/TwitchLib.Client.sln index e583df61..eec8deb8 100644 --- a/TwitchLib.Client.sln +++ b/TwitchLib.Client.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2027 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36310.24 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TwitchLib.Client", "TwitchLib.Client\TwitchLib.Client.csproj", "{44B88EFA-1500-4005-AF27-A9BCB9DD79C1}" EndProject @@ -17,6 +17,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{8C69E628 EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwitchLib.Client.Benchmark", "TwitchLib.Client.Benchmark\TwitchLib.Client.Benchmark.csproj", "{7E666AC9-B717-4E00-A3CB-16950275D3FD}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwitchLib.Client.Example", "TwitchLib.Client.Example\TwitchLib.Client.Example.csproj", "{0C5D0C17-346C-6CE8-EC3E-4DCAC37152FC}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -43,6 +45,10 @@ Global {7E666AC9-B717-4E00-A3CB-16950275D3FD}.Debug|Any CPU.Build.0 = Debug|Any CPU {7E666AC9-B717-4E00-A3CB-16950275D3FD}.Release|Any CPU.ActiveCfg = Release|Any CPU {7E666AC9-B717-4E00-A3CB-16950275D3FD}.Release|Any CPU.Build.0 = Release|Any CPU + {0C5D0C17-346C-6CE8-EC3E-4DCAC37152FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0C5D0C17-346C-6CE8-EC3E-4DCAC37152FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0C5D0C17-346C-6CE8-EC3E-4DCAC37152FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0C5D0C17-346C-6CE8-EC3E-4DCAC37152FC}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From 2f9c3280ad249e88f59ef06dfee63cdd9d6e2587 Mon Sep 17 00:00:00 2001 From: AoshiW Date: Sun, 27 Jul 2025 22:22:37 +0200 Subject: [PATCH 2/3] Update README and Example --- README.md | 12 +++-- TwitchLib.Client.Example/Program.cs | 68 ++++++++++++++++++++++++++++- 2 files changed, 74 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 03559c7a..a8258334 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ -# TwitchLib.Client +# TwitchLib.Client Client component of TwitchLib. +> [!TIP] +> With the introduction of Chat on EventSub, it is recommended to upgrade your chatbots that are using Twitch IRC to use EventSub (for reading chat messages and roomstates) and Twitch API (for sending chat messages). + ## Installation | NuGet | | [![TwitchLib.Client][1]][2] | @@ -13,16 +16,17 @@ Client component of TwitchLib. [1]: https://img.shields.io/nuget/v/TwitchLib.Client.svg?label=TwitchLib.Client [2]: https://www.nuget.org/packages/TwitchLib.Client -## Breaking Changes in Version 4.0.1 +## ⚠ Breaking Changes in Version 4.0.1 ⚠ Version 4.0.1 contains breaking changes. +- Removed obsolete methods. - Methods are now asynchronous. (The return value changed from `void` to `Task` and gains `Async` suffix) - Events are now asynchronous (return value changed from `void` to `Task`) +- `Add/RemoveChatCommandIdentifier` methods were removed, use `ChatCommandIdentifiers` property instead (same applies to whisper); +- `OnLog` event was removed (you can still use `ILoggerFactory` to get logs) TODO -- OnLog=> ILoggerFactory - suffix Event => EventArgs -- command identifiers ## Minimal Setup Step 1: Create a new Console project diff --git a/TwitchLib.Client.Example/Program.cs b/TwitchLib.Client.Example/Program.cs index afc1a904..26eba3fc 100644 --- a/TwitchLib.Client.Example/Program.cs +++ b/TwitchLib.Client.Example/Program.cs @@ -9,20 +9,25 @@ ); var credentials = new ConnectionCredentials(); // anonymous user, add Username and OAuth token to get the ability to send messages -var client = new TwitchClient(loggerFactory: loggerFactory); +var client = new TwitchClient(loggerFactory: loggerFactory) +{ + ChatCommandIdentifiers = { '!', '?' }, // you can customize the command identifiers, if not set, defaults to '!' +}; client.Initialize(credentials); client.OnConnected += Client_OnConnected; client.OnJoinedChannel += Client_OnJoinedChannel; client.OnMessageReceived += Client_OnMessageReceived; +client.OnChatCommandReceived += Client_OnChatCommandReceived; + await client.ConnectAsync(); await Task.Delay(Timeout.Infinite); async Task Client_OnConnected(object? sender, OnConnectedEventArgs e) { - await client.JoinChannelAsync("channel_name"); // replace with the channel you want to join + await client.JoinChannelAsync("piratesoftware"); // replace with the channel you want to join } async Task Client_OnJoinedChannel(object? sender, OnJoinedChannelArgs e) @@ -35,3 +40,62 @@ async Task Client_OnMessageReceived(object? sender, OnMessageReceivedArgs e) { Console.WriteLine($"{e.ChatMessage.Username}#{e.ChatMessage.Channel}: {e.ChatMessage.Message}"); } + +async Task Client_OnChatCommandReceived(object? sender, OnChatCommandReceivedArgs e) +{ + var channel = e.ChatMessage.Channel; + var command = e.Command; + + switch (command.Name.ToLower()) + { + case "info": + await client.SendMessageAsync(channel, "Hi, I am a bot created using TwitchLib.Client."); + break; + case "repeat": + if (string.IsNullOrWhiteSpace(command.ArgumentsAsString)) + return; + await client.SendMessageAsync(channel, command.ArgumentsAsString); + break; + case "leave": + if (!e.ChatMessage.IsBroadcaster) + return; + await client.SendMessageAsync(channel, "Goodbye! I am leaving the channel."); + await client.LeaveChannelAsync(channel); + break; + case "help": + if (command.ArgumentsAsList.Count is 0) + { + var helpText = "Available commands: !info, !repeat , !help [command]"; + if (e.ChatMessage.IsBroadcaster) + helpText += ", !leave"; + + await client.SendMessageAsync(channel, helpText); + return; + } + switch (command.ArgumentsAsList[0]) + { + case "info": + await client.SendMessageAsync(channel, "The !info command provides information about the bot."); + break; + case "repeat": + await client.SendMessageAsync(channel, "The !repeat command repeats the message you provide."); + break; + case "help": + await client.SendMessageAsync(channel, "The !help command provides information about available commands."); + break; + case "leave": + if (!e.ChatMessage.IsBroadcaster) + return; + + await client.SendMessageAsync(channel, "The !leave command makes the bot leave the channel."); + break; + default: + await client.SendMessageAsync(channel, $"No help available for command: {command.ArgumentsAsList[0]}"); + break; + } + break; + default: + Console.WriteLine($"Unknown command: {command.Name}"); + break; + } +} From 6697772363d60f166cb87d277601cf3c17f5974e Mon Sep 17 00:00:00 2001 From: AoshiW Date: Wed, 6 Aug 2025 14:15:08 +0200 Subject: [PATCH 3/3] update readme --- README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a8258334..c3b75df4 100644 --- a/README.md +++ b/README.md @@ -24,9 +24,11 @@ Version 4.0.1 contains breaking changes. - Events are now asynchronous (return value changed from `void` to `Task`) - `Add/RemoveChatCommandIdentifier` methods were removed, use `ChatCommandIdentifiers` property instead (same applies to whisper); - `OnLog` event was removed (you can still use `ILoggerFactory` to get logs) - -TODO -- suffix Event => EventArgs +- removed builders classes (removed `TwitchLib.Client.Models.Builders namespace`) +- changed public fields to properties +- rewritten all models in `TwitchLib.Client.Models` + - some props/classes can be slightly renamed + - some properties (`IsModerator`, `IsSubscriber`, `HasTurbo`, `IsVip`, `IsPartner`, `IsStaff`) moved to the `UserDetails` property ## Minimal Setup Step 1: Create a new Console project