KickNetLib 1.0.1

dotnet add package KickNetLib --version 1.0.1
                    
NuGet\Install-Package KickNetLib -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="KickNetLib" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="KickNetLib" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="KickNetLib" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add KickNetLib --version 1.0.1
                    
#r "nuget: KickNetLib, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package KickNetLib@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=KickNetLib&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=KickNetLib&version=1.0.1
                    
Install as a Cake Tool

<p align="center"> <img src="https://github.com/Rubarez/KickNetLib/blob/master/res/KickNetLibLogo.png" style="max-height: 250px !important;"> </p>

<p align="center"> <a href="https://www.microsoft.com/net"><img src="https://img.shields.io/badge/-.NET%208.0-blueviolet" style="max-height: 300px;"></a> <a href="https://www.microsoft.com/net"><img src="https://img.shields.io/badge/-.NET%209.0-blueviolet" style="max-height: 300px;"></a> <img src="https://img.shields.io/badge/Platform-.NET-lightgrey.svg" style="max-height: 300px;"> <a href="https://github.com/Rubarez/KickNetLib/blob/master/LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" style="max-height: 300px;"></a> <a href="https://www.nuget.org/packages/KickNetLib"><img src="https://img.shields.io/nuget/dt/KickNetLib?label=NuGet&color=orange" style="max-height: 300px;"></a> </p>

<p align="center"> <a href='https://ko-fi.com/rubarez' target='_blank'> <img height='30' style='border:0;height:38px;' src='https://storage.ko-fi.com/cdn/kofi6.png?v=6' border='0' alt='Buy Me a Coffee at ko-fi.com' /> </a>

About <i>KickNetLib</i> ℹ️

KickNetLib is a library in C# for use into .NET 8 and .NET 9. The library interacts with the official API and the Webhooks of Kick. (https://kick.com).

KickNetLib Features 🔝

[Client (Webhooks)]
  • Read and validate incoming webhooks
    • Enable/Disable signature validation
  • Reading Channel events
    • New follower (channel.followed)
    • New renewal subscription (channel.subscription.renewal)
    • New gift subscriptions (channel.subscription.gifts)
    • New subscriptor (channel.subscription.new)
  • Reading Chat events
    • ChatMessageSent (chat.message.sent)
  • Reading Live stream events
    • Live stream status updated to ON (livestream.status.updated)
    • Live stream status updated to OF (livestream.status.updated)
[API]
  • Authentication Flow
    • Authorization Endpoint (/oauth/authorize)
    • Token Endpoint (/oauth/token)
    • Refresh Token Endpoint (/oauth/token)
    • Revoke Token Endpoint (/oauth/revoke)
  • Categories
    • Get channels by name (GET /categories?q=)
    • Get category by category_id (GET /categories/:category_id)
  • Channels
    • Get Channels filter by Broadcaster User IDs (GET /channels?broadcaster_user_id=)
    • Update the title and category of the channel (PATCH /channels)
  • Chat
    • Send a message to the chat as BOT and USER (POST /chat)
  • Public key
    • Get the public key for verify signatures (GET /public-key)
  • Users
    • Get information about token passed (POST /token/introspect)
    • Get users filter by User IDs (GET /users?id=)

Projects 📁

The repo has a 6 projects:

  • KickNetDesktopForms

    • It is a tool-app developed in windows forms. Is used to facilitate testing and perform operations quickly.
    • It Is only for develop or test prouposes.
  • KickNetLib.Api

    • It is the project that interacts with the Kick API.
  • KickNetLib.Client

    • It is the project that interacts with the Kick Webhooks.
  • KickNetLib.Shared

    • The project provides shared resources for the API and Webhooks.
  • KickNetLib

    • Is the project Meta-Package for nuget.
  • KickNetLib.Tests

    • It is the project for tests. TODO.
  • KickNetLib.WebApi

    • Is the project skeleton with all you need to start build your app.

Before starting 📐

First, you need to create a new app on Kick: https://kick.com/settings/developer

Follow the instructions of the docs: https://docs.kick.com/getting-started/kick-apps-setup

How to use 📝

Installing ⏩

KickNetLib is available on NuGet. To install all packages, you can run the following commands:

PM> Install-Package KickNetLib

Or from the .NET CLI as:

dotnet add package KickNetLib

Using KickNetLib

The simple way: 💊

You can follow the structure of the skeleton web API. KickNetLib.WebApi

In the other way 💣

You’ll find all the information below.

[Webhooks]

With Dependency Injection 💉

- Configuration 🔧

First, you need to provide a configuration for WebHooks in the appsettings.json like this:

"KickWebHookSettings": {
  "ValidateSender": true,
  "PublicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq/+l1WnlRrGSolDMA+A8\n6rAhMbQGmQ2SapVcGM3zq8ANXjnhDWocMqfWcTd95btDydITa10kDvHzw9WQOqp2\nMZI7ZyrfzJuz5nhTPCiJwTwnEtWft7nV14BYRDHvlfqPUaZ+1KR4OCaO/wWIk/rQ\nL/TjY0M70gse8rlBkbo2a8rKhu69RQTRsoaf4DVhDPEeSeI5jVrRDGAMGL3cGuyY\n6CLKGdjVEM78g3JfYOvDU/RvfqD7L89TZ3iN94jrmWdGz34JNlEI5hqK8dd7C5EF\nBEbZ5jgB8s8ReQV8H+MkuffjdAj3ajDDX3DOJMIut1lBrUVD1AaSrGCKHooWoL2e\ntwIDAQAB\n-----END PUBLIC KEY-----"
}
Basic
Field Description Type Default Value
ValidateSender Enable or disable if the system must verify kick is the sender. Bool true
PublicKeyPem Provide a Public Key Pem for checking the message sign. String (No default provided)
- Usage

You can easily add KickNetLib.Client via extension method .AddKickLibClient(builder.Configuration);, that will register all related services with Scoped lifetime.

Now, you can use KickClient with the IKickClient interface in your controller like this:

public class MyController : ControllerBase
{
	private readonly IKickClient _kickClient;
	
	public MyController(IKickClient kickClient) {
		_kickClient = kickClient;
	}
	
	private async Task Method() {
		await _kickClient.WebHook.ReciveWebHook(HttpContext);
	}
}

Without Dependency Injection 📄

First you need provide a configuration creating a object kickClient, and then you can use it.

string PublicKeyPem = @"-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq/+l1WnlRrGSolDMA+A8
6rAhMbQGmQ2SapVcGM3zq8ANXjnhDWocMqfWcTd95btDydITa10kDvHzw9WQOqp2
MZI7ZyrfzJuz5nhTPCiJwTwnEtWft7nV14BYRDHvlfqPUaZ+1KR4OCaO/wWIk/rQ
L/TjY0M70gse8rlBkbo2a8rKhu69RQTRsoaf4DVhDPEeSeI5jVrRDGAMGL3cGuyY
6CLKGdjVEM78g3JfYOvDU/RvfqD7L89TZ3iN94jrmWdGz34JNlEI5hqK8dd7C5EF
BEbZ5jgB8s8ReQV8H+MkuffjdAj3ajDDX3DOJMIut1lBrUVD1AaSrGCKHooWoL2e
twIDAQAB
-----END PUBLIC KEY-----"; 

IKickClient kickClient = new KickClient(validateSender: true, PublicKeyPem: PublicKeyPem);

private async Task Method() {
	await _kickClient.WebHook.ReciveWebHook(httpContext);
}

[API]

With Dependency Injection 💉

- Configuration 🔧

First you need provide a configuration for Api in the appsettings.json like this:

"KickApiSettings": {
"BaseUrl": "https://api.kick.com/public/",
"AccessToken": "",
"KickOAuthSettings": {
	"BaseUrl": "https://id.kick.com/",
	"AuthorizationEndpointPath": "oauth/authorize",
	"TokenEndpointPath": "oauth/token",
	"RevokeEndpointTokenPath": "oauth/revoke",
	"RedirectUri": "YOUR_REDIRECT_URL",
	"ClientID": "YOUR_CLIENT_ID",
	"ClientSecret": "YOUR_CLIENT_SECRET",
	"Scopes": [ "user:read", "channel:read", "channel:write", "chat:write", "streamkey:read", "events:subscribe" ]
	}
}
Basic
Field Description Type Default Value
BaseUrl The url base of kick API. String https://api.kick.com/public/
AccessToken If you have an access token with more persistence like normal, you can put here. String (No default provided)
Auth
Field Description Type Default Value
BaseUrl The url base of kick API auth. String https://id.kick.com/
AuthorizationEndpointPath The path action of authorization endpoint. String oauth/authorize
TokenEndpointPath The path action of authorization for exchange a token. String oauth/token
RevokeEndpointTokenPath The path action to revoke a token. String oauth/token
RedirectUri The URI to redirect users to after authorization. You need to configure the same value in your app kick. String http://localhost:7121/api/authcallback
ClientID Your app kick client ID. You can get it in https://kick.com/settings/developer. String (No default provided)
ClientSecret Your app kick client secret. You can get it in https://kick.com/settings/developer. String (No default provided)
Scopes These scopes are for apps using OAuth 2.1 authorization code grants for authorization. You need get Permissions configured in app Kick Array of String [ "user:read", "channel:read", "channel:write", "chat:write", "streamkey:read", "events:subscribe" ]
- Usage

You can easily add KickNetLib.Api via extension method .AddKickLibApi(builder.Configuration);, that will register all related services with Scoped lifetime.

Now you can use KickApi with the interface IKickApi in your controller like this:

public class MyController : ControllerBase
{
	private readonly IKickApi _kickApi;
	
	public MyController(IKickApi kickAp) {
		_kickApi = kickApi;
	}
	
	private async Task Method() {
		// Get Category by Id
		await _kickApi.Categories.GetCategoryByIdAsync(1);
		
		// Get users by Ids
		await _kickApi.Users.GetUserByIdsAsync(["1"]);
	}
}

+ Without Dependency Injection 📄

First you need provide a configuration creating a object kickApi, and then you can use it.

public class Main
{
	private _kickOAuthSettings = new KickOAuthSettings()
	{
		BaseUrl = "https://id.kick.com/",
		AuthorizationEndpointPath = "oauth/authorize",
		TokenEndpointPath = "oauth/token",
		RevokeEndpointTokenPath = "oauth/revoke",
		RedirectUri = "YOUR_REDIRECT_URL",
		ClientID = "YOUR_CLIENT_ID",
		ClientSecret = "YOUR_CLIENT_SECRET",
		Scopes = KickScope.AllScopes
	};

	private _kickApiSettings = new KickApiSettings()
	{
		BaseUrl = "https://api.kick.com/public/",
		AccessToken = ""
	};
	
	private async Task Method() {
		// You must have a AccessToken to use kickApi
		// For generate it, follow the manual
		KickApi kickApi = new KickApi(_kickApiSettings);
		
		// Get Category by Id
		await _kickApi.Categories.GetCategoryByIdAsync(1);
		
		// Get users by Ids
		await _kickApi.Users.GetUserByIdsAsync(["1"]);
	}
}

Examples ↘️

Authentication flow

Call ProcessAuthorization

This method open a browser with a kick security page https://id.kick.com/oauth/authorize to confirm permissions.

// Call the authentication process of the Kick API. 
// The scopes are defined in the appsettings.json file
_kickApi.Authentication.ProcessAuthorization();

If you want override the scopes to send as you want

// Call the authentication process of the Kick API
// With your custom scopes user:read and channel:read
 _kickApi.Authentication.ProcessAuthorization(["user:read", "channel:read"]);
Callback

You need to implement a callback to manage info recived from kick. This info will be use to exchange for an access token.

// Extract 'code' and 'state' query parameters from the URL
string code = HttpContext.Request.Query["code"];
string codeVerifier = HttpContext.Request.Query["state"];

// Check if both the 'code' and 'state' are present
if (!string.IsNullOrEmpty(code) && !string.IsNullOrEmpty(codeVerifier))
{
	// Log the received authorization code for debugging
	_logger.LogDebug("Authorization code received: " + code);

	// Exchange the authorization code for an access token
	var tokenResponse = _kickApi.Authentication.ExchangeAuthCodeForAccessToken(code, codeVerifier);

	// Log that we received an authorization code
	_logger.LogDebug("Authorization code received and exchanged for access token.");
	return Ok(tokenResponse); // Return the access token response
}
Refresh Token
// Exchange the refresh token for a new access token
var tokenResponse = _kickApi.Authentication.ExchangeTokenFromRefreshToken("YOUR_REFRESH_TOKEN");
Revoke Token
// Revoke the provided token using the Kick API
// You can use your access token or refresh token
var resultRevoke = _kickApi.Authentication.RevokeToken("YOUR_TOKEN", TokenType.AccessToken);

API

_kickApi object has a diffrent properties to manage the apis. Like: Categories, Authentication, Chat, Channels, etc.

// If the access token is available in the configuration file (e.g., config.json), we can call the API.
// Note: Token expire is short. Be carefull with this.
// Here, the 'GetCategoryByIdAsync' method fetches the category with ID 1 (with no explicit access token)
var category = await _kickApi.Categories.GetCategoryByIdAsync(1);

OR

// If the access token is stored elsewhere (e.g., in Redis, session, or other storage),
// it can be passed explicitly as an argument to the 'GetCategoryByIdAsync' method.
var category = await _kickApi.Categories.GetCategoryByIdAsync(1, "MY_ACCESS_TOKEN");

WebHooks

In the configuration kick app https://kick.com/settings/developer you need provide an URL.

These url likes to: https://www.mywebhooklistener.com/api/webhook

You need create an endpoint to recive the webhooks.

public class WebHookMinimalController : ControllerBase
{
    private readonly IKickClient _kickClient;  // The KickClient to interact with the Kick API
    private readonly ILogger<WebHookMinimalController> _logger;  // Logger to log information and errors

    // Constructor to inject dependencies into the controller
    public WebHookMinimalController(
        IKickClient kickClient,  // Injecting the KickClient to interact with the Kick API
        ILogger<WebHookMinimalController> logger)  // Injecting the Logger to log events and errors
    {
        _kickClient = kickClient;  // Assigning the injected KickClient to the field
        _logger = logger;  // Assigning the injected Logger to the field

        // Subscribing to various webhook events when the controller is initialized
        _kickClient.WebHook.Events.OnChatMessageSent += Events_OnChatMessageSent;  // Event triggered when a chat message is sent
        _kickClient.WebHook.Events.OnChannelFollowed += Events_OnChannelFollowed;  // Event triggered when a channel is followed
        _kickClient.WebHook.Events.OnChannelGiftedSubscription += Events_OnChannelGiftedSubscription;  // Event triggered when a channel receives a gifted subscription
        _kickClient.WebHook.Events.OnChannelNewSubscription += Events_OnChannelNewSubscription;  // Event triggered when a channel gets a new subscription
        _kickClient.WebHook.Events.OnChannelSubscriptionRenewal += Events_OnChannelSubscriptionRenewal;  // Event triggered when a channel's subscription is renewed
        _kickClient.WebHook.Events.OnLivestreamStatusUpdated += Events_OnLivestreamStatusUpdated;  // Event triggered when a livestream's status is updated
    }

    // Event handler for the OnLivestreamStatusUpdated event
    void Events_OnLivestreamStatusUpdated(object? sender, LivestreamStatusUpdatedEventArgs e)
    {
        _logger.LogInformation("OnLivestreamStatusUpdated: {@data}", e.Data);  // Log the event data
    }

    // Event handler for the OnChannelSubscriptionRenewal event
    void Events_OnChannelSubscriptionRenewal(object? sender, ChannelSubscriptionRenewalEventArgs e)
    {
        _logger.LogInformation("OnChannelSubscriptionRenewal: {@data}", e.Data);  // Log the event data
    }

    // Event handler for the OnChannelNewSubscription event
    void Events_OnChannelNewSubscription(object? sender, ChannelNewSubscriptionEventArgs e)
    {
        _logger.LogInformation("OnChannelNewSubscription: {@data}", e.Data);  // Log the event data
    }

    // Event handler for the OnChannelGiftedSubscription event
    void Events_OnChannelGiftedSubscription(object? sender, ChannelGiftedSubscriptionEventArgs e)
    {
        _logger.LogInformation("OnChannelGiftedSubscription: {@data}", e.Data);  // Log the event data
    }

    // Event handler for the OnChannelFollowed event
    void Events_OnChannelFollowed(object? sender, ChannelFollowedEventArgs e)
    {
        _logger.LogInformation("OnChannelFollowed: {@data}", e.Data);  // Log the event data
    }

    // Event handler for the OnChatMessageSent event
    void Events_OnChatMessageSent(object? sender, ChatMessageSentEventArgs e)
    {
        _logger.LogInformation("OnChatMessageSent: {@data}", e.Data);  // Log the event data
    }

    // This method will handle incoming POST requests to the 'api/webhookminimal' endpoint
    [HttpPost("webhook")]
    public async Task<IActionResult> ReceiveWebHook()
    {
        try
        {
            // Call the KickClient's method to process the incoming webhook using the current HTTP context
            await _kickClient.WebHook.ReciveWebHook(HttpContext);

            // If everything goes fine, return HTTP 200 OK
            return Ok();
        }
        catch (Exception ex)
        {
            // If an exception occurs while processing the webhook, log the error
            _logger.LogError(ex, "Error processing webhook.");

            // Return an HTTP 500 Internal Server Error response if an error occurs during webhook processing
            return StatusCode(500, "Internal server error");
        }
    }
}
Test Real WebHooks in localhost

You need to use ngrok https://ngrok.com/ for this test.

#To get a public URL pointing your local server.

ngrok http http://localhost:7121

Now, the program will show you a public URL. It Looks like: https://02e0-213-177-211-49.ngrok-free.app

You need provide it to kick, inside the app configuration: https://kick.com/settings/developer

Now you are available to recive the webhooks.

You can test it sending a message in the chat. You will see the info in the log.

Test Fake WebHooks in localhost

You can use Postman https://www.postman.com/ to send fake data while your app is listening webhooks.

Fake data can be found here. You can import the project into postman and use it.

Important: Be secure to set the ValidateSender to false in configuration file to test it

Kick Desktop Tool 🔧

<p align="center"> <img src="https://github.com/Rubarez/KickNetLib/blob/master/res/Desktop2.jpg" style="max-height: 250px !important;"> </p>

The project contains an application tool for Windows.

The application provide a simple interface to create an access token, refresh it, revoke it, and finally test the API and Webhooks.

For test real Webhook you need to use ngrok https://ngrok.com/ for this test. And configure, in code (Desktop tool), the listener.

IMPORTANT: Check all kick app configurations https://kick.com/settings/developer to match URL with the desktop tool listeners.

Disclaimer 🏃

By using the KickNetLib software, you agree to the following terms and conditions. This software is provided to you "as-is," without any guarantees or warranties of any kind, express or implied. The following terms apply to the fullest extent permitted by law:

Software Use: The software is provided for your use, but it is your responsibility to ensure that it is used appropriately and in accordance with applicable laws and regulations. We do not warrant that the software is error-free or will meet your specific requirements.

No Warranty: We provide no warranties, either express or implied, regarding the software. This includes, but is not limited to, warranties of merchantability, fitness for a particular purpose, accuracy, or non-infringement. We do not guarantee the software’s performance, availability, or functionality.

Risk of Use: You acknowledge and agree that you are using the software at your own risk. We are not responsible for any damage, loss of data, interruption of business, or any other damages or issues that may arise from using the software.

No Liability for Damages: In no event shall we be liable for any direct, indirect, incidental, special, consequential, or punitive damages arising out of the use of the software, even if we have been advised of the possibility of such damages. This includes, but is not limited to, data loss, system failure, or loss of profit.

Performance and Availability: We do not guarantee that the software will operate uninterrupted or error-free. We make no claims regarding the reliability or availability of the software at all times. We are not responsible for any downtime, disruptions, or failures that may occur.

Third-Party Software: The software may interact with or rely on third-party services or components, which are outside our control. We make no guarantees regarding the performance or reliability of such third-party services, and we disclaim all liability associated with them.

Modification and Updates: We reserve the right to modify, update, or discontinue the software at any time without notice. We do not commit to providing updates, fixes, or support for the software, and any future updates or modifications may alter its functionality.

No Support or Maintenance: We are under no obligation to provide support, maintenance, or troubleshooting for the software. Any support provided is at our discretion and may be limited.

Severability: If any provision of this disclaimer is held to be invalid or unenforceable by a court of competent jurisdiction, the remainder of the disclaimer will remain in full force and effect.

Acknowledgment: By using this software, you acknowledge that you have read, understood, and agree to be bound by this full disclaimer. If you do not agree with any part of this disclaimer, you must not use the software.

License 📜

See MIT License.

Fully developed by 💻

🇪🇸 Rubén Álvarez Mel - Senior .Net developer Link to my Linkedin

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 155 3/17/2025
1.0.0 231 3/16/2025

Library supports official API and Webhooks.