public async Task <bool> UpdateConversationActivityAsync(ConversationRecord record)
        {
            var tableClient = StorageAccount.CreateCloudTableClient();
            var tableRef    = tableClient.GetTableReference(CONVERSATION_TABLE_NAME);
            await tableRef.CreateIfNotExistsAsync();

            var blobClient    = StorageAccount.CreateCloudBlobClient();
            var blobContainer = blobClient.GetContainerReference(COVNERSATION_LOCK_NAME);

            blobContainer.CreateIfNotExists();

            var lockBlob = blobContainer.GetBlockBlobReference($"{record.UserID}.lock");

            if (!lockBlob.Exists())
            {
                lockBlob.UploadText("");
            }
            try
            {
                var leaseId = lockBlob.AcquireLease(
                    TimeSpan.FromSeconds(15),
                    null);
                try
                {
                    var tableOperation = TableOperation.InsertOrMerge(record);
                    var result         = tableRef.Execute(tableOperation);

                    var newRecord = tableRef.Execute(TableOperation.Retrieve <DynamicTableEntity>
                                                     (
                                                         record.PartitionKey,
                                                         record.RowKey
                                                     ));

                    return(true);
                }
                catch (Exception exp)
                {
                    throw;
                }
                finally
                {
                    lockBlob.ReleaseLease(AccessCondition.GenerateLeaseCondition(leaseId));
                }
            }
            catch (Exception exp)
            {
                throw;
            }
            finally
            {
            }
        }
        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 PostAcceptStatusEventAsync()
        {
            using (var readStream = new StreamReader(Request.Body, Encoding.UTF8))
            {
                var body = await readStream.ReadToEndAsync();

                if (!Authenticate(Request, body))
                {
                    return;
                }

                try
                {
                    var wbhookData = JsonConvert.DeserializeObject <Models.AcceptStatusEvent.WebhookData>(body);
                    foreach (var change in wbhookData.body.changes)
                    {
                        if (change?.originatorMetadata?.role == "ASSIGNED_AGENT")
                        {
                            // Agent has accepted the conversation
                            var convId = change?.conversationId;
                            ConversationRecord conversationRec;
                            if (_conversationMap.ConversationRecords.TryGetValue(convId, out conversationRec))
                            {
                                if (conversationRec.IsAcknowledged || conversationRec.IsClosed)
                                {
                                    // Already acked this one
                                    break;
                                }

                                var newConversationRec = new ConversationRecord
                                {
                                    ConversationReference = conversationRec.ConversationReference,
                                    IsClosed       = conversationRec.IsClosed,
                                    IsAcknowledged = true
                                };

                                // Update atomically -- only one will succeed
                                if (_conversationMap.ConversationRecords.TryUpdate(convId, newConversationRec, conversationRec))
                                {
                                    var evnt = EventFactory.CreateHandoffStatus(newConversationRec.ConversationReference.Conversation, "accepted") as Activity;
                                    await _adapter.ProcessActivityAsync(evnt, _creds.MsAppId, newConversationRec.ConversationReference, _bot.OnTurnAsync, default(CancellationToken));
                                }
                            }
                        }
                    }
                }
                catch { }
            }
            Response.StatusCode = (int)HttpStatusCode.OK;
        }
        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);
            }
        }
Example #5
0
 public async Task <bool> UpdateConversationActivityAsync(ConversationRecord record)
 {
     return(await ConvManager.UpdateConversationActivityAsync(record));
 }