public async Task <List <string> > RunOrchestrator(
            [OrchestrationTrigger] IDurableOrchestrationContext context)
        {
            using var disposable = context.PushLoggerProperties();
            var phone   = context.GetInput <string>();
            var outputs = new List <string>();

            var proxy =
                context.CreateEntityProxy <INotifySubscriptionEntity>(NotifySubscriptionEntity.BuildId(phone, EventNameApproved));

            try
            {
                await proxy.Subscribe(context.InstanceId);

                await context.CallActivityWithRetryAsync(nameof(SendMessageActivity), _retryOptions, phone);                 // might fail, better include retry mechanism

                var approvalNotification = await proxy.GetLatestNotification()                                               // get latest, maybe already approved (optional)
                                           ?? await WaitForUserAction(context, _timeToWait, EventNameApproved);              // wait for user approval

                outputs.Add(approvalNotification != null
                                                                                        ? $"We have approval from {phone} at {approvalNotification.Timestamp}"
                                                                                        : $"No approval from {phone} after waiting {_timeToWait}");
            }
            finally
            {
                await proxy.Unsubscribe(context.InstanceId);
            }
            return(outputs);
        }
        public async Task <HttpResponseMessage> ReceiveMessage(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "ReceiveMessage/{phone}/{message}")] HttpRequestMessage req,
            string phone, string message,
            [DurableClient] IDurableEntityClient entityClient,               // need the durable entity client
            [DurableClient] IDurableOrchestrationClient orchestrationClient) // and the Orchestration client
        {
            if (!message.Equals("APPROVE", StringComparison.InvariantCultureIgnoreCase) &&
                !message.Equals("REJECT", StringComparison.InvariantCultureIgnoreCase))
            {
                return(new HttpResponseMessage(HttpStatusCode.BadRequest));
            }

            var notifyPayload = new NotifyPayload()
            {
                Phone = phone, EventName = message.ToUpperInvariant(), Timestamp = TimeService.UtcNow
            };

            var notifySubscriptionEntityId = NotifySubscriptionEntity.BuildId(phone, notifyPayload.EventName);
            var entity = await entityClient.ReadEntityStateAsync <NotifySubscriptionEntity>(notifySubscriptionEntityId);

            await entityClient.SignalEntityAsync(notifySubscriptionEntityId, nameof(NotifySubscriptionEntity.RegisterNotification),
                                                 notifyPayload);                                    // send a signal to the entity

            if (entity.EntityExists && entity.EntityState.InstancesToNotify.Length > 0)             // we have live subscribers
            {
                foreach (var instanceId in entity.EntityState.InstancesToNotify)
                {
                    await orchestrationClient.RaiseEventAsync(instanceId, notifyPayload.EventName, notifyPayload);                     // notify all subscribers
                }
            }
            else
            {
                _log.Trace(LogEventLevel.Verbose, message: "No subscribed instances to notify");
            }


            return(new HttpResponseMessage(HttpStatusCode.OK));
        }