Outlook REST API 500 LegacyPagingToken error - outlook

I am using the Microsoft Outlook REST API to synchronize messages in a folder using skipTokens with the Prefer: odata.track-changes header.
After 62 successful rounds of results, I get an error 500 ErrorInternalServerError with the message Unable to cast object of type 'LegacyPagingToken' to type 'Microsoft.Exchange.Services.OData.Model.SkipToken'
I have tried:
Retrying the same query (https://outlook.office.com/api/v2.0/me/MailFolders/Inbox/messages/?%24skipToken=1BWUA9eXs5dN89tPsr_FOvtzINQAA0Cwk5o), which results in the same error
Restarting the sync, which results in the same error at the same point
Adding a new message to the Inbox and restarting the sync, which results in the same error at the same point
Moving the messages from that part of the sync to another folder (in case the messages themselves were causing the problem), which results in the same error at the same point
Has anybody run into this error or have suggestions on what might cause it or workarounds?

It looks like the issue was on my end while parsing the skipToken from the #odata.nextLink response. The token in the original question is invalid - the actual skipToken passed back from the API had -AAAA on the end. After 63 queries, in which the skipToken increments, the Base64 encoded form started using characters the regexp I was using didn't find. Switching from a \w regexp to a proper URL parser solved the problem.

Related

Outlook REST API 410 Error: SyncStateNotFound

I get a 410 when syncing messages:
{\"code\":\"SyncStateNotFound\",\"message\":\"The sync state
generation is not found; generation=1;[highest=4][4][2][3].\"}
This only occurs when syncing messages for select mailfolders on select accounts. It occurs when making a post-initial sync using the relevant delta token. I can recreate this via making
GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages/?$deltaToken={delta_token}
In Microsoft's Outlook Sandbox.
Here are the literal steps it takes to reproduce deterministically:
1) Initial Message Sync:
GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages
2) Sync with initial delta token:
GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages/?$deltaToken={delta_token}
3) Sync with skip token until delta token:
GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages/?$skipToken={skip_token}
4) ERROR OCCURS HERE: Mailfolder receives update, so I re-sync messages with delta token from (3). The call below throws a 410 and I can't sync messages.
GET https://outlook.office365.com/api/v2.0/me/MailFolders('{folder_id}')/messages/?$deltaToken={delta_token}
To reiterate: I've isolated this to just testing in the Outlook sandbox, and it still occurs. Testing as in making the GET call to sync (i.e., make perform (2)) using the deltaToken from (3) and its corresponding folderId as query parameters.
Dumb Mistake: Passed in initial delta token as opposed to current.

Seeing a lot of "stream error: stream ID 1221; PROTOCOL_ERROR" since 23rd March from a single Linode DC

We've had a lot of these errors from only one of our DCs - running the same code as others globally.
For example:
2017/03/31 13:22:03 Error sending request to BigQuery (attempt 1 of 3): Post https://www.googleapis.com/bigquery/v2/projects/coull-delta/datasets/demand/tables/table_name/insertAll?alt=json: stream error: stream ID 1221; PROTOCOL_ERROR
It uses the Big Query Go package from google - https://godoc.org/google.golang.org/api
Anyone got any ideas? Seen this before? As I said, exactly the same code running in other places with no issue.

IRS AIR 1095B Manifest Schema -- OriginalReceiptID

I'm attempting to upload AIR test 2C via the IRS UI web portal and received the following submission error: "The manifest file does not match our current schema. In particular, our system has detected a potential issue with the following element(s)" OriginalReceiptID
Here's our manifest file:
top portion of our manifest file
Can anyone find the errors of my ways?
You need to provide the OriginalReceiptId (on the Manifest) only when sending a Replacement record type for a previously "Rejected" Transmission.
The OriginalUniqueSubmissionId (on the 1094-C) should be provided only when sending a Replacement record type for a previously "Rejected" Submission.
Note: You will receive Transmission-level error if you include both the OriginalReceiptId and OriginalUniqueSubmissionId. The type of rejection dictates which one is needed to be used. The Type of Rejection is caused by either the Transmission or Submission, and is defined by the reason for the rejection and the structure of the Error Data File received from the status response.
CorrectedUniqueSubmissionId on the 1094-C is used when sending a
Correction record type for a previously "Accepted" or "Accepted with Errors" 1094-C record.
CorrectedUniqueRecordId on the 1095-C is used when sending a
Correction record type for a previously "Accepted" or "Accepted with Errors" 1095-C record.
I don't think you need original receipt id for the correction files, it is for rejected files. refer to IRS air composition referece guide at https://www.irs.gov/pub/irs-pdf/p5165.pdf

Scraping Real Time Visitors from Google Analytics

I have a lot of sites and want to build a dashboard showing the number of real time visitors on each of them on a single page. (would anyone else want this?) Right now the only way to view this information is to open a new tab for each site.
Google doesn't have a real-time API, so I'm wondering if it is possible to scrape this data. Eduardo Cereto found out that Google transfers the real-time data over the realtime/bind network request. Anyone more savvy have an idea of how I should start? Here's what I'm thinking:
Figure out how to authenticate programmatically
Inspect all of the realtime/bind requests to see how they change. Does each request have a unique key? Where does that come from? Below is my breakdown of the request:
https://www.google.com/analytics/realtime/bind?VER=8
&key= [What is this? Where does it come from? 21 character lowercase alphanumeric, stays the same each request]
&ds= [What is this? Where does it come from? 21 character lowercase alphanumeric, stays the same each request]
&pageId=rt-standard%2Frt-overview
&q=t%3A0%7C%3A1%3A0%3A%2Ct%3A11%7C%3A1%3A5%3A%2Cot%3A0%3A0%3A4%2Cot%3A0%3A0%3A3%2Ct%3A7%7C%3A1%3A10%3A6%3D%3DREFERRAL%3B%2Ct%3A10%7C%3A1%3A10%3A%2Ct%3A18%7C%3A1%3A10%3A%2Ct%3A4%7C5%7C2%7C%3A1%3A10%3A2!%3Dzz%3B%2C&f
The q variable URI decodes to this (what the?):
t:0|:1:0:,t:11|:1:5:,ot:0:0:4,ot:0:0:3,t:7|:1:10:6==REFERRAL;,t:10|:1:10:,t:18|:1:10:,t:4|5|2|:1:10:2!=zz;,&f
&RID=rpc
&SID= [What is this? Where does it come from? 16 character uppercase alphanumeric, stays the same each request]
&CI=0
&AID= [What is this? Where does it come from? integer, starts at 1, increments weirdly to 150 and then 298]
&TYPE=xmlhttp
&zx= [What is this? Where does it come from? 12 character lowercase alphanumeric, changes each request]
&t=1
Inspect all of the realtime/bind responses to see how they change. How does the data come in? It looks like some altered JSON. How many times do I need to connect to get the data? Where is the active visitors on site number in there? Here is a dump of sample data:
19
[[151,["noop"]
]
]
388
[[152,["rt",[{"ot:0:0:4":{"timeUnit":"MINUTES","overTimeData":[{"values":[49,53,52,40,42,55,49,41,51,52,47,42,62,82,76,71,81,66,81,86,71,66,65,65,55,51,53,73,71,81],"name":"Total"}]},"ot:0:0:3":{"timeUnit":"SECONDS","overTimeData":[{"values":[0,1,1,1,1,0,1,0,1,1,1,0,2,0,2,2,1,0,0,0,0,0,2,1,1,2,1,2,0,5,1,0,2,1,1,1,2,0,2,1,0,5,1,1,2,0,0,0,0,0,0,0,0,0,1,1,0,3,2,0],"name":"Total"}]}}]]]
]
388
[[153,["rt",[{"ot:0:0:4":{"timeUnit":"MINUTES","overTimeData":[{"values":[52,53,52,40,42,55,49,41,51,52,47,42,62,82,76,71,81,66,81,86,71,66,65,65,55,51,53,73,71,81],"name":"Total"}]},"ot:0:0:3":{"timeUnit":"SECONDS","overTimeData":[{"values":[2,1,1,1,1,1,0,1,0,1,1,1,0,2,0,2,2,1,0,0,0,0,0,2,1,1,2,1,2,0,5,1,0,2,1,1,1,2,0,2,1,0,5,1,1,2,0,0,0,0,0,0,0,0,0,1,1,0,3,2],"name":"Total"}]}}]]]
]
388
[[154,["rt",[{"ot:0:0:4":{"timeUnit":"MINUTES","overTimeData":[{"values":[53,53,52,40,42,55,49,41,51,52,47,42,62,82,76,71,81,66,81,86,71,66,65,65,55,51,53,73,71,81],"name":"Total"}]},"ot:0:0:3":{"timeUnit":"SECONDS","overTimeData":[{"values":[0,3,1,1,1,1,1,0,1,0,1,1,1,0,2,0,2,2,1,0,0,0,0,0,2,1,1,2,1,2,0,5,1,0,2,1,1,1,2,0,2,1,0,5,1,1,2,0,0,0,0,0,0,0,0,0,1,1,0,3],"name":"Total"}]}}]]]
]
Let me know if you can help with any of the items above!
To get the same, Google has launched new Real Time API. With this API you can easily retrieve real time online visitors as well as several Google Analytics with following dimensions and metrics. https://developers.google.com/analytics/devguides/reporting/realtime/dimsmets/
This is quite similar to Google Analytics API. To start development on this,
https://developers.google.com/analytics/devguides/reporting/realtime/v3/devguide
With Google Chrome I can see the data on the Network Panel.
The request endpoint is https://www.google.com/analytics/realtime/bind
Seems like the connection stays open for 2.5 minutes, and during this time it just keeps getting more and more data.
After about 2.5 minutes the connection is closed and a new one is open.
On the Network panel you can only see the data for the connections that are terminated. So leave it open for 5 minutes or so and you can start to see the data.
I hope that can give you a place to start.
Having google in the loop seems pretty redundant. Suggest you use a common element delivered on demand from the dashboard server and include this item by absolute URL on all pages to be monitored for a given site. The script outputting the item can read the IP of the browser asking and these can all be logged into a database and filtered for uniqueness giving a real time head count.
<?php
$user_ip = $_SERVER["REMOTE_ADDR"];
/// Some MySQL to insert $user_ip to the database table for website XXX goes here
$file = 'tracking_image.gif';
$type = 'image/gif';
header('Content-Type:'.$type);
header('Content-Length: ' . filesize($file));
readfile($file);
?>
Ammendum:
A database can also add a timestamp to every row of data it stores. This can be used to further filter results and provide the number of visitors in the last hour or minute.
Client side Javascript with AJAX for fine tuning or overkill
The onblur and onfocus javascript commands can be used to tell if the the page is visible, pass the data back to the dashboard server via Ajax. http://www.thefutureoftheweb.com/demo/2007-05-16-detect-browser-window-focus/
When a visitor closes a page this can also be detected by the javascript onunload function in the body tag and Ajax can be used to send data back to the server one last time before the browser finally closes the page.
As you may also wish to collect some information about the visitor like Google analytics does this page https://panopticlick.eff.org/ has a lot of javascript that can be examined and adapted.
I needed/wanted realtime data for personal use so I reverse-engineered their system a little bit.
Instead of binding to /bind I get data from /getData (no pun intended).
At /getData the minimum request is apparently: https://www.google.com/analytics/realtime/realtime/getData?pageId&key={{propertyID}}&q=t:0|:1
Here's a short explanation of the possible query parameters and syntax, please remember that these are all guesses and I don't know all of them:
Query Syntax: pageId&key=propertyID&q=dataType:dimensions|:page|:limit:filters
Values:
pageID: Required but seems to only be used for internal analytics.
propertyID: a{{accountID}}w{{webPropertyID}}p{{profileID}}, as specified at the Documentation link below. You can also find this in the URL of all analytics pages in the UI.
dataType:
t: Current data
ot: Overtime/Past
c: Unknown, returns only a "count" value
dimensions (| separated or alone), most values are only applicable for t:
1: Country
2: City
3: Location code?
4: Latitude
5: Longitude
6: Traffic source type (Social, Referral, etc.)
7: Source
8: ?? Returns (not set)
9: Another location code? longer.
10: Page URL
11: Visitor Type (new/returning)
12: ?? Returns (not set)
13: ?? Returns (not set)
14: Medium
15: ?? Returns "1"
page:
At first this seems to work for pagination but after further analysis it looks like it's also used to specify which of the 6 pages (Overview, Locations, Traffic Sources, Content, Events and Conversions) to return data for.
For some reason 0 returns an impossibly high metrictotal
limit: Result limit per page, maximum of 50
filters:
Syntax is as specified at the Documentation 2 link below except the OR is specified using | instead of a comma.6==CUSTOM;1==United%20States
You can also combine multiple queries in one request by comma separating them (i.e. q=t:1|2|:1|:10,t:6|:1|:10).
Following the above "documentation", if you wanted to build a query that requests the page URL and city of the top 10 active visitors with a traffic source type of CUSTOM located in the US you would use this URL: https://www.google.com/analytics/realtime/realtime/getData?key={{propertyID}}&pageId&q=t:10|2|:1|:10:6==CUSTOM;1==United%20States
Documentation
Documentation 2
I hope that my answer is readable and (although it's a little late) sufficiently answers your question and helps others in the future.

Simplest Ad Hoc report request in Adwords generates no data. Why?

The following report definition continues to produce no data against all accounts:
<reportDefinition xmlns="https://adwords.google.com/api/adwords/cm/v201109">
<selector>
<fields>AccountDescriptiveName</fields>
<fields>AccountId</fields>
</selector>
<reportName>1_91_123_skinny</reportName>
<reportType>ACCOUNT_PERFORMANCE_REPORT</reportType>
<dateRangeType>YESTERDAY</dateRangeType>
<downloadFormat>TSV</downloadFormat>
</reportDefinition>
I don't get any error messages. Just no data from what would seem to be a perfectly legit reportDefinition? I've been using similar ones for some time with no problems. Any ideas?
The core issue is with zero-impression behavior:
http://googleadsdeveloper.blogspot.com/2011/12/zero-impression-data-in-adwords-api.html
The ACCOUNT_PERFORMANCE_REPORT doesn't support zero-impression rows, and even if you do have impressions you'll need ensure that you request the Impressions field.

Resources