Mail Widget
This commit is contained in:
parent
42dad815dd
commit
7f9b128d47
@ -960,6 +960,14 @@ export async function getEmails(
|
||||
skip
|
||||
);
|
||||
|
||||
logger.debug('[EMAIL] Graph API returned emails', {
|
||||
userId,
|
||||
folder,
|
||||
mailCredentialId: graphCheck.mailCredentialId,
|
||||
count: graphResult.value?.length || 0,
|
||||
hasNextLink: !!graphResult['@odata.nextLink'],
|
||||
});
|
||||
|
||||
// Get mailboxes (folders)
|
||||
const graphFolders = await fetchGraphMailFolders(graphCheck.mailCredentialId);
|
||||
const mailboxes = graphFolders.map(f => f.displayName);
|
||||
@ -969,6 +977,21 @@ export async function getEmails(
|
||||
convertGraphMessageToEmailMessage(msg, folder, accountId || 'default')
|
||||
);
|
||||
|
||||
// Ensure emails are sorted by date (newest first) - Graph API should already do this, but double-check
|
||||
emails.sort((a, b) => {
|
||||
const dateA = a.date instanceof Date ? a.date.getTime() : new Date(a.date).getTime();
|
||||
const dateB = b.date instanceof Date ? b.date.getTime() : new Date(b.date).getTime();
|
||||
return dateB - dateA; // Descending order (newest first)
|
||||
});
|
||||
|
||||
logger.debug('[EMAIL] Converted and sorted emails', {
|
||||
userId,
|
||||
folder,
|
||||
count: emails.length,
|
||||
firstEmailDate: emails[0]?.date,
|
||||
lastEmailDate: emails[emails.length - 1]?.date,
|
||||
});
|
||||
|
||||
// Calculate total (Graph API doesn't provide total count directly, so we estimate)
|
||||
const totalEmails = graphResult['@odata.nextLink']
|
||||
? (page * perPage) + 1 // Has more pages
|
||||
|
||||
@ -99,13 +99,15 @@ export interface GraphMailFolder {
|
||||
|
||||
/**
|
||||
* Fetch emails from a Microsoft mailbox folder using Graph API
|
||||
* Note: Microsoft Graph API doesn't support $skip for pagination, only $top and $skipToken
|
||||
*/
|
||||
export async function fetchGraphEmails(
|
||||
mailCredentialId: string,
|
||||
folderId: string = 'Inbox',
|
||||
top: number = 50,
|
||||
skip: number = 0,
|
||||
filter?: string
|
||||
filter?: string,
|
||||
skipToken?: string
|
||||
): Promise<{
|
||||
value: GraphMailMessage[];
|
||||
'@odata.nextLink'?: string;
|
||||
@ -117,19 +119,47 @@ export async function fetchGraphEmails(
|
||||
let url = `/me/mailFolders/${folderId}/messages`;
|
||||
const params = new URLSearchParams({
|
||||
'$top': top.toString(),
|
||||
'$skip': skip.toString(),
|
||||
'$orderby': 'receivedDateTime desc',
|
||||
'$select': 'id,subject,from,toRecipients,ccRecipients,body,bodyPreview,receivedDateTime,sentDateTime,isRead,hasAttachments,importance,flag',
|
||||
});
|
||||
|
||||
// Microsoft Graph API supports $skip for messages endpoint, but it's more reliable to use $skipToken
|
||||
// For the first page (skip=0), don't use $skip
|
||||
// For subsequent pages, we can use $skip but $skipToken is preferred
|
||||
if (skip > 0 && !skipToken) {
|
||||
params.append('$skip', skip.toString());
|
||||
}
|
||||
|
||||
// Use skipToken if provided (for server-driven pagination from @odata.nextLink)
|
||||
// This is the preferred method for pagination in Graph API
|
||||
if (skipToken) {
|
||||
params.append('$skiptoken', skipToken);
|
||||
}
|
||||
|
||||
if (filter) {
|
||||
params.append('$filter', filter);
|
||||
}
|
||||
|
||||
url += `?${params.toString()}`;
|
||||
|
||||
logger.debug('Fetching emails from Microsoft Graph API', {
|
||||
mailCredentialId,
|
||||
folderId,
|
||||
top,
|
||||
skip,
|
||||
skipToken: skipToken ? 'present' : 'none',
|
||||
url,
|
||||
});
|
||||
|
||||
const response = await client.get(url);
|
||||
|
||||
logger.debug('Microsoft Graph API response', {
|
||||
mailCredentialId,
|
||||
folderId,
|
||||
emailCount: response.data?.value?.length || 0,
|
||||
hasNextLink: !!response.data?.['@odata.nextLink'],
|
||||
});
|
||||
|
||||
return response.data;
|
||||
} catch (error: any) {
|
||||
logger.error('Error fetching emails from Microsoft Graph', {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user