Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Webhook: 503 error on fetching the signed events public key #489

Closed
gopala000 opened this issue Apr 19, 2023 · 3 comments
Closed

Webhook: 503 error on fetching the signed events public key #489

gopala000 opened this issue Apr 19, 2023 · 3 comments
Assignees
Labels
question Someone is asking a question

Comments

@gopala000
Copy link

gopala000 commented Apr 19, 2023

I'm using StrongGrid 0.98.0. I get 503 error on calling WebhookSettings.GetSignedEventsPublicKeyAsync() in production environment. But it works fine in test environment. On looking at the settings in SendGrid console both environments are setup exactly the same. Any thoughts on what could be the issue?

Exception while executing function: Functions.SendGridCallbackFunction Result: Failure
Exception: System.AggregateException: One or more errors occurred. (503: Service Unavailable)
 ---> StrongGrid.Utilities.SendGridException: 503: Service Unavailable
   at StrongGrid.Utilities.SendGridErrorHandler.OnResponse(IResponse response, Boolean httpErrorAsException)
   at Pathoschild.Http.Client.Internal.Request.Execute()
   at StrongGrid.Internal.AsObject[T](IRequest request, String propertyName, Boolean throwIfPropertyIsMissing, JsonSerializerOptions options)
   at SecureSave.Jobs.WebHooks.SendGridCallbackFunction.Run(HttpRequestData req, FunctionContext executionContext) in D:\a\1\s\SecureSave.Jobs\WebHooks\SendGridCallbackFunction.cs:line 51
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionInvoker`2.<>c.<InvokeAsync>b__6_0(Task`1 t) in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionInvoker.cs:line 32
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__273_0(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionExecutor.ExecuteAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionExecutor.cs:line 45
   at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 16
   at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request, WorkerOptions workerOptions) in D:\a\_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 84
Stack:    at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionInvoker`2.<>c.<InvokeAsync>b__6_0(Task`1 t) in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionInvoker.cs:line 32
   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__273_0(Object obj)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at Microsoft.Azure.Functions.Worker.Invocation.DefaultFunctionExecutor.ExecuteAsync(FunctionContext context) in D:\a\_work\1\s\src\DotNetWorker.Core\Invocation\DefaultFunctionExecutor.cs:line 45
   at Microsoft.Azure.Functions.Worker.OutputBindings.OutputBindingsMiddleware.Invoke(FunctionContext context, FunctionExecutionDelegate next) in D:\a\_work\1\s\src\DotNetWorker.Core\OutputBindings\OutputBindingsMiddleware.cs:line 16
   at Microsoft.Azure.Functions.Worker.Handlers.InvocationHandler.InvokeAsync(InvocationRequest request, WorkerOptions workerOptions) in D:\a\_work\1\s\src\DotNetWorker.Grpc\Handlers\InvocationHandler.cs:line 84 

Code snippet:

            string logMessage = string.Empty;

            // Get your public key
            var strongGridClient = new StrongGrid.Client(_emailSettings.SendGridKey);
            var publicKey = await strongGridClient.WebhookSettings.GetSignedEventsPublicKeyAsync().ConfigureAwait(false);

            // Get the signature and the timestamp from the request headers
            // SIGNATURE_HEADER_NAME is a convenient constant provided so you don't have to remember the name of the header
            req.Headers.TryGetValues(WebhookParser.SIGNATURE_HEADER_NAME, out IEnumerable<string> signatures);
            var signature = signatures?.FirstOrDefault();

            // TIMESTAMP_HEADER_NAME is a convenient constant provided so you don't have to remember the name of the header
            req.Headers.TryGetValues(WebhookParser.TIMESTAMP_HEADER_NAME, out IEnumerable<string> timestamps);
            var timestamp = timestamps?.FirstOrDefault();

            // Parse the events. The signature will be automatically validated and a security exception thrown if unable to validate
            try
            {
                var parser = new WebhookParser();
                var events = await parser.ParseSignedEventsWebhookAsync(req.Body, publicKey, signature, timestamp).ConfigureAwait(false);

                // ... do something with the events...
                foreach(var e in events.OrderBy(r => r.Timestamp).ToArray())
                {
                    // My code

                }
            }
@Jericho Jericho added the question Someone is asking a question label Apr 20, 2023
@Jericho Jericho self-assigned this Apr 20, 2023
@Jericho
Copy link
Owner

Jericho commented Apr 20, 2023

HTTP errors in the 500 range indicate that the server can't complete the request because it encountered a problem. More specifically, 503 Service Unavailable error means that a website's server is not available right now. Most of the time, it occurs because the server is too busy or maintenance is being performed on it.

So, I encourage you to contact SendGrid directly to report this problem to them but keep us in the loop, let us know how they resolve it.

@Jericho
Copy link
Owner

Jericho commented Apr 27, 2023

@gopala000 I haven't heard back from you so I'm going to assume you were able to resolve the issue.

@Jericho Jericho closed this as completed Apr 27, 2023
@gopala000
Copy link
Author

My key was generated couple of years ago. SendGrid said permission may not be correctly set for webhook and asked to regenerate the key and try. I'll update if the issue persists. Thanks for your help!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Someone is asking a question
Projects
None yet
Development

No branches or pull requests

2 participants