How to get the hub notification that is not full? - c#

I have a notification hub, and it, have a hub-namespace and it is almost full.
I'll create another hub, how do I programmatically know (Android), which one should I enter the user?
Android source code:
public class NotificationSettings {
public static String SenderId = "MyFirebaseSenderId";
public static String HubName = "myhub-hub";
public static String HubListenConnectionString = "Endpoint=sb://myapp.serv.../;SharedAccessKeyName=D..ure;SharedAccessKey=K..t/n8I/X..=";
}
RegistrationIntent:
public class RegistrationIntentService extends IntentService {
private static final String TAG = "RegIntentService";
private NotificationHub hub;
public RegistrationIntentService() {
super(TAG);
}
public ApplicationUtils getApplicationUtils() {
return (ApplicationUtils) getApplication();
}
#Override
protected void onHandleIntent(Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
String resultString = null;
String regID = null;
String storedToken = null;
String tag = null;
try {
tag ="_UserId:" + getApplicationUtils().getUsuario().Id;
} catch (Exception e){
return;
}
try {
if(FirebaseInstanceId.getInstance() == null){
FirebaseApp.initializeApp(this);
}
String FCM_token = FirebaseInstanceId.getInstance().getToken();
SaveSharedPreferences.setFCM(getApplicationContext(),FCM_token);
Log.d(TAG, "FCM Registration Token: " + FCM_token);
// Storing the registration id that indicates whether the generated token has been
// sent to your server. If it is not stored, send the token to your server,
// otherwise your server should have already received the token.
if (((regID=sharedPreferences.getString("registrationID", null)) == null)){
NotificationHub hub = new NotificationHub(NotificationSettings.HubName,
NotificationSettings.HubListenConnectionString, this);
Log.d(TAG, "Attempting a new registration with NH using FCM token : " + FCM_token);
regID = hub.register(FCM_token, tag).getRegistrationId();
// If you want to use tags...
// Refer to : https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-routing-tag-expressions/
// regID = hub.register(token, "tag1,tag2").getRegistrationId();
resultString = "New NH Registration Successfully - RegId : " + regID;
Log.d(TAG, resultString);
sharedPreferences.edit().putString("registrationID", regID ).apply();
sharedPreferences.edit().putString("FCMtoken", FCM_token ).apply();
}
// Check if the token may have been compromised and needs refreshing.
else if (!((storedToken=sharedPreferences.getString("FCMtoken", "")).equals(FCM_token))) {
NotificationHub hub = new NotificationHub(NotificationSettings.HubName,
NotificationSettings.HubListenConnectionString, this);
Log.d(TAG, "NH Registration refreshing with token : " + FCM_token);
regID = hub.register(FCM_token, tag).getRegistrationId();
// If you want to use tags...
// Refer to : https://azure.microsoft.com/en-us/documentation/articles/notification-hubs-routing-tag-expressions/
// regID = hub.register(token, "tag1,tag2").getRegistrationId();
resultString = "New NH Registration Successfully - RegId : " + regID;
Log.d(TAG, resultString);
sharedPreferences.edit().putString("registrationID", regID ).apply();
sharedPreferences.edit().putString("FCMtoken", FCM_token ).apply();
}
else {
resultString = "Previously Registered Successfully - RegId : " + regID;
}
} .............................................
Now, it follows my downend code below, I do not know if it would be important in this case. But, it is developed in C # .Net:
public static async void sendPushNotification(ApiController controller, DataObjects.Notification notification)
{
// Get the settings for the server project.
HttpConfiguration config = controller.Configuration;
MobileAppSettingsDictionary settings =
controller.Configuration.GetMobileAppSettingsProvider().GetMobileAppSettings();
// Get the Notification Hubs credentials for the Mobile App.
string notificationHubName = settings.NotificationHubName;
string notificationHubConnection = settings
.Connections[MobileAppSettingsKeys.NotificationHubConnectionString].ConnectionString;
// Create a new Notification Hub client.
NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString(notificationHubConnection, notificationHubName);
// Android payload
JObject data = new JObject();
data.Add("Id", notification.Id);
data.Add("Descricao", notification.Descricao);
...
//alteração com a colocação da tag priority em caso de erro teste sem
var androidNotificationPayload = "{ \"data\" : {\"message\":" + JsonConvert.SerializeObject(data) + "}}";
try
{
// Send the push notification and log the results.
String tag = "_UserId:"+notification.Id_usuario;
//var result = await hub.SendGcmNativeNotificationAsync(androidNotificationPayload);
var result = await hub.SendGcmNativeNotificationAsync(androidNotificationPayload, tag);
// Write the success result to the logs.
config.Services.GetTraceWriter().Info(result.State.ToString());
}
catch (System.Exception ex)
{
// Write the failure result to the logs.
config.Services.GetTraceWriter().Error(ex.Message, null, "Push.SendAsync Error");
}
}
I need a lot of help on this issue.
Thank you so much for this.

According to your description, I suggest you could write a api method which will insert new user to the notification hub(not on the client side) after checking the registrations is full or not.
We could use NotificationHubClient.GetAllRegistrationsAsync Method to get all AllRegistrations to local. Then we could count its number.
After checking successfully, then we will check enter user to which hub.
The workflow is:
New user registered:
Client: Send the user information to server web api method
Server: Check the notification hub is full(By calling NotificationHubClient.GetAllRegistrationsAsync or directly registered user if it failed registered into new hub)
Besides, notification hub provides different pricing tier.
I suggest you could consider scaling up your pricing tier to support multiple active devices.

Related

Not working example for Dialogflow V2 api

Experienced problems with C# SDK documentation which can be found here:
http://googleapis.github.io/google-cloud-dotnet/docs/Google.Cloud.Dialogflow.V2/api/Google.Cloud.Dialogflow.V2.SessionsClient.html#Google_Cloud_Dialogflow_V2_SessionsClient_Create_Google_Api_Gax_Grpc_ServiceEndpoint_Google_Cloud_Dialogflow_V2_SessionsSettings_
No reference for method ToChannelCredentials().
We cannot connect the SDK to dialogflow, even with blank project. Is this method still existing or deprecated?
using Google.Cloud.Dialogflow.V2;
using Google.Apis.Auth.OAuth2;
using Grpc.Auth;
using Grpc.Core;
...
GoogleCredential cred = GoogleCredential.FromFile("/path/to/credentials.json");
Channel channel = new Channel(
SessionsClient.DefaultEndpoint.Host, SessionsClient.DefaultEndpoint.Port, cred.ToChannelCredentials());
SessionsClient client = SessionsClient.Create(channel);
...
// Shutdown the channel when it is no longer required.
channel.ShutdownAsync().Wait();
Have you tried connecting using the service account private key ? (Json file)
Follow these steps (working example in C#)
After you create a Dialogflow agent go to the agent's settings --> General --> click on the Service Account link
You will be sent to to google cloud platform where you can create a service account
After you create a service account, there will be an option to create a KEY, create it and download the (JSON) format of it
This key will be used to connect from your C# project to the Dialogflow agent
Install Google.Cloud.Dialogflow.V2 package in your project
Create for example a Dialogflow manager class (check below for an example)
public class DialogflowManager {
private string _userID;
private string _webRootPath;
private string _contentRootPath;
private string _projectId;
private SessionsClient _sessionsClient;
private SessionName _sessionName;
public DialogflowManager(string userID, string webRootPath, string contentRootPath, string projectId) {
_userID = userID;
_webRootPath = webRootPath;
_contentRootPath = contentRootPath;
_projectId = projectId;
SetEnvironmentVariable();
}
private void SetEnvironmentVariable() {
try {
Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", _contentRootPath + "\\Keys\\{THE_DOWNLOADED_JSON_FILE_HERE}.json");
} catch (ArgumentNullException) {
throw;
} catch (ArgumentException) {
throw;
} catch (SecurityException) {
throw;
}
}
private async Task CreateSession() {
// Create client
_sessionsClient = await SessionsClient.CreateAsync();
// Initialize request argument(s)
_sessionName = new SessionName(_projectId, _userID);
}
public async Task < QueryResult > CheckIntent(string userInput, string LanguageCode = "en") {
await CreateSession();
QueryInput queryInput = new QueryInput();
var queryText = new TextInput();
queryText.Text = userInput;
queryText.LanguageCode = LanguageCode;
queryInput.Text = queryText;
// Make the request
DetectIntentResponse response = await _sessionsClient.DetectIntentAsync(_sessionName, queryInput);
return response.QueryResult;
}
}
And then this can be called like this for example to get detect Intents
DialogflowManager dialogflow = new DialogflowManager("{INSERT_USER_ID}",
_hostingEnvironment.WebRootPath,
_hostingEnvironment.ContentRootPath,
"{INSERT_AGENT_ID");
var dialogflowQueryResult = await dialogflow.CheckIntent("{INSERT_USER_INPUT}");

Continuous push message giving BadRequest from Azure

My service is register with azzure notification hub. And using my .net server API it push notification to particular device within particular time frame.
Everything goes right except when I try to send multiple push in same code it stuck with "BadRequest" except first one.
Below is the code
public static async void SendAzzurePushNotification()
{
for (int i = 0; i < 10; i++)
{
HttpStatusCode pushNotificationStatus = await CreateAndPushAsync("user_37");
Console.WriteLine(pushNotificationStatus);
}
}
static async Task<HttpStatusCode> CreateAndPushAsync(string tag)
{
HttpStatusCode pushNotificationStatus = HttpStatusCode.NotImplemented;
try
{
HttpResponseMessage response = null;
string uri = "<HUBURI>";
client.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("SharedAccessSignature", <SASTOKEN>);
client.DefaultRequestHeaders.Add("ServiceBusNotification-Format", "gcm");
client.DefaultRequestHeaders.Add("ServiceBusNotification-Tags", tag);
client.DefaultRequestHeaders.Add("x-ms-version", "2015-01");
response = await client.PostAsync(uri,
new StringContent("{\"data\":{\"message\":\"Notification Hub test notification\"}}", Encoding.UTF8, "application/json"));
pushNotificationStatus = response.StatusCode;
}
catch (Exception ex)
{
throw;
}
return pushNotificationStatus;
}
Above code give me Created status for first time and then BadRequest after that. If same api I call from client like postman. It work fine.
I also tried nuget package from azure notification hub, regarding which code is as below. Which solve my above issue but it won't return me any status code which I can have in my above code for success.
NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString("<CONNECTIONSTRING>", "<HUB>");
NotificationOutcome outcome = await hub.SendGcmNativeNotificationAsync("{\"data\":{\"message\":\"Notification Hub test notification\"}}", "user_37");
Call send method with your tags and your notification-data
private static readonly string Endpoint = #"Your End Point";
private static readonly string HubName = #"You Hub Name";
private static NotificationHubClient Hub { get { return NotificationHubClient.CreateClientFromConnectionString(Endpoint, HubName); } }
public static async Task Send(string[] tags, object data)
{
try
{
string payload = string.Empty;
string json_gcm = string.Empty;
if (data.GetType() != typeof(string))
{
//If your notification data is of type
payload = JsonConvert.SerializeObject(data);
json_gcm = "{ \"data\" : " + payload + "}";
}
else
{
//If your notification data is simply is in string
payload = Convert.ToString(data);
json_gcm = "{ \"data\" : {\"message\":\"" + payload + "\"}}";
}
// Android
NotificationOutcome gcmOutcome = null;
gcmOutcome = await Hub.SendGcmNativeNotificationAsync(json_gcm, tags);
if (gcmOutcome != null)
{
if (!((gcmOutcome.State == NotificationOutcomeState.Abandoned) || (gcmOutcome.State == NotificationOutcomeState.Unknown)))
{
//Do code when notification successfully send to Android
}
}
}
catch (Exception ex)
{
//Do code when any exception occurred while sending notification
}
}
NotificationOutcomeState: Gives you status code in the form of enum that represent your notification has been successfully sent or not.
You may ignore if-else block as your need.
Try once may it help you

How do invoke the Paypal IPN using the REST API c# .net

I am having problems invoking the PayPal IPN. I dont know which URL to give or which URL i am meant to give. I have looked all over the internet for help but there does not seem to be anything available hence why i have come here.
So firstly, i have the PaymentWithPaypal Action
public ActionResult PaymentWithPaypal(int? id, Page page)
{
//getting the apiContext as earlier
APIContext apiContext = Models.Configuration.GetAPIContext();
try
{
string payerId = Request.Params["PayerID"];
if (string.IsNullOrEmpty(payerId))
{
string baseURI = Request.Url.Scheme + "://" + Request.Url.Authority + "/ControllerName/PaymentWithPayPal?";
var guid = Guid.NewGuid().ToString();
//CreatePayment function gives us the payment approval url
//on which payer is redirected for paypal acccount payment
var createdPayment = this.CreatePayment(apiContext, baseURI + "guid=" + guid);
//get links returned from paypal in response to Create function call
var links = createdPayment.links.GetEnumerator();
string paypalRedirectUrl = null;
while (links.MoveNext())
{
Links lnk = links.Current;
if (lnk.rel.ToLower().Trim().Equals("approval_url"))
{
//saving the payapalredirect URL to which user will be redirected for payment
paypalRedirectUrl = lnk.href;
}
}
// saving the paymentID in the key guid
Session.Add(guid, createdPayment.id);
return Redirect(paypalRedirectUrl);
}
else
{
// This section is executed when we have received all the payments parameters
// from the previous call to the function Create
// Executing a payment
var guid = Request.Params["guid"];
var executedPayment = ExecutePayment(apiContext, payerId, Session[guid] as string);
if (executedPayment.state.ToLower() != "approved")
{
return View("FailureView");
}
}
}
catch (Exception ex)
{
Logger.Log("Error" + ex.Message);
return View("FailureView");
}
return View("SuccessView");
}
This is the code for the IPN.
[HttpPost]
public HttpStatusCodeResult Receive()
{
//Store the IPN received from PayPal
LogRequest(Request);
//Fire and forget verification task
Task.Run(() => VerifyTask(Request));
//Reply back a 200 code
return new HttpStatusCodeResult(HttpStatusCode.OK);
}
private void VerifyTask(HttpRequestBase ipnRequest)
{
var verificationResponse = string.Empty;
try
{
var verificationRequest = (HttpWebRequest)WebRequest.Create("https://www.sandbox.paypal.com/cgi-bin/webscr");
//Set values for the verification request
verificationRequest.Method = "POST";
verificationRequest.ContentType = "application/x-www-form-urlencoded";
var param = Request.BinaryRead(ipnRequest.ContentLength);
var strRequest = Encoding.ASCII.GetString(param);
//Add cmd=_notify-validate to the payload
strRequest = "cmd=_notify-validate&" + strRequest;
verificationRequest.ContentLength = strRequest.Length;
//Attach payload to the verification request
var streamOut = new StreamWriter(verificationRequest.GetRequestStream(), Encoding.ASCII);
streamOut.Write(strRequest);
streamOut.Close();
//Send the request to PayPal and get the response
var streamIn = new StreamReader(verificationRequest.GetResponse().GetResponseStream());
verificationResponse = streamIn.ReadToEnd();
streamIn.Close();
}
catch (Exception exception)
{
Logger.Log("Error" + exception.Message);
//Capture exception for manual investigation
}
ProcessVerificationResponse(verificationResponse);
}
private void LogRequest(HttpRequestBase request)
{
// Persist the request values into a database or temporary data store
}
private void ProcessVerificationResponse(string verificationResponse)
{
if (verificationResponse.Equals("VERIFIED"))
{
Logger.Log("Verified");
// check that Payment_status=Completed
// check that Txn_id has not been previously processed
// check that Receiver_email is your Primary PayPal email
// check that Payment_amount/Payment_currency are correct
// process payment
}
else if (verificationResponse.Equals("INVALID"))
{
Logger.Log(verificationResponse);
}
else
{
//Log error
}
}
Now to clear things up. My understanding of the IPN is that when a customer purchases an item, the SELLER will get an email telling them that they have sold a product and then from this you can access transactionId etc.
So in my view i have a form with a button that looks like this.
#Html.ActionLink("Buy Now", "PaymentWithPaypal", new { Id = Model.Id, #class = "" })
This is what takes the customer to paypal where they can then purchase but this is where i am stuck because im not sure how to call the IPN or if it needs its own view.
ANY CLARITY WOULD BE OF MUCH HELP AT THIS MOMENT IN TIME.
One way is to put this under PayPal account settings. Once you click on your "App", below it you see the redirect url option. Just add it there. Paypal .net sdk doesn't have the option to pass notify_url. All other modes have. Because, paypal.net sdk accepts return_url which is usually the same action method as also mentioned in your code.
Check this:
https://developer.paypal.com/docs/classic/ipn/integration-guide/IPNSetup/#
In case you want to achieve real time events, you need to use webhooks now. Documentation below:
https://github.com/paypal/PayPal-NET-SDK/wiki/Webhook-Event-Validation

Azure Notification Hubs with Android - Sending notifications to subsets of users

I am currently building an Android messaging app and I am trying to send notifications to all users who are part of a group. I have an Azure Notification Hub set up which is working fine for sending a notification to all devices that are registered, but I cannot seem to get it working for just a subset of all user ie a group.
The devices register with Azure and with GCM on startup.
I have tried using "Tags" to try send a notification to an individual but I am not sure if I am doing it right... I must not be because it isn't working!
In the following code I am trying to send a notification to an individual by using their username as a Tag...
This is the code in my service to send a notification:
// POST api/notification
public async Task<IHttpActionResult> Post([FromBody]Notification notification)
{
var notificationToSave = new Notification
{
NotificationGuid = Guid.NewGuid().ToString(),
TimeStamp = DateTime.UtcNow,
Message = notification.Message,
SenderName = notification.SenderName
};
var recipientNames = await GetRecipientNamesFromNotificationHub();
var recipientNamesString = CreateCustomRecipientNamesString(recipientNames);
string notificationJsonPayload =
"{\"data\" : " +
" {" +
" \"message\": \"" + notificationToSave.Message + "\"," +
" \"senderName\": \"" + notificationToSave.SenderName + "\"," +
" \"recipientNames\": \"" + recipientNamesString + "\"" +
" }" +
"}";
var result = await _hubClient.SendGcmNativeNotificationAsync(notificationJsonPayload, "ken#test.com"); // If this second parameter is omitted then a notification is sent to all registered devices.
notificationToSave.TrackingId = result.TrackingId;
notificationToSave.Recipients = recipientNames;
await Session.StoreAsync(notificationToSave);
return Ok(notificationToSave);
}
And this is how I am registering a device on the Android side:
private void sendRegistrationIdToBackend(String registrationId) {
String backendBaseUrl = "http://myurl.net/";
if (backendBaseUrl == null || backendBaseUrl == "")
{
return;
}
PushNotificationClient client = new PushNotificationClient(backendBaseUrl);
Device device = createDevice(registrationId);
client.registerDevice(device, new Callback<Device>() {
#Override
public void success(Device device, Response response) {
//writeStringToSharedPreferences(SettingsActivity.SETTINGS_KEY_DEVICEGUID, device.DeviceGuid);
Toast.makeText(context, "Device successfully registered with backend, DeviceGUID=" + device.DeviceGuid, Toast.LENGTH_LONG).show();
}
#Override
public void failure(RetrofitError retrofitError) {
Toast.makeText(context, "Backend registration error:" + retrofitError.getMessage(), Toast.LENGTH_LONG).show();
}
});
Log.i(TAG, registrationId);
}
private Device createDevice(String registrationId) {
Device device = new Device();
device.Platform = "Android";
device.Token = registrationId;
device.UserName = LogInActivity.loggedInUser;
device.DeviceGuid = null;
//todo set device.PlatformDescription based on Android version
device.SubscriptionCategories = new ArrayList<>();
device.SubscriptionCategories.add("ken#test.com"); // This should be adding this username as a Tag which is referenced in the service.... Not sure if this is how I should do it!
return device;
}
This is how I registering a device:
private async Task<RegistrationDescription> RegisterDeviceWithNotificationHub(Device device)
{
var hubTags = new HashSet<string>()
.Add("user", new[] { device.UserName })
.Add("category", device.SubscriptionCategories);
var hubRegistrationId = device.HubRegistrationId ?? "0";//null or empty string as query input throws exception
var hubRegistration = await _hubClient.GetRegistrationAsync<RegistrationDescription>(hubRegistrationId);
if (hubRegistration != null)
{
hubRegistration.Tags = hubTags;
await _hubClient.UpdateRegistrationAsync(hubRegistration);
}
else
{
hubRegistration = await _hubClient.CreateGcmNativeRegistrationAsync(device.Token, hubTags);
}
return hubRegistration;
}
good evening.
You should try check your registrations by using Visual studio 2015.
Install it, connect azure, azure hubs, registred devices. And try send your test message on test token (+check "does your registration exist on notification hub").

Windows store app C# Catch Error

I am developing a Windows store app, however I used this method to generate an user id when the app open by first time
private string host = "http://etc.com";
public async void RegisterUsuario() {
string displayName = await UserInformation.GetDisplayNameAsync();
string url = host + "/json/Register.php?code=" + displayName;
try
{
var http = new HttpClient();
var jsonText = await http.GetStringAsync(url);
var jsonValues = JsonArray.Parse(jsonText)[0];
var status = jsonValues.GetObject().GetNamedString("status");
if (status == "error")
{
var dialog = new MessageDialog("No se pudo registrar tu usuario", "¡Oops!");
await dialog.ShowAsync();
}
else
{
ApplicationDataContainer localSettings = ApplicationData.Current.LocalSettings;
localSettings.Values["usuario"] = jsonValues.GetObject().GetNamedNumber("id");
}
}
catch {
alertCatch("No se pudo registrar tu usuario");
}
}
THE JSON RESPONSE:
[{"status":"success","id":32}]
The problem:
In my pc always works fine, but when I submit the app to the windows store I always get this:
http://imgur.com/lOT09l7
the same error that will show the app in the CATCH.
Can you help me, maybe something in the appxmanifest?
In capabilities I selected private and public networks

Categories