Skip to content

Add attachment download functionality#2

Merged
Huijiro merged 4 commits into
mainfrom
attachments
Oct 9, 2025
Merged

Add attachment download functionality#2
Huijiro merged 4 commits into
mainfrom
attachments

Conversation

@Huijiro

@Huijiro Huijiro commented Oct 9, 2025

Copy link
Copy Markdown
Collaborator
  • Add AttachmentService with Download method for downloading email attachments
  • Add DownloadUrl field to WebhookAttachment type
  • Add comprehensive tests for attachment downloads
  • Add AGENTS.md with project documentation for AI assistants

Summary by CodeRabbit

  • New Features

    • Added attachment download capability in the client to retrieve email attachments.
  • Documentation

    • Added AGENTS.md describing SDK architecture, conventions, error handling, testing, and contribution guidelines.
  • Types

    • Webhook attachment payloads now include a download URL.
  • Tests

    • Added tests for attachment downloads (including filenames with spaces), auth header validation, and error scenarios (not found, unauthorized).

- Add AttachmentService with Download method for downloading email attachments
- Add DownloadUrl field to WebhookAttachment type
- Add comprehensive tests for attachment downloads
- Add AGENTS.md with project documentation for AI assistants

Amp-Thread-ID: https://ampcode.com/threads/T-01712ca1-af4c-4679-983b-98421810bb50
Co-authored-by: Amp <amp@ampcode.com>
@coderabbitai

coderabbitai Bot commented Oct 9, 2025

Copy link
Copy Markdown

Walkthrough

Adds AttachmentService with Download(ctx, emailID, filename) exposed via Inbound.Attachment(), adds WebhookAttachment.DownloadUrl to types.go, introduces attachment download tests, and adds new SDK guidance documentation in AGENTS.md.

Changes

Cohort / File(s) Summary
Docs
AGENTS.md
New documentation describing SDK structure, conventions, error handling, type design, testing guidelines, and contribution patterns.
Attachment service
inbound.go
Added AttachmentService type and NewAttachmentService, Download(ctx, emailID, filename) ([]byte, error), and Inbound.Attachment() accessor; minor formatting tweak.
Types (webhook)
types.go
Added exported field WebhookAttachment.DownloadUrl string.
Tests (attachments)
attachment_test.go
New tests for Attachment().Download covering successful downloads (including filenames with spaces), 401/404 error cases, and checks for HTTP method and Authorization header.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Dev as Caller
  participant SDK as Inbound (SDK)
  participant AS as AttachmentService
  participant HTTP as HTTP Server

  Dev->>SDK: Attachment().Download(ctx, emailID, filename)
  SDK->>AS: resolve service
  AS->>HTTP: GET /attachments/{emailID}/{filename}\nAuthorization: Bearer <api-key>
  alt 2xx
    HTTP-->>AS: binary payload
    AS-->>SDK: []byte
    SDK-->>Dev: []byte
  else 4xx/5xx
    HTTP-->>AS: error status (+ optional JSON body)
    AS-->>SDK: error
    SDK-->>Dev: error
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Poem

I thump my paws on binary trails,
I fetch the bytes where payloads sail.
Filenames with spaces, I scout with care,
Headers snug, I nudge them bare.
A carrot-clipped reply—bytes in my lair. 🥕📎

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly and accurately describes the primary change—introducing the ability to download attachments via the SDK. It focuses on the main feature without unnecessary details. A teammate scanning PR history will immediately understand the added functionality.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch attachments

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1b21b06 and f9b2677.

📒 Files selected for processing (1)
  • attachment_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
attachment_test.go (1)
inbound.go (1)
  • NewClient (56-71)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test (1.21.x, windows-latest)
  • GitHub Check: test (1.22.x, windows-latest)
🔇 Additional comments (4)
attachment_test.go (4)

1-11: LGTM! Package and imports are correct.

The package declaration and imports are appropriate for the test requirements, including necessary packages for HTTP testing, URL encoding, and string manipulation.


13-63: Test structure is comprehensive and well-designed.

The table-driven test approach covers the essential scenarios including success cases, filename encoding (spaces), and multiple error conditions (404, 401). The test cases properly utilize the errorContains field for error validation.


65-107: LGTM! Mock server implementation is thorough and correct.

The mock server properly validates:

  • HTTP method (GET)
  • URL path construction with proper escaping via url.PathEscape and r.URL.EscapedPath()
  • Authorization header
  • Response handling for both success and error cases

The client creation and Download method invocation are correctly implemented with appropriate error handling.


108-127: LGTM! Test assertions are comprehensive and correct.

The error and success case assertions properly validate:

  • Error presence when expected
  • Error message content via errorContains field
  • Absence of errors in success cases
  • Correctness of downloaded data

The test provides good coverage of the AttachmentService.Download functionality.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
AGENTS.md (1)

15-24: Add language identifier to fenced code block.

The project structure code block on line 15 is missing a language identifier. While not critical for a directory tree, adding text or plaintext as the identifier improves rendering consistency.

Apply this diff:

-```
+```text
 .
 ├── inbound.go              # Main client and service implementations
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 52c901e and 83d02a5.

📒 Files selected for processing (4)
  • AGENTS.md (1 hunks)
  • attachment_test.go (1 hunks)
  • inbound.go (3 hunks)
  • types.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
attachment_test.go (2)
inbound.go (1)
  • NewClient (56-71)
types.go (1)
  • WebhookAttachment (781-787)
🪛 markdownlint-cli2 (0.18.1)
AGENTS.md

9-9: Bare URL used

(MD034, no-bare-urls)


10-10: Bare URL used

(MD034, no-bare-urls)


15-15: Fenced code blocks should have a language specified

(MD040, fenced-code-language)


192-192: Bare URL used

(MD034, no-bare-urls)


193-193: Bare URL used

(MD034, no-bare-urls)


194-194: Bare URL used

(MD034, no-bare-urls)


195-195: Bare URL used

(MD034, no-bare-urls)


196-196: Bare URL used

(MD034, no-bare-urls)


197-197: Bare URL used

(MD034, no-bare-urls)


198-198: Bare URL used

(MD034, no-bare-urls)


199-199: Bare URL used

(MD034, no-bare-urls)


200-200: Bare URL used

(MD034, no-bare-urls)


201-201: Bare URL used

(MD034, no-bare-urls)


202-202: Bare URL used

(MD034, no-bare-urls)


203-203: Bare URL used

(MD034, no-bare-urls)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test (1.22.x, windows-latest)
  • GitHub Check: test (1.21.x, windows-latest)
🔇 Additional comments (6)
AGENTS.md (1)

1-260: LGTM! Comprehensive documentation for AI assistants.

The documentation provides excellent guidance covering:

  • Project structure and architecture
  • Service patterns and conventions
  • Testing guidelines with concrete examples
  • API reference links
  • Common implementation patterns

This will be very helpful for AI assistants working on the SDK.

inbound.go (3)

615-624: LGTM! Service structure follows established patterns.

The AttachmentService implementation correctly follows the service pattern used throughout the SDK with a client reference and constructor.


672-674: LGTM! Accessor method correctly exposes the service.

The Attachment() accessor follows the established pattern for exposing services from the main client.


625-649: Fix unsafe error string formatting and clarify webhook download flow.

The implementation has two concerns:

  1. Line 643: Using fmt.Errorf("%s", errorResp.Error) with an untrusted error string is unsafe if it contains format verbs like %s or %d. These would be interpreted as format specifiers, potentially causing panics or unexpected output.

  2. Webhook downloads: The method always constructs the endpoint from emailID and filename, but doesn't utilize WebhookAttachment.DownloadUrl. Please clarify: should this method support downloading directly from webhook-provided URLs, or should callers parse the DownloadUrl to extract parameters?

Apply this diff to fix the error formatting:

 		if json.Unmarshal(respBody, &errorResp) == nil && errorResp.Error != "" {
-			return nil, fmt.Errorf("%s", errorResp.Error)
+			return nil, errors.New(errorResp.Error)
 		}

Add this import if not already present:

 import (
 	"bytes"
 	"context"
 	"encoding/json"
+	"errors"
 	"fmt"

Likely an incorrect or invalid review comment.

attachment_test.go (1)

11-114: LGTM! Comprehensive test coverage.

The test thoroughly covers:

  • Successful downloads with standard and space-containing filenames
  • Error scenarios (404, 401)
  • HTTP method and authorization header verification
  • Data integrity validation
types.go (1)

786-786: Clarify usage of DownloadUrl. The new DownloadUrl field on WebhookAttachment (types.go:786) is set in tests but never used by AttachmentService.Download, which still constructs the URL from emailID+filename. Should Download support a full URL, callers parse this field, or is it purely informational?

Comment thread attachment_test.go Outdated

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 83d02a5 and 0b1b3b8.

📒 Files selected for processing (1)
  • attachment_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
attachment_test.go (1)
inbound.go (1)
  • NewClient (56-71)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test (1.22.x, windows-latest)
  • GitHub Check: test (1.21.x, windows-latest)
🔇 Additional comments (1)
attachment_test.go (1)

30-36: Verify URL encoding for filename with spaces.

With the URL path validation added (see previous comment), this test case will properly verify that spaces in filenames are correctly encoded as %20 in the URL path.

Once you implement the URL path validation, this test case will automatically validate proper encoding of the space character.

Comment thread attachment_test.go
Comment thread attachment_test.go
- Add errorContains field validation to check error messages
- Validate URL path construction and filename escaping
- Add net/url import for PathEscape validation

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
attachment_test.go (1)

13-129: Consider adding edge case tests.

While the current test coverage is solid, consider adding tests for:

  • Empty emailID or filename parameters to ensure proper validation
  • Network timeout scenarios if the Download method handles them
  • Server returning unexpected content types

These would strengthen the test suite but are not critical for the initial implementation.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0b1b3b8 and 1b21b06.

📒 Files selected for processing (1)
  • attachment_test.go (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
attachment_test.go (1)
inbound.go (1)
  • NewClient (56-71)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: test (1.22.x, windows-latest)
  • GitHub Check: test (1.21.x, windows-latest)
🔇 Additional comments (5)
attachment_test.go (5)

1-11: LGTM! Imports are appropriate.

All necessary packages are imported and used in the tests.


13-63: LGTM! Test cases cover key scenarios.

The test table includes appropriate success cases (including filename with spaces) and error cases. The errorContains field is properly defined and matches the mock server's error responses.


67-98: LGTM! Mock server properly validates requests.

The handler correctly validates the HTTP method, URL path with proper escaping (addressing previous review feedback), and Authorization header. Response handling for both success and error cases is appropriate.


101-104: LGTM! Client setup follows standard test pattern.

Client creation is straightforward with appropriate error handling.


119-126: LGTM! Success case assertions are correct.

Proper verification that no error occurred and the downloaded data matches the expected response.

Comment thread attachment_test.go
@Huijiro Huijiro merged commit 4bddd15 into main Oct 9, 2025
8 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.

1 participant