fix: surface email attachments on tickets#376
Open
akash2017sky wants to merge 4 commits into
Open
Conversation
Inbound email attachments now land on the resulting Azure DevOps work item across all three Microsoft Graph attachment types, on both new ticket and thread-reply paths. - Switch poll body fetch from text to HTML so `<img src="cid:...">` refs survive for rewriting. - Handle `referenceAttachment` (OneDrive / SharePoint): try the Graph download URL, fall back to a clickable link in the description. - Handle `itemAttachment` (forwarded .eml): record a tagged "Forwarded message: <subject> (not extracted)" note so it doesn't vanish silently. - Split upload + link so attachments are uploaded first; build a `cid -> DevOps URL` map and rewrite inline image refs in the body. - Run the same upload + rewrite + link flow on thread replies, not just new tickets. - Per-attachment failures log the work item id + filename and never block ticket creation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
fileAttachment,referenceAttachment,itemAttachment), on both new-ticket and thread-reply paths.cid:references in pasted screenshots are rewritten to point at the uploaded DevOps attachment URL so images render inline in the description / comment instead of showing a broken-image icon.Fixes
Fixes #362
What this covers
fileAttachment+isInline: true+cid:)<img cid:>reference stripped, image silently disappeared from the descriptioncid:ref is rewritten to the DevOps attachment URL — image renders inlinereferenceAttachment) — Outlook auto-converts files >35 MB or when "Modern Attachments" is enabled@microsoft.graph.downloadUrlfirst; if 200 the file is uploaded as a normal attachment. Otherwise the source URL appears in a "Cloud attachments" section in the description.eml(itemAttachment)Forwarded message: <subject> (not extracted)so it doesn't vanish silently[ZapDesk #N]in subject) with attachmentscid:rewrite + link flow runs; comment HTML renders inline images, files appear under AttachmentsFiles changed
src/lib/email-poll.ts— switched bodyPreferheader to HTML; rewrotefetchAttachmentsto handle all three Graph attachment types; passesbodyTypethrough to ingest.src/lib/email-clean.ts— addedsanitizeEmailHtml,stripHtmlSignature,rewriteCidReferences,renderEmailBodyHtml.src/lib/email-ingest.ts— splituploadAttachmentintouploadAttachmentBlob+linkAttachment; buildcid → urlmap; rewrite body before storage; thread-reply path resolves project from work item id and runs the same flow.src/types/index.ts— extendedEmailWebhookPayloadwith optionalbodyType,contentId,isInline,referenceUrl,itemSubject(backward compatible).Test plan
Local (manual)
.env:MAIL_POLL_MAILBOX,EMAIL_WEBHOOK_SECRET,AZURE_DEVOPS_PAT,MAIL_*Graph creds.Email: <your-sender-domain>(e.g.Email: gmail.com).bun install && bun run dev— wait forReady on http://localhost:3102..eml).fetched: 1, ingested: 1, failed: 0withaction: "ticket_created"and aticketId.https://dev.azure.com/<org>/<project>/_workitems/edit/<ticketId>. Expected:Forwarded message: <subject> (not extracted).Thread-reply path
[ZapDesk #N]subject tag, with another pasted screenshot + attachment.action: "comment_added"for the same ticket id; the new Discussion comment renders the inline screenshot and the file appears under Attachments.Failure path (graceful degradation)
AZURE_DEVOPS_PAT, send a test email, trigger the poll.[Ingest] ticket #N attachment failed (filename): .... Restore PAT after.Verified end-to-end
supporttest@knowall.aipolling into the Internal project — produced ticket #5813 with the test email's attachments surfaced as expected.Automated checks
bun run typecheck— passesbun run lint— passes (only pre-existing warnings in unrelated files)prettier --checkon the four changed files — passesOut of scope (per issue)
🤖 Generated with Claude Code