feat: Add Audiences, Contacts, and Broadcasts API support#7
feat: Add Audiences, Contacts, and Broadcasts API support#7themusicman wants to merge 4 commits into
Conversation
- Introduced `Resend.Audiences` module with functions to create, list, retrieve, and delete audiences. - Added `Resend.Audiences.Audience` struct to represent audience data. - Updated `mix.exs` to include new modules in the project. - Implemented comprehensive tests for audience management functionalities.
- Added `Resend.Contacts` module with functions to create, list, retrieve, update, and delete contacts within audiences. - Introduced `Resend.Contacts.Contact` struct to represent individual contact data. - Updated `mix.exs` to include the new Contacts module. - Implemented comprehensive tests for contact management functionalities.
- Introduced `Resend.Broadcasts` module with functions to create, list, retrieve, update, send, and delete broadcasts. - Added `Resend.Broadcasts.Broadcast` struct to represent broadcast data. - Updated `mix.exs` to include the new Broadcasts module. - Implemented comprehensive tests for broadcast management functionalities.
- Removed redundant fields from success body assertions in `broadcasts_test.exs`. - Updated assertions to focus on the `id` field, enhancing clarity and maintainability of tests.
There was a problem hiding this comment.
Pull Request Overview
This PR significantly expands the Resend Elixir client by adding support for three new API endpoint categories: Audiences, Contacts, and Broadcasts. The purpose is to provide complete CRUD operations for audience management and email campaign functionality.
Key Changes
- Added complete Audiences module for creating and managing email audience groups
- Added Contacts module for managing individual contacts within audiences
- Added Broadcasts module for creating and sending email campaigns to audiences
- Updated the Client module to support PATCH HTTP method
- Added comprehensive test coverage for all new functionality
Reviewed Changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| lib/resend/audiences.ex | New module providing CRUD operations for audience management |
| lib/resend/audiences/audience.ex | Audience struct definition with casting functionality |
| lib/resend/contacts.ex | New module for managing contacts within audiences |
| lib/resend/contacts/contact.ex | Contact struct definition with casting functionality |
| lib/resend/broadcasts.ex | New module for email campaign management |
| lib/resend/broadcasts/broadcast.ex | Broadcast struct definition with casting functionality |
| lib/resend/client.ex | Added PATCH method support for update operations |
| mix.exs | Updated documentation structure to include new modules |
| test/resend/audiences_test.exs | Comprehensive test suite for audiences functionality |
| test/resend/audiences/audience_test.exs | Unit tests for audience struct casting |
| test/resend/contacts_test.exs | Comprehensive test suite for contacts functionality |
| test/resend/contacts/contact_test.exs | Unit tests for contact struct casting |
| test/resend/broadcasts_test.exs | Comprehensive test suite for broadcasts functionality |
| test/resend/broadcasts/broadcast_test.exs | Unit tests for broadcast struct casting |
| # When called with 2 args, the second arg is interpreted as broadcast_id | ||
| # So we need to use the default client and pass broadcast_id and opts | ||
| assert {:ok, %Broadcast{id: ^broadcast_id}} = | ||
| Resend.Broadcasts.send(Resend.client(), broadcast_id, scheduled_at: scheduled_at) |
There was a problem hiding this comment.
The function call explicitly passes Resend.client() which is redundant since the send/3 function already defaults to Resend.client(). This should be simplified to Resend.Broadcasts.send(broadcast_id, scheduled_at: scheduled_at) for consistency with the test on line 375 in the same file.
| Resend.Broadcasts.send(Resend.client(), broadcast_id, scheduled_at: scheduled_at) | |
| Resend.Broadcasts.send(broadcast_id, scheduled_at: scheduled_at) |
|
|
||
| # Fix: Same issue here, need to use proper argument order | ||
| assert {:ok, %Broadcast{id: ^broadcast_id}} = | ||
| Resend.Broadcasts.send(Resend.client(), broadcast_id, scheduled_at: nil) |
There was a problem hiding this comment.
Same issue as line 379 - the explicit Resend.client() call is redundant and inconsistent with other test patterns. Should be simplified to Resend.Broadcasts.send(broadcast_id, scheduled_at: nil).
| Resend.Broadcasts.send(Resend.client(), broadcast_id, scheduled_at: nil) | |
| Resend.Broadcasts.send(broadcast_id, scheduled_at: nil) |
| case Keyword.has_key?(opts, :scheduled_at) do | ||
| true -> %{scheduled_at: opts[:scheduled_at]} | ||
| false -> %{} |
There was a problem hiding this comment.
The send function's body construction logic should handle DateTime serialization consistently. When scheduled_at is a DateTime, it should be converted to ISO8601 format before being included in the request body to ensure proper API communication.
| case Keyword.has_key?(opts, :scheduled_at) do | |
| true -> %{scheduled_at: opts[:scheduled_at]} | |
| false -> %{} | |
| case Keyword.get(opts, :scheduled_at) do | |
| %DateTime{} = datetime -> %{scheduled_at: DateTime.to_iso8601(datetime)} | |
| nil -> %{} | |
| value -> %{scheduled_at: value} |
This PR expands the Resend Elixir client by adding support for three new API endpoints:
🎯 New Features
Audiences Module
Contacts Module
Broadcasts Module
🔧 Technical Improvements
📋 Changes Summary
🧪 Testing
All new modules include comprehensive test suites with:
This expands the Resend Elixir client to support the full Resend API surface area for audience and campaign management.