1
0
mirror of https://github.com/bitwarden/server synced 2026-01-14 06:23:46 +00:00
Files
server/src/Core/Dirt/Services/Implementations/SlackIntegrationHandler.cs
Brant DeBow 86a68ab637 Move all event integration code to Dirt (#6757)
* Move all event integration code to Dirt

* Format to fix lint
2025-12-30 10:59:19 -05:00

77 lines
3.2 KiB
C#

using Bit.Core.Dirt.Models.Data.EventIntegrations;
namespace Bit.Core.Dirt.Services.Implementations;
public class SlackIntegrationHandler(
ISlackService slackService)
: IntegrationHandlerBase<SlackIntegrationConfigurationDetails>
{
public override async Task<IntegrationHandlerResult> HandleAsync(IntegrationMessage<SlackIntegrationConfigurationDetails> message)
{
var slackResponse = await slackService.SendSlackMessageByChannelIdAsync(
message.Configuration.Token,
message.RenderedTemplate,
message.Configuration.ChannelId
);
if (slackResponse is null)
{
return IntegrationHandlerResult.Fail(
message,
IntegrationFailureCategory.TransientError,
"Slack response was null"
);
}
if (slackResponse.Ok)
{
return IntegrationHandlerResult.Succeed(message);
}
var category = ClassifySlackError(slackResponse.Error);
return IntegrationHandlerResult.Fail(
message,
category,
slackResponse.Error
);
}
/// <summary>
/// Classifies a Slack API error code string as an <see cref="IntegrationFailureCategory"/> to drive
/// retry behavior and operator-facing failure reporting.
/// </summary>
/// <remarks>
/// <para>
/// Slack responses commonly return an <c>error</c> string when <c>ok</c> is false. This method maps
/// known Slack error codes to failure categories.
/// </para>
/// <para>
/// Any unrecognized error codes default to <see cref="IntegrationFailureCategory.TransientError"/> to avoid
/// incorrectly marking new/unknown Slack failures as non-retryable.
/// </para>
/// </remarks>
/// <param name="error">The Slack error code string (e.g. <c>invalid_auth</c>, <c>rate_limited</c>).</param>
/// <returns>The corresponding <see cref="IntegrationFailureCategory"/>.</returns>
private static IntegrationFailureCategory ClassifySlackError(string error)
{
return error switch
{
"invalid_auth" => IntegrationFailureCategory.AuthenticationFailed,
"access_denied" => IntegrationFailureCategory.AuthenticationFailed,
"token_expired" => IntegrationFailureCategory.AuthenticationFailed,
"token_revoked" => IntegrationFailureCategory.AuthenticationFailed,
"account_inactive" => IntegrationFailureCategory.AuthenticationFailed,
"not_authed" => IntegrationFailureCategory.AuthenticationFailed,
"channel_not_found" => IntegrationFailureCategory.ConfigurationError,
"is_archived" => IntegrationFailureCategory.ConfigurationError,
"rate_limited" => IntegrationFailureCategory.RateLimited,
"ratelimited" => IntegrationFailureCategory.RateLimited,
"message_limit_exceeded" => IntegrationFailureCategory.RateLimited,
"internal_error" => IntegrationFailureCategory.TransientError,
"service_unavailable" => IntegrationFailureCategory.ServiceUnavailable,
"fatal_error" => IntegrationFailureCategory.ServiceUnavailable,
_ => IntegrationFailureCategory.TransientError
};
}
}