Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions examples/broadcasts.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@
print("Updated broadcast!")
print(updated_broadcast)

duplicated: resend.Broadcasts.DuplicateResponse = resend.Broadcasts.duplicate(
id=broadcast["id"]
)
print("Duplicated broadcast with ID: {}".format(duplicated["id"]))
print(duplicated)
resend.Broadcasts.remove(id=duplicated["id"])
print("Removed the duplicate!")

send_params: resend.Broadcasts.SendParams = {
"broadcast_id": broadcast["id"],
}
Expand Down
58 changes: 58 additions & 0 deletions resend/broadcasts/_broadcasts.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,24 @@ class CancelResponse(BaseResponse):
id of the canceled broadcast
"""

class DuplicateResponse(BaseResponse):
"""
DuplicateResponse is the class that wraps the response of the duplicate method.

Attributes:
object (str): object type: "broadcast"
id (str): id of the duplicated broadcast
"""

object: str
"""
object type: "broadcast"
"""
id: str
"""
id of the duplicated broadcast
"""

class RemoveResponse(BaseResponse):
"""
RemoveResponse is the class that wraps the response of the remove method.
Expand Down Expand Up @@ -556,6 +574,26 @@ def cancel(cls, id: str) -> CancelResponse:
).perform_with_content()
return resp

@classmethod
def duplicate(cls, id: str) -> DuplicateResponse:
"""
Duplicate a broadcast.
see more: https://resend.com/docs/api-reference/broadcasts/duplicate-broadcast

Creates a new draft with the same content as the source, named after it with " (copy)" appended.

Args:
id (str): The broadcast ID

Returns:
DuplicateResponse: The duplicate response object
"""
path = f"/broadcasts/{id}/duplicate"
resp = request.Request[Broadcasts.DuplicateResponse](
Comment thread
gabrielmfern marked this conversation as resolved.
path=path, params={}, verb="post"
).perform_with_content()
return resp

@classmethod
def remove(cls, id: str) -> RemoveResponse:
"""
Expand Down Expand Up @@ -731,6 +769,26 @@ async def cancel_async(cls, id: str) -> CancelResponse:
).perform_with_content()
return resp

@classmethod
async def duplicate_async(cls, id: str) -> DuplicateResponse:
"""
Duplicate a broadcast (async).
see more: https://resend.com/docs/api-reference/broadcasts/duplicate-broadcast

Creates a new draft with the same content as the source, named after it with " (copy)" appended.

Args:
id (str): The broadcast ID

Returns:
DuplicateResponse: The duplicate response object
"""
path = f"/broadcasts/{id}/duplicate"
resp = await AsyncRequest[Broadcasts.DuplicateResponse](
path=path, params={}, verb="post"
).perform_with_content()
return resp

@classmethod
async def remove_async(cls, id: str) -> RemoveResponse:
"""
Expand Down
2 changes: 1 addition & 1 deletion resend/version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
__version__ = "2.44.0"
__version__ = "2.45.0"


def get_version() -> str:
Expand Down
27 changes: 27 additions & 0 deletions tests/broadcasts_async_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,33 @@ async def test_should_cancel_broadcasts_async_raise_exception_when_no_content(
"78261eea-8f8b-4381-83c6-79fa7120f1cf"
)

async def test_broadcasts_duplicate_async(self) -> None:
self.set_mock_json(
{
"object": "broadcast",
"id": "3d4a472d-bc6d-4dd2-aa9d-d3d50ce87222",
}
)

duplicated = await resend.Broadcasts.duplicate_async(
"78261eea-8f8b-4381-83c6-79fa7120f1cf"
)
assert duplicated["id"] == "3d4a472d-bc6d-4dd2-aa9d-d3d50ce87222"
assert duplicated["object"] == "broadcast"
assert (
self.mock.call_args.kwargs["url"]
== "https://api.resend.com/broadcasts/78261eea-8f8b-4381-83c6-79fa7120f1cf/duplicate"
)

async def test_should_duplicate_broadcasts_async_raise_exception_when_no_content(
self,
) -> None:
self.set_mock_json(None)
with pytest.raises(NoContentError):
_ = await resend.Broadcasts.duplicate_async(
"78261eea-8f8b-4381-83c6-79fa7120f1cf"
)

async def test_broadcasts_remove_async(self) -> None:
self.set_mock_json(
{
Expand Down
18 changes: 18 additions & 0 deletions tests/broadcasts_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,24 @@ def test_broadcasts_cancel(self) -> None:
assert canceled["id"] == "78261eea-8f8b-4381-83c6-79fa7120f1cf"
assert canceled["object"] == "broadcast"

def test_broadcasts_duplicate(self) -> None:
self.set_mock_json(
{
"object": "broadcast",
"id": "3d4a472d-bc6d-4dd2-aa9d-d3d50ce87222",
}
)

duplicated = resend.Broadcasts.duplicate(
"78261eea-8f8b-4381-83c6-79fa7120f1cf"
)
assert duplicated["id"] == "3d4a472d-bc6d-4dd2-aa9d-d3d50ce87222"
assert duplicated["object"] == "broadcast"
assert (
self.mock.call_args.kwargs["url"]
== "https://api.resend.com/broadcasts/78261eea-8f8b-4381-83c6-79fa7120f1cf/duplicate"
)

def test_broadcasts_remove(self) -> None:
self.set_mock_json(
{
Expand Down
Loading