public async Task StartAsync(IDialogContext context)
        {
            Logger.Info("StartAsync...");
            var incoming = context.Activity as Activity;
            var jsonText = JsonConvert.SerializeObject(incoming.ChannelData);

            Logger.Info($"JsonText={jsonText}");
            var channelData = JsonConvert.DeserializeObject <OCSBot.Shared.Models.DirectLineChannelData>(jsonText);

            Logger.Info($"ChannelData.DirectLineBotID={channelData.DirectLineBotID}");
            var storage           = new AgentStatusStorage(ConfigurationHelper.GetString("BotStatusDBConnectionString"));
            var localConversation = (await storage.FindMyConversationActivityAsync(channelData.UserID)).FirstOrDefault();

            Logger.Info($"localConversation={localConversation}");

            var resumptionCookie = UrlToken.Decode <ResumptionCookie>(localConversation.LocalActivity);
            var localActivity    = resumptionCookie.GetMessage();
            var message          = ((Activity)context.Activity).Text.Replace("reply:", "");

            message = $"[{incoming.From.Name}]{message}";
            var reply = localActivity.CreateReply(message);

            Logger.Info($"reply={JsonConvert.SerializeObject(reply)}");
            var localConnector = new ConnectorClient(new Uri(localActivity.ServiceUrl),
                                                     new MicrosoftAppCredentials(
                                                         ConfigurationHelper.GetString("MicrosoftAppId"),
                                                         ConfigurationHelper.GetString("MicrosoftAppPassword")),
                                                     true);

            Microsoft.Bot.Connector.Conversations localConversations = new Microsoft.Bot.Connector.Conversations(localConnector);
            localConversations.ReplyToActivity(reply);
            Logger.Info("Done");
        }
Beispiel #2
0
        private async Task <Microsoft.Bot.Connector.DirectLine.Activity> PostToAgentBotAsync2(Microsoft.Bot.Connector.DirectLine.Activity activityFromUser)
        {
            var directLineSecret = Configuration.ConfigurationHelper.GetString("AgentBot_DirectLine_Secret");
            var agentStatusDB    = Configuration.ConfigurationHelper.GetString("BotStatusDBConnectionString");
            var agentStorage     = new AgentStatusStorage(agentStatusDB);
            var agent            = await agentStorage.QueryAgentStatusAsync(activityFromUser.Recipient.Id);

            using (var client = new ConnectorClient(new Uri("https://smba.trafficmanager.net/apis")))
            {
                var recipient = new Microsoft.Bot.Connector.ChannelAccount(/*agent.AgentIdInChannel*/ "29:1Gk7vrlkdaMoN6fCtrycxkJfHcPS8zvi49Gukq4XuZAo");
                var from      = new Microsoft.Bot.Connector.ChannelAccount("");
                //var conversatoin = await client.Conversations.CreateDirectConversationAsync(from, recipient);
                var message = new Microsoft.Bot.Connector.Activity
                {
                    Text         = activityFromUser.Text,
                    From         = from,
                    Conversation = new Microsoft.Bot.Connector.ConversationAccount
                    {
                        Id = agent.ConversationId
                    },
                    Recipient = recipient
                };
                var response = await client.Conversations.SendToConversationAsync(message);

                return(null);
            }
        }
        private async Task PostToOCSUser(IDialogContext context, Microsoft.Bot.Connector.Activity activity)
        {
            Logger.Info($"Agent [{activity.From.Id}] is replying");
            var         storage = new AgentStatusStorage(ConfigurationHelper.GetString("BotStatusDBConnectionString"));
            AgentStatus agent   = await storage.QueryAgentStatusAsync(activity.From.Id);

            ConversationRecord conv = (await storage.FindMyConversationActivityAsync(agent.Id)).FirstOrDefault();

            var uri = new Uri("https://directline.botframework.com");

            Logger.Info($"PostToOCSUser::{agent.Id}/{agent.Name}");
            DirectLineClientCredentials creds = new DirectLineClientCredentials(ConfigurationHelper.GetString("OCSBot_DirectLine_Secret"));   //lot into the bot framework

            Microsoft.Bot.Connector.DirectLine.DirectLineClient client = new Microsoft.Bot.Connector.DirectLine.DirectLineClient(uri, creds); //connect the client
            var conversation           = client.Conversations.StartConversation();
            DirectLineChannelData data = new DirectLineChannelData()
            {
                UserID          = conv.RemoteUserId,
                UserName        = conv.RemoteUserName,
                DirectLineBotID = conv.RemoteBotId
            };

            client.Conversations.PostActivity(conversation.ConversationId,
                                              new Microsoft.Bot.Connector.DirectLine.Activity
            {
                From = new Microsoft.Bot.Connector.DirectLine.ChannelAccount
                {
                    Id   = agent.Id,
                    Name = $"{agent.Name}@agent"
                },
                Type        = Microsoft.Bot.Connector.ActivityTypes.Message,
                Text        = activity.Text,
                ChannelData = data
            });

            //var remoteConnector = new ConnectorClient(
            //                            baseUri: new Uri(remoteActivity.ServiceUrl),
            //                            credentials: new MicrosoftAppCredentials(
            //                                            appId: ConfigurationHelper.GetString("MicrosoftAppId"),
            //                                            password: ConfigurationHelper.GetString("MicrosoftAppPassword")
            //                                        ),
            //                            addJwtTokenRefresher: true
            //                            );
            //Logger.Info($"remoteActivity={JsonConvert.SerializeObject(remoteActivity)}");
            //remoteConnector.Conversations.SendToConversation(reply);

            ////reply.From.Name += activity.From.Name + "@agent";
            //Logger.Info($"reply created:{JsonConvert.SerializeObject(reply)}");
            //remoteConnector.Conversations.ReplyToActivity(reply);
            //Logger.Info($"replied");
        }
        public async Task DispatchAsync(IDialogContext context, IAwaitable <Microsoft.Bot.Connector.IMessageActivity> item)
        {
            Microsoft.Bot.Connector.Activity activity = (Microsoft.Bot.Connector.Activity) await item;
            Logger.Info($"message received from {activity.From.Name}/{activity.From.Id} : {JsonConvert.SerializeObject(activity)}");
            Logger.Info($"message received to {activity.Recipient.Name}/{activity.Recipient.Id}");

            var storage = new AgentStatusStorage(
                ConfigurationHelper.GetString("BotStatusDBConnectionString"));

            if (activity.From.Name.EndsWith("@ocsuser"))
            {
                //Messages from OCS User, when message from OCS User sent to this method, it has to be coming from DirectLine
                AgentStatus agent = null;
                //retrieve ChannelData which includes channelId for our conversation
                //TODO:figure out a way that simplier
                JObject o  = (JObject)activity.ChannelData;
                var     os = JsonConvert.SerializeObject(o);
                DirectLineChannelData channelData = JsonConvert.DeserializeObject <DirectLineChannelData>(os);

                Logger.Info($"ChannelData = {channelData}");
                //ConversationStatus conversation = null;
                Logger.Info($"RoundTrip = {channelData.RoundTrip}");
                //first message send to agent, find an available agent
                //TODO:the agent has been selected in OCS Bot, need to make it sync
                //      Instead of selecting another one here...
                agent = (await storage.FindAvailableAgentsAsync()).FirstOrDefault();
                var convRecord = (await storage.FindConversationActivityAsync(a => a.UserID == agent.Id)).FirstOrDefault();
                convRecord.RemoteConversationID = channelData.ConversationId;
                convRecord.RemoteBotId          = activity.From.Id;//remote user id actually...
                convRecord.RemoteActivity       = UrlToken.Encode <ResumptionCookie>(
                    new ResumptionCookie((Microsoft.Bot.Connector.Activity)activity));
                convRecord.RemoteUserId   = channelData.UserID;
                convRecord.RemoteUserName = channelData.UserName;
                await storage.UpdateConversationActivityAsync(convRecord);

                Logger.Info($"agent:{agent}");
                if (!agent.IsLoggedIn)
                {
                    //Agent somehow is occupied (logout?)
                    Logger.Info("Agent is occupied");
                    var             reply     = activity.CreateReply($"Agent is occupied");
                    ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
                    await connector.Conversations.ReplyToActivityAsync(reply);
                }
                else
                {
                    //Agnet is available to answer questions, send message to agent
                    Logger.Info("Sending to conversation...");

                    //TODO:Need to check if current agent is this user
                    //agent.IsOccupied = true;
                    //await storage.UpdateAgentStatusAsync(agent);

                    //First retrieve last conversaion if exists
                    //resumptionCookie = UrlToken.Decode<ResumptionCookie>(conversation.AgentResumptionCookie);
                    var localResumptionCookie = UrlToken.Decode <ResumptionCookie>(convRecord.LocalActivity);
                    Logger.Info($"AgentBot::LocalResumptionCookie:{localResumptionCookie}");
                    var localActivity  = localResumptionCookie.GetMessage();
                    var localReply     = localActivity.CreateReply($"[{activity.From.Name}]{activity.Text}");
                    var localConnector = new ConnectorClient(new Uri(localActivity.ServiceUrl),
                                                             new MicrosoftAppCredentials(
                                                                 ConfigurationHelper.GetString("MicrosoftAppId"),
                                                                 ConfigurationHelper.GetString("MicrosoftAppPassword")),
                                                             true);

                    Microsoft.Bot.Connector.Conversations localConversation = new Microsoft.Bot.Connector.Conversations(localConnector);
                    localConversation.ReplyToActivity(localReply);
                    Logger.Info("done");


                    return;
                }
            }
            else
            {
                resumptionCookie = new ResumptionCookie(await item);
                await MessageReceivedAsync(context, item);
            }
        }
        public async Task <bool> HumanProcess(IDialogContext context)
        {
            //TODO:end human investigating process
            var statusDB = Configuration.ConfigurationHelper.GetString("BotStatusDBConnectionString");
            var db       = new AgentStatusStorage(statusDB);
            var agents   = await db.FindAvailableAgentsAsync();

            var agent = agents.FirstOrDefault();

            Logger.Info($"Human Investigating:{IsHumanInvestigating}");

            if (agent != null)
            {
                //from bot to agent
                //find agent's conversation record
                var agentConversation   = (await db.FindMyConversationActivityAsync(agent.Id)).FirstOrDefault();
                var localConversation   = (await db.FindMyConversationActivityAsync(context.Activity.From.Id)).FirstOrDefault();
                ResumptionCookie cookie = new ResumptionCookie((Microsoft.Bot.Connector.IMessageActivity)context.Activity);
                if (localConversation == null)
                {
                    localConversation = new ConversationRecord();
                }
                localConversation.UserID              = context.Activity.From.Id;
                localConversation.LocalUserName       = context.Activity.From.Name;
                localConversation.LocalBotId          = context.Activity.Recipient.Id;
                localConversation.LocalChannelID      = context.Activity.ChannelId;
                localConversation.LocalConversationID = context.Activity.Conversation.Id;
                localConversation.LocalActivity       = UrlToken.Encode <ResumptionCookie>(cookie);

                var resp2 = await PostToAgentBotAsync(new Microsoft.Bot.Connector.DirectLine.Activity()
                {
                    Type = Microsoft.Bot.Connector.DirectLine.ActivityTypes.Message,
                    From = new Microsoft.Bot.Connector.DirectLine.ChannelAccount(
                        /*id: agentConversation.LocalBotId,*/
                        id: context.Activity.From.Id,
                        name: context.Activity.From.Name
                        ),
                    Recipient = new Microsoft.Bot.Connector.DirectLine.ChannelAccount(
                        id: agentConversation.UserID),
                    ChannelId = agent.ChannelId,
                    Text      = $"{context.Activity.AsMessageActivity().Text}"
                });

                await db.UpdateConversationActivityAsync(localConversation);


                SetHumanInvestigating(true, context.Activity.From.Id, context.Activity.From.Name);

                return(true);
            }
            else
            {
                var connector = new ConnectorClient(new Uri(context.Activity.ServiceUrl));
                connector.Conversations.ReplyToActivity(context.Activity.Conversation.Id,
                                                        context.Activity.Id,
                                                        new Microsoft.Bot.Connector.Activity
                {
                    Type      = Microsoft.Bot.Connector.DirectLine.ActivityTypes.Message,
                    Text      = Messages.BOT_NO_AGENTS_AVAILABLE,
                    From      = context.Activity.Recipient,
                    Recipient = context.Activity.From,
                    ChannelId = context.Activity.ChannelId
                });
                SetHumanInvestigating(false, null, null);
                return(false);
            }
        }
        private async Task <Microsoft.Bot.Connector.DirectLine.Activity> PostToAgentBotAsync(Microsoft.Bot.Connector.DirectLine.Activity activityFromUser)
        {
            var directLineSecret = Configuration.ConfigurationHelper.GetString("AgentBot_DirectLine_Secret");
            var agentStatusDB    = Configuration.ConfigurationHelper.GetString("BotStatusDBConnectionString");
            var dc           = new DirectLineClient(directLineSecret);
            var agentStorage = new AgentStatusStorage(agentStatusDB);
            var agent        = await agentStorage.QueryAgentStatusAsync(activityFromUser.Recipient.Id);

            ConversationStatus convStatus = null;

            //var agentConversations = await agentStorage.QueryConversationStatusAsync(agent.Id);

            try
            {
                var uri = new Uri("https://directline.botframework.com");
                DirectLineClientCredentials creds  = new DirectLineClientCredentials(directLineSecret);                                //lot into the bot framework
                DirectLineClient            client = new DirectLineClient(uri, creds);                                                 //connect the client
                Microsoft.Bot.Connector.DirectLine.Conversations convs = new Microsoft.Bot.Connector.DirectLine.Conversations(client); //get the list of conversations belonging to the bot? Or does this start a new collection of conversations?

                Microsoft.Bot.Connector.DirectLine.Conversation conversation = null;
                if (string.IsNullOrEmpty(_agentConversationId))
                {
                    conversation         = dc.Conversations.StartConversation();
                    _agentConversationId = conversation.ConversationId;
                }
                else
                {
                    conversation = new Microsoft.Bot.Connector.DirectLine.Conversation()
                    {
                        ConversationId = _agentConversationId,
                    };
                }
                Logger.Info($"activityFromUser - From.Name:{activityFromUser.From.Name} - From.Id:{activityFromUser.From.Id}");
                Logger.Info($"activityFromUser - Recipient.Name:{activityFromUser.Recipient.Name} - Recipient.Id:{activityFromUser.Recipient.Name}");
                var toAgent = new Microsoft.Bot.Connector.DirectLine.Activity
                {
                    Type = Microsoft.Bot.Connector.DirectLine.ActivityTypes.Message,
                    Text = activityFromUser.Text,
                    From = new Microsoft.Bot.Connector.DirectLine.ChannelAccount
                    {
                        Id   = activityFromUser.From.Id,/*activityFromUser.From.Id,*/
                        Name = $"{activityFromUser.From.Name}@ocsuser"
                    },
                    Recipient   = activityFromUser.Recipient,
                    ChannelId   = agent.ChannelId,
                    ChannelData = new DirectLineChannelData
                    {
                        RoundTrip      = 0,
                        ConversationId = _agentConversationId,
                        UserID         = activityFromUser.From.Id,
                        UserName       = activityFromUser.From.Name
                    }
                };

                var resp = await dc.Conversations.PostActivityAsync(
                    conversation.ConversationId,
                    toAgent);

                Logger.Info($"OCSBot::Dialog:PostToAgent() - {JsonConvert.SerializeObject(toAgent)}");
                //convStatus = (await agentStorage.QueryConversationStatusAsync(agent.Id)).OrderByDescending(o => o.Timestamp).FirstOrDefault();
                //convStatus.OCSDirectlineConversationId = conversation.ConversationId;
                //convStatus.OCSEndUserId = activityFromUser.From.Id;
                //convStatus.OCSEndUserName = activityFromUser.From.Name;
                //convStatus.OCSBotName = activityFromUser.Recipient.Name;
                //convStatus.OCSBotId = activityFromUser.Recipient.Id;
                //await agentStorage.UpdateConversationStatusAsync(convStatus);
                return(null);
            }
            catch (Exception exp)
            {
                Logger.Info($"OCSBot::PostToAgent() - Exception while posting to Agent:{exp.Message}");
                throw;
            }
        }