public static async Task <bool> UserRegistrationOrchestration( [OrchestrationTrigger] DurableOrchestrationContext context) { var input = context.GetInput <UserRegistrationInput>(); // 1. Send confirmation email var sendConfirmationEmailInput = new SendConfirmationEmailInput { RegistrationConfirmationURL = $"{input.BaseUri}/emailconfirmation/{input.InstanceId}", Email = input.Email, Name = input.Name }; await context.CallActivityAsync(nameof(SendConfirmationEmailActivity), sendConfirmationEmailInput); // 2. Setup timer and wait for external event to be executed. Whatever comes first continues using (var cts = new CancellationTokenSource()) { var expiredAt = context.CurrentUtcDateTime.Add(TimeSpan.FromSeconds(30)); var customStatus = new UserRegistrationOrchestatorStatus { Text = "Waiting for email confirmation", ExpireAt = expiredAt }; #if DEBUG // only send the confirmation URL back in debug mode customStatus.RegistrationConfirmationURL = sendConfirmationEmailInput.RegistrationConfirmationURL; #endif context.SetCustomStatus(customStatus); var confirmationButtonClicked = context.WaitForExternalEvent <bool>("EmailConfirmationReceived"); var timeout = context.CreateTimer(expiredAt, cts.Token); var winner = await Task.WhenAny(confirmationButtonClicked, timeout); // Cancel the timer if it has not yet been completed if (!timeout.IsCompleted) { cts.Cancel(); } if (winner == confirmationButtonClicked) { // TODO: add here logic to actually create the user in your database context.SetCustomStatus(new UserRegistrationOrchestatorStatus { Text = "Email activation succeeded" }); return(true); } else { context.SetCustomStatus(new UserRegistrationOrchestatorStatus { Text = "Email activation timed out" }); return(false); } } }
public static void SendConfirmationEmailActivity( [ActivityTrigger] SendConfirmationEmailInput input, [SendGrid(ApiKey = "sendGridApiKey")] out SendGridMessage message, TraceWriter log) { message = new SendGridMessage(); message.AddTo(input.Email); message.SetSubject("[Azure Durable Function Demo] - User registration confirmation"); var htmlContent = new StringBuilder(); htmlContent .AppendLine("<html>") .AppendLine($"<head><meta name=\"viewport\" content=\"width=device-width\" /><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" /><title>Email confirmation</title>") .AppendLine("<body>") .AppendLine($"<p>Hello {input.Name}</p>") .AppendLine($"<p>To activate your account open this page: <a href=\"{input.RegistrationConfirmationURL}\">{input.RegistrationConfirmationURL}</a></p>") .AppendLine("</body></html>"); message.AddContent("text/html", htmlContent.ToString()); message.SetFrom(new EmailAddress("*****@*****.**")); log.Info($"Email sent to {input.Email} with confirmation URL {input.RegistrationConfirmationURL}"); }