Skip to content

Improve attachment handling and sync_labels_api robustness#66

Merged
trufurs merged 5 commits into
version-16-hotfixfrom
sync-fix
Jun 1, 2026
Merged

Improve attachment handling and sync_labels_api robustness#66
trufurs merged 5 commits into
version-16-hotfixfrom
sync-fix

Conversation

@dpk404

@dpk404 dpk404 commented Jun 1, 2026

Copy link
Copy Markdown

Description

This pull request introduces several improvements and bug fixes to the Gmail thread integration, focusing on more efficient attachment handling, improved API flexibility, and enhanced email object initialization. The most significant changes are grouped below:

Attachment Handling Optimization:

  • Refactored get_attachments_data in activity.py to batch-fetch all referenced File URLs in a single database query, eliminating the previous N+1 query pattern and skipping missing files to avoid rendering errors.

API Usability Improvements:

  • Updated sync_labels_api to accept both string and dictionary arguments, and added validation to ensure a doc_name is provided, improving robustness and flexibility of the API.

Email Object Initialization Enhancements:

  • Modified GmailInboundMail to accept an optional email_account parameter and set its attachment_limit to None during initialization, allowing for more flexible handling of email account properties.
  • Updated create_new_email to pass the gmail_account to GmailInboundMail, ensuring the email object is initialized with the correct account context.

Relevant Technical Choices

Testing Instructions

Additional Information:

Screenshot/Screencast

Checklist

  • I have carefully reviewed the code before submitting it for review.
  • This code is adequately covered by unit tests to validate its functionality.
  • I have conducted thorough testing to ensure it functions as intended.
  • A member of the QA team has reviewed and tested this PR (To be checked by QA or code reviewer)

Fixes #

trufurs and others added 3 commits May 15, 2026 14:32
Two bugs in the old per-attachment loop:

1. frappe.db.get_value("File", file_doc_name, "file_url") returns None
   when the File row has been deleted. The function then wrote
   attachment["file_url"] = None and returned it. The timeline_message_box
   template renders a.file_url.split("/") to derive the filename, which
   crashed with "Cannot read properties of null" — the whole form
   timeline failed to render.

2. The frappe.db.get_value call was inside the per-attachment loop,
   so a thread with N attachments did N round-trips against tabFile.

Now a single frappe.db.get_all collects every referenced file_url, and
attachments whose File row is gone are dropped from the returned list
so the template never sees a null file_url.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the Gmail thread integration by optimizing attachment URL resolution for timeline rendering, making the sync_labels_api endpoint more flexible/robust, and enhancing inbound email initialization with account context.

Changes:

  • Batch-fetch File.file_url values when building attachment metadata and skip missing files to avoid template crashes.
  • Update sync_labels_api to accept both JSON-string and dict inputs, with stronger argument validation.
  • Extend GmailInboundMail initialization to accept an optional account context and pass the Gmail account from create_new_email.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 6 comments.

File Description
frappe_gmail_thread/utils/helpers.py Passes account context into GmailInboundMail during email creation and adjusts initialization behavior.
frappe_gmail_thread/frappe_gmail_thread/doctype/gmail_account/gmail_account.py Expands sync_labels_api input handling (string/dict) and adds validation paths.
frappe_gmail_thread/api/activity.py Refactors attachment URL resolution to avoid N+1 queries and filters invalid/missing attachments for safe rendering.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread frappe_gmail_thread/utils/helpers.py
Comment thread frappe_gmail_thread/api/activity.py
Comment thread frappe_gmail_thread/api/activity.py
Comment thread frappe_gmail_thread/utils/helpers.py
@trufurs trufurs changed the base branch from develop to version-16-hotfix June 1, 2026 12:06
Comment thread frappe_gmail_thread/utils/helpers.py Outdated
if not hasattr(self.email_account, "attachment_limit"):
self.email_account.attachment_limit = None

super().__init__(content, email_account=self.email_account)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see that the Email class does not accept any email_account or kwargs arguments. Reference: https://github.com/frappe/frappe/blob/fcdc612120cd68cc21e756ace9b941df025ccc0e/frappe/email/receive.py#L399

Can you confirm if this is tested and working (and how)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me verify, and fix this

@shivamsn97 shivamsn97 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving this, and closing #47 as both tries to solves the same problem.

@trufurs trufurs merged commit 912f766 into version-16-hotfix Jun 1, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants