{"id":15605288,"url":"https://github.com/alertulabs/hooki","last_synced_at":"2025-04-26T18:53:42.656Z","repository":{"id":257807232,"uuid":"865103679","full_name":"AlertuLabs/Hooki","owner":"AlertuLabs","description":"Hooki: A .NET library for creating strongly-typed webhook payloads. Simplify Discord, Slack, and Microsoft Teams integrations with type-safe POCOs. Build, serialize, and send webhooks effortlessly.","archived":false,"fork":false,"pushed_at":"2025-01-05T00:02:04.000Z","size":591,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-30T08:25:19.142Z","etag":null,"topics":["c-sharp","discord","dotnet","json","library","microsoftteams","nuget-package","payload","sdk","slack","webhook"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AlertuLabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-30T01:20:12.000Z","updated_at":"2025-01-05T00:02:07.000Z","dependencies_parsed_at":null,"dependency_job_id":"04a28512-dca7-4dac-bf52-17f0f3b8ce88","html_url":"https://github.com/AlertuLabs/Hooki","commit_stats":{"total_commits":121,"total_committers":1,"mean_commits":121.0,"dds":0.0,"last_synced_commit":"28fba1dce31ae143bc79564d990332a64d3bb452"},"previous_names":["alertulabs/hooki"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlertuLabs%2FHooki","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlertuLabs%2FHooki/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlertuLabs%2FHooki/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AlertuLabs%2FHooki/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AlertuLabs","download_url":"https://codeload.github.com/AlertuLabs/Hooki/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250864155,"owners_count":21499609,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c-sharp","discord","dotnet","json","library","microsoftteams","nuget-package","payload","sdk","slack","webhook"],"created_at":"2024-10-03T04:03:52.186Z","updated_at":"2025-04-25T17:43:50.472Z","avatar_url":"https://github.com/AlertuLabs.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n  \u003cimg src=\"./assets/hooki-icon.png\" alt=\"logo\" width=\"100\" height=\"auto\" /\u003e\n  \u003ch1\u003eHooki\u003c/h1\u003e\n  \n  \u003cp\u003e\n    An awesome library created by \u003ca href=\"https://alertu.io\"\u003eAlertu\u003c/a\u003e to help with implementing incoming webhooks for various applications! \n  \u003c/p\u003e\n  \n\u003c!-- Badges --\u003e\n\u003cp\u003e\n    \u003ca href=\"https://www.nuget.org/packages/Hooki/\"\u003e\n      \u003cimg src=\"https://img.shields.io/nuget/dt/Hooki.svg\" alt=\"nuget downloads\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://www.nuget.org/packages/Hooki/\"\u003e\n      \u003cimg src=\"https://img.shields.io/nuget/v/Hooki.svg\" alt=\"latest version\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/AlertuLabs/Hooki/graphs/contributors\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/contributors/AlertuLabs/Hooki\" alt=\"contributors\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/last-commit/AlertuLabs/Hooki\" alt=\"last update\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/AlertuLabs/Hooki/network/members\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/forks/AlertuLabs/Hooki\" alt=\"forks\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/AlertuLabs/Hooki/stargazers\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/stars/AlertuLabs/Hooki\" alt=\"stars\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/AlertuLabs/Hooki/issues/\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/issues/AlertuLabs/Hooki\" alt=\"open issues\" /\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/AlertuLabs/Hooki/blob/master/LICENSE\"\u003e\n      \u003cimg src=\"https://img.shields.io/github/license/AlertuLabs/Hooki.svg\" alt=\"license\" /\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n   \n\u003ch4\u003e\n    \u003ca href=\"https://github.com/AlertuLabs/Hooki/tree/main/docs/examples\"\u003eView Examples\u003c/a\u003e\n  \u003cspan\u003e · \u003c/span\u003e\n    \u003ca href=\"https://github.com/AlertuLabs/Hooki/tree/main/docs\"\u003eDocumentation\u003c/a\u003e\n  \u003cspan\u003e · \u003c/span\u003e\n    \u003ca href=\"https://github.com/AlertuLabs/Hooki/issues/\"\u003eReport Bug\u003c/a\u003e\n  \u003cspan\u003e · \u003c/span\u003e\n    \u003ca href=\"https://github.com/AlertuLabs/Hooki/issues/\"\u003eRequest Feature\u003c/a\u003e\n  \u003c/h4\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n    \u003cimg width=\"48\" height=\"48\" src=\"https://img.icons8.com/color/48/discord--v2.png\" alt=\"Discord logo\"/\u003e\n    \u003cimg width=\"48\" height=\"48\" src=\"https://img.icons8.com/color/48/microsoft-teams.png\" alt=\"Microsoft Teams logo\"/\u003e\n    \u003cimg width=\"48\" height=\"48\" src=\"https://img.icons8.com/color-glass/48/slack-new.png\" alt=\"Slack logo\"/\u003e  \n\u003c/div\u003e\n\n\u003cbr /\u003e\n\n\u003c!-- Table of Contents --\u003e\n# 📔 Table of Contents\n\n- [About Hooki](#-about-hooki)\n  * [Features](#-features)\n  * [Why use Hooki?](#-why-use-hooki)\n- [Trusted By](#-trusted-by)\n- [Getting Started](#-getting-started)\n  * [Prerequisites](#-prerequisites)\n- [Usage](#-usage)\n- [Roadmap](#-roadmap)\n- [Contributing](#-contributing)\n  * [Code of Conduct](#-code-of-conduct)\n- [License](#-license)\n- [Contact](#-contact)\n- [Acknowledgements](#-acknowledgements)\n  \n\n\u003c!-- About Hooki --\u003e\n## 🌟 About Hooki\n\n\u003c!-- Features --\u003e\n### 🎯 Features\n\n- Strongly typed POCOs for the following platforms:\n  - Discord Webhook API\n  - Slack Block Kit SDK\n  - Microsoft Teams Message Card\n- Compile-time checks for missing properties\n- Type safety ensuring correct payload structure\n- Leveraging existing platform SDKs and standards\n\n\u003c!-- Why use Hooki? --\u003e\n### 🪝 Why use Hooki?\n\nHooki 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.\n\n**Main Benefits:**\n- **Simplified Development:** Pre-built POCOs for common webhook JSON payloads across various platforms.\n- **Type Safety:** Strongly-typed classes ensure compile-time checks and prevent runtime errors.\n- **Clean Code:** Eliminates the need for anonymous objects and inline JSON strings.\n- **Focus on Content:** Concentrate on your payload's data and style rather than low-level JSON structure.\n- **Flexibility:** Easily extensible for custom webhook requirements while maintaining type safety.\n\n\u003c!-- Trusted By --\u003e\n## 🏢 Trusted By\n\n\u003cdiv align=\"center\"\u003e\n  \u003ctable\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\"\u003e\n        \u003ca href=\"https://cloudcat.dev\"\u003e\n          \u003cimg src=\"https://cloudcat.dev/logo.svg\" width=\"100px;\" alt=\"Cloudcat Logo\"/\u003e\n        \u003c/a\u003e\n      \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd align=\"center\"\u003eCloudcat.dev\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/table\u003e\n\u003c/div\u003e\n\n\u003c!-- Getting Started --\u003e\n##  🧰 Getting Started\n\n\u003c!-- Prerequisites --\u003e\n### ‼️ Prerequisites\n\nThe only requirement is compatibility with .net 8.0.x or .net 9.0.x\n\n\u003c!-- Usage --\u003e\n## 👀 Usage\n\n```csharp\nusing System;\nusing System.Net.Http;\nusing System.Text;\nusing System.Text.Json;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.Logging;\n\nusing Hooki.Discord.Enums;\nusing Hooki.Discord.Models.BuildingBlocks;\nusing Hooki.Discord.Models;\n\npublic class DiscordWebhookService\n{\n    private readonly IHttpClientFactory _httpClientFactory;\n    private readonly ILogger\u003cDiscordWebhookService\u003e _logger;\n\n    public DiscordWebhookService(IHttpClientFactory httpClientFactory, ILogger\u003cDiscordWebhookService\u003e logger)\n    {\n        _httpClientFactory = httpClientFactory;\n        _logger = logger;\n    }\n\n    private DiscordWebhookPayload CreateDiscordPayload()\n    {\n        return new DiscordWebhookPayload\n        {\n            Username = \"Alertu Webhook\",\n            AvatarUrl = \"https://example-url/image.png\",\n            Embeds = new List\u003cDiscordEmbed\u003e\n            {\n                new DiscordEmbed\n                {\n                    Author = new DiscordEmbedAuthor\n                    {\n                        Name = \"Alertu\",\n                        Url = \"https://alertu.io\",\n                        IconUrl = \"https://example-url/image.png\"\n                    },\n                    Title = $\"Azure Metric Alert triggered\",\n                    Description = $\"[**View in Alertu**](https://alertu.io) | [**View in Azure**](https://portal.azure.com)\",\n                    Color = 959721,\n                    Fields = new List\u003cDiscordEmbedField\u003e\n                    {\n                        new DiscordEmbedField { Name = \"Summary\", Value = \"This is a test summary\", Inline = false },\n                        new DiscordEmbedField { Name = \"Organization Name\", Value = \"Test Organization\", Inline = true },\n                        new DiscordEmbedField { Name = \"Project Name\", Value = \"Test Project\", Inline = true },\n                        new DiscordEmbedField { Name = \"Cloud Provider\", Value = \"Azure\", Inline = true },\n                        new DiscordEmbedField { Name = \"Resources\", Value = \"test-redis, test-postgreSQL\", Inline = true },\n                        new DiscordEmbedField { Name = \"Severity\", Value = \"Critical\", Inline = true },\n                        new DiscordEmbedField { Name = \"Status\", Value = \"Open\", Inline = true },\n                        new DiscordEmbedField { Name = \"Triggered At\", Value = DateTimeOffset.UtcNow.ToString(\"f\"), Inline = true },\n                        new DiscordEmbedField { Name = \"Resolved At\", Value = DateTimeOffset.UtcNow.ToString(\"f\"), Inline = true }\n                    }\n                }\n            }\n        };\n    }\n\n    public async Task SendWebhookAsync(string webhookUrl, CancellationToken cancellationToken)\n    {\n        try\n        {\n            var discordPayload = CreateDiscordPayload();\n            var jsonString = discordPayload.Serialize();\n\n            using var client = _httpClientFactory.CreateClient();\n            var content = new StringContent(jsonString, Encoding.UTF8, \"application/json\");\n\n            var response = await client.PostAsync(webhookUrl, content, cancellationToken);\n            response.EnsureSuccessStatusCode();\n\n            _logger.LogInformation($\"Successfully posted a Discord message to the webhook URL: {webhookUrl}\");\n        }\n        catch (HttpRequestException ex)\n        {\n            _logger.LogError(ex, $\"Failed to post Discord message to webhook URL: {webhookUrl}\");\n            throw;\n        }\n    }\n}\n\n// Example usage\npublic class ExampleController\n{\n    private readonly DiscordWebhookService _discordWebhookService;\n\n    public ExampleController(DiscordWebhookService discordWebhookService)\n    {\n        _discordWebhookService = discordWebhookService;\n    }\n\n    public async Task SendDiscordNotification()\n    {\n        string webhookUrl = \"https://discord.com/api/webhooks/your-webhook-url-here\";\n        await _discordWebhookService.SendWebhookAsync(webhookUrl, CancellationToken.None);\n    }\n}\n```\n\n\u003c!-- Roadmap --\u003e\n## 🧭 Roadmap\n\n* [x] POCOs\n* [x] Implement Unit Tests\n* [x] Implement Integration Tests\n* [ ] Builders are implemented but the Slack builder needs work to be more fluent\n* [ ] Implement POCOs for Discord message components\n* [ ] Introduce Validation\n* [ ] Support other languages?\n\n\u003c!-- Contributing --\u003e\n## 👋 Contributing\n\n\u003ca href=\"https://github.com/AlertuLabs/Hooki/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=AlertuLabs/Hooki\" /\u003e\n\u003c/a\u003e\n\nContributions are always welcome!\n\nPlease read [Contributing](https://github.com/AlertuLabs/Hooki/blob/main/.github/CONTRIBUTING.md) for ways to get started.\n\n\u003c!-- Code of Conduct --\u003e\n### 📜 Code of Conduct\n\nPlease read the [Code of Conduct](https://github.com/AlertuLabs/Hooki/blob/main/.github/CODE_OF_CONDUCT.md)\n\n\u003c!-- License --\u003e\n## ⚠️ License\n\nDistributed under MIT License. See LICENSE.txt for more information.\n\n\u003c!-- Contact --\u003e\n## 🤝 Contact\n\n[@adamthewilliam](https://twitter.com/adamthewilliam)\n\n\u003c!-- Acknowledgments --\u003e\n## 💎 Acknowledgements\n\n - [Readme Template](https://github.com/Louis3797/awesome-readme-template)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falertulabs%2Fhooki","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falertulabs%2Fhooki","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falertulabs%2Fhooki/lists"}