Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion Samples/HelloWorld/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
.AddMessageActionsHandler<DoOtherStuff>()
.AddAppMentionHandler<DoStuff>()
.AddTeamJoinHandler<OnTeamJoins>()
.AddEmojiChangedHandler<OnEmojiChanged>();
.AddEmojiChangedHandler<OnEmojiChanged>()
.AddAppMentionHandler<IThrowExceptions>();


var app = builder.Build();
Expand Down Expand Up @@ -72,3 +73,13 @@ public Task<EventHandledResponse> Handle(EventMetaData eventMetadata, EmojiChang
return Task.FromResult(new EventHandledResponse("OK"));
}
}

class IThrowExceptions : IHandleAppMentions
{
public bool ShouldHandle(AppMentionEvent slackEvent) => slackEvent.Text.Contains("throw-exception");

public Task<EventHandledResponse> Handle(EventMetaData eventMetadata, AppMentionEvent slackEvent)
{
throw new Exception("Quack! Something went wrong!");
}
}
6 changes: 3 additions & 3 deletions Samples/HelloWorld/test.http
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Mimicks a payload slack would send for app_mention events, like "@yourbot dostuff" in this case:
GET http://localhost:1337/
GET http://localhost:5000/
X-Slack-Request-Timestamp: 12331231
X-Slack-Signature: v0:abc123etcetc

Expand All @@ -8,14 +8,14 @@ X-Slack-Signature: v0:abc123etcetc
"event": {
"type": "app_mention",
"user": "USRAR1YTV",
"text" : "<@BOT123> dostuff",
"text" : "<@BOT123> dostuff and throw-exception",
"channel": "C92QZTVEF"
}
}

###
# Verification request
GET http://localhost:1337
GET http://localhost:5000

{
"token": "Jhj5dZrVaK7ZwHHjRyZWjbDl",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public static IApplicationBuilder UseSlackbot(this IApplicationBuilder app, bool
app.UseMiddleware<SlackbotEventAuthMiddleware>();
}

app.UseMiddleware<ErrorHandlingMiddleware>();
app.UseMiddleware<HttpItemsManager>();
app.MapWhen(Challenge.ShouldRun, b => b.UseMiddleware<Challenge>());
app.MapWhen(Uninstall.ShouldRun, b => b.UseMiddleware<Uninstall>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,9 @@ public async Task Invoke(HttpContext context)
else
{
logger.LogInformation($"Handling using {handler.GetType()}");
try
{
logger.LogInformation($"Handling using {handler.GetType()}");
var response = await handler.Handle(metadata, appHomeOpenedEvent);
logger.LogInformation(response.Response);
}
catch (Exception e)
{
logger.LogError(e, e.Message);
}
logger.LogInformation($"Handling using {handler.GetType()}");
var response = await handler.Handle(metadata, appHomeOpenedEvent);
logger.LogInformation(response.Response);
}

await next(context);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.Runtime.ExceptionServices;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Slackbot.Net.Endpoints.Abstractions;
Expand All @@ -24,6 +25,8 @@ public async Task Invoke(HttpContext context)
["Slack_Channel"] = appMentionEvent?.Channel,
["Slack_User"] = appMentionEvent?.User
});
ExceptionDispatchInfo capturedException = null;

foreach (var handler in handlers)
{
try
Expand All @@ -33,12 +36,14 @@ public async Task Invoke(HttpContext context)
}
catch (Exception e)
{
logger.LogError(e, e.Message);
capturedException = ExceptionDispatchInfo.Capture(e);
}
}


context.Response.StatusCode = 200;
if (capturedException != null)
{
capturedException?.Throw();
}
}

public static bool ShouldRun(HttpContext ctx)
Expand Down
1 change: 0 additions & 1 deletion source/src/Slackbot.Net.Endpoints/Middlewares/Challenge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ public Challenge(RequestDelegate next, ILogger<Challenge> logger)
public async Task Invoke(HttpContext context)
{
var challenge = context.Items[HttpItemKeys.ChallengeKey];

_logger.LogInformation($"Handling challenge request. Challenge: {challenge}");
context.Response.StatusCode = 200;
context.Response.ContentType = "application/json";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
namespace Slackbot.Net.Endpoints.Middlewares;

public class EmojiChangedEvents(
#pragma warning disable CS9113 // Parameter is unread.
RequestDelegate next,
#pragma warning restore CS9113 // Parameter is unread.
ILogger<EmojiChangedEvents> logger,
IEnumerable<IHandleEmojiChanged> responseHandlers
)
Expand All @@ -24,16 +26,9 @@ public async Task Invoke(HttpContext context)
else
{
logger.LogInformation("Handling using {HandlerType}", handler.GetType());
try
{
logger.LogInformation("Handling using {HandlerType}", handler.GetType());
var response = await handler.Handle(metadata, emojiChanged);
logger.LogInformation("Handler response: {Response}", response.Response);
}
catch (Exception e)
{
logger.LogError(e, e.Message);
}
logger.LogInformation("Handling using {HandlerType}", handler.GetType());
var response = await handler.Handle(metadata, emojiChanged);
logger.LogInformation("Handler response: {Response}", response.Response);
}

context.Response.StatusCode = 200;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;

namespace Slackbot.Net.Endpoints.Middlewares;

public class ErrorHandlingMiddleware(RequestDelegate next, ILogger<HttpItemsManager> logger)
{
public async Task InvokeAsync(HttpContext context)
{
try
{
await next(context);
}
catch (Exception e)
{
logger.LogError(e, e.Message);
context.Response.Headers.Append("x-slack-no-retry", "1");
context.Response.StatusCode = 500;
await context.Response.WriteAsync("An error occurred while processing the slack event request. Plz do not retry.");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public async Task Invoke(HttpContext context)
else
{
var metadata = JsonSerializer.Deserialize<EventMetaData>(body, WebOptions);
if (jObject.RootElement.GetProperty("event") is JsonElement @event)
if (jObject.RootElement.GetProperty("event") is var @event)
{
var slackEvent = ToEventType(@event, body);
context.Items.Add(HttpItemKeys.EventMetadataKey, metadata);
Expand Down Expand Up @@ -78,7 +78,7 @@ private static SlackEvent ToEventType(JsonElement eventJson, string raw)
case EventTypes.TeamJoin:
return JsonSerializer.Deserialize<TeamJoinEvent>(json, WebOptions);
case EventTypes.EmojiChanged:
return JsonSerializer.Deserialize<EmojiChangedEvent>(json, WebOptions);
return JsonSerializer.Deserialize<EmojiChangedEvent>(json, WebOptions);
default:
var unknownSlackEvent = JsonSerializer.Deserialize<UnknownSlackEvent>(json, WebOptions);
unknownSlackEvent.RawJson = raw;
Expand Down
12 changes: 2 additions & 10 deletions source/src/Slackbot.Net.Endpoints/Middlewares/InteractiveEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,8 @@ private async Task HandleMessageAction(MessageActionInteraction messageAction)
else
{
logger.LogInformation($"Handling using {handler.GetType()}");
try
{
logger.LogInformation($"Handling using {handler.GetType()}");
var response = await handler.Handle(messageAction);
logger.LogInformation(response.Response);
}
catch (Exception e)
{
logger.LogError(e, e.Message);
}
var response = await handler.Handle(messageAction);
logger.LogInformation(response.Response);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,19 +32,9 @@ public async Task Invoke(HttpContext context)
else
{
_logger.LogInformation($"Handling using {handler.GetType()}");
try
{
_logger.LogInformation($"Handling using {handler.GetType()}");
var response = await handler.Handle(metadata, memberJoinedChannelEvent);
_logger.LogInformation(response.Response);
}
catch (Exception e)
{
_logger.LogError(e, e.Message);
}
var response = await handler.Handle(metadata, memberJoinedChannelEvent);
_logger.LogInformation(response.Response);
}

context.Response.StatusCode = 200;
}

public static bool ShouldRun(HttpContext ctx)
Expand Down
14 changes: 4 additions & 10 deletions source/src/Slackbot.Net.Endpoints/Middlewares/TeamJoinEvents.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
namespace Slackbot.Net.Endpoints.Middlewares;

public class TeamJoinEvents(
#pragma warning disable CS9113 // Parameter is unread.
RequestDelegate next,
#pragma warning restore CS9113 // Parameter is unread.
ILogger<TeamJoinEvents> logger,
IEnumerable<IHandleTeamJoin> responseHandlers
)
Expand All @@ -24,16 +26,8 @@ public async Task Invoke(HttpContext context)
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);
}
var response = await handler.Handle(metadata, teamJoinEvent);
logger.LogInformation("Handler response: {Response}", response.Response);
}

context.Response.StatusCode = 200;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,15 @@ public class EmojiChangedEvent : SlackEvent
public string SubType { get; init; } = string.Empty; // subtype: add, remove, rename
public string? Name { get; set; } // subtype: add
public string[] Names { get; set; } = []; //subtype: remove
public string OldName { get; set; } // subtype: rename
public string NewName { get; set; } // subtype: rename
public string? OldName { get; set; } // subtype: rename
public string? NewName { get; set; } // subtype: rename
public Uri? Value { get; set; }// subtypes: add, rename

public EmojiChange CreateSubType() => SubType switch
{
SubTypeAdd => new EmojiAdded { Name = Name!, Value = Value! },
SubTypeRemove => new EmojiRemoved { Names = Names },
SubTypeRename => new EmojiRenamed { OldName = OldName, NewName = NewName, Value = Value },
SubTypeRename => new EmojiRenamed { OldName = OldName!, NewName = NewName!, Value = Value },
_ => new UnknownEmojiChange()
};
}
Expand All @@ -29,7 +29,7 @@ public class EmojiChange();
public class EmojiAdded : EmojiChange
{
public required string Name { get; init; }
public Uri Value { get; init; }
public required Uri Value { get; init; }
}

public class EmojiRemoved : EmojiChange
Expand All @@ -39,9 +39,9 @@ public class EmojiRemoved : EmojiChange

public class EmojiRenamed : EmojiChange
{
public string OldName { get; set; } // subtype: rename
public string NewName { get; set; } // subtype: rename
public Uri? Value { get; set; }// subtypes: add, rename
public required string OldName { get; init; } // subtype: rename
public required string NewName { get; init; } // subtype: rename
public required Uri? Value { get; init; }// subtypes: add, rename
}

public class UnknownEmojiChange() : EmojiChange;
Expand Down