Replies: 6 comments
-
Also, here is a code checking the same broken behavior for users.threads.list: Codeasync test2() {
console.log(
"Performing test if 'users.threads.list' returns threads sorted by decreasing dates and historyIDs of their first messages.",
)
const count = 100
const cfg: GmailApi.Params$Resource$Users$Threads$List = {
userId: 'me',
maxResults: count,
}
const resp = await Auth.catchAllOAuth(() => this.api.users.threads.list(cfg))
if (resp.isErr()) {
console.error('GMail API query error.', resp.error)
return
}
const list = resp.value.data.threads
if (list == null) {
console.error('GMail API invalid response.')
return
}
let isHistoryIdDecreasing = true
let isDateDecreasing = true
let prevHistoryId: null | number = null
let prevDate: null | number = null
let i = 0
for (const thread of list) {
i++
const id = thread.id
if (id == null) {
console.error('Thread is missing the "id" field.')
return
}
const threadQuery = {userId: 'me', id}
const threadResp = await Auth.catchAllOAuth(() => this.api.users.threads.get(threadQuery))
if (threadResp.isErr()) {
console.error('GMail API query error.', threadResp.error)
return
}
if (threadResp.value.data.messages == null) {
console.error('Thread is missing the "messages" field.')
return
}
const firstMessage = threadResp.value.data.messages[0]
if (firstMessage == null) {
console.error('Thread is missing the first message.')
return
}
const historyIdStr = firstMessage.historyId
const dateStr = firstMessage.internalDate
if (!historyIdStr || !dateStr) {
console.error('First message is missing the "historyId" or "internalDate" field.')
return
}
const historyId = parseInt(historyIdStr, 10)
const date = parseInt(dateStr, 10)
let localIsHistoryIdDecreasing = true
let localIsDateDecreasing = true
if (prevHistoryId != null && prevHistoryId < historyId) {
isHistoryIdDecreasing = false
localIsHistoryIdDecreasing = false
}
if (prevDate != null && prevDate < date) {
isDateDecreasing = false
localIsDateDecreasing = false
}
prevHistoryId = historyId
prevDate = date
console.log(
`${i}/${count}: historyId: ${historyId}, date: ${date}, isHistoryIdDecreasing: ${localIsHistoryIdDecreasing}, isDateDecreasing: ${localIsDateDecreasing}`,
)
}
console.log({isHistoryIdDecreasing, isDateDecreasing})
} Output:
|
Beta Was this translation helpful? Give feedback.
-
Also, to make it more visual, I plotted the time I get from ![]() And here is plot of ![]() |
Beta Was this translation helpful? Give feedback.
-
What is even worse, it appears that Codeasync test_invariants_history_list() {
console.log(
"Performing test if 'users.history.list' returns history records sorted by increasing update date.",
)
const viz = (t: boolean) => (t ? '✅' : '❌')
const count = 100
const cfg: GmailApi.Params$Resource$Users$Messages$List = {
userId: 'me',
maxResults: count,
}
const resp = await Auth.catchAllOAuth(() => this.api.users.messages.list(cfg))
if (resp.isErr()) {
console.error('GMail API query error.', resp.error)
return
}
const list = resp.value.data.messages
if (list == null) {
console.error('GMail API invalid response.')
return
}
const lastMessage = list[list.length - 1]
if (lastMessage == null) {
console.error('Last message is missing.')
return
}
const lastMessageId = lastMessage.id
if (lastMessageId == null) {
console.error('Last message is missing the "id" field.')
return
}
const lastMessageQuery = {userId: 'me', id: lastMessageId}
const lastMessageResp = await Auth.catchAllOAuth(() =>
this.api.users.messages.get(lastMessageQuery),
)
if (lastMessageResp.isErr()) {
console.error('GMail API query error.', lastMessageResp.error)
return
}
const startHistoryId = lastMessageResp.value.data.historyId
if (startHistoryId == null) {
console.error('Last message is missing the "historyId" field.')
return
}
const historyCfg: GmailApi.Params$Resource$Users$History$List = {
userId: 'me',
startHistoryId,
maxResults: 500,
}
const historyResp = await Auth.catchAllOAuth(() => this.api.users.history.list(historyCfg))
if (historyResp.isErr()) {
console.error('GMail API query error.', historyResp.error)
return
}
const historyList = historyResp.value.data.history
if (historyList == null) {
console.error('GMail API invalid response.')
return
}
let localDateIncreasing = true
let prevDate: null | number = null
const updateCount = historyList.length
let i = 0
for (const update of historyList) {
i++
if (update.messages == null) {
console.error('Update is missing the "messages" field.')
return
}
let m = 0
for (const message of update.messages) {
m++
if (message.id == null) {
console.error('Message is missing the "id" field.')
return
}
const messageQuery = {userId: 'me', id: message.id}
const messageResp = await Auth.catchAllOAuth(() =>
this.api.users.messages.get(messageQuery),
)
if (messageResp.isErr()) {
console.error('GMail API query error.', messageResp.error)
continue
}
const dateStr = messageResp.value.data.internalDate
if (!dateStr) {
console.error('Message is missing the "internalDate" field.')
return
}
const date = parseInt(dateStr, 10)
if (prevDate != null && prevDate > date) {
localDateIncreasing = false
} else {
localDateIncreasing = true
}
prevDate = date
console.log(
`${i}/${updateCount}[${m}]: date: ${date}, dateIncreasing: ${viz(localDateIncreasing)}`,
)
}
}
} Output
|
Beta Was this translation helpful? Give feedback.
-
Moreover, as you can see in the above test, |
Beta Was this translation helpful? Give feedback.
-
I also got the same case, and my sync process was broken due to these inconvenients. |
Beta Was this translation helpful? Give feedback.
-
Hi there! Thanks for the writeup @wdanilo! As you mentioned this is likely an API issue. As this is mostly a generated library unfortunately we don't have much pull to help. I'll convert this to a discussion so people can follow along! |
Beta Was this translation helpful? Give feedback.
-
Description
users.messages.list returns messages in a little bit random order.
I also reported the issue here, but knowing Google's issue tracker, I will get a sensible reply there in a few years, so trying my luck here as well :(
Code
I'm using the following code:
Output
Summary
As you can see, the message internalDate is sometimes ... increasing. I've observed the same behavior for users.threads.list. In such a scenario:
What is described here: https://developers.google.com/gmail/api/guides/sync is not true, I can't query for the first message of users.messages.list, remember its historyId and assume this is the newest historyId, as this might NOT be the newest message.
What is described here: https://developers.google.com/gmail/api/reference/rest/v1/users.history/list (
History IDs increase chronologically but are not contiguous with random gaps in between valid IDs
) is not true, as you can see, historyIDs are sometimes increasing for older messages.Beta Was this translation helpful? Give feedback.
All reactions