Hooki

logo

Hooki

An awesome library created by Alertu to help with implementing incoming webhooks for various applications!

nuget downloads latest version contributors last update forks stars open issues license

View Examples ยท Documentation ยท Report Bug ยท Request Feature

Discord logo Microsoft Teams logo Slack logo


๐Ÿ“” Table of Contents

๐ŸŒŸ About Hooki

๐ŸŽฏ Features

๐Ÿช Why use Hooki?

Hooki is a powerful .NET library designed to simplify the creation of webhook payloads for popular platforms like Discord, Slack, and Microsoft Teams. It provides a set of strongly-typed C# POCO classes that serve as building blocks, allowing developers to easily construct and serialize webhook payloads into JSON format.

Main Benefits:

๐Ÿข Trusted By

Cloudcat Logo
Cloudcat.dev

๐Ÿงฐ Getting Started

โ€ผ๏ธ Prerequisites

The only requirement is compatibility with .net 8.0.x or .net 9.0.x

๐Ÿ‘€ Usage

using System;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;

using Hooki.Discord.Enums;
using Hooki.Discord.Models.BuildingBlocks;
using Hooki.Discord.Models;

public class DiscordWebhookService
{
    private readonly IHttpClientFactory _httpClientFactory;
    private readonly ILogger<DiscordWebhookService> _logger;

    public DiscordWebhookService(IHttpClientFactory httpClientFactory, ILogger<DiscordWebhookService> logger)
    {
        _httpClientFactory = httpClientFactory;
        _logger = logger;
    }

    private DiscordWebhookPayload CreateDiscordPayload()
    {
        return new DiscordWebhookPayload
        {
            Username = "Alertu Webhook",
            AvatarUrl = "https://example-url/image.png",
            Embeds = new List<DiscordEmbed>
            {
                new DiscordEmbed
                {
                    Author = new DiscordEmbedAuthor
                    {
                        Name = "Alertu",
                        Url = "https://alertu.io",
                        IconUrl = "https://example-url/image.png"
                    },
                    Title = $"Azure Metric Alert triggered",
                    Description = $"[**View in Alertu**](https://alertu.io) | [**View in Azure**](https://portal.azure.com)",
                    Color = 959721,
                    Fields = new List<DiscordEmbedField>
                    {
                        new DiscordEmbedField { Name = "Summary", Value = "This is a test summary", Inline = false },
                        new DiscordEmbedField { Name = "Organization Name", Value = "Test Organization", Inline = true },
                        new DiscordEmbedField { Name = "Project Name", Value = "Test Project", Inline = true },
                        new DiscordEmbedField { Name = "Cloud Provider", Value = "Azure", Inline = true },
                        new DiscordEmbedField { Name = "Resources", Value = "test-redis, test-postgreSQL", Inline = true },
                        new DiscordEmbedField { Name = "Severity", Value = "Critical", Inline = true },
                        new DiscordEmbedField { Name = "Status", Value = "Open", Inline = true },
                        new DiscordEmbedField { Name = "Triggered At", Value = DateTimeOffset.UtcNow.ToString("f"), Inline = true },
                        new DiscordEmbedField { Name = "Resolved At", Value = DateTimeOffset.UtcNow.ToString("f"), Inline = true }
                    }
                }
            }
        };
    }

    public async Task SendWebhookAsync(string webhookUrl, CancellationToken cancellationToken)
    {
        try
        {
            var discordPayload = CreateDiscordPayload();
            var jsonString = discordPayload.Serialize();

            using var client = _httpClientFactory.CreateClient();
            var content = new StringContent(jsonString, Encoding.UTF8, "application/json");

            var response = await client.PostAsync(webhookUrl, content, cancellationToken);
            response.EnsureSuccessStatusCode();

            _logger.LogInformation($"Successfully posted a Discord message to the webhook URL: {webhookUrl}");
        }
        catch (HttpRequestException ex)
        {
            _logger.LogError(ex, $"Failed to post Discord message to webhook URL: {webhookUrl}");
            throw;
        }
    }
}

// Example usage
public class ExampleController
{
    private readonly DiscordWebhookService _discordWebhookService;

    public ExampleController(DiscordWebhookService discordWebhookService)
    {
        _discordWebhookService = discordWebhookService;
    }

    public async Task SendDiscordNotification()
    {
        string webhookUrl = "https://discord.com/api/webhooks/your-webhook-url-here";
        await _discordWebhookService.SendWebhookAsync(webhookUrl, CancellationToken.None);
    }
}

๐Ÿงญ Roadmap

๐Ÿ‘‹ Contributing

Contributions are always welcome!

Please read Contributing for ways to get started.

๐Ÿ“œ Code of Conduct

Please read the Code of Conduct

โš ๏ธ License

Distributed under MIT License. See LICENSE.txt for more information.

๐Ÿค Contact

@adamthewilliam

๐Ÿ’Ž Acknowledgements