PostToBot.cs
1 //
2 // Copyright (c) Microsoft. All rights reserved.
3 // Licensed under the MIT license.
4 //
5 // Microsoft Bot Framework: http://botframework.com
6 //
7 // Bot Builder SDK GitHub:
8 // https://github.com/Microsoft/BotBuilder
9 //
10 // Copyright (c) Microsoft Corporation
11 // All rights reserved.
12 //
13 // MIT License:
14 // Permission is hereby granted, free of charge, to any person obtaining
15 // a copy of this software and associated documentation files (the
16 // "Software"), to deal in the Software without restriction, including
17 // without limitation the rights to use, copy, modify, merge, publish,
18 // distribute, sublicense, and/or sell copies of the Software, and to
19 // permit persons to whom the Software is furnished to do so, subject to
20 // the following conditions:
21 //
22 // The above copyright notice and this permission notice shall be
23 // included in all copies or substantial portions of the Software.
24 //
25 // THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND,
26 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
29 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
30 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
31 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 //
33 
34 using System;
35 using System.Diagnostics;
36 using System.Net.Mime;
37 using System.Resources;
38 using System.Threading;
39 using System.Threading.Tasks;
43 using Microsoft.Bot.Connector;
44 
45 namespace Microsoft.Bot.Builder.Dialogs.Internals
46 {
50  public interface IPostToBot
51  {
58  Task PostAsync(IActivity activity, CancellationToken token);
59  }
60 
61  public sealed class NullPostToBot : IPostToBot
62  {
63  private readonly IPostToBot inner;
64 
65  public NullPostToBot(IPostToBot inner)
66  {
67  SetField.NotNull(out this.inner, nameof(inner), inner);
68  }
69 
70  async Task IPostToBot.PostAsync(IActivity activity, CancellationToken token)
71  {
72  await this.inner.PostAsync(activity, token);
73  }
74  }
75 
79  public sealed class SetAmbientThreadCulture : IPostToBot
80  {
81  private readonly IPostToBot inner;
82  private readonly ILocaleFinder localeFinder;
83 
84  public SetAmbientThreadCulture(IPostToBot inner, ILocaleFinder localeFinder)
85  {
86  SetField.NotNull(out this.inner, nameof(inner), inner);
87  SetField.NotNull(out this.localeFinder, nameof(localeFinder), localeFinder);
88  }
89 
90  async Task IPostToBot.PostAsync(IActivity activity, CancellationToken token)
91  {
92  var locale = await this.localeFinder.FindLocale(activity, token);
93  using (var localeScope = new LocalizedScope(locale))
94  {
95  await this.inner.PostAsync(activity, token);
96  }
97  }
98  }
99 
104  public sealed class SerializeByConversation : IPostToBot
105  {
106  private readonly IPostToBot inner;
107  private readonly IAddress address;
108  private readonly IScope<IAddress> scopeForCookie;
109 
110  public SerializeByConversation(IPostToBot inner, IAddress address, IScope<IAddress> scopeForCookie)
111  {
112  SetField.NotNull(out this.inner, nameof(inner), inner);
113  SetField.NotNull(out this.address, nameof(address), address);
114  SetField.NotNull(out this.scopeForCookie, nameof(scopeForCookie), scopeForCookie);
115  }
116 
117  async Task IPostToBot.PostAsync(IActivity activity, CancellationToken token)
118  {
119  using (await this.scopeForCookie.WithScopeAsync(this.address, token))
120  {
121  await this.inner.PostAsync(activity, token);
122  }
123  }
124  }
125 
130  {
131  private readonly IPostToBot inner;
132  private readonly IBotToUser botToUser;
133  private readonly ResourceManager resources;
134  private readonly TraceListener trace;
135 
136  public PostUnhandledExceptionToUser(IPostToBot inner, IBotToUser botToUser, ResourceManager resources, TraceListener trace)
137  {
138  SetField.NotNull(out this.inner, nameof(inner), inner);
139  SetField.NotNull(out this.botToUser, nameof(botToUser), botToUser);
140  SetField.NotNull(out this.resources, nameof(resources), resources);
141  SetField.NotNull(out this.trace, nameof(trace), trace);
142  }
143 
144  async Task IPostToBot.PostAsync(IActivity activity, CancellationToken token)
145  {
146  try
147  {
148  await this.inner.PostAsync(activity, token);
149  }
150  catch (Exception error)
151  {
152  try
153  {
154  if (Debugger.IsAttached)
155  {
156  var message = this.botToUser.MakeMessage();
157  message.Text = $"Exception: { error.Message}";
158  message.Attachments = new[]
159  {
160  new Attachment(contentType: MediaTypeNames.Text.Plain, content: error.StackTrace)
161  };
162 
163  await this.botToUser.PostAsync(message);
164  }
165  else
166  {
167  await this.botToUser.PostAsync(this.resources.GetString("UnhandledExceptionToUser"));
168  }
169  }
170  catch (Exception inner)
171  {
172  this.trace.WriteLine(inner);
173  }
174 
175  throw;
176  }
177  }
178  }
179 }
This IPostToBot service converts any unhandled exceptions to a message sent to the user...
Definition: PostToBot.cs:129
Namespace for Microsoft Bot Builder SDK extensions to the Microsoft Bot Connector SDK...
Definition: KeyboardCard.cs:40
Namespace for the Microsoft Bot Connector SDK.
This class sets the ambient thread culture for a scope of code with a using-block.
This IPostToBot service sets the ambient thread culture based on the IMessageActivity.Locale.
Definition: PostToBot.cs:79
This IPostToBot service serializes the execution of a particular conversation&#39;s code to avoid concurr...
Definition: PostToBot.cs:104
Definition: PostToBot.cs:61
Namespace for internal machinery that is not useful for most developers and may change in the future...
Methods to send a message from the user to the bot.
Definition: PostToBot.cs:50
The key that minimally and completely identifies a bot&#39;s conversation with a user on a channel...
Definition: Address.cs:45
Task PostAsync(IActivity activity, CancellationToken token)
Post an item (e.g. message or other external event) to the bot.
PostUnhandledExceptionToUser(IPostToBot inner, IBotToUser botToUser, ResourceManager resources, TraceListener trace)
Definition: PostToBot.cs:136
SerializeByConversation(IPostToBot inner, IAddress address, IScope< IAddress > scopeForCookie)
Definition: PostToBot.cs:110
The interface for finding and setting locale for LocalizedScope in SetAmbientThreadCulture.
Definition: LocaleFinder.cs:14
Shared properties for all activities
Definition: IActivity.cs:9
An attachment within an activity
Definition: Attachment.cs:17
NullPostToBot(IPostToBot inner)
Definition: PostToBot.cs:65
SetAmbientThreadCulture(IPostToBot inner, ILocaleFinder localeFinder)
Definition: PostToBot.cs:84
Namespace for the internal fibers machinery that is not useful for most developers and may change in ...
Methods to send a message from the bot to the user.
Definition: BotToUser.cs:51
Provide an abstraction to serialize access to an item for a using-block scope of code.
Definition: Scope.cs:47
Root namespace for the Microsoft Bot Builder SDK.