Duplicate CallRecords from MS Graph API - microsoft-graph-api

I have set up a webhook/subscription mechanism to receive push notifications of Teams calls. I am then passing those ID values to the CallRecord API endpoint to retrieve call data. This is then being streamed using Stream Analytics to a database.
Going through the data, there are lots of duplicate calls with the same call ID being pushed at various different times several hours apart in some cases.
I have noticed that the CallRecord API endpoint as of yesterday has been moved out of beta/preview. Is this a bug?

Short version:
In my case what removed the duplicates was responding with status 200 ok at the end of my notificationUrl handler.
Long version:
I had the (same?) problem of receiving the same change notification for the same callRecord id and the same subscription every 5 minutes.
I was using a http triggered flow for the notificationUrl but only consumed the data and didn't respond.
Then I saw the Microsoft video introducing deltas and change notifications again and noticed that the azure function in their example responds with okay in the end.
After I added a http 200 response in my Flow, the duplicate change notifications stopped after the next run.

Related

Apple Push Notifications from a serverless MongoDB App Services backend

I have been setting up Apple Push Notifications for an iOS app, using JSON Web Tokens rather than certificates.
I can generate a JWT and make the required POST request from within the app (using the Swift-JWT package) and the notification is delivered.
I am using MongoDB Realm, which has serverless functions (in JavaScript with a Node environment) that are called from the iOS app. A scheduled trigger updates my JWT, as Apple advise it should be refreshed every hour.
However, despite trying several Node modules for making the POST request there were always errors (like “BadDeviceToken” or “InvalidProviderToken”).
I finally got it working using the node-apn package! However, I have two queries about using it in this serverless function context:
It tries to keep a connection open to the Apple server, which would be fine, except it might mean a new connection is opened every time the function is called. Calling Provider.shutdown() does not seem to stop the connection. I don’t think I can have a long-running process to receive future requests in a serverless context.
Apple advise not refreshing the JWT more often than every 20 minutes. node-apn manages the JWT for you, but in a serverless context, will it be generating a new token every time the function is called? Notifications do seem to get delivered every time I test it in development mode (to the Apple sandbox endpoint).
I’d be grateful for clarity on these points, and whether node-apn is appropriate to use in serverless functions.
Update
Provider.shutdown() not working seems to be a recognised issue.
I was able to shut down using this workaround:
Provider.client.endpointManager._endpoints.forEach(endpoint => endpoint.destroy());
I would still like to know about whether it is reasonable for this to be used in a serverless function. I am concerned about JWT being refreshed with every request, which Apple may not like!
I have scanned through Apple's documentation on this and given some thought to your question about refreshing tokens within a serverless context.
You could imagine the following approach for ensuring that you refresh the token no more than once every 20 minutes and at least once every hour, as per Apple's documentation:
Generate the token for sending a single notification request
Send the notification, and then after, in the background, save that token to some collection (e.g apn_tokens) inside of MongoDB (optionally alongside a createdAt timestamp field)
On the next request to send a push notifcation, fetch the stored JWT token from your server.
If the token's createdAt date (or iat field on the JWT itself) is less than an hour (or within some threshold less than the hour e.g 50 mins), then reuse the token in sending the push notification request
Otherwise, restart the process from step 1!
Note on this process: It would require that your database (or theapn_tokens collection) is only accessible from trusted sources (i.e your cloud application/functions alone), if they aren't already. Clients should not have access to this table in any way. You can imagine setting Collection-Level Access Control for your serverless environment. As an extra layer of security, you could imagine deleting "expired" tokens after re-generation in step 1, such that there is only one token present in the table at any time in order to prevent potentially active tokens from laying around in the database without use.
I hope this helps!

Alamofire for iOS Track Number of Active Download Requests

I am trying to find a simple way to display a counter in the status bar of my app that shows the current number of active downloads using the AlamoFire package in the default session.
We have both data downloads and image/document downloads that occur sumiltainiously. I cannot find a solution as all my searches either return information about the authtoken interceptor or how to cancel request. I have tried using snippets from both of those solutions but cannot get the function to return more than 1 active request when I know there is actually 3 - 25 active requests in process.
Currently I am using a notification that I created to says a request has started and adding 1 to the counter. I am then also sending a notification when a request completes either successful or unsuccessful that subtracts 1 from the counter. The issue comes when the app is placed in the background and/or there was a request that was retried by the interceptor causing the count to go negative or get stuck being positive.
I have handled the uploads by using my uploads queue and simply retrieving the count. I do not have a similar queue for downloads as the history of them is not as important to us and we don't have start, in process, and completed triggers for them like we do uploads.

What happens with Microsoft Graph webhooks if the receiver is down?

The documentation for Microsoft Graph webhooks is not clear on the durability of events. If a client creates a subscription and then subsequently goes down (say, for maintenance), what happens to events that occur while the client is unavailable? Are they queued and retried by the Microsoft Graph until the client comes back online, or are they lost? If they are queued, for how long?
Graph Webhook will try to send the events a number of times within 4 hours window. If the client does not come back online after 4 hours, then these events will be deleted.

iOS: Unable to fetch Offline messages for XMPP Chat

I am facing an issue with the presence status, following the documentation and XMPPframework example code. I have written a chat application.
Problem : When the user 1 & 2 are online I get the status successfully and they can chat with each other. However when the user 2 goes physically offline via (Wifi OFF / 3G Off) User 1 is not getting the offline status from XMPP and hence what ever messages are sent from that instant of time are lost when the user 2 comes online.
It seems since the user 2 is not notified or stored as offline in XMPP and hence its not storing the offline messages to push back to user 2 when it comes online.
I have tried to resolve this by explicitly writing a [goOffline] call to XMPP, however the call is shown in 'SEND log' for 'user 2' but not received in 'RECV log' in user 1 from XMPP, due to which the message are lost in between.
Also tried with other sources replies.
Set status for presence available and send XMPP
priority changed with values non-negative
XMPPArchiving work but this is not what I wanted.
Server side Mod_zero push enables but get only first message push notification sometimes.
Setting limit on ejabberd.cfg file for users and offline message limit.
request for offline message pull.
Can anyone help me with this?
This is very typical situation where client losses network but server can't detect that it is offline.
To detect status of each client, server need to send PING packets to every client and wait for response.
If client responds then fine otherwise server will mark that client as offline and every other online client will be informed automatically.
Here is PING Module implementation for ejabberd XMPP Server (hope you are using ejabberd server):
mod_ping:
send_pings: true
ping_interval: 10
timeout_action: kill
ping_ack_timeout: 10
This has to be written in ejabberd.yml configuration file.
At client side also we need to enable ping module to respond to server pings as:
private var xmppPing: XMPPPing?
xmppPing = XMPPPing()
xmppPing!.activate(xmppStream!)
This code has to be written while we setupStream() for iOS.
For detailed info, please go through mod_ping documentations.
Sounds like your problem is at server level. The server thinks that the user is online so it sends the message but nobody gets it. This does not really have a simple solution.
1.
The best solution would be delivery receipts. Where basically when the message is sent to your client, your client returns a confirmation of delivery receipt. If the server does not get that receipt it would resend the message every n time. Depending on your XMPP server you might find a already made solution, of not you would have to roll out your own.
2.
A possible hack would be to have your server always store and deliver last 10 messages and then at client side you discard repeated... This also depends on your server implementation. XMPP MUC and PubSub have resources along these lines.
For a long term scalable solution, you'll need to deal with this both at server and client level.

IOS api call continuously

If I have a app in which the user can set remainders for when there is a new article in a blog. And we can find out if there is a new article in the blog by sending a api request. How should I make the app to continuously send requests to the api. Is there an other way to do this or should we just keep sending requests to api continuously. And if so in how much time interval should we send it.
Thanks
In this case delegating the check for updates to some sort of server side would be ideal. The server side logic could send push notifications to your clients.

Resources