-
Notifications
You must be signed in to change notification settings - Fork 66
/
Copy pathHandoffMiddleware.cs
192 lines (162 loc) · 7.54 KB
/
HandoffMiddleware.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
using IntermediatorBotSample.CommandHandling;
using IntermediatorBotSample.ConversationHistory;
using IntermediatorBotSample.MessageRouting;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Connector.Authentication;
using Microsoft.Bot.Schema;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Underscore.Bot.MessageRouting;
using Underscore.Bot.MessageRouting.DataStore;
using Underscore.Bot.MessageRouting.DataStore.Azure;
using Underscore.Bot.MessageRouting.DataStore.Local;
using Underscore.Bot.MessageRouting.Results;
namespace IntermediatorBotSample.Middleware
{
public class HandoffMiddleware : IMiddleware
{
private const string KeyAzureTableStorageConnectionString = "AzureTableStorageConnectionString";
private const string KeyRejectConnectionRequestIfNoAggregationChannel = "RejectConnectionRequestIfNoAggregationChannel";
private const string KeyPermittedAggregationChannels = "PermittedAggregationChannels";
private const string KeyNoDirectConversationsWithChannels = "NoDirectConversationsWithChannels";
public IConfiguration Configuration
{
get;
protected set;
}
public MessageRouter MessageRouter
{
get;
protected set;
}
public MessageRouterResultHandler MessageRouterResultHandler
{
get;
protected set;
}
public CommandHandler CommandHandler
{
get;
protected set;
}
public MessageLogs MessageLogs
{
get;
protected set;
}
public HandoffMiddleware(IConfiguration configuration)
{
Configuration = configuration;
string connectionString = Configuration[KeyAzureTableStorageConnectionString];
IRoutingDataStore routingDataStore = null;
if (string.IsNullOrEmpty(connectionString))
{
System.Diagnostics.Debug.WriteLine($"WARNING!!! No connection string found - using {nameof(InMemoryRoutingDataStore)}");
routingDataStore = new InMemoryRoutingDataStore();
}
else
{
System.Diagnostics.Debug.WriteLine($"Found a connection string - using {nameof(AzureTableRoutingDataStore)}");
routingDataStore = new AzureTableRoutingDataStore(connectionString);
}
MessageRouter = new MessageRouter(
routingDataStore,
new MicrosoftAppCredentials(Configuration["MicrosoftAppId"], Configuration["MicrosoftAppPassword"]));
//MessageRouter.Logger = new Logging.AggregationChannelLogger(MessageRouter);
MessageRouterResultHandler = new MessageRouterResultHandler(MessageRouter);
ConnectionRequestHandler connectionRequestHandler =
new ConnectionRequestHandler(GetChannelList(KeyNoDirectConversationsWithChannels));
CommandHandler = new CommandHandler(
MessageRouter,
MessageRouterResultHandler,
connectionRequestHandler,
GetChannelList(KeyPermittedAggregationChannels));
MessageLogs = new MessageLogs(connectionString);
}
public async Task OnTurnAsync(ITurnContext context, NextDelegate next, CancellationToken ct)
{
Activity activity = context.Activity;
if (activity.Type is ActivityTypes.Message)
{
bool.TryParse(
Configuration[KeyRejectConnectionRequestIfNoAggregationChannel],
out bool rejectConnectionRequestIfNoAggregationChannel);
// Store the conversation references (identities of the sender and the recipient [bot])
// in the activity
MessageRouter.StoreConversationReferences(activity);
AbstractMessageRouterResult messageRouterResult = null;
// Check the activity for commands
if (await CommandHandler.HandleCommandAsync(context) == false)
{
// No command detected/handled
// Let the message router route the activity, if the sender is connected with
// another user/bot
messageRouterResult = await MessageRouter.RouteMessageIfSenderIsConnectedAsync(activity);
if (messageRouterResult is MessageRoutingResult
&& (messageRouterResult as MessageRoutingResult).Type == MessageRoutingResultType.NoActionTaken)
{
// No action was taken by the message router. This means that the user
// is not connected (in a 1:1 conversation) with a human
// (e.g. customer service agent) yet.
// Check for cry for help (agent assistance)
if (!string.IsNullOrWhiteSpace(activity.Text)
&& activity.Text.ToLower().Contains("human"))
{
// Create a connection request on behalf of the sender
// Note that the returned result must be handled
messageRouterResult = MessageRouter.CreateConnectionRequest(
MessageRouter.CreateSenderConversationReference(activity),
rejectConnectionRequestIfNoAggregationChannel);
}
else
{
// No action taken - this middleware did not consume the activity so let it propagate
await next(ct).ConfigureAwait(false);
}
}
}
// Uncomment to see the result in a reply (may be useful for debugging)
//if (messageRouterResult != null)
//{
// await MessageRouter.ReplyToActivityAsync(activity, messageRouterResult.ToString());
//}
// Handle the result, if necessary
await MessageRouterResultHandler.HandleResultAsync(messageRouterResult);
}
else
{
// No action taken - this middleware did not consume the activity so let it propagate
await next(ct).ConfigureAwait(false);
}
}
/// <summary>
/// Extracts the channel list from the settings matching the given key.
/// </summary>
/// <returns>The list of channels or null, if none found.</returns>
private IList<string> GetChannelList(string key)
{
IList<string> channelList = null;
string channels = Configuration[key];
if (!string.IsNullOrWhiteSpace(channels))
{
System.Diagnostics.Debug.WriteLine($"Channels by key \"{key}\": {channels}");
string[] channelArray = channels.Split(',');
if (channelArray.Length > 0)
{
channelList = new List<string>();
foreach (string channel in channelArray)
{
channelList.Add(channel.Trim());
}
}
}
else
{
System.Diagnostics.Debug.WriteLine($"No channels defined by key \"{key}\" in app settings");
}
return channelList;
}
}
}