Today I’ll show you how to create a simple Skype bot that will reply with the same text message you send to it.
You’ll be using .Net Core and Microsoft Bot Framework. As you already know not every library has been ported to .Net Core so you’ll have to use the Microsoft Bot Connector API – v3.0 to bring the bot to life.
Let me show you what it takes to create a simple bot:
Register the bot
Head to the Register bot page and fill the required fields.
For the messaging endpoint use something like: https://{url of your bot}/api/messages
Also get your Microsoft App ID and password from the Microsoft Application registration portal, and save them cause you’ll need them to fill the BotCredentials in our sample.
Create a new .NET Core Web the project
1md bot
2cd bot
3dotnet new -t web
Add the following dependencies to your project.json file
1 "Microsoft.AspNet.WebApi.Client": "5.2.3",
2 "System.Runtime.Serialization.Xml": "4.1.1",
3 "Microsoft.Extensions.Caching.Memory": "1.0.0",
4 "Microsoft.Extensions.Options.ConfigurationExtensions": "1.0.0",
5 "Microsoft.Extensions.DependencyInjection": "1.0.0",
6 "Microsoft.Extensions.DependencyInjection.Abstractions": "1.0.0"
And restore the packages
1dotnet restore
Add the following section to your appsettings.json file
Replace the values with those of your registered bot.
1"BotCredentials": {
2 "ClientId": "{Replace with your ClientId}",
3 "ClientSecret": "{Replace with your ClientSecret}"
4 }
Replace the ConfigureServices in you Startup class
You’ll be using options to inject configurations (BotCredentials) to the controller and in Memory Cache to save tokens to avoid authenticating the bot on every call.
1 // This method gets called by the runtime. Use this method to add services to the container.
2 public void ConfigureServices(IServiceCollection services)
3 {
4 // Adding options so we can inject configurations.
5 services.AddOptions();
6
7 // Register the bot credentials section
8 services.Configure<BotCredentials>(Configuration.GetSection("BotCredentials"));
9
10 // we'll be catching tokens, so enable MemoryCache.
11 services.AddMemoryCache();
12
13 services.AddMvc();
14 }
Create a BotCredentials class
This class will hold the bot credentials
1namespace WebApplication
2{
3 /// <summary>
4 /// Bot Credentials
5 /// </summary>
6 public class BotCredentials
7 {
8 /// <summary>
9 /// CLientId
10 /// </summary>
11 public string ClientId { get; set; }
12
13 /// <summary>
14 /// ClientSecret
15 /// </summary>
16 public string ClientSecret { get; set; }
17 }
18}
Create TokenResponse class
1namespace WebApplication
2{
3 /// <summary>
4 /// Token Response
5 /// </summary>
6 public class TokenResponse
7 {
8 /// <summary>
9 /// Property to hold the token
10 /// </summary>
11 public string access_token { get; set; }
12 }
13}
Create a MessagesController class
1namespace WebApplication.Controllers
2{
3 using System;
4 using System.Collections.Generic;
5 using System.Dynamic;
6 using System.Net.Http;
7 using System.Net.Http.Headers;
8 using System.Threading.Tasks;
9 using Microsoft.AspNetCore.Mvc;
10 using Microsoft.Extensions.Caching.Memory;
11 using Microsoft.Extensions.Options;
12
13 /// <summary>
14 /// This controller will receive the skype messages and handle them to the EchoBot service.
15 /// </summary>
16 [Route("api/[controller]")]
17 public class MessagesController : Controller
18 {
19 /// <summary>
20 /// memoryCache
21 /// </summary>
22 IMemoryCache memoryCache;
23
24 /// <summary>
25 /// Bot Credentials
26 /// </summary>
27 BotCredentials botCredentials;
28
29 /// <summary>
30 /// Constructor
31 /// </summary>
32 ///
33 ///
34 public MessagesController(IMemoryCache memoryCache, IOptions<BotCredentials> botCredentials)
35 {
36 this.memoryCache = memoryCache;
37 this.botCredentials = botCredentials.Value;
38 }
39
40 /// <summary>
41 /// This method will be called every time the bot receives an activity. This is the messaging endpoint
42 /// </summary>
43 ///
44 /// <returns>201 Created</returns>
45 [HttpPost]
46 public virtual async Task<IActionResult> Post([FromBody] dynamic activity)
47 {
48 // Get the conversation id so the bot answers.
49 var conversationId = activity.from.id.ToString();
50
51 // Get a valid token
52 string token = await this.GetBotApiToken();
53
54 // send the message back
55 using (var client = new HttpClient())
56 {
57 // I'm using dynamic here to make the code simpler
58 dynamic message = new ExpandoObject();
59 message.type = "message/text";
60 message.text = activity.text;
61
62 // Set the toekn in the authorization header.
63 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
64
65 // Post the message
66 await client.PostAsJsonAsync<ExpandoObject>(
67 $"https://api.skype.net/v3/conversations/{conversationId}/activities",
68 message as ExpandoObject);
69 }
70
71 return Created(Url.Content("~/"), string.Empty);
72 }
73
74 /// <summary>
75 /// Gets and caches a valid token so the bot can send messages.
76 /// </summary>
77 /// <returns>The token</returns>
78 private async Task<string> GetBotApiToken()
79 {
80 // Check to see if we already have a valid token
81 string token = memoryCache.Get("token")?.ToString();
82 if (string.IsNullOrEmpty(token))
83 {
84 // we need to get a token.
85 using (var client = new HttpClient())
86 {
87 // Create the encoded content needed to get a token
88 var parameters = new Dictionary<string, string>
89 {
90 {"client_id", this.botCredentials.ClientId },
91 {"client_secret", this.botCredentials.ClientSecret },
92 {"scope", "https://graph.microsoft.com/.default" },
93 {"grant_type", "client_credentials" }
94 };
95 var content = new FormUrlEncodedContent(parameters);
96
97 // Post
98 var response = await client.PostAsync("https://login.microsoftonline.com/common/oauth2/v2.0/token", content);
99
100 // Get the token response
101 var tokenResponse = await response.Content.ReadAsAsync<TokenResponse>();
102
103 token = tokenResponse.access_token;
104
105 // Cache the token for 15 minutes.
106 memoryCache.Set(
107 "token",
108 token,
109 new DateTimeOffset(DateTime.Now.AddMinutes(15)));
110 }
111 }
112
113 return token;
114 }
115 }
116}
Deploy your bot and add it to your skype
- Deploy your bot (I deployed it to an Azure Web App)
- Head to the My Bots section of the Microsoft Bot Framework page and add the bot to your skype contacts.
Talk to your bot
No you can talk to your bot!
You can get the code here: https://github.com/cmendible/dotnetcore.samples/tree/main/echobot
Hope it helps!
Comments