From a5edde8db9f7b4415ffe224b342a2ce706fe4d28 Mon Sep 17 00:00:00 2001 From: Ole Magnus Urdahl Date: Wed, 28 May 2025 12:46:21 +0200 Subject: [PATCH 1/3] Add Team Join event https://api.slack.com/events/team_join Update TeamJoinEvents.cs --- .../Abstractions/IHandleTeamJoin.cs | 8 ++++ .../src/Slackbot.Net.Endpoints/EventTypes.cs | 1 + .../Hosting/IAppBuilderExtensions.cs | 1 + .../Hosting/ISlackbotHandlersBuilder.cs | 1 + .../Hosting/SlackBotHandlersBuilder.cs | 6 +++ .../Middlewares/TeamJoinEvents.cs | 46 +++++++++++++++++++ .../Models/Events/TeamJoinEvent.cs | 6 +++ 7 files changed, 69 insertions(+) create mode 100644 source/src/Slackbot.Net.Endpoints/Abstractions/IHandleTeamJoin.cs create mode 100644 source/src/Slackbot.Net.Endpoints/Middlewares/TeamJoinEvents.cs create mode 100644 source/src/Slackbot.Net.Endpoints/Models/Events/TeamJoinEvent.cs diff --git a/source/src/Slackbot.Net.Endpoints/Abstractions/IHandleTeamJoin.cs b/source/src/Slackbot.Net.Endpoints/Abstractions/IHandleTeamJoin.cs new file mode 100644 index 0000000..db6e1bb --- /dev/null +++ b/source/src/Slackbot.Net.Endpoints/Abstractions/IHandleTeamJoin.cs @@ -0,0 +1,8 @@ +using Slackbot.Net.Endpoints.Models.Events; + +namespace Slackbot.Net.Endpoints.Abstractions; + +public interface IHandleTeamJoin +{ + Task Handle(EventMetaData eventMetadata, TeamJoinEvent memberjoined); +} diff --git a/source/src/Slackbot.Net.Endpoints/EventTypes.cs b/source/src/Slackbot.Net.Endpoints/EventTypes.cs index 2d4cd46..49da691 100644 --- a/source/src/Slackbot.Net.Endpoints/EventTypes.cs +++ b/source/src/Slackbot.Net.Endpoints/EventTypes.cs @@ -7,4 +7,5 @@ public static class EventTypes public const string AppMention = "app_mention"; public const string MemberJoinedChannel = "member_joined_channel"; public const string AppHomeOpened = "app_home_opened"; + public const string TeamJoin = "team_join"; } diff --git a/source/src/Slackbot.Net.Endpoints/Hosting/IAppBuilderExtensions.cs b/source/src/Slackbot.Net.Endpoints/Hosting/IAppBuilderExtensions.cs index 7474284..8015bae 100644 --- a/source/src/Slackbot.Net.Endpoints/Hosting/IAppBuilderExtensions.cs +++ b/source/src/Slackbot.Net.Endpoints/Hosting/IAppBuilderExtensions.cs @@ -19,6 +19,7 @@ public static IApplicationBuilder UseSlackbot(this IApplicationBuilder app, bool app.MapWhen(MemberJoinedEvents.ShouldRun, b => b.UseMiddleware()); app.MapWhen(AppHomeOpenedEvents.ShouldRun, b => b.UseMiddleware()); app.MapWhen(InteractiveEvents.ShouldRun, b => b.UseMiddleware()); + app.MapWhen(TeamJoinEvents.ShouldRun, b => b.UseMiddleware()); return app; } diff --git a/source/src/Slackbot.Net.Endpoints/Hosting/ISlackbotHandlersBuilder.cs b/source/src/Slackbot.Net.Endpoints/Hosting/ISlackbotHandlersBuilder.cs index 8a7b19b..0007357 100644 --- a/source/src/Slackbot.Net.Endpoints/Hosting/ISlackbotHandlersBuilder.cs +++ b/source/src/Slackbot.Net.Endpoints/Hosting/ISlackbotHandlersBuilder.cs @@ -16,4 +16,5 @@ public ISlackbotHandlersBuilder AddInteractiveBlockActionsHandler() public ISlackbotHandlersBuilder AddNoOpAppMentionHandler() where T : class, INoOpAppMentions; public ISlackbotHandlersBuilder AddMessageActionsHandler() where T : class, IHandleMessageActions; + public ISlackbotHandlersBuilder AddTeamJoinHandler() where T : class, IHandleTeamJoin; } diff --git a/source/src/Slackbot.Net.Endpoints/Hosting/SlackBotHandlersBuilder.cs b/source/src/Slackbot.Net.Endpoints/Hosting/SlackBotHandlersBuilder.cs index 8c3ab9a..2a958f5 100644 --- a/source/src/Slackbot.Net.Endpoints/Hosting/SlackBotHandlersBuilder.cs +++ b/source/src/Slackbot.Net.Endpoints/Hosting/SlackBotHandlersBuilder.cs @@ -53,4 +53,10 @@ public ISlackbotHandlersBuilder AddMessageActionsHandler() where T : class, I services.AddSingleton(); return this; } + + public ISlackbotHandlersBuilder AddTeamJoinHandler() where T : class, IHandleTeamJoin + { + services.AddSingleton(); + return this; + } } diff --git a/source/src/Slackbot.Net.Endpoints/Middlewares/TeamJoinEvents.cs b/source/src/Slackbot.Net.Endpoints/Middlewares/TeamJoinEvents.cs new file mode 100644 index 0000000..4e3dcf0 --- /dev/null +++ b/source/src/Slackbot.Net.Endpoints/Middlewares/TeamJoinEvents.cs @@ -0,0 +1,46 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.Logging; +using Slackbot.Net.Endpoints.Abstractions; +using Slackbot.Net.Endpoints.Models.Events; + +namespace Slackbot.Net.Endpoints.Middlewares; + +internal class TeamJoinEvents( + ILogger logger, + IEnumerable responseHandlers +) +{ + public async Task Invoke(HttpContext context) + { + var teamJoinEvent = (TeamJoinEvent)context.Items[HttpItemKeys.SlackEventKey]; + var metadata = (EventMetaData)context.Items[HttpItemKeys.EventMetadataKey]; + var handler = responseHandlers.FirstOrDefault(); + + if (handler == null) + { + logger.LogError("No handler registered for IHandleTeamJoinEvents"); + } + else + { + logger.LogInformation("Handling using {HandlerType}", handler.GetType()); + try + { + logger.LogInformation("Handling using {HandlerType}", handler.GetType()); + var response = await handler.Handle(metadata, teamJoinEvent); + logger.LogInformation("Handler response: {Response}", response.Response); + } + catch (Exception e) + { + logger.LogError(e, e.Message); + } + } + + context.Response.StatusCode = 200; + } + + public static bool ShouldRun(HttpContext ctx) + { + return ctx.Items.ContainsKey(HttpItemKeys.EventTypeKey) + && ctx.Items[HttpItemKeys.EventTypeKey].ToString() == EventTypes.TeamJoin; + } +} diff --git a/source/src/Slackbot.Net.Endpoints/Models/Events/TeamJoinEvent.cs b/source/src/Slackbot.Net.Endpoints/Models/Events/TeamJoinEvent.cs new file mode 100644 index 0000000..f0570c4 --- /dev/null +++ b/source/src/Slackbot.Net.Endpoints/Models/Events/TeamJoinEvent.cs @@ -0,0 +1,6 @@ +namespace Slackbot.Net.Endpoints.Models.Events; + +public class TeamJoinEvent : SlackEvent +{ + public string User { get; set; } +} From c5d9cd9c06e9d536d5c13e2e511d76770d3fd7db Mon Sep 17 00:00:00 2001 From: Ole Magnus Urdahl Date: Thu, 29 May 2025 21:33:25 +0200 Subject: [PATCH 2/3] Add Id to Block element input for input retention --- source/src/Slackbot.Net.Shared/BlockElements.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/src/Slackbot.Net.Shared/BlockElements.cs b/source/src/Slackbot.Net.Shared/BlockElements.cs index 2bbb6a7..1e219bd 100644 --- a/source/src/Slackbot.Net.Shared/BlockElements.cs +++ b/source/src/Slackbot.Net.Shared/BlockElements.cs @@ -38,7 +38,8 @@ public class ContextBlock : IBlock public class InputBlock : IBlock { - public string type { get; set;} = BlockTypes.Input; + public string block_id { get; set; } + public string type { get; set; } = BlockTypes.Input; public IElement element { get; set; } public Text label { get; set; } public bool dispatch_action { get; set; } From 4cb5bf46b37201fdb226466fa8dee87380f7f753 Mon Sep 17 00:00:00 2001 From: Ole Magnus Urdahl Date: Mon, 2 Jun 2025 09:07:11 +0200 Subject: [PATCH 3/3] Add RadioButtonElement https://api.slack.com/reference/block-kit/block-elements#radio --- .../src/Slackbot.Net.Shared/BlockElements.cs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/source/src/Slackbot.Net.Shared/BlockElements.cs b/source/src/Slackbot.Net.Shared/BlockElements.cs index 1e219bd..d3c56a7 100644 --- a/source/src/Slackbot.Net.Shared/BlockElements.cs +++ b/source/src/Slackbot.Net.Shared/BlockElements.cs @@ -176,16 +176,26 @@ public class OverflowElement : IElement public class DatePickerElement : IElement { - public string type { get; set;} = ElementTypes.DatePicker; + public string type { get; set; } = ElementTypes.DatePicker; public string action_id { get; set; } public Text placeholder { get; set; } public string initial_date { get; set; } public Confirm confirm { get; set; } } +public class RadioButtonsElement : IElement +{ + public string type { get; set; } = ElementTypes.RadioButtons; + public string action_id { get; set; } + public Option[] options { get; set; } + public string initial_option { get; set; } + public Confirm confirm { get; set; } + public bool focus_on_load { get; set; } +} + public class PlainTextElement : IElement { - public string type { get; set;} = ElementTypes.PlainTextInput; + public string type { get; set; } = ElementTypes.PlainTextInput; public string action_id { get; set; } public Text placeholder { get; set; } } @@ -224,9 +234,10 @@ public static class ElementTypes public const string Overflow = "overflow"; public const string DatePicker = "datepicker"; public const string PlainTextInput = "plain_text_input"; + public const string RadioButtons = "radio_buttons"; } - + public interface IHaveType { string type { get; set; } } public interface IElement : IHaveType { } -public interface IBlock : IHaveType { } \ No newline at end of file +public interface IBlock : IHaveType { }