facebook bot Failed to fetch the file from the url - botframework

My facebook bot has 2200 subscriber , so I am using the below code to send them an image daily . However , this code is failing for most of the users with the error as captured from bot framework
public static class MessagesSender
{
public static void SendSpecificMessage(string botName, string serviceURL, string botId, string messageCode, string messageText, string imageURL, Customer customer , Guid logId)
{
var connector = new ConnectorClient(new Uri(serviceURL));
Thread thread = new Thread(() => SendMessage(botName, serviceURL, botId, messageCode, messageText, imageURL, customer, connector , logId));
thread.Start();
}
private static void SendMessage(string botName, string serviceURL, string botId, string messageCode, string messageText, string imageURL, Customer customer, ConnectorClient connector , Guid logId)
{
try
{
Task.Run(async () =>
{
IMessageActivity message = Activity.CreateMessageActivity();
//defining accounts
var userAccount = new ChannelAccount(name: customer.name, id: customer.fromidstate);
var botAccount = new ChannelAccount(name: botName, id: botId);
//creating conversation
var conversationId = await connector.Conversations.CreateDirectConversationAsync(botAccount, userAccount);
message.From = botAccount;
message.Recipient = userAccount;
message.Text = "Daily Image";
message.Conversation = new ConversationAccount(id: conversationId.Id.Replace("#", string.Empty));
if (!string.IsNullOrEmpty(imageURL))
{
message.Attachments = new List<Attachment>();
message.Attachments.Add(new Attachment()
{
ContentUrl = imageURL,
ContentType = "image"
});
}
await connector.Conversations.SendToConversationAsync((Activity)message);
}).Wait();
}
catch ( Exception ex)
{
throw ex;
}
}
}
{"error":{"message":"(#100) Failed to fetch the file from the url","type":"OAuthException","code":100,"error_subcode":2018008,"fbtrace_id":"G8ZFKZLCmNp"}}
I am not sure what to do because when I am sending one message it's working fine but not all the 2200 messages isnt delivered , If i send it for 10 persons it's fine. and also the main problem is that the text gets delivered but not the image

The error is being returned by the Facebook API. It looks like you are hitting a throttling limit. The solution is to slow down the rate at which you send images.
You can check the error return code ("613") if you want to confirm
Facebook error codes

Related

how to delete the posted adaptive messge in MSteams using c# code

the below code is getting error while deleting the message based on the channel id
public async Task DeleteSentNotification(
string conversationId,
string recipientId,
string serviceUrl,
string tenantId,
string name)
{
// Set the service URL in the trusted list to ensure the SDK includes the token in the request.
MicrosoftAppCredentials.TrustServiceUrl(serviceUrl);
var conversationReference = new ConversationReference
{
ServiceUrl = serviceUrl,
Conversation = new ConversationAccount
{
TenantId = tenantId,
Id = conversationId,
name = name,(AdaptiveCard Json)
},
};
await this.botAdapter.ContinueConversationAsync(
botAppId: this.microsoftAppId,
reference: conversationReference,
callback: async (turnContext, cancellationToken) =>
{
try
{
// Delete message.
await turnContext.DeleteActivityAsync(conversationReference);
}
catch (ErrorResponseException e)
{
var errorMessage = $"{e.GetType()}: {e.Message}";
}
},
cancellationToken: CancellationToken.None);
// return response;
}
DeleteActivityAsync has two overloads, but they're both basically aimed towards deleting an "Activity" (i.e. a specific message or thread). If you want to use the overload that takes in a conversationReference, then that means your conversationReference needs to have the ActivityId set (see here for more on the property). Alternatively, you can use the overload that takes in an activityId (it looks like this: public System.Threading.Tasks.Task DeleteActivityAsync (string activityId, System.Threading.CancellationToken cancellationToken = default);), and then you need to pass in the activityId.
Essentially, as stated at the beginning of my answer, you're telling it to delete an "Activity", but you're not telling it which Activity. See here for the docs: https://learn.microsoft.com/en-us/dotnet/api/microsoft.bot.builder.turncontext.deleteactivityasync?view=botbuilder-dotnet-stable

MS Teams: How to initiate a private chat/conversation to a user from a c# backend

I currently try to send a private notification to a user.
What I currently have is a connected bot and connector in my MS Teams environment.
In my c# backend I have the bot which inherit from the ActivityHandler, the tenant id and the user id of ms teams.
The case is now:
Someone is creating an object (for example a Task) in my backend by making an API Post call and I want to notify the user in ms teams.
My idea was now to instantiate the Bot in my API controller (including the ITurnContext). Then with the bot find the right ms teams environment with the tenant id and user id, create a new chat/conversation and send the message. But I guess this is not the right way or I do something wrong. Because I think there is no way to initialise the ITurnContext from my code or?
This is my code and my idea was to use the CreatePrivateConversation method in my API controller.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net.Http;
using System.Security.Claims;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Bot.Builder;
using Microsoft.Bot.Builder.Teams;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Connector.Authentication;
using Microsoft.Bot.Schema;
using Microsoft.Bot.Schema.Teams;
namespace IntegrationsService.Bots
{
public class ProactiveBot : ActivityHandler
{
double _secondsToReply = 3;
ICredentialProvider _credentialProvider;
public ProactiveBot(ICredentialProvider credentialProvider)
{
_credentialProvider = credentialProvider;
}
public async Task<ConversationResourceResponse> CreatePrivateConversation(string message, ITurnContext turnContext)
{
ConnectorClient _client = new ConnectorClient(
new Uri(turnContext.Activity.ServiceUrl),
await GetMicrosoftAppCredentialsAsync(turnContext),
new HttpClient());
var channelData = turnContext.Activity.GetChannelData<TeamsChannelData>();
var conversationParameter = new ConversationParameters
{
Bot = turnContext.Activity.Recipient,
Members = new[] { new ChannelAccount("userid") },
// IsGroup = true,
ChannelData = channelData,
TenantId = channelData.Tenant.Id,
Activity = MessageFactory.Text(message)
};
var response = await _client.Conversations.CreateConversationAsync(conversationParameter);
return response;
}
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
try
{
await turnContext.SendActivityAsync(MessageFactory.Text($"I'll reply to you in {_secondsToReply} seconds."));
QueueReplyAndSendItProactively(turnContext).Wait();
}
catch (Exception e)
{
Debug.WriteLine(e.Message);
throw e;
}
}
public async Task QueueReplyAndSendItProactively(ITurnContext turnContext)
{
string conversationMessage = "I created my own conversation.";
string replyMessage = "I proactively replied to this conversation.";
var task = Task.Run(async () =>
{
await Task.Delay(TimeSpan.FromSeconds(_secondsToReply));
// Let the Bot Proactively create a a conversation.
var response = await CreateConversation(conversationMessage, turnContext);
// Reply to the conversation which the bot created.
await ProactivelyReplyToConversation(response.Id, replyMessage, turnContext);
return Task.CompletedTask;
});
await task;
}
public async Task<ConversationResourceResponse> CreateConversation(string message, ITurnContext turnContext)
{
ConnectorClient _client = new ConnectorClient(new Uri(turnContext.Activity.ServiceUrl), await GetMicrosoftAppCredentialsAsync(turnContext), new HttpClient());
var channelData = turnContext.Activity.GetChannelData<TeamsChannelData>();
var conversationParameter = new ConversationParameters
{
Bot = turnContext.Activity.Recipient,
IsGroup = true,
ChannelData = channelData,
TenantId = channelData.Tenant.Id,
Activity = MessageFactory.Text(message)
};
var response = await _client.Conversations.CreateConversationAsync(conversationParameter);
return response;
}
public async Task ProactivelyReplyToConversation(string conversationId, string message, ITurnContext turnContext)
{
ConnectorClient _client = new ConnectorClient(new Uri(turnContext.Activity.ServiceUrl), await GetMicrosoftAppCredentialsAsync(turnContext), new HttpClient());
var reply = MessageFactory.Text(message);
reply.Conversation = new ConversationAccount(isGroup: true, id: conversationId);
await _client.Conversations.SendToConversationAsync(reply);
}
private async Task<MicrosoftAppCredentials> GetMicrosoftAppCredentialsAsync(ITurnContext turnContext)
{
ClaimsIdentity claimsIdentity = turnContext.TurnState.Get<ClaimsIdentity>("BotIdentity");
Claim botAppIdClaim = claimsIdentity.Claims?.SingleOrDefault(claim => claim.Type == AuthenticationConstants.AudienceClaim)
??
claimsIdentity.Claims?.SingleOrDefault(claim => claim.Type == AuthenticationConstants.AppIdClaim);
string appPassword = await _credentialProvider.GetAppPasswordAsync(botAppIdClaim.Value).ConfigureAwait(false);
return new MicrosoftAppCredentials(botAppIdClaim.Value, appPassword);
}
protected override async Task OnMembersAddedAsync(IList<ChannelAccount> membersAdded, ITurnContext<IConversationUpdateActivity> turnContext, CancellationToken cancellationToken)
{
foreach (var member in membersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
await turnContext.SendActivityAsync(MessageFactory.Text($"Hello and Welcome!"), cancellationToken);
}
}
}
}
}
Thanks for the help.
There is no way to initialize the ITurnContext from code.
So If you want to send a private proactive message to user, You need to follow below steps
"OnConversationUpdateActivityAsync" method will be called when user install bot. You can get required parameters like ConversationId, ServiceUrl from turnContext.Activity.From object. you can store these details in database when each user installs the bot.
OnConversationUpdateActivityAsync(
ITurnContext turnContext,
CancellationToken cancellationToken)
When user makes an POST API call, you need to pass user id or AadID based on which you can query database and get user details which are needed to send proactive message. Now you can call "CreatePrivateConversation" method and send the proactive message

Forward Hero Card from Skype Chatbot with functional buttons (or deeplinking chatbot and passing a reference)

Is there a way to create a hero card that has buttons that keep working when it is forwarded to another user?
We want to build a chatbot that enables you to share things with someone else. So first you talk to the chatbot (mainly via buttons) to setup a thing and then you forward that to one of your contacts so that they can participate. With Facebook Messenger we can directly call a share action that pops up the share dialog with which the user can forward a card to a contact. Using a m.me/123?ref=456 URL in a button of the card the receiver can open a conversation with the chatbot in the correct context. I managed to do something similar for Telegram.
I try to replicate this with other services. With Skype there is no way to explicitly call the share action, but I can write a message "Please forward the next card to the user you want to share this with:" [and then I display that card]. Now I give that card a button with a postBack action that should open the correct context, but that button seems to be non functional. When tapping it no post back is sent to the chatbot.
Is there a way to implement something like what I described for Facebook Messenger with Skype? Or is there a way to deep link to a chatbot passing some reference?
(I'd rather have the later for a second use case anyway, where a user puts a share button on their website that then opens Skype in a conversation with the chatbot, passing the reference. I have that for Messenger and Telegram.)
Edit: What I would like to do would basically be the following. I use nodejs, but only the ChatConnector class and not the UniversalBot class.
connector.send([
{
type: 'message',
address,
textFomrat: 'plain',
text: 'Forward the next message to people you want to share THING with:',
},
{
type: 'message',
address,
attachments: [{
contentType: 'application/vnd.microsoft.card.hero',
content: {
title: name,
images: [{
url: image_url
}],
buttons: [{
type: 'postBack',
title: 'Chat with this bot about THING',
value: 'open:' + thing_id,
}]
}
}],
}
], callback);
I'm not sure how you're sending cards to the other user, but here's an example in .net where the buttons sent will function as expected for the other user:
using Microsoft.Bot.Builder.Dialogs;
using System;
using System.Threading.Tasks;
using Microsoft.Bot.Connector;
using Microsoft.Bot.Builder.FormFlow;
using System.Collections.Generic;
using System.Collections.Concurrent;
using Microsoft.Bot.Builder.ConnectorEx;
using Newtonsoft.Json;
namespace CardsBot
{
[Serializable]
public class SendToUserDialog : IDialog<object>
{
static ConcurrentDictionary<string, ConversationReference> _cachedConversationReferences = new ConcurrentDictionary<string, ConversationReference>();
private const string HelpString = "Enter 'Send Card' to send a card to another user. 'Send Message' to send a json message to another user. Or 'List Users' to see who is ready to receive messages.";
public async Task StartAsync(IDialogContext context)
{
context.Wait(this.MessageReceivedAsync);
}
public async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> argument)
{
var message = await argument;
string upperText = message.Text.Replace(" ", "").ToUpper();
if (upperText == "SENDCARD")
{
IFormDialog<SendCardForm> form = new FormDialog<SendCardForm>(new SendCardForm(), SendCardForm.BuildForm, FormOptions.PromptInStart);
context.Call(form, AfterSendCardComplete);
}
else if (upperText == "SENDMESSAGE")
{
IFormDialog<SendMessageForm> form = new FormDialog<SendMessageForm>(new SendMessageForm(), SendMessageForm.BuildForm, FormOptions.PromptInStart);
context.Call(form, AfterSendMessageFormComplete);
}
else if (upperText == "LISTUSERS")
{
var names = String.Join(", ", _cachedConversationReferences.Keys);
await context.PostAsync($"Users : {names}");
}
else
{
if (!context.UserData.ContainsKey("name"))
{
var getNamePrompt = new PromptDialog.PromptString("What is your name?", "Please enter your name.", 3);
context.Call(getNamePrompt, AfterNamePrompt);
}
else
{
await context.PostAsync($"You said: {message.Text} ({HelpString})");
context.Wait(MessageReceivedAsync);
}
}
}
private async Task AfterSendMessageFormComplete(IDialogContext context, IAwaitable<SendMessageForm> result)
{
var sendMessageForm = await result;
if (string.IsNullOrEmpty(sendMessageForm.RecipientName))
{
await context.PostAsync("A recipient name was not provided. Cannot send the message to nobody.");
}
else
{
ConversationReference conversation = null;
if (_cachedConversationReferences.TryGetValue(sendMessageForm.RecipientName, out conversation))
{
var originalReply = conversation.GetPostToBotMessage().CreateReply();
var replyMessage = GetMessage(originalReply, sendMessageForm.MessageJson);
var connector = new ConnectorClient(new Uri(originalReply.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(replyMessage);
await context.PostAsync($"Message was sent to {sendMessageForm.RecipientName} on {replyMessage.ChannelId} channel.");
}
else
{
await context.PostAsync($"No recipient found matching the name {sendMessageForm.RecipientName}");
}
}
}
private async Task AfterNamePrompt(IDialogContext context, IAwaitable<string> result)
{
var name = await result;
context.UserData.SetValue("name", name);
await context.PostAsync($"Thanks. What would you like to do now {name}? {HelpString}");
var conversationReference = context.Activity.ToConversationReference();
_cachedConversationReferences.AddOrUpdate(name, conversationReference, (oldVal, newVal) => conversationReference);
}
public Activity GetMessage(Activity originalReply, string messageJson)
{
var reply = JsonConvert.DeserializeObject<Activity>(messageJson);
reply.ChannelId = originalReply.ChannelId;
reply.Timestamp = originalReply.Timestamp;
reply.From = originalReply.From;
reply.Conversation = originalReply.Conversation;
reply.Recipient = originalReply.Recipient;
reply.Id = originalReply.Id;
reply.ReplyToId = originalReply.ReplyToId;
reply.ServiceUrl = originalReply.ServiceUrl;
return reply;
}
private async Task AfterSendCardComplete(IDialogContext context, IAwaitable<SendCardForm> result)
{
var SendCardForm = await result;
if (string.IsNullOrEmpty(SendCardForm.RecipientName))
{
await context.PostAsync("A recipient name was not provided. Cannot send a card to nobody.");
}
else
{
ConversationReference conversation = null;
if (_cachedConversationReferences.TryGetValue(SendCardForm.RecipientName, out conversation))
{
var reply = conversation.GetPostToBotMessage().CreateReply();
reply.Attachments.Add(GetCard(SendCardForm.Text, SendCardForm.Buttons.Value));
var connector = new ConnectorClient(new Uri(reply.ServiceUrl));
await connector.Conversations.ReplyToActivityAsync(reply);
}
else
{
await context.PostAsync($"No recipient found matching the name {SendCardForm.RecipientName}");
}
}
}
public Attachment GetCard(string text, int numberOfButtons)
{
var card = new HeroCard(text);
card.Buttons = new List<CardAction>(GetCardActions(numberOfButtons));
return card.ToAttachment();
}
private IEnumerable<CardAction> GetCardActions(int numberOfButtons)
{
for (int counter = 1; counter < numberOfButtons; counter++)
{
yield return new CardAction()
{
Title = $"button{counter}",
Type = ActionTypes.ImBack,
Value = $"button{counter}"
};
}
}
}
[Serializable]
public class SendMessageForm
{
[Prompt("Who would you like to send this message to (enter the name of the recipient)?")]
public string RecipientName { get; set; }
[Prompt("Paste in the .json of the message you would like to Send.")]
public string MessageJson { get; set; }
public static IForm<SendMessageForm> BuildForm()
{
return new FormBuilder<SendMessageForm>()
.AddRemainingFields()
.Confirm("Is this information correct?{*}")
.Build();
}
}
[Serializable]
public class SendCardForm
{
[Prompt("What would you like for the card text?")]
public string Text { get; set; }
[Prompt("How many buttons?")]
public int? Buttons { get; set; }
[Prompt("Who would you like to send the card to?")]
public string RecipientName { get; set; }
public static IForm<SendCardForm> BuildForm()
{
return new FormBuilder<SendCardForm>()
.AddRemainingFields()
.Confirm("Is this information correct?{*}")
.Build();
}
}
}

Connect to Server using xamarin forms

I'm developing Xamarin Cross platform application. I'm trying to connect to server (http://test.net/login/clientlogin), I need to send these fields (password = "xyz"; platform = iphone; (useremail) = "test#test.com";) along with the request. So that server will check these parameters and returns XML. But we don't know how to add these fields to the request.
When i open the above string url (http://*****/login/clientlogin) i am getting login screen, with in that we have username, password and platform text fields.
Thanks in advance!!!..
This should get you started presuming you are adding the values as headers in the request:
public class TestClient
{
HttpClient client;
public TestClient(){
this.client = new HttpClient ();
}
public void AddHeadersAndGet(){
client.DefaultRequestHeaders.Add ("username", "whatevertheusernameis");
this.GetAsync<WhateverObjectTypeYouAreReceiving> ("theurloftheservice");
}
public async Task<T> GetAsync<T>(string address){
HttpResponseMessage response = null;
response = await client.GetAsync (address);
if (response.IsSuccessStatusCode) {
try {
var responseString = await response.Content.ReadAsStringAsync ();
return new T (Serializer.DeserializeObject<T> (responseString),
response.StatusCode);
} catch (Exception ex) {
}
} else {
}
}
}
The key line for you is:
client.DefaultRequestHeaders.Add ("username", "whatevertheusernameis");

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