I have used below code for showing a welcome message to user.
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
// Implement user deletion here
// If we handle user deletion, return a real message
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
string replyMessage = string.Empty;
replyMessage = Responses.Greeting;
return message.CreateReply(replyMessage);
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
// Handle add/remove from contact lists
// Activity.From + Activity.Action represent what happened
}
else if (message.Type == ActivityTypes.Typing)
{
// Handle knowing tha the user is typing
}
else if (message.Type == ActivityTypes.Ping)
{
}
return null;
}
Below method is used to call HandleSystemMessage, if activity type is not message.
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
string reply = "";
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
if (activity.Type == ActivityTypes.Message)
{
stLuis = await LuisHelper.ParseUserInput(activity.Text);
string userResponse = activity.Text.ToLower();
switch (stLuis.topScoringIntent.intent)
{
case "Greetings":
reply = Responses.Greeting;
break;
case "None":
reply = Responses.None;
break;
default:
break;
}
}
if (reply != "")
await connector.Conversations.ReplyToActivityAsync(activity.CreateReply(reply));
}
else
{
var reply1 = HandleSystemMessage(activity);
if (reply1 != null)
await connector.Conversations.ReplyToActivityAsync(reply1);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
This code works with Skype. But when I add same bot in Microsoft teams, it doesn't show a welcome message.
By now (2016-12-30) MSFT Teams does not send any message at all when you add a bot to "contact list". This is a known limitation and to be addressed in the nearest future, as MSFT guys say.
In the meantime to get a ConversationUpdate message to the bot, the user will have to first initiate a conversation with the bot.
As a workaround you can handle special text sent from user, like "start", or just the very first incoming message, if your bot is stateful enough.
Related
According this it seems it's impossible to show welcome messages in Microsoft teams while using ActivityTypes.ConversationUpdate last year..
I wonder whether it is possible now. Any suggestion?
I have tried this but it seems not work.
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
// Implement user deletion here
// If we handle user deletion, return a real message
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
// Handle conversation state changes, like members being added and removed
// Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
// Not available in all channels
if (message.Conversation.IsGroup == true)
{
bool addedBot = false;
Activity newMessage = new Activity();
string res = "";
for (int i = 0; i < message.MembersAdded.Count; i++)
{
if (message.MembersAdded[i].Id == message.Recipient.Id)
{
addedBot = true;
break;
}
}
if (message.MembersAdded.Count > 0 && addedBot == false)
{
ConnectorClient connector = new ConnectorClient(new Uri(message.ServiceUrl));
Activity reply = message.CreateReply("test");
connector.Conversations.ReplyToActivityAsync(reply);
}
}
else
{
ConnectorClient connector = new ConnectorClient(new Uri(message.ServiceUrl));
Activity reply = message.CreateReply("test");
connector.Conversations.ReplyToActivityAsync(reply);
}
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
// Handle add/remove from contact lists
// Activity.From + Activity.Action represent what happened
}
else if (message.Type == ActivityTypes.Typing)
{
// Handle knowing tha the user is typing
}
//else if (message.Type == ActivityTypes.Ping)
//{
//}
return null;
}
2018/09/06
It works.
My code works. But it seems it's impossible to send other existing users 1to1 message when bot is added.
I want continuous conversation chat in Microsoft Bot framework.
if(user says hello)
{
reply = what u want to listen hi or hello
-----if(user says hi)
-----{
--------reply= hi
-----}
----if(user says hello)
-- {
-------reply= hello
---}
}
means bot should also ask question and answer it accordingly..
Assuming this is C# and that you are using an IDialog<T> based dialog, you could do the following:
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
{
var message = await result;
if (message.Text.Equals("hello", StringComparison.InvariantCultureIgnoreCase))
{
PromptDialog.Text(context, this.ResumeAfterPrompt, "What u want to listen hi or hello");
}
else
{
// do something
context.Wait(this.MessageReceivedAsync);
}
}
private async Task ResumeAfterPrompt(IDialogContext context, IAwaitable<string> result)
{
try
{
var userMessage = await result;
switch (userMessage.ToLowerInvariant())
{
case "hi":
await context.PostAsync("hi");
break;
case "hello":
await context.PostAsync("hello");
break;
default:
// do something;
break;
}
}
catch (TooManyAttemptsException)
{
// do something with the exception
}
context.Wait(this.MessageReceivedAsync);
}
In the bot web chat, when I type a message, the bot says "sending" first and then changes to "couldn't send, Retry". But the message is sent and I am getting the reply. How can I avoid this? Do I need to increase the message timeout? If so, where I need to set it?
This is the code snippet. I am using C# SDK where I have coded in MessageReceivedASync method
namespace Bot_Application1.Dialogs
{
public class HRBotDialog : IDialog<object>
{
public static string dialogcontext = "";
public async Task StartAsync(IDialogContext context)
{
context.Wait(MessageReceivedAsync);
}
private async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
{
// Get the text passed
var message = await argument;
string typedText = message.Text.ToLower();
string answer = "My Answer";
if ((typedText == "hi") || (typedText == "hello"))
{
answer = message.Text;
}
else if ((typedText == "how many personal days do i have left") || (typedText.Contains("personal days")))
{
answer = "Looks like you have 2 remaining for this year";
}
I am adding the controller code here
//[BotAuthentication]
public class MessagesController : ApiController
{
/// <summary>
/// POST: api/Messages
/// Receive a message from a user and reply to it
/// </summary>
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, () => new HRBotDialog());
}
else
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
var reply = HandleSystemMessage(activity);
if (reply != null)
await connector.Conversations.ReplyToActivityAsync(reply);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
// Implement user deletion here
// If we handle user deletion, return a real message
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
string replyMessage = string.Empty;
if (message.MembersAdded.Any(o => o.Id == message.Recipient.Id))
{
replyMessage += $"How can I help you? \n";
return message.CreateReply(replyMessage);
}
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
// Handle add/remove from contact lists
// Activity.From + Activity.Action represent what happened
}
else if (message.Type == ActivityTypes.Typing)
{
// Handle knowing tha the user is typing
}
else if (message.Type == ActivityTypes.Ping)
{
}
return null;
}
}
Please try adding the Serializable attribute to your HRBotDialog like this:
[Serializable]
public class HRBotDialog : IDialog<object>
{
//...code...
}
Trying out MS Bot QnA Maker.
I was able to load an FAQ from a site. After running the sandbox bot couldn't find a way to add an answer to a new question. Where can this be done?
As a start point you can use this simple sample provided by Microsoft.
There is a file called MessageController where all the messages are handled.
To make a simple Q&A just modify this function of that file:
public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
// check if activity is of type message
if (activity != null && activity.GetActivityType() == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, () => new EchoDialog());
}
else
{
HandleSystemMessage(activity);
}
return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
To something like this:
public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)
{
// check if activity is of type message
if (activity != null && activity.GetActivityType() == ActivityTypes.Message)
{
if (activity.Text.ToLower() == "what is your name?")
{
var reply = activity.CreateReply("Superbot!");
await Conversation.SendAsync(activity, () => new EchoDialog());
}
else
{
HandleSystemMessage(activity);
}
return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);
}
}
And you'll get a bot which answers "Superbot!" to question "What is your name?".
I have created a simple stock bot from the video. I have registered the bot for Skype, Facebook Messenger and E-Mail.
Skype, Facebook messenger works great and replies to the messages are received.
The problem which I have is with the E-Mail. When I send a E-Mail to the bot, for example, "Stock Price of MSFT" it sends an reply e-mail with the stock price and then it sends the same mail again and again without stopping until i remove the e-mail from the dev.botframework.com. Has anyone faced this issue. Is there any additional configuration which is needed to avoid this.
Eg: I sent a message to the bot e-mail saying "What is the stock price of msft" ?
I get a reply back with "Stock Price of msft is ... " from the bot. And the same reply e-mail I am getting continuously until I disable the E-MAIL Bot service..
MessageControl.cs:
using System;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Description;
using Microsoft.Bot.Connector;
using Newtonsoft.Json;
namespace StockBot2
{
[BotAuthentication]
public class MessagesController : ApiController
{
/// <summary>
/// POST: api/Messages
/// Receive a message from a user and reply to it
/// </summary>
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
ConnectorClient connector = new ConnectorClient(new Uri(activity.ServiceUrl));
string StockRateString;
StockLUIS StLUIS = await GetEntityFromLUIS(activity.Text);
if (StLUIS.intents.Count() > 0)
{
switch (StLUIS.intents[0].intent)
{
case "StockPrice":
StockRateString = await GetStock(StLUIS.entities[0].entity);
break;
case "StockPrice2":
StockRateString = await GetStock(StLUIS.entities[0].entity);
break;
default:
StockRateString = "Sorry, I am not getting you...";
break;
}
}
else
{
StockRateString = "Sorry, I am not getting you...";
}
// return our reply to the user
Activity reply = activity.CreateReply(StockRateString);
await connector.Conversations.ReplyToActivityAsync(reply);
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
private Activity HandleSystemMessage(Activity message)
{
if (message.Type == ActivityTypes.DeleteUserData)
{
// Implement user deletion here
// If we handle user deletion, return a real message
}
else if (message.Type == ActivityTypes.ConversationUpdate)
{
// Handle conversation state changes, like members being added and removed
// Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
// Not available in all channels
}
else if (message.Type == ActivityTypes.ContactRelationUpdate)
{
// Handle add/remove from contact lists
// Activity.From + Activity.Action represent what happened
}
else if (message.Type == ActivityTypes.Typing)
{
// Handle knowing tha the user is typing
}
else if (message.Type == ActivityTypes.Ping)
{
}
return null;
}
private async Task<string> GetStock(string StockSymbol)
{
double? dblStockValue = await YahooBot.GetStockRateAsync(StockSymbol);
if (dblStockValue == null)
{
return string.Format("This \"{0}\" is not an valid stock symbol", StockSymbol);
}
else
{
return string.Format("Stock Price of {0} is {1}", StockSymbol, dblStockValue);
}
}
private static async Task<StockLUIS> GetEntityFromLUIS(string Query)
{
Query = Uri.EscapeDataString(Query);
StockLUIS Data = new StockLUIS();
using (HttpClient client = new HttpClient())
{
string RequestURI = "https://api.projectoxford.ai/luis/v1/application?id=1c85d9de-7c8d-4ceb-ba11-860f02ce911b&subscription-key=fe48030063c6458587138c4dcd258737&q=" + Query;
HttpResponseMessage msg = await client.GetAsync(RequestURI);
if (msg.IsSuccessStatusCode)
{
var JsonDataResponse = await msg.Content.ReadAsStringAsync();
Data = JsonConvert.DeserializeObject<StockLUIS>(JsonDataResponse);
}
}
return Data;
}
}
}
YahooBot.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
namespace StockBot2
{
public class YahooBot
{
public static async Task<double?> GetStockRateAsync(string StockSymbol)
{
try
{
string ServiceURL = $"http://finance.yahoo.com/d/quotes.csv?s={StockSymbol}&f=sl1d1nd";
string ResultInCSV;
using (WebClient client = new WebClient())
{
ResultInCSV = await client.DownloadStringTaskAsync(ServiceURL).ConfigureAwait(false);
}
var FirstLine = ResultInCSV.Split('\n')[0];
var Price = FirstLine.Split(',')[1];
if (Price != null && Price.Length >= 0)
{
double result;
if (double.TryParse(Price, out result))
{
return result;
}
}
return null;
}
catch (WebException ex)
{
//handle your exception here
throw ex;
}
}
}
}