2. Configure incoming webhook for the channel where we want to receive the messages
3. Copy url from WebHook and create a new section in our appsettings.json file. i.e.
"SlackSettings": { "NotifyChannelUrl": "https://hooks.slack.com/services/..." },
4. Create a new filter to catch exceptions:
public class SlackExceptionFilterAttribute : ExceptionFilterAttribute { private readonly SlackNotificationService _slackNotificationService; private readonly IHostingEnvironment _hostingEnvironment; public SlackExceptionFilterAttribute(SlackNotificationService slackNotificationService, IHostingEnvironment hostingEnvironment) { _slackNotificationService = slackNotificationService; _hostingEnvironment = hostingEnvironment; } public async override Task OnExceptionAsync(ExceptionContext context) { try { if (context.Exception is Shared.Exceptions.INotFoundException) { context.Result = new NotFoundResult(); return; } string url = GetAbsoluteUri(context.HttpContext); if (_hostingEnvironment.IsProduction()) await _slackNotificationService.NotifyException(url, context.Exception.GetType().Name, context.Exception.Message); } catch (Exception) { } } private string GetAbsoluteUri(HttpContext httpContext) { var request = httpContext.Request; UriBuilder uriBuilder = new UriBuilder(); uriBuilder.Scheme = request.Scheme; uriBuilder.Host = request.Host.Host; uriBuilder.Path = request.Path.ToString(); uriBuilder.Query = request.QueryString.ToString(); return uriBuilder.Uri.ToString(); } }
5. Add the filter in the startup file
services.AddMvc(opt => { opt.Filters.Add<SlackExceptionFilterAttribute>(); })
6. Create the notificacion service class:
public class SlackNotificationService { private readonly SlackSettings _slackSettings; private readonly IHttpContextAccessor _httpContextAccessor; public SlackNotificationService(IHttpContextAccessor httpContextAccessor, IOptions<Secrets> option) { _slackSettings = option.Value.SlackSettings; _httpContextAccessor = httpContextAccessor; } public async Task NotifyException(string url, string errorType, string errorMessage) { string userAgent = _httpContextAccessor.HttpContext.Request.Headers["User-Agent"].ToString(); var ip = _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress?.ToString() ?? string.Empty; var fields = new List<Field>() { new Field() { Short = true, Title = "User Agent", Value = userAgent }, new Field() { Short = true, Title = "User IP", Value = ip }, new Field() { Short = true, Title = "Message", Value = $"{errorType} - {errorMessage}" }, new Field() { Short = true, Title = "HTTP Method", Value = _httpContextAccessor.HttpContext.Request.Method } }; var slackMessage = new SlackMessage() { text = $"Exception in ...", attachments = new List<Attachment>() { new Attachment() { color = "danger", author_name = "Apply Website", title = url, title_link = url, fields = fields } } }; if ((_slackSettings != null) && (!string.IsNullOrWhiteSpace(_slackSettings.NotifyChannelUrl))) { using (var client = new HttpClient()) { var content = JsonConvert.SerializeObject(slackMessage); var response = await client.PostAsync(new Uri(_slackSettings.NotifyChannelUrl), new StringContent(content)); } } } public class SlackMessage { public List<Attachment> attachments { get; set; } public string text { get; set; } } public class Field { [JsonProperty("short")] public bool Short { get; set; } [JsonProperty("title")] public string Title { get; set; } [JsonProperty("value")] public string Value { get; set; } } public class Attachment { public string author_name; public string title; public string title_link; public string color { get; set; } public List<Field> fields { get; set; } } }
Comentarios
Publicar un comentario