Summary
Google Calendar events include file attachments (name, URL, MIME type) in the response. Outlook currently skips attachments entirely. The Microsoft Graph SDK exposes GetHasAttachments() and GetAttachments() on events, but fetching them requires additional query parameters. Modern Outlook defaults to OneDrive/SharePoint links (which already have URLs), but raw file uploads are also possible.
Current behavior
- Google: Extracts attachments from the event payload directly. Each attachment has a
title, fileUrl (Google Drive link), and mimeType, mapped to core.Attachment.
- Outlook:
parseGraphEvent in events.go does not read attachments. The Attachments field on core.Event is always nil.
What needs to change
1. Expand attachments in the query
Graph API doesn't return attachment data by default. The event query needs $expand=attachments added as a query parameter so attachment metadata comes back inline with each event.
In events.go (fetchEventsFromCalendar), the request configuration needs to include:
requestConfig.QueryParameters.Expand = []string{"attachments"}
2. Handle attachment types
Graph API has three attachment types:
| Type |
What it is |
URL |
| ReferenceAttachment |
OneDrive/SharePoint link (default in modern Outlook) |
GetSourceUrl() — already a clickable link, direct parallel to Google Drive links |
| FileAttachment |
Raw file uploaded to the event |
Construct https://graph.microsoft.com/v1.0/me/events/{event-id}/attachments/{attachment-id}/$value |
| ItemAttachment |
Embedded Outlook items (emails, events) |
Skip — not useful for calendar display |
ReferenceAttachment is the most common in practice since modern Outlook defaults to sharing OneDrive links rather than uploading file content.
3. Parse attachments from the Graph response
Each event's GetAttachments() returns a slice of attachment items. Relevant properties:
GetName() — file name (e.g. meeting-notes.pdf)
GetContentType() — MIME type (e.g. application/pdf)
GetSize() — file size in bytes
GetId() — attachment ID (needed for FileAttachment download URL)
GetSourceUrl() — direct link (ReferenceAttachment only)
4. Map to core.Attachment
// ReferenceAttachment (OneDrive/SharePoint link)
core.Attachment{
Title: getName(),
FileURL: getSourceUrl(), // already a direct link
MIMEType: getContentType(),
}
// FileAttachment (raw upload)
core.Attachment{
Title: getName(),
FileURL: fmt.Sprintf("https://graph.microsoft.com/v1.0/me/events/%s/attachments/%s/$value", eventID, attachmentID),
MIMEType: getContentType(),
}
Edge cases
- Large attachments: Graph API returns attachment content inline if
$expand is used and the attachment is under 3MB. Larger attachments need a separate GET request. For tsk (read-only, metadata only), we only need the name/type/URL — not the content bytes.
- Events with no attachments:
GetHasAttachments() can be checked first to skip parsing when there are none.
- Pagination interaction: Verify that
$expand=attachments works correctly with the existing PageIterator for event pagination.
Effort
Small. The attachment model already exists in core.Attachment, the display toggle is already wired up, and Google already populates it. ReferenceAttachments (OneDrive links) are trivial — just read the source URL. FileAttachments need a constructed download URL. Most of the work is adding $expand=attachments to the query and type-switching on the attachment kind.
Generated by Claude Opus 4.6
Summary
Google Calendar events include file attachments (name, URL, MIME type) in the response. Outlook currently skips attachments entirely. The Microsoft Graph SDK exposes
GetHasAttachments()andGetAttachments()on events, but fetching them requires additional query parameters. Modern Outlook defaults to OneDrive/SharePoint links (which already have URLs), but raw file uploads are also possible.Current behavior
title,fileUrl(Google Drive link), andmimeType, mapped tocore.Attachment.parseGraphEventinevents.godoes not read attachments. TheAttachmentsfield oncore.Eventis alwaysnil.What needs to change
1. Expand attachments in the query
Graph API doesn't return attachment data by default. The event query needs
$expand=attachmentsadded as a query parameter so attachment metadata comes back inline with each event.In
events.go(fetchEventsFromCalendar), the request configuration needs to include:2. Handle attachment types
Graph API has three attachment types:
GetSourceUrl()— already a clickable link, direct parallel to Google Drive linkshttps://graph.microsoft.com/v1.0/me/events/{event-id}/attachments/{attachment-id}/$valueReferenceAttachment is the most common in practice since modern Outlook defaults to sharing OneDrive links rather than uploading file content.
3. Parse attachments from the Graph response
Each event's
GetAttachments()returns a slice of attachment items. Relevant properties:GetName()— file name (e.g.meeting-notes.pdf)GetContentType()— MIME type (e.g.application/pdf)GetSize()— file size in bytesGetId()— attachment ID (needed for FileAttachment download URL)GetSourceUrl()— direct link (ReferenceAttachment only)4. Map to core.Attachment
Edge cases
$expandis used and the attachment is under 3MB. Larger attachments need a separate GET request. For tsk (read-only, metadata only), we only need the name/type/URL — not the content bytes.GetHasAttachments()can be checked first to skip parsing when there are none.$expand=attachmentsworks correctly with the existingPageIteratorfor event pagination.Effort
Small. The attachment model already exists in
core.Attachment, the display toggle is already wired up, and Google already populates it. ReferenceAttachments (OneDrive links) are trivial — just read the source URL. FileAttachments need a constructed download URL. Most of the work is adding$expand=attachmentsto the query and type-switching on the attachment kind.Generated by Claude Opus 4.6