// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
using Microsoft.Bot.Connector.DirectLine;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
namespace Microsoft.PowerVirtualAgents.Samples.BotConnectorApp
{
public class BotConnectorApp
{
private static string _watermark = null;
private const int _botReplyWaitIntervalInMilSec = 3000;
private const string _botDisplayName = "Bot";
private const string _userDisplayName = "You";
private static string s_endConversationMessage;
private static BotService s_botService;
///
/// Start BotConnectorApp console
/// See for information on how to update bot settings in App.config
/// Takes user input and output bot reply, until user types EndConversationMessage
///
public static void Main(string[] args)
{
var botId = ConfigurationManager.AppSettings["BotId"] ?? string.Empty;
var tenantId = ConfigurationManager.AppSettings["BotTenantId"] ?? string.Empty;
var botTokenEndpoint = ConfigurationManager.AppSettings["BotTokenEndpoint"] ?? string.Empty;
var botName = ConfigurationManager.AppSettings["BotName"] ?? string.Empty;
s_endConversationMessage = ConfigurationManager.AppSettings["EndConversationMessage"] ?? "quit";
if (string.IsNullOrEmpty(botId) || string.IsNullOrEmpty(tenantId) || string.IsNullOrEmpty(botTokenEndpoint) || string.IsNullOrEmpty(botName))
{
Console.WriteLine("Update App.config and start again.");
Console.WriteLine("Press any key to exit");
Console.Read();
Environment.Exit(0);
}
s_botService = new BotService()
{
BotName = botName,
BotId = botId,
TenantId = tenantId,
TokenEndPoint = botTokenEndpoint,
};
StartConversation().Wait();
}
private static async Task StartConversation()
{
var token = await s_botService.GetTokenAsync();
using (var directLineClient = new DirectLineClient(token))
{
var conversation = await directLineClient.Conversations.StartConversationAsync();
var conversationtId = conversation.ConversationId;
string inputMessage;
while (!string.Equals(inputMessage = GetUserInput(), s_endConversationMessage, StringComparison.OrdinalIgnoreCase))
{
// Send user message using directlineClient
await directLineClient.Conversations.PostActivityAsync(conversationtId, new Activity()
{
Type = ActivityTypes.Message,
From = new ChannelAccount { Id = "userId", Name = "userName" },
Text = inputMessage,
TextFormat = "plain",
Locale = "en-Us",
});
Console.WriteLine($"{_botDisplayName}:");
Thread.Sleep(_botReplyWaitIntervalInMilSec);
// Get bot response using directlinClient
List responses = await GetBotResponseActivitiesAsync(directLineClient, conversationtId);
BotReply(responses);
}
}
}
///
/// Prompt for user input
///
/// user message as string
private static string GetUserInput()
{
Console.WriteLine($"{_userDisplayName}:");
var inputMessage = Console.ReadLine();
return inputMessage;
}
///
/// Use directlineClient to get bot response
///
/// List of DirectLine activities
/// directline client
/// current conversation ID
/// name of bot to connect to
private static async Task> GetBotResponseActivitiesAsync(DirectLineClient directLineClient, string conversationtId)
{
ActivitySet response = null;
List result = new List();
do
{
response = await directLineClient.Conversations.GetActivitiesAsync(conversationtId, _watermark);
if (response == null)
{
// response can be null if directLineClient token expires
Console.WriteLine("Conversation expired. Press any key to exit.");
Console.Read();
directLineClient.Dispose();
Environment.Exit(0);
}
_watermark = response?.Watermark;
result = response?.Activities?.Where(x =>
x.Type == ActivityTypes.Message &&
string.Equals(x.From.Name, s_botService.BotName, StringComparison.Ordinal)).ToList();
if (result != null && result.Any())
{
return result;
}
Thread.Sleep(1000);
} while (response != null && response.Activities.Any());
return new List();
}
///
/// Print bot reply to console
///
/// List of DirectLine activities
///
private static void BotReply(List responses)
{
responses?.ForEach(responseActivity =>
{
// responseActivity is standard Microsoft.Bot.Connector.DirectLine.Activity
// See https://github.com/Microsoft/botframework-sdk/blob/master/specs/botframework-activity/botframework-activity.md for reference
// Showing examples of Text & SuggestedActions in response payload
if (!string.IsNullOrEmpty(responseActivity.Text))
{
Console.WriteLine(string.Join(Environment.NewLine, responseActivity.Text));
}
if (responseActivity.SuggestedActions != null && responseActivity.SuggestedActions.Actions != null)
{
var options = responseActivity.SuggestedActions?.Actions?.Select(a => a.Title).ToList();
Console.WriteLine($"\t{string.Join(" | ", options)}");
}
});
}
}
}