private static void SendNotification(string deviceToken, string title, string body, int badgeCount, string sound) { //Create our push services broker var push = new PushBroker(); //Wire up the events for all the services that the broker registers push.OnNotificationSent += NotificationSent; push.OnChannelException += ChannelException; push.OnServiceException += ServiceException; push.OnNotificationFailed += NotificationFailed; push.OnDeviceSubscriptionExpired += DeviceSubscriptionExpired; push.OnDeviceSubscriptionChanged += DeviceSubscriptionChanged; push.OnChannelCreated += ChannelCreated; push.OnChannelDestroyed += ChannelDestroyed; //------------------------------------------------ //IMPORTANT NOTE about Push Service Registrations //------------------------------------------------ //Some of the methods in this sample such as 'RegisterAppleServices' depend on you referencing the correct //assemblies, and having the correct 'using PushSharp;' in your file since they are extension methods!!! // If you don't want to use the extension method helpers you can register a service like this: //push.RegisterService<WindowsPhoneToastNotification>(new WindowsPhonePushService()); //If you register your services like this, you must register the service for each type of notification //you want it to handle. In the case of WindowsPhone, there are several notification types! //------------------------- // APPLE NOTIFICATIONS //------------------------- //Configure and start Apple APNS // IMPORTANT: Make sure you use the right Push certificate. Apple allows you to generate one for connecting to Sandbox, // and one for connecting to Production. You must use the right one, to match the provisioning profile you build your // app with! var appleCert = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "../../../Resources/OLBPhoneSandboxCertificate.p12")); //IMPORTANT: If you are using a Development provisioning Profile, you must use the Sandbox push notification server // (so you would leave the first arg in the ctor of ApplePushChannelSettings as 'false') // If you are using an AdHoc or AppStore provisioning profile, you must use the Production push notification server // (so you would change the first arg in the ctor of ApplePushChannelSettings to 'true') ApplePushChannelSettings appleSettings = new ApplePushChannelSettings(false, appleCert, "0lbSandb0x"); push.RegisterAppleService(appleSettings); //Extension method AppleNotification notification = new AppleNotification(); notification.ForDeviceToken(deviceToken); AppleNotificationAlert alert = new AppleNotificationAlert(); if (!string.IsNullOrWhiteSpace(title)) { alert.Title = title; } if (!string.IsNullOrWhiteSpace(body)) { alert.Body = body; } notification.WithAlert(alert); if (badgeCount >= 0) { notification.WithBadge(badgeCount); } if (!string.IsNullOrWhiteSpace(sound)) { notification.WithSound(sound); } push.QueueNotification(notification); //--------------------------- // ANDROID GCM NOTIFICATIONS //--------------------------- //Configure and start Android GCM //IMPORTANT: The API KEY comes from your Google APIs Console App, under the API Access section, // by choosing 'Create new Server key...' // You must ensure the 'Google Cloud Messaging for Android' service is enabled in your APIs Console push.RegisterGcmService(new GcmPushChannelSettings("AIzaSyAQTRCFjVX5LQ0dOd4Gue4_mUuv3jlPMrg")); //Fluent construction of an Android GCM Notification //IMPORTANT: For Android you MUST use your own RegistrationId here that gets generated within your Android app itself! push.QueueNotification( new GcmNotification().ForDeviceRegistrationId("APA91bHr5W1cNl5mcZ_iWqGKVnvcXeZwYdVGCCFjt0M8egamRAIq5lCASbUQe-3E9M74CiD8Moildh4SC8Qj6qUUpCnNOQ5v17A9go1enqDipOGSaeiDU_I3fGroneA7tL3FAMlN60nW") .WithJson("{\"alert\":\"Hello Leslie!\",\"badge\":7,\"sound\":\"sound.caf\"}")) ; //----------------------------- // // WINDOWS PHONE NOTIFICATIONS // //----------------------------- // //Configure and start Windows Phone Notifications // push.RegisterWindowsPhoneService(); // //Fluent construction of a Windows Phone Toast notification // //IMPORTANT: For Windows Phone you MUST use your own Endpoint Uri here that gets generated within your Windows Phone app itself! // push.QueueNotification(new WindowsPhoneToastNotification() // .ForEndpointUri(new Uri("DEVICE REGISTRATION CHANNEL URI HERE")) // .ForOSVersion(WindowsPhoneDeviceOSVersion.MangoSevenPointFive) // .WithBatchingInterval(BatchingInterval.Immediate) // .WithNavigatePath("/MainPage.xaml") // .WithText1("PushSharp") // .WithText2("This is a Toast")); // // // //------------------------- // // WINDOWS NOTIFICATIONS // //------------------------- // //Configure and start Windows Notifications // push.RegisterWindowsService(new WindowsPushChannelSettings("WINDOWS APP PACKAGE NAME HERE", // "WINDOWS APP PACKAGE SECURITY IDENTIFIER HERE", "CLIENT SECRET HERE")); // //Fluent construction of a Windows Toast Notification // push.QueueNotification(new WindowsToastNotification() // .AsToastText01("This is a test") // .ForChannelUri("DEVICE CHANNEL URI HERE")); Console.WriteLine("Waiting for Queue to Finish..."); //Stop and wait for the queues to drains push.StopAllServices(); Console.WriteLine("Queue Finished, press return to exit..."); Console.ReadLine(); }
/// <summary> /// The main processor method used to process a single push notification, checks if the processing will be an immediate single push or regular thread looping model. /// Looks up for a single (or more if you wish) entity in the databae which has not been processed. /// Puts the fetched unprocessed push notification entity to processing over the Push Sharp API. /// Finally saves the state of processing. /// </summary> /// <param name="databaseContext">The current database context to be used for processing to the database.</param> /// <param name="pushNotification">A single push notification entity to be processed and saved.</param> /// <param name="isDirectSinglePush">Decides wethere the processing will take place immediately for the sent notification or will the method lookup from the database for a first unprocessed push notification.</param> /// <returns>True if all OK, false if not.</returns> public bool ProcessNotification(PushSharpDatabaseContext dbContext, PushNotification pushNotification = null, bool isDirectSinglePush = false) { _databaseContext = dbContext; _isDirectSinglePush = isDirectSinglePush; if (_isDirectSinglePush) { InitBroker(); } On(DisplayMessage, "Checking for unprocessed notifications..."); PushNotification notificationEntity = pushNotification; try { if (notificationEntity != null) { // save a new immediate unprocessed push notification _databaseContext.PushNotification.Add(pushNotification); _databaseContext.SaveChanges(); // reload the entity notificationEntity = _databaseContext.PushNotification .Where(x => x.ID == pushNotification.ID) .Include(x => x.MobileDevice) .Include(x => x.MobileDevice.Client) .FirstOrDefault(); } else // take one latest unprocessed notification, this can be changed to take any set size instead of one { notificationEntity = _databaseContext.PushNotification.FirstOrDefault(s => s.Status == (int)PushNotificationStatus.Unprocessed && s.CreatedAt <= DateTime.Now); } } catch (Exception ex) { On(DisplayErrorMessage, "EX. ERROR: Check for unprocessed notifications: " + ex.Message); SimpleErrorLogger.LogError(ex); } // Process i.e. push the push notification via PushSharp... if (notificationEntity != null) { bool messagePushed = true; On(DisplayStatusMessage, "Processing notification..."); On(DisplayMessage, "ID " + notificationEntity.ID + " for " + notificationEntity.MobileDevice.Client.Username + " -> " + notificationEntity.Message); //--------------------------- // ANDROID GCM NOTIFICATIONS //--------------------------- if (notificationEntity.MobileDevice.SmartphonePlatform == "android") { var gcmNotif = new GcmNotification() { Tag = notificationEntity.ID }; string msg = JsonConvert.SerializeObject(new { message = notificationEntity.Message }); gcmNotif.ForDeviceRegistrationId(notificationEntity.MobileDevice.PushNotificationsRegistrationID) .WithJson(msg); _broker.QueueNotification(gcmNotif); UpdateNotificationQueued(notificationEntity); } ////------------------------- //// APPLE iOS NOTIFICATIONS ////------------------------- else if (notificationEntity.MobileDevice.SmartphonePlatform == "ios") { var appleNotif = new AppleNotification() { Tag = notificationEntity.ID }; var msg = new AppleNotificationPayload(notificationEntity.Message); appleNotif.ForDeviceToken(notificationEntity.MobileDevice.PushNotificationsRegistrationID) .WithPayload(msg) .WithSound("default"); _broker.QueueNotification(appleNotif); UpdateNotificationQueued(notificationEntity); } //---------------------- // WINDOWS NOTIFICATIONS //---------------------- else if (notificationEntity.MobileDevice.SmartphonePlatform.Equals("wp") || notificationEntity.MobileDevice.SmartphonePlatform.Equals("wsa")) { var wNotif = new WindowsToastNotification() { Tag = notificationEntity.ID }; wNotif.ForChannelUri(notificationEntity.MobileDevice.PushNotificationsRegistrationID) .AsToastText02("PushSharp Notification", notificationEntity.Message); _broker.QueueNotification(wNotif); UpdateNotificationQueued(notificationEntity); } else { On(DisplayErrorMessage, "ERROR: Unsupported device OS: " + notificationEntity.MobileDevice.SmartphonePlatform); notificationEntity.Status = (int)PushNotificationStatus.Error; notificationEntity.ModifiedAt = DateTime.Now; notificationEntity.Description = "(Processor) Unsupported device OS: " + notificationEntity.MobileDevice.SmartphonePlatform; SimpleErrorLogger.LogError(new Exception("EX. ERROR: " + notificationEntity.Description)); messagePushed = false; } try { // Save changes to DB to keep the correct state of messages _databaseContext.SaveChanges(); // bubble out the single push error, else return true to continue iteration if (_isDirectSinglePush) { return(messagePushed); } return(true); } catch (Exception ex) { On(DisplayErrorMessage, "EX. ERROR: Updating notification, DB save failed: " + ex.Message); SimpleErrorLogger.LogError(ex); // bubble out the single push error, else return true to continue iteration if (_isDirectSinglePush) { return(false); } return(true); } finally { if (_isDirectSinglePush) { KillBroker(_databaseContext); } } } else { if (_isDirectSinglePush) { KillBroker(_databaseContext); } // no messages were queued, take a nap... return(false); } }