How to show welcome message in Microsoft teams using Microsoft bot framework SDK3 C# - botframework

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.

Related

Xamarin IOS InAppBiling plugin how to get receipt-data

I use Plugin.InAppBiling for In-App Purchase ios. I want to know Purchase receipt data.
here is my code.
private async Task<bool> MakePurchase(string productId)
{
var billing = CrossInAppBilling.Current;
try
{
var connected = await billing.ConnectAsync();
if (!connected)
{
return false;
}
var verify = DependencyService.Get<IInAppBillingVerifyPurchase>();
var purchase = await CrossInAppBilling.Current.PurchaseAsync(productId, ItemType.InAppPurchase, verify);
if (purchase == null)
{
return false;
}
else if (purchase.State == PurchaseState.Purchased)
{
if (Device.RuntimePlatform == Device.iOS)
{
Console.WriteLine("CHECK");
if(verify == null)
{
Console.WriteLine("null");
}
else
{
Console.WriteLine($"{verify}");
}
}
return true;
}
return false;
}
finally
{
await billing.DisconnectAsync();
}
}
The payment process goes well. but verify is just return null.
I understood verify as receipt-data. It's right?
How do I get a base64 encoded string receipt-data?
The documentation you also link to clearly states that you need to implement IInAppBillingVerifyPurchase yourself. There is no implementation of this in the plugin.
So you need to create your own class and register it in the IoC container:
[assembly: Dependency(typeof(MyIAPVerification))]
public class MyIAPVerification : IInAppBillingVerifyPurchase
{
// implementation here
}
Only then will your verify instance not be null.

couldn't send retry but the message has been sent

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...
}

Xamarin Android Receive and Send SMS more than 160 characters

I'm writting sms application, which get from server by restapi number and message where to send and also receive sms from receipent. I have issue when received sms has more than 160 characters. And issue is when I have more than 160 characters to send by SMS.
Receive sms code:
public override void OnReceive(Context context, Intent intent)
{
if (intent.HasExtra("pdus"))
{
var smsArray = (Java.Lang.Object[])intent.Extras.Get("pdus");
foreach(var item in smsArray)
{
var sms = SmsMessage.CreateFromPdu((byte[])item);
SendReceivedStatus(sms.OriginatingAddress, sms.MessageBody);
}
}
}
SendReceivedStatus(sms.OriginatingAddress, sms.MessageBody);
It's a my method that convert to json receipentNumber and message.
Now my send sms code:
var sent = PendingIntent.GetBroadcast(Application.Context, 0, new Intent("SMS_SENT"), 0);
SmsManager.Default.SendTextMessage(responseModel.receipent, null, responseModel.message, sent, null);
protected override void OnResume()
{
base.OnResume();
var smsSentReceiver = new SMSSentReceiver();
RegisterReceiver(smsSentReceiver, new IntentFilter("SMS_SENT"));
}
public override void OnReceive(Context context, Intent intent)
{
switch ((int)ResultCode)
{
case (int)Result.Ok:
SenderActivity.resultsms = true;
SendStatus();
break;
case (int)SmsResultError.GenericFailure:
SenderActivity.resultsms = false;
SendStatus();
break;
case (int)SmsResultError.NoService:
SenderActivity.resultsms = false;
SendStatus();
break;
case (int)SmsResultError.NullPdu:
SenderActivity.resultsms = false;
SendStatus();
break;
case (int)SmsResultError.RadioOff:
SenderActivity.resultsms = false;
SendStatus();
break;
}
}
How to pack these messages?
Since SmsMessage.CreateFromPdu((byte[])) is deprecated since Android API level 19, here I also provide method to receive message more than 160 characters after KitKat version, here is my demo:
[BroadcastReceiver(Enabled = true, Label = "SMS Receiver")]
[IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" })]
public class SMSReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Bundle bundle = intent.Extras;
if (bundle != null)
{
if (Build.VERSION.SdkInt >= BuildVersionCodes.Kitkat)
{
SmsMessage[] msgs = Telephony.Sms.Intents.GetMessagesFromIntent(intent);
var smstext = new StringBuilder();
foreach (var msg in msgs)
{
smstext.Append(msg.DisplayMessageBody.ToString());
}
Console.WriteLine(smstext.ToString());//output the received sms
}
else
{
var smsArray = (Java.Lang.Object[])bundle.Get("pdus");
SmsMessage[] messages = new SmsMessage[smsArray.Length];
for (int i = 0; i < smsArray.Length; i++)
{
messages[i] = SmsMessage.CreateFromPdu((byte[])smsArray[i]);
}
StringBuilder content = new StringBuilder();
if (messages.Length > 0)
{
foreach (var message in messages)
{
content.Append(message.DisplayMessageBody.ToString());
}
}
Console.WriteLine(content.ToString());//output the received sms
}
}
Toast.MakeText(context, "Received intent!", ToastLength.Short).Show();
}
}
I've tested my demo on Android 6.0 device and it works fine, I now can't find a Android 4.0 device for testing, but I think the method should work here. Any problem about this issue, please leave a comment.

show welcome message in Microsoft teams using Microsoft bot framework

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.

Azure Notification Hub and WP8 Intermitant notifications

This is a fairly long piece of code but I am getting nowhere with this and cannot see any issues, although I am new to using notification hubs. I am trying to register for targeted notifications (the logged on user) using the notification hub in Azure. After the registration, a test notification is sent.
The issue I am having is that sometimes the notification is sent to the device, and sometimes it is not. It mostly isn't but occasionally when I step through the code on the server, i will get the notification on the emulator come through. Once when I deployed the app to my phone the notification came though on the emulator! I cannot discover a pattern.
My Controller class looks like this;
private NotificationHelper hub;
public RegisterController()
{
hub = NotificationHelper.Instance;
}
public async Task<RegistrationDescription> Post([FromBody]JObject registrationCall)
{
var obj = await hub.Post(registrationCall);
return obj;
}
And the helper class (which is used elsewhere so is not directly in the controller) looks like this;
public static NotificationHelper Instance = new NotificationHelper();
public NotificationHubClient Hub { get; set; }
// Create the client in the constructor.
public NotificationHelper()
{
var cn = "<my-cn>";
Hub = NotificationHubClient.CreateClientFromConnectionString(cn, "<my-hub>");
}
public async Task<RegistrationDescription> Post([FromBody] JObject registrationCall)
{
// Get the registration info that we need from the request.
var platform = registrationCall["platform"].ToString();
var installationId = registrationCall["instId"].ToString();
var channelUri = registrationCall["channelUri"] != null
? registrationCall["channelUri"].ToString()
: null;
var deviceToken = registrationCall["deviceToken"] != null
? registrationCall["deviceToken"].ToString()
: null;
var userName = HttpContext.Current.User.Identity.Name;
// Get registrations for the current installation ID.
var regsForInstId = await Hub.GetRegistrationsByTagAsync(installationId, 100);
var updated = false;
var firstRegistration = true;
RegistrationDescription registration = null;
// Check for existing registrations.
foreach (var registrationDescription in regsForInstId)
{
if (firstRegistration)
{
// Update the tags.
registrationDescription.Tags = new HashSet<string>() {installationId, userName};
// We need to handle each platform separately.
switch (platform)
{
case "windows":
var winReg = registrationDescription as MpnsRegistrationDescription;
winReg.ChannelUri = new Uri(channelUri);
registration = await Hub.UpdateRegistrationAsync(winReg);
break;
case "ios":
var iosReg = registrationDescription as AppleRegistrationDescription;
iosReg.DeviceToken = deviceToken;
registration = await Hub.UpdateRegistrationAsync(iosReg);
break;
}
updated = true;
firstRegistration = false;
}
else
{
// We shouldn't have any extra registrations; delete if we do.
await Hub.DeleteRegistrationAsync(registrationDescription);
}
}
// Create a new registration.
if (!updated)
{
switch (platform)
{
case "windows":
registration = await Hub.CreateMpnsNativeRegistrationAsync(channelUri,
new string[] {installationId, userName});
break;
case "ios":
registration = await Hub.CreateAppleNativeRegistrationAsync(deviceToken,
new string[] {installationId, userName});
break;
}
}
// Send out a test notification.
await SendNotification(string.Format("Test notification for {0}", userName), userName);
return registration;
And finally, my SendNotification method is here;
internal async Task SendNotification(string notificationText, string tag)
{
try
{
var toast = PrepareToastPayload("<my-hub>", notificationText);
// Send a notification to the logged-in user on both platforms.
await NotificationHelper.Instance.Hub.SendMpnsNativeNotificationAsync(toast, tag);
//await hubClient.SendAppleNativeNotificationAsync(alert, tag);
}
catch (ArgumentException ex)
{
// This is expected when an APNS registration doesn't exist.
Console.WriteLine(ex.Message);
}
}
I suspect the issue is in my phone client code, which is here and SubscribeToService is called immediately after WebAPI login;
public void SubscribeToService()
{
_channel = HttpNotificationChannel.Find("mychannel");
if (_channel == null)
{
_channel = new HttpNotificationChannel("mychannel");
_channel.Open();
_channel.BindToShellToast();
}
_channel.ChannelUriUpdated += async (o, args) =>
{
var hub = new NotificationHub("<my-hub>", "<my-cn>");
await hub.RegisterNativeAsync(args.ChannelUri.ToString());
await RegisterForMessageNotificationsAsync();
};
}
public async Task RegisterForMessageNotificationsAsync()
{
using (var client = GetNewHttpClient(true))
{
// Get the info that we need to request registration.
var installationId = LocalStorageManager.GetInstallationId(); // a new Guid
var registration = new Dictionary<string, string>()
{
{"platform", "windows"},
{"instId", installationId},
{"channelUri", _channel.ChannelUri.ToString()}
};
var request = new HttpRequestMessage(HttpMethod.Post, new Uri(ApiUrl + "api/Register/RegisterForNotifications"));
request.Content = new StringContent(JsonConvert.SerializeObject(registration), Encoding.UTF8, "application/json");
string message;
try
{
HttpResponseMessage response = await client.SendAsync(request);
message = await response.Content.ReadAsStringAsync();
}
catch (Exception ex)
{
message = ex.Message;
}
_registrationId = message;
}
}
Any help would be greatly appriciated as I have been stuck on this now for days! I know this is a lot of code to paste up here but it is all relevant.
Thanks,
EDIT: The SubscribeToService() method is called when the user logs in and authenticates with the WebAPI. The method is here;
public async Task<User> SendSubmitLogonAsync(LogonObject lo)
{
_logonObject = lo;
using (var client = GetNewHttpClient(false))
{
var logonString = String.Format("grant_type=password&username={0}&password={1}", lo.username, lo.password);
var sc = new StringContent(logonString, Encoding.UTF8);
var response = await client.PostAsync("Token", sc);
if (response.IsSuccessStatusCode)
{
_logonResponse = await response.Content.ReadAsAsync<TokenResponseModel>();
var userInfo = await GetUserInfoAsync();
if (_channel == null)
SubscribeToService();
else
await RegisterForMessageNotificationsAsync();
return userInfo;
}
// ...
}
}
I have solved the issue. There are tons of fairly poorly organised howto's for azure notification hubs and only one of them has this note toward the bottom;
NOTE:
You will not receive the notification when you are still in the app.
To receive a toast notification while the app is active, you must
handle the ShellToastNotificationReceived event.
This is why I was experiencing intermittent results, as i assumed you would still get a notification if you were in the app. And this little note is pretty well hidden.
Have you used proper tag / tag expressions while register/send the message. Also, Where are you storing the id back from the notification hub. It should be used when you update the channel uri (it will expire).
I would suggest to start from scratch.
Ref: http://msdn.microsoft.com/en-us/library/dn530749.aspx

Resources