Getting two many push notifications from google calendar api after an action - asp.net-web-api

I am developing an app that syncs with my google calendar with my database.
I Have everything running, but I have a problem.
Every time I do an action (add, delete, update) on my google calendar I receive multiple push notifications for the same event, and after a few events, I get blocked by Google services (403-user-rate-limit-exceeded).
to every notification i am answering with the proper status code, here is my code:
[HttpPost, Route("notifications")]
public HttpResponseMessage Notifications()
{
try
{
this.googleCalendarService.PerformEventsSync();
var response = this.Request.CreateResponse(HttpStatusCode.OK);
response.Content = new StringContent("200");
return response;
}
catch (Exception e)
{
log.Error(e);
return this.Request.CreateResponse(HttpStatusCode.InternalServerError);
}
}

Ok, so i found what was going on.
Turns out that while I was debugging and deploying my app I was creating multiple watch channels.
What i did:
Created a variable to save my active channel id and it's expiration time
On each received notification I retrieve the header "X-Goog-Channel-ID"
Before preforming my sync I assure that its comming from the correct channel (my app can only have one channel)
When my expiration time is coming to an end I refresh my channel
Thank you

Related

Spring Webflex: Push Server Sent Event to Specific Users

I have been following this for reference. I am developing a spring-boot app which will have authenticated users. Once logged in, a user will subscribe to an event by visiting a specific URL.
This spring-boot app will also either support MQTT (or maybe just HTTP requests) in which information for a specific user will be sent. I would like to then display this sent information to the user using web flux/SSE if the user has subscribed.
Many users can be logged in at any given time, and they will have all subscribed to the updates. How do I manage all the different sinks for each logged in user?
I believe it's possible to get the current user when they visit the authenticated URL, but what's a method of storing all of the sinks for each logged in user?
I appreciate it.
You already got the answer in the comment section.
Lets assume that this is the message format you would be publishing.
public class Message {
private int intendedUserId;
private String message;
// getters and setters
}
Just have 1 processor and sink from the processor.
FluxProcessor<Message> processor;
FluxSink<Message> sink;
Push all the messages via the sink.
sink.next(msg);
Your controller would be more or less like this. Here I assume you have some method to get the user id authtoken.getUserId(). Here the filter is part of the Flux.
#GetMapping(value = "/msg", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
public Flux<Message> getMessages(){
return processer
.filter(msg -> msg.getIntendedUserId() == authtoken.getUserId());
}

Sending a message from parent page to AWS Lex Bot

I'm trying to restrict my Lex Bot to only show results of a SQL Search that a certain User has access to. For example, if User A only has access to records that belong to User A, the Bot will not allow User A to search for records that belong to User B.
Right now, I've got my Bot set up on a website that I've hosted via AWS S3. The issue I'm facing right now is getting my user's login information from the parent page (the website I've set up in S3) and sending it to my Lex Bot (which I've embedded as an Iframe).
The login to the page is done via Google Login which saves an Access Token in my SQL Database. I'd like to know how I can send this access token to my Lex Bot so I can authenticate it via Lambda. (I've already got the Lambda portion done, just need to know how to get the message from the parent page. Ideally, this part happens before the User talks to the Bot, which means a postback message so the user cannot see this information)
Things I've tried:
- I've tried doing a separate lambda function to handle this part only but don't really know how to integrate it into the website.
- I've tried using event listeners but am not very sure if the message goes to the bot or just the IFrame.
Right now, I'm out of ideas and any help would be greatly appreciated.
I managed to finally do it by adding a Javascript function to post a message. It doesn't look very professional but it works.
function isBotMinimized() {
return $('.' + lexWebUi.options.containerClass)
.hasClass('lex-web-ui--minimize');
}
function sendMessage() {
return Promise.resolve()
.then(function () {
return !isBotMinimized() ||
lexWebUi.sendMessageToIframe({ event: 'toggleMinimizeUi' });
})
.then(function () {
return lexWebUi.sendMessageToIframe({ event: 'postText', message: "Welcome"});
})
.then(function () { console.log('message succesfully sent'); })
.catch(function (error) { console.error('error sending message ', error); });
}

Invoking InvokeApiAsync Mobile App Services

I'm working on a Xamarin.Forms project, and I'm having a really weird issue. This code is actually executing in Xamarin.Droid project.
When I try to do this
var user = await client.LoginAsync(this, MobileServiceAuthenticationProvider.Facebook);
if (user != null)
{
try
{
// executes this line
var userInfo = await client.InvokeApiAsync("/.auth/me");
// down here nothing is executed and userInfo is never set with the data
}
catch (Exception e)
{
// never enter to this block
}
}
The userInfo variable is never set with the data, and no exceptions and nothing rare in the Output.
I already tried client.InvokeApiAsync("/.auth/me", HttpMethod.Get, null) but no works neither.
I know this is quite short information but I haven't anything else, because no exception is raised.
Thanks.
I followed this article to add authentication to my Xamarin Forms app. It worked fine on my side. There are some things you need to check on your project.
Have you published your Azure Mobile Service to Azure and turn on the Authentication & configured Facebook app-id and secret.
Have you connected your mobile service from your mobile client.
I finally figured out what was the problem. The event handler that initiates the logic of authentication, returned void instead of Task, so the async call never continues after await call.
This is something for remind.
Thanks #Amor - MSFT for your answer.

How to avoid 'Choose Account' screen with Google Calendar API?

Our app is importing the next 1000 events from a user's Google calendar API. We ran into the problem where nginx would timeout. To get around this I'm putting the pagination data into a session variable and making separate HTTP requests to the API. This works except for one problem: every time we make a new HTTP request the API asks the user to choose which account they want to use (one user with multiple gmail accounts). I would have thought that the pagination data would include account selection but this is apparently not the case. How can I programmatically select the email account within the HTTP request?
You can store it once
public static void setmCredential(GoogleAccountCredential _mCredential) {
mCredential = _mCredential;
mService = new com.google.api.services.calendar.Calendar.Builder(
transport, jsonFactory, mCredential)
.setApplicationName("YourApplicationName")
.build();
}
And then when caliing pass it like this
new MakeRequestTask(AccountCredential.mService).execute();

Does Notification Cloud URI have any limits?

I have working with Push Notification in WindowsPhone. I'm able to send the Notification from the server and receive it in Windows Phone.
I'm using the url for cloud generated by the below code. Does any of you guys knows is there any limitation for this url like time limit or licensing etc..
Since when my app is get launched we need to create n no of url for the every user.
/// Holds the push channel that is created or found.
HttpNotificationChannel pushChannel;
// The name of our push channel.
string channelName = "ToastSampleChannel";
InitializeComponent();
// Try to find the push channel.
pushChannel = HttpNotificationChannel.Find(channelName);
// If the channel was not found, then create a new connection to the push service.
if (pushChannel == null)
{
pushChannel = new HttpNotificationChannel(channelName);
// Register for all the events before attempting to open the channel.
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
// Register for this notification only if you need to receive the notifications while your application is running.
pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
pushChannel.Open();
// Bind this new channel for toast events.
pushChannel.BindToShellToast();
}
else
{
// The channel was already open, so just register for all the events.
pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(PushChannel_ChannelUriUpdated);
pushChannel.ErrorOccurred += new EventHandler<NotificationChannelErrorEventArgs>(PushChannel_ErrorOccurred);
// Register for this notification only if you need to receive the notifications while your application is running.
pushChannel.ShellToastNotificationReceived += new EventHandler<NotificationEventArgs>(PushChannel_ShellToastNotificationReceived);
// Display the URI for testing purposes. Normally, the URI would be passed back to your web service at this point.
System.Diagnostics.Debug.WriteLine(pushChannel.ChannelUri.ToString());
MessageBox.Show(String.Format("Channel Uri is {0}",
pushChannel.ChannelUri.ToString()));
}
Thanks in advance.
Thanks
Kamal.
As I know, there are only three limits with Push Notifications:
MPNS allows both unauthenticated and authenticated notifications. However, unauthenticated push requests are throttled if they exceed 500 messages per day (per device). There are no such restrictions on authenticated requests which uses client SSL for authentication.
1 notification channel per application
Maximum notification channels on device are 30

Resources