/// <summary>
        /// Create your proactive message here
        /// </summary>
        /// <returns></returns>
        private BotCallbackHandler CreateCallback(ProactiveMessageRequestBody req)
        {
            return(async(turnContext, token) =>
            {
                try
                {
                    Activity proactiveMessage = turnContext.Activity.CreateReply();;

                    if (req.Attachments != null)
                    {
                        //We want to display multiple attachments as carousel
                        if (req.Attachments.Count > 1)
                        {
                            proactiveMessage = MessageFactory.Carousel(req.Attachments.ToArray()) as Activity;
                        }
                        else
                        {
                            proactiveMessage.Attachments = req.Attachments;
                        }
                    }


                    if (String.IsNullOrEmpty(req.Message))
                    {
                        proactiveMessage.Text = req.Message;
                    }

                    if (req.SuggestedActions != null)
                    {
                        proactiveMessage.SuggestedActions = req.SuggestedActions;
                    }

                    // Send the user a proactive confirmation message.
                    await turnContext.SendActivityAsync(proactiveMessage);
                }
                catch (Exception e)
                {
                    //TODO handle error logging
                    throw e;
                }
            });
        }
        /// <summary>
        /// Every conversation turn for our Echo Bot will call this method.
        /// There are no dialogs used, since it's "single turn" processing, meaning a single
        /// request and response.
        /// </summary>
        /// <param name="turnContext">A <see cref="ITurnContext"/> containing all the data needed
        /// for processing this conversation turn. </param>
        /// <param name="cancellationToken">(Optional) A <see cref="CancellationToken"/> that can be used by other objects
        /// or threads to receive notice of cancellation.</param>
        /// <returns>A <see cref="Task"/> that represents the work queued to execute.</returns>
        /// <seealso cref="BotStateSet"/>
        /// <seealso cref="ConversationState"/>
        /// <seealso cref="IMiddleware"/>
        public async Task OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken = default(CancellationToken))
        {
            Reference = turnContext.Activity.GetConversationReference();

            // Handle Message activity type, which is the main activity type for shown within a conversational interface
            // Message activities may contain text, speech, interactive cards, and binary or unknown attachments.
            // see https://aka.ms/about-bot-activity-message to learn more about the message and other activity types
            if (turnContext.Activity.Type == ActivityTypes.Message)
            {
                //This should be sent out from your backend responsbile for generating proactive message requests
                //Bellow you can find examples of supported content for proactive message by this sample

                if (turnContext.Activity.Text.ToLower().StartsWith("proactive"))
                {
                    var card = new HeroCard
                    {
                        Text    = "You can upload an image or select one of the following choices",
                        Buttons = new List <CardAction>()
                        {
                            new CardAction(ActionTypes.ImBack, title: "1. Inline Attachment", value: "1"),
                            new CardAction(ActionTypes.ImBack, title: "2. Internet Attachment", value: "2"),
                            new CardAction(ActionTypes.ImBack, title: "3. Uploaded Attachment", value: "3"),
                        }
                    };

                    var sa = new SuggestedActions()
                    {
                        Actions = new List <CardAction>()
                        {
                            new CardAction()
                            {
                                Title = "Red", Type = ActionTypes.ImBack, Value = "Red"
                            },
                            new CardAction()
                            {
                                Title = "Yellow", Type = ActionTypes.ImBack, Value = "Yellow"
                            },
                            new CardAction()
                            {
                                Title = "Blue", Type = ActionTypes.ImBack, Value = "Blue"
                            },
                        }
                    };

                    var message = new ProactiveMessageRequestBody()
                    {
                        ConversationReference = await _accessors.ConversationReferenceState.GetAsync(turnContext),
                        Message     = "Hello",
                        Attachments = new List <Attachment>()
                        {
                            card.ToAttachment(), card.ToAttachment()
                        },
                        SuggestedActions = sa
                    };

                    //SET this based on the adress of your proactive endpoint
                    var localProactiveEndpoint = "http://localhost:3978/api/proactive";

                    await turnContext.SendActivityAsync("Proactive message incoming...");

                    // send the conversation reference and message to the bot's proactive endpoint
                    var messageContent = JsonConvert.SerializeObject(message);

                    //In production this would be implemented on the side of backend service, which initiates proactive messages
                    using (var client = new HttpClient())
                    {
                        var buffer      = System.Text.Encoding.UTF8.GetBytes(messageContent);
                        var byteContent = new ByteArrayContent(buffer);
                        byteContent.Headers.ContentType = new MediaTypeHeaderValue("application/json");

                        var result = await client.PostAsync(localProactiveEndpoint, byteContent);
                    }
                }
                else
                {
                    // Get the conversation state from the turn context.
                    var state = await _accessors.CounterState.GetAsync(turnContext, () => new CounterState());

                    // Bump the turn count for this conversation.
                    state.TurnCount++;

                    // Set the property using the accessor.
                    await _accessors.CounterState.SetAsync(turnContext, state);

                    // Save the new turn count into the conversation state.
                    await _accessors.ConversationState.SaveChangesAsync(turnContext);

                    // Echo back to the user whatever they typed.
                    var responseMessage = $"Turn {state.TurnCount}: You sent '{turnContext.Activity.Text}'\n";
                    await turnContext.SendActivityAsync(responseMessage);
                }
            }
            else
            {
                if (turnContext.Activity.MembersAdded.Count > 0)
                {
                    foreach (var m in turnContext.Activity.MembersAdded)
                    {
                        if (m.Id != turnContext.Activity.Recipient.Id)
                        {
                            // store the conversation reference for the newly added user
                            // in production scenario you want to store conversation reference in an external store e.g. Cosmos DB, Table Storage etc.
                            await _accessors.ConversationReferenceState.SetAsync(turnContext, turnContext.Activity.GetConversationReference());

                            await _accessors.ConversationState.SaveChangesAsync(turnContext);
                        }
                    }

                    await turnContext.SendActivityAsync($"{turnContext.Activity.Type} event detected");
                }
            }
        }