Ejemplo n.º 1
0
        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);
                }
            }
        }
Ejemplo n.º 2
0
        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}");
        }