universal-mcp-applications 0.1.33__py3-none-any.whl → 0.1.39rc16__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of universal-mcp-applications might be problematic. Click here for more details.
- universal_mcp/applications/BEST_PRACTICES.md +1 -1
- universal_mcp/applications/ahrefs/app.py +92 -238
- universal_mcp/applications/airtable/app.py +36 -135
- universal_mcp/applications/apollo/app.py +124 -477
- universal_mcp/applications/asana/app.py +605 -1755
- universal_mcp/applications/aws_s3/app.py +63 -119
- universal_mcp/applications/bill/app.py +644 -2055
- universal_mcp/applications/box/app.py +1246 -4159
- universal_mcp/applications/braze/app.py +410 -1476
- universal_mcp/applications/browser_use/README.md +15 -1
- universal_mcp/applications/browser_use/__init__.py +1 -0
- universal_mcp/applications/browser_use/app.py +91 -26
- universal_mcp/applications/cal_com_v2/app.py +207 -625
- universal_mcp/applications/calendly/app.py +103 -242
- universal_mcp/applications/canva/app.py +75 -140
- universal_mcp/applications/clickup/app.py +331 -798
- universal_mcp/applications/coda/app.py +240 -520
- universal_mcp/applications/confluence/app.py +497 -1285
- universal_mcp/applications/contentful/app.py +40 -155
- universal_mcp/applications/crustdata/app.py +44 -123
- universal_mcp/applications/dialpad/app.py +451 -924
- universal_mcp/applications/digitalocean/app.py +2071 -6082
- universal_mcp/applications/domain_checker/app.py +3 -54
- universal_mcp/applications/e2b/app.py +17 -68
- universal_mcp/applications/elevenlabs/README.md +27 -3
- universal_mcp/applications/elevenlabs/app.py +741 -74
- universal_mcp/applications/exa/README.md +8 -4
- universal_mcp/applications/exa/app.py +415 -186
- universal_mcp/applications/falai/README.md +5 -7
- universal_mcp/applications/falai/app.py +156 -232
- universal_mcp/applications/figma/app.py +91 -175
- universal_mcp/applications/file_system/app.py +2 -13
- universal_mcp/applications/firecrawl/app.py +198 -176
- universal_mcp/applications/fireflies/app.py +59 -281
- universal_mcp/applications/fpl/app.py +92 -529
- universal_mcp/applications/fpl/utils/fixtures.py +15 -49
- universal_mcp/applications/fpl/utils/helper.py +25 -89
- universal_mcp/applications/fpl/utils/league_utils.py +20 -64
- universal_mcp/applications/ghost_content/app.py +70 -179
- universal_mcp/applications/github/app.py +30 -67
- universal_mcp/applications/gong/app.py +142 -302
- universal_mcp/applications/google_calendar/app.py +26 -78
- universal_mcp/applications/google_docs/README.md +15 -14
- universal_mcp/applications/google_docs/app.py +103 -206
- universal_mcp/applications/google_drive/app.py +194 -793
- universal_mcp/applications/google_gemini/app.py +68 -59
- universal_mcp/applications/google_mail/README.md +1 -0
- universal_mcp/applications/google_mail/app.py +93 -214
- universal_mcp/applications/google_searchconsole/app.py +25 -58
- universal_mcp/applications/google_sheet/README.md +2 -1
- universal_mcp/applications/google_sheet/app.py +226 -624
- universal_mcp/applications/google_sheet/helper.py +26 -53
- universal_mcp/applications/hashnode/app.py +57 -269
- universal_mcp/applications/heygen/README.md +10 -32
- universal_mcp/applications/heygen/app.py +339 -811
- universal_mcp/applications/http_tools/app.py +10 -32
- universal_mcp/applications/hubspot/README.md +1 -1
- universal_mcp/applications/hubspot/app.py +7508 -99
- universal_mcp/applications/jira/app.py +2419 -8334
- universal_mcp/applications/klaviyo/app.py +739 -1621
- universal_mcp/applications/linkedin/README.md +18 -1
- universal_mcp/applications/linkedin/app.py +729 -251
- universal_mcp/applications/mailchimp/app.py +696 -1851
- universal_mcp/applications/markitdown/app.py +8 -20
- universal_mcp/applications/miro/app.py +333 -815
- universal_mcp/applications/ms_teams/app.py +420 -1407
- universal_mcp/applications/neon/app.py +144 -250
- universal_mcp/applications/notion/app.py +38 -53
- universal_mcp/applications/onedrive/app.py +26 -48
- universal_mcp/applications/openai/app.py +43 -166
- universal_mcp/applications/outlook/README.md +22 -9
- universal_mcp/applications/outlook/app.py +403 -141
- universal_mcp/applications/perplexity/README.md +2 -1
- universal_mcp/applications/perplexity/app.py +161 -20
- universal_mcp/applications/pipedrive/app.py +1021 -3331
- universal_mcp/applications/posthog/app.py +272 -541
- universal_mcp/applications/reddit/app.py +65 -164
- universal_mcp/applications/resend/app.py +72 -139
- universal_mcp/applications/retell/app.py +23 -50
- universal_mcp/applications/rocketlane/app.py +252 -965
- universal_mcp/applications/scraper/app.py +114 -142
- universal_mcp/applications/semanticscholar/app.py +36 -78
- universal_mcp/applications/semrush/app.py +44 -78
- universal_mcp/applications/sendgrid/app.py +826 -1576
- universal_mcp/applications/sentry/app.py +444 -1079
- universal_mcp/applications/serpapi/app.py +44 -146
- universal_mcp/applications/sharepoint/app.py +27 -49
- universal_mcp/applications/shopify/app.py +1748 -4486
- universal_mcp/applications/shortcut/app.py +275 -536
- universal_mcp/applications/slack/app.py +43 -125
- universal_mcp/applications/spotify/app.py +206 -405
- universal_mcp/applications/supabase/app.py +174 -283
- universal_mcp/applications/tavily/app.py +2 -2
- universal_mcp/applications/trello/app.py +853 -2816
- universal_mcp/applications/twilio/app.py +27 -62
- universal_mcp/applications/twitter/api_segments/compliance_api.py +4 -14
- universal_mcp/applications/twitter/api_segments/dm_conversations_api.py +6 -18
- universal_mcp/applications/twitter/api_segments/likes_api.py +1 -3
- universal_mcp/applications/twitter/api_segments/lists_api.py +5 -15
- universal_mcp/applications/twitter/api_segments/trends_api.py +1 -3
- universal_mcp/applications/twitter/api_segments/tweets_api.py +9 -31
- universal_mcp/applications/twitter/api_segments/usage_api.py +1 -5
- universal_mcp/applications/twitter/api_segments/users_api.py +14 -42
- universal_mcp/applications/whatsapp/app.py +35 -186
- universal_mcp/applications/whatsapp/audio.py +2 -6
- universal_mcp/applications/whatsapp/whatsapp.py +17 -51
- universal_mcp/applications/whatsapp_business/app.py +86 -299
- universal_mcp/applications/wrike/app.py +80 -153
- universal_mcp/applications/yahoo_finance/app.py +19 -65
- universal_mcp/applications/youtube/app.py +120 -306
- universal_mcp/applications/zenquotes/app.py +3 -3
- {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/METADATA +4 -2
- {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/RECORD +115 -119
- {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/WHEEL +1 -1
- universal_mcp/applications/hubspot/api_segments/__init__.py +0 -0
- universal_mcp/applications/hubspot/api_segments/api_segment_base.py +0 -54
- universal_mcp/applications/hubspot/api_segments/crm_api.py +0 -7337
- universal_mcp/applications/hubspot/api_segments/marketing_api.py +0 -1467
- {universal_mcp_applications-0.1.33.dist-info → universal_mcp_applications-0.1.39rc16.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
from typing import Any
|
|
2
|
-
|
|
3
2
|
from universal_mcp.applications.application import APIApplication
|
|
4
3
|
from universal_mcp.exceptions import NotAuthorizedError, ToolError
|
|
5
4
|
from universal_mcp.integrations import Integration
|
|
6
|
-
|
|
7
5
|
import resend
|
|
8
6
|
|
|
9
7
|
|
|
@@ -12,33 +10,22 @@ class ResendApp(APIApplication):
|
|
|
12
10
|
super().__init__(name="resend", integration=integration, **kwargs)
|
|
13
11
|
self._api_key = None
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
def api_key(self) -> str:
|
|
13
|
+
async def get_api_key(self) -> str:
|
|
17
14
|
"""
|
|
18
15
|
A property that lazily retrieves, validates, and caches the Resend API key from integration credentials. On first access, it configures the `resend` library, raising an error if authentication fails. This ensures the application is authenticated for all subsequent API calls within the class.
|
|
19
16
|
"""
|
|
20
17
|
if self._api_key is None:
|
|
21
18
|
if not self.integration:
|
|
22
19
|
raise NotAuthorizedError("Resend integration not configured.")
|
|
23
|
-
credentials = self.integration.
|
|
24
|
-
api_key = (
|
|
25
|
-
credentials.get("api_key")
|
|
26
|
-
or credentials.get("API_KEY")
|
|
27
|
-
or credentials.get("apiKey")
|
|
28
|
-
)
|
|
20
|
+
credentials = await self.integration.get_credentials_async()
|
|
21
|
+
api_key = credentials.get("api_key") or credentials.get("API_KEY") or credentials.get("apiKey")
|
|
29
22
|
if not api_key:
|
|
30
23
|
raise NotAuthorizedError("Resend API key not found in credentials.")
|
|
31
24
|
self._api_key = api_key
|
|
32
25
|
resend.api_key = self._api_key
|
|
33
26
|
return self._api_key
|
|
34
27
|
|
|
35
|
-
def send_email(
|
|
36
|
-
self,
|
|
37
|
-
from_email: str,
|
|
38
|
-
to_emails: list[str],
|
|
39
|
-
subject: str,
|
|
40
|
-
text: str,
|
|
41
|
-
) -> dict[str, Any]:
|
|
28
|
+
async def send_email(self, from_email: str, to_emails: list[str], subject: str, text: str) -> dict[str, Any]:
|
|
42
29
|
"""
|
|
43
30
|
Sends a single email with a specified subject and text body to a list of recipients via the Resend API. Unlike `send_batch_emails`, which processes multiple distinct emails at once, this function is designed for dispatching one individual email composition per API call.
|
|
44
31
|
|
|
@@ -57,23 +44,15 @@ class ResendApp(APIApplication):
|
|
|
57
44
|
Tags:
|
|
58
45
|
send, email, api, communication, important
|
|
59
46
|
"""
|
|
60
|
-
self.
|
|
61
|
-
params: resend.Emails.SendParams = {
|
|
62
|
-
"from": from_email,
|
|
63
|
-
"to": to_emails,
|
|
64
|
-
"subject": subject,
|
|
65
|
-
"text": text,
|
|
66
|
-
}
|
|
47
|
+
api_key = await self.get_api_key()
|
|
48
|
+
params: resend.Emails.SendParams = {"from": from_email, "to": to_emails, "subject": subject, "text": text}
|
|
67
49
|
try:
|
|
68
50
|
email = resend.Emails.send(params)
|
|
69
51
|
return email
|
|
70
52
|
except Exception as e:
|
|
71
53
|
raise ToolError(f"Failed to send email: {e}")
|
|
72
54
|
|
|
73
|
-
def send_batch_emails(
|
|
74
|
-
self,
|
|
75
|
-
emails: list[dict[str, Any]],
|
|
76
|
-
) -> dict[str, Any]:
|
|
55
|
+
async def send_batch_emails(self, emails: list[dict[str, Any]]) -> dict[str, Any]:
|
|
77
56
|
"""
|
|
78
57
|
Sends multiple emails (1-100) in a single API request. Unlike the `send_email` function which handles a single message, this accepts a list of email objects for efficient, high-volume delivery. It validates that the batch size is within the allowed limits before making the API call.
|
|
79
58
|
|
|
@@ -89,11 +68,9 @@ class ResendApp(APIApplication):
|
|
|
89
68
|
Tags:
|
|
90
69
|
batch, send, emails, resend-api
|
|
91
70
|
"""
|
|
92
|
-
self.
|
|
71
|
+
api_key = await self.get_api_key()
|
|
93
72
|
if not 1 <= len(emails) <= 100:
|
|
94
|
-
raise ToolError(
|
|
95
|
-
"The number of emails in a batch must be between 1 and 100."
|
|
96
|
-
)
|
|
73
|
+
raise ToolError("The number of emails in a batch must be between 1 and 100.")
|
|
97
74
|
params: list[resend.Emails.SendParams] = emails
|
|
98
75
|
try:
|
|
99
76
|
sent_emails_response = resend.Batch.send(params)
|
|
@@ -101,7 +78,7 @@ class ResendApp(APIApplication):
|
|
|
101
78
|
except Exception as e:
|
|
102
79
|
raise ToolError(f"Failed to send batch emails: {e}")
|
|
103
80
|
|
|
104
|
-
def retrieve_email_by_id(self, email_id: str) -> dict[str, Any]:
|
|
81
|
+
async def retrieve_email_by_id(self, email_id: str) -> dict[str, Any]:
|
|
105
82
|
"""
|
|
106
83
|
Retrieves the details and status of a single email from the Resend API using its unique identifier. This function allows for looking up a specific email that has already been sent or scheduled, distinct from functions that initiate sending.
|
|
107
84
|
|
|
@@ -117,14 +94,14 @@ class ResendApp(APIApplication):
|
|
|
117
94
|
Tags:
|
|
118
95
|
retrieve, email, management
|
|
119
96
|
"""
|
|
120
|
-
self.
|
|
97
|
+
api_key = await self.get_api_key()
|
|
121
98
|
try:
|
|
122
99
|
email = resend.Emails.get(email_id=email_id)
|
|
123
100
|
return email
|
|
124
101
|
except Exception as e:
|
|
125
102
|
raise ToolError(f"Failed to retrieve email: {e}")
|
|
126
103
|
|
|
127
|
-
def reschedule_email(self, email_id: str, scheduled_at: str) -> dict[str, Any]:
|
|
104
|
+
async def reschedule_email(self, email_id: str, scheduled_at: str) -> dict[str, Any]:
|
|
128
105
|
"""
|
|
129
106
|
Modifies the delivery time for a specific, previously scheduled email using its ID. It updates the `scheduled_at` attribute to a new ISO 8601 formatted time, effectively rescheduling its dispatch. This differs from `cancel_scheduled_email`, which permanently stops the send.
|
|
130
107
|
|
|
@@ -141,18 +118,15 @@ class ResendApp(APIApplication):
|
|
|
141
118
|
Tags:
|
|
142
119
|
update, email, async_job, management
|
|
143
120
|
"""
|
|
144
|
-
self.
|
|
145
|
-
params: resend.Emails.UpdateParams = {
|
|
146
|
-
"id": email_id,
|
|
147
|
-
"scheduled_at": scheduled_at,
|
|
148
|
-
}
|
|
121
|
+
api_key = await self.get_api_key()
|
|
122
|
+
params: resend.Emails.UpdateParams = {"id": email_id, "scheduled_at": scheduled_at}
|
|
149
123
|
try:
|
|
150
124
|
response = resend.Emails.update(params=params)
|
|
151
125
|
return response
|
|
152
126
|
except Exception as e:
|
|
153
127
|
raise ToolError(f"Failed to update scheduled email: {e}")
|
|
154
128
|
|
|
155
|
-
def cancel_scheduled_email(self, email_id: str) -> dict[str, Any]:
|
|
129
|
+
async def cancel_scheduled_email(self, email_id: str) -> dict[str, Any]:
|
|
156
130
|
"""
|
|
157
131
|
Cancels a previously scheduled email using its unique ID, preventing it from being sent. This function calls the Resend API's cancellation endpoint, returning a confirmation response. It is distinct from `update_scheduled_email`, which reschedules the email instead of stopping its transmission.
|
|
158
132
|
|
|
@@ -168,14 +142,14 @@ class ResendApp(APIApplication):
|
|
|
168
142
|
Tags:
|
|
169
143
|
cancel, email, management
|
|
170
144
|
"""
|
|
171
|
-
self.
|
|
145
|
+
api_key = await self.get_api_key()
|
|
172
146
|
try:
|
|
173
147
|
response = resend.Emails.cancel(email_id=email_id)
|
|
174
148
|
return response
|
|
175
149
|
except Exception as e:
|
|
176
150
|
raise ToolError(f"Failed to cancel scheduled email: {e}")
|
|
177
151
|
|
|
178
|
-
def create_domain(self, name: str) -> dict[str, Any]:
|
|
152
|
+
async def create_domain(self, name: str) -> dict[str, Any]:
|
|
179
153
|
"""
|
|
180
154
|
Registers a new sending domain with the Resend service using the provided name. This is a prerequisite for sending emails from your own domain and returns a dictionary containing details of the new domain object, which can then be verified and managed with other domain-related functions.
|
|
181
155
|
|
|
@@ -191,7 +165,7 @@ class ResendApp(APIApplication):
|
|
|
191
165
|
Tags:
|
|
192
166
|
create, domain, management, api, batch, important
|
|
193
167
|
"""
|
|
194
|
-
self.
|
|
168
|
+
api_key = await self.get_api_key()
|
|
195
169
|
params: resend.Domains.CreateParams = {"name": name}
|
|
196
170
|
try:
|
|
197
171
|
domain = resend.Domains.create(params)
|
|
@@ -199,7 +173,7 @@ class ResendApp(APIApplication):
|
|
|
199
173
|
except Exception as e:
|
|
200
174
|
raise ToolError(f"Failed to create domain: {e}")
|
|
201
175
|
|
|
202
|
-
def get_domain(self, domain_id: str) -> dict[str, Any]:
|
|
176
|
+
async def get_domain(self, domain_id: str) -> dict[str, Any]:
|
|
203
177
|
"""
|
|
204
178
|
Retrieves the details of a specific domain from the Resend API using its unique ID. Unlike `list_domains`, which fetches all domains, this function targets a single record and returns a dictionary containing the domain's properties, like its verification status and tracking settings.
|
|
205
179
|
|
|
@@ -215,14 +189,14 @@ class ResendApp(APIApplication):
|
|
|
215
189
|
Tags:
|
|
216
190
|
retrieve, domain, management
|
|
217
191
|
"""
|
|
218
|
-
self.
|
|
192
|
+
api_key = await self.get_api_key()
|
|
219
193
|
try:
|
|
220
194
|
domain = resend.Domains.get(domain_id=domain_id)
|
|
221
195
|
return domain
|
|
222
196
|
except Exception as e:
|
|
223
197
|
raise ToolError(f"Failed to retrieve domain: {e}")
|
|
224
198
|
|
|
225
|
-
def verify_domain(self, domain_id: str) -> dict[str, Any]:
|
|
199
|
+
async def verify_domain(self, domain_id: str) -> dict[str, Any]:
|
|
226
200
|
"""
|
|
227
201
|
Triggers the verification process for a registered domain using its unique ID. This action is crucial for authorizing the domain to send emails via Resend and returns an API response containing the verification status and necessary DNS records to complete the process.
|
|
228
202
|
|
|
@@ -238,19 +212,15 @@ class ResendApp(APIApplication):
|
|
|
238
212
|
Tags:
|
|
239
213
|
verify, domain
|
|
240
214
|
"""
|
|
241
|
-
self.
|
|
215
|
+
api_key = await self.get_api_key()
|
|
242
216
|
try:
|
|
243
217
|
response = resend.Domains.verify(domain_id=domain_id)
|
|
244
218
|
return response
|
|
245
219
|
except Exception as e:
|
|
246
220
|
raise ToolError(f"Failed to verify domain: {e}")
|
|
247
221
|
|
|
248
|
-
def update_domain_settings(
|
|
249
|
-
self,
|
|
250
|
-
domain_id: str,
|
|
251
|
-
open_tracking: bool | None = None,
|
|
252
|
-
click_tracking: bool | None = None,
|
|
253
|
-
tls: str | None = None,
|
|
222
|
+
async def update_domain_settings(
|
|
223
|
+
self, domain_id: str, open_tracking: bool | None = None, click_tracking: bool | None = None, tls: str | None = None
|
|
254
224
|
) -> dict[str, Any]:
|
|
255
225
|
"""
|
|
256
226
|
Updates settings for a specific domain identified by its ID. This function can modify configurations like open and click tracking, and TLS enforcement. It returns the updated domain object from the API, raising a ToolError if the update fails. Only the provided settings are modified.
|
|
@@ -270,7 +240,7 @@ class ResendApp(APIApplication):
|
|
|
270
240
|
Tags:
|
|
271
241
|
update, domain, management
|
|
272
242
|
"""
|
|
273
|
-
self.
|
|
243
|
+
api_key = await self.get_api_key()
|
|
274
244
|
params: resend.Domains.UpdateParams = {"id": domain_id}
|
|
275
245
|
if open_tracking is not None:
|
|
276
246
|
params["open_tracking"] = open_tracking
|
|
@@ -284,7 +254,7 @@ class ResendApp(APIApplication):
|
|
|
284
254
|
except Exception as e:
|
|
285
255
|
raise ToolError(f"Failed to update domain: {e}")
|
|
286
256
|
|
|
287
|
-
def list_domains(self) -> list[dict[str, Any]]:
|
|
257
|
+
async def list_domains(self) -> list[dict[str, Any]]:
|
|
288
258
|
"""
|
|
289
259
|
Fetches a complete list of all domains registered with the Resend account. Unlike `get_domain`, which retrieves a single domain by ID, this provides a comprehensive overview of all configured domains for management and verification tasks.
|
|
290
260
|
|
|
@@ -297,14 +267,14 @@ class ResendApp(APIApplication):
|
|
|
297
267
|
Tags:
|
|
298
268
|
list, domains, important, management
|
|
299
269
|
"""
|
|
300
|
-
self.
|
|
270
|
+
api_key = await self.get_api_key()
|
|
301
271
|
try:
|
|
302
272
|
domains = resend.Domains.list()
|
|
303
273
|
return domains
|
|
304
274
|
except Exception as e:
|
|
305
275
|
raise ToolError(f"Failed to list domains: {e}")
|
|
306
276
|
|
|
307
|
-
def remove_domain(self, domain_id: str) -> dict[str, Any]:
|
|
277
|
+
async def remove_domain(self, domain_id: str) -> dict[str, Any]:
|
|
308
278
|
"""
|
|
309
279
|
Permanently removes a specific domain from the Resend account using its unique ID. This function makes an authenticated API call to delete the domain, distinguishing it from retrieval (`get_domain`) or modification (`update_domain`) operations, and raises an error if the process fails.
|
|
310
280
|
|
|
@@ -320,14 +290,14 @@ class ResendApp(APIApplication):
|
|
|
320
290
|
Tags:
|
|
321
291
|
remove, management, api, domain
|
|
322
292
|
"""
|
|
323
|
-
self.
|
|
293
|
+
api_key = await self.get_api_key()
|
|
324
294
|
try:
|
|
325
295
|
response = resend.Domains.remove(domain_id=domain_id)
|
|
326
296
|
return response
|
|
327
297
|
except Exception as e:
|
|
328
298
|
raise ToolError(f"Failed to remove domain: {e}")
|
|
329
299
|
|
|
330
|
-
def create_api_key(self, name: str) -> dict[str, Any]:
|
|
300
|
+
async def create_api_key(self, name: str) -> dict[str, Any]:
|
|
331
301
|
"""
|
|
332
302
|
Creates a new API key for authenticating with the Resend service, identified by a specified name. It returns a dictionary containing the new key object, including the generated token required for subsequent API requests.
|
|
333
303
|
|
|
@@ -343,7 +313,7 @@ class ResendApp(APIApplication):
|
|
|
343
313
|
Tags:
|
|
344
314
|
create, api-key, authentication
|
|
345
315
|
"""
|
|
346
|
-
self.
|
|
316
|
+
api_key = await self.get_api_key()
|
|
347
317
|
params: resend.ApiKeys.CreateParams = {"name": name}
|
|
348
318
|
try:
|
|
349
319
|
api_key_obj = resend.ApiKeys.create(params)
|
|
@@ -351,7 +321,7 @@ class ResendApp(APIApplication):
|
|
|
351
321
|
except Exception as e:
|
|
352
322
|
raise ToolError(f"Failed to create API key: {e}")
|
|
353
323
|
|
|
354
|
-
def list_api_keys(self) -> list[dict[str, Any]]:
|
|
324
|
+
async def list_api_keys(self) -> list[dict[str, Any]]:
|
|
355
325
|
"""
|
|
356
326
|
Retrieves a list of all API keys for the authenticated Resend account. This read-only operation allows for auditing and viewing existing credentials, contrasting with `create_api_key` and `remove_api_key` which are used to add or delete keys.
|
|
357
327
|
|
|
@@ -367,14 +337,14 @@ class ResendApp(APIApplication):
|
|
|
367
337
|
Tags:
|
|
368
338
|
list, api, important
|
|
369
339
|
"""
|
|
370
|
-
self.
|
|
340
|
+
api_key = await self.get_api_key()
|
|
371
341
|
try:
|
|
372
342
|
keys = resend.ApiKeys.list()
|
|
373
343
|
return keys
|
|
374
344
|
except Exception as e:
|
|
375
345
|
raise ToolError(f"Failed to list API keys: {e}")
|
|
376
346
|
|
|
377
|
-
def remove_api_key(self, api_key_id: str) -> dict[str, Any]:
|
|
347
|
+
async def remove_api_key(self, api_key_id: str) -> dict[str, Any]:
|
|
378
348
|
"""
|
|
379
349
|
Deletes a specific Resend API key identified by its unique ID. This function, part of the key management suite alongside `create_api_key` and `list_api_keys`, returns an API confirmation response or raises a `ToolError` if the operation fails.
|
|
380
350
|
|
|
@@ -390,20 +360,14 @@ class ResendApp(APIApplication):
|
|
|
390
360
|
Tags:
|
|
391
361
|
remove, api-key, management
|
|
392
362
|
"""
|
|
393
|
-
self.
|
|
363
|
+
api_key = await self.get_api_key()
|
|
394
364
|
try:
|
|
395
365
|
response = resend.ApiKeys.remove(api_key_id=api_key_id)
|
|
396
366
|
return response
|
|
397
367
|
except Exception as e:
|
|
398
368
|
raise ToolError(f"Failed to remove API key: {e}")
|
|
399
369
|
|
|
400
|
-
def register_broadcast(
|
|
401
|
-
self,
|
|
402
|
-
audience_id: str,
|
|
403
|
-
from_email: str,
|
|
404
|
-
subject: str,
|
|
405
|
-
html: str,
|
|
406
|
-
) -> dict[str, Any]:
|
|
370
|
+
async def register_broadcast(self, audience_id: str, from_email: str, subject: str, html: str) -> dict[str, Any]:
|
|
407
371
|
"""
|
|
408
372
|
Registers a new email broadcast campaign for a specific audience using the Resend API. This function creates the broadcast object but does not send it; use the `send_broadcast` function to dispatch the created campaign to the audience.
|
|
409
373
|
|
|
@@ -422,20 +386,15 @@ class ResendApp(APIApplication):
|
|
|
422
386
|
Tags:
|
|
423
387
|
broadcast, email, important
|
|
424
388
|
"""
|
|
425
|
-
self.
|
|
426
|
-
params: resend.Broadcasts.CreateParams = {
|
|
427
|
-
"audience_id": audience_id,
|
|
428
|
-
"from": from_email,
|
|
429
|
-
"subject": subject,
|
|
430
|
-
"html": html,
|
|
431
|
-
}
|
|
389
|
+
api_key = await self.get_api_key()
|
|
390
|
+
params: resend.Broadcasts.CreateParams = {"audience_id": audience_id, "from": from_email, "subject": subject, "html": html}
|
|
432
391
|
try:
|
|
433
392
|
broadcast = resend.Broadcasts.create(params)
|
|
434
393
|
return broadcast
|
|
435
394
|
except Exception as e:
|
|
436
395
|
raise ToolError(f"Failed to create broadcast: {e}")
|
|
437
396
|
|
|
438
|
-
def get_broadcast(self, broadcast_id: str) -> dict[str, Any]:
|
|
397
|
+
async def get_broadcast(self, broadcast_id: str) -> dict[str, Any]:
|
|
439
398
|
"""
|
|
440
399
|
Retrieves a specific broadcast's complete details, including its status and content, by its unique ID. Unlike `list_broadcasts` which retrieves all broadcasts, this function targets a single entry for inspection.
|
|
441
400
|
|
|
@@ -451,19 +410,14 @@ class ResendApp(APIApplication):
|
|
|
451
410
|
Tags:
|
|
452
411
|
retrieve, broadcast
|
|
453
412
|
"""
|
|
454
|
-
self.
|
|
413
|
+
api_key = await self.get_api_key()
|
|
455
414
|
try:
|
|
456
415
|
broadcast = resend.Broadcasts.get(id=broadcast_id)
|
|
457
416
|
return broadcast
|
|
458
417
|
except Exception as e:
|
|
459
418
|
raise ToolError(f"Failed to retrieve broadcast: {e}")
|
|
460
419
|
|
|
461
|
-
def update_broadcast(
|
|
462
|
-
self,
|
|
463
|
-
broadcast_id: str,
|
|
464
|
-
html: str | None = None,
|
|
465
|
-
subject: str | None = None,
|
|
466
|
-
) -> dict[str, Any]:
|
|
420
|
+
async def update_broadcast(self, broadcast_id: str, html: str | None = None, subject: str | None = None) -> dict[str, Any]:
|
|
467
421
|
"""
|
|
468
422
|
Updates the HTML content and/or subject of an existing broadcast, identified by its ID. Requires that at least one modifiable field (html or subject) is provided. This function alters a broadcast's content, differing from `send_broadcast` which triggers its delivery.
|
|
469
423
|
|
|
@@ -481,25 +435,21 @@ class ResendApp(APIApplication):
|
|
|
481
435
|
Tags:
|
|
482
436
|
update, management, broadcast, api
|
|
483
437
|
"""
|
|
484
|
-
self.
|
|
438
|
+
api_key = await self.get_api_key()
|
|
485
439
|
params: resend.Broadcasts.UpdateParams = {"id": broadcast_id}
|
|
486
440
|
if html is not None:
|
|
487
441
|
params["html"] = html
|
|
488
442
|
if subject is not None:
|
|
489
443
|
params["subject"] = subject
|
|
490
444
|
if len(params) == 1:
|
|
491
|
-
raise ToolError(
|
|
492
|
-
"At least one field (e.g., html, subject) must be provided for the update."
|
|
493
|
-
)
|
|
445
|
+
raise ToolError("At least one field (e.g., html, subject) must be provided for the update.")
|
|
494
446
|
try:
|
|
495
447
|
updated_broadcast = resend.Broadcasts.update(params)
|
|
496
448
|
return updated_broadcast
|
|
497
449
|
except Exception as e:
|
|
498
450
|
raise ToolError(f"Failed to update broadcast: {e}")
|
|
499
451
|
|
|
500
|
-
def send_or_schedule_broadcast(
|
|
501
|
-
self, broadcast_id: str, scheduled_at: str | None = None
|
|
502
|
-
) -> dict[str, Any]:
|
|
452
|
+
async def send_or_schedule_broadcast(self, broadcast_id: str, scheduled_at: str | None = None) -> dict[str, Any]:
|
|
503
453
|
"""
|
|
504
454
|
Initiates the delivery of a pre-existing broadcast, identified by its ID, to its target audience. The broadcast can be sent immediately or scheduled for a future time via the optional `scheduled_at` parameter. It returns the API response upon execution.
|
|
505
455
|
|
|
@@ -516,7 +466,7 @@ class ResendApp(APIApplication):
|
|
|
516
466
|
Tags:
|
|
517
467
|
broadcast, send, api, management
|
|
518
468
|
"""
|
|
519
|
-
self.
|
|
469
|
+
api_key = await self.get_api_key()
|
|
520
470
|
params: resend.Broadcasts.SendParams = {"broadcast_id": broadcast_id}
|
|
521
471
|
if scheduled_at:
|
|
522
472
|
params["scheduled_at"] = scheduled_at
|
|
@@ -526,7 +476,7 @@ class ResendApp(APIApplication):
|
|
|
526
476
|
except Exception as e:
|
|
527
477
|
raise ToolError(f"Failed to send broadcast: {e}")
|
|
528
478
|
|
|
529
|
-
def remove_draft_broadcast(self, broadcast_id: str) -> dict[str, Any]:
|
|
479
|
+
async def remove_draft_broadcast(self, broadcast_id: str) -> dict[str, Any]:
|
|
530
480
|
"""
|
|
531
481
|
Deletes a broadcast from the Resend service using its unique ID. This action is restricted to broadcasts that have a 'draft' status and have not been sent, returning the API's response upon successful removal or raising an error if the operation fails.
|
|
532
482
|
|
|
@@ -542,14 +492,14 @@ class ResendApp(APIApplication):
|
|
|
542
492
|
Tags:
|
|
543
493
|
remove, broadcast, api-management, draft-status
|
|
544
494
|
"""
|
|
545
|
-
self.
|
|
495
|
+
api_key = await self.get_api_key()
|
|
546
496
|
try:
|
|
547
497
|
response = resend.Broadcasts.remove(id=broadcast_id)
|
|
548
498
|
return response
|
|
549
499
|
except Exception as e:
|
|
550
500
|
raise ToolError(f"Failed to remove broadcast: {e}")
|
|
551
501
|
|
|
552
|
-
def list_broadcasts(self) -> list[dict[str, Any]]:
|
|
502
|
+
async def list_broadcasts(self) -> list[dict[str, Any]]:
|
|
553
503
|
"""
|
|
554
504
|
Retrieves a list of all broadcasts associated with the authenticated account. Unlike `get_broadcast` which fetches a single item by ID, this function returns a list of dictionaries, each containing the attributes of a specific broadcast. Raises a `ToolError` on API failure.
|
|
555
505
|
|
|
@@ -562,14 +512,14 @@ class ResendApp(APIApplication):
|
|
|
562
512
|
Tags:
|
|
563
513
|
list, broadcast, api, management, important
|
|
564
514
|
"""
|
|
565
|
-
self.
|
|
515
|
+
api_key = await self.get_api_key()
|
|
566
516
|
try:
|
|
567
517
|
broadcasts = resend.Broadcasts.list()
|
|
568
518
|
return broadcasts
|
|
569
519
|
except Exception as e:
|
|
570
520
|
raise ToolError(f"Failed to list broadcasts: {e}")
|
|
571
521
|
|
|
572
|
-
def create_audience(self, name: str) -> dict[str, Any]:
|
|
522
|
+
async def create_audience(self, name: str) -> dict[str, Any]:
|
|
573
523
|
"""
|
|
574
524
|
Creates a new audience, a named list for contacts, within the Resend service. This function requires a name for the audience and returns a dictionary representing the newly created object, enabling subsequent management of contacts within that specific list.
|
|
575
525
|
|
|
@@ -585,7 +535,7 @@ class ResendApp(APIApplication):
|
|
|
585
535
|
Tags:
|
|
586
536
|
create, audience, management, important
|
|
587
537
|
"""
|
|
588
|
-
self.
|
|
538
|
+
api_key = await self.get_api_key()
|
|
589
539
|
params: resend.Audiences.CreateParams = {"name": name}
|
|
590
540
|
try:
|
|
591
541
|
audience = resend.Audiences.create(params)
|
|
@@ -593,7 +543,7 @@ class ResendApp(APIApplication):
|
|
|
593
543
|
except Exception as e:
|
|
594
544
|
raise ToolError(f"Failed to create audience: {e}")
|
|
595
545
|
|
|
596
|
-
def get_audience(self, audience_id: str) -> dict[str, Any]:
|
|
546
|
+
async def get_audience(self, audience_id: str) -> dict[str, Any]:
|
|
597
547
|
"""
|
|
598
548
|
Retrieves the details of a single audience using its unique ID. This provides a targeted lookup for one audience, distinct from `list_audiences` which fetches all available audiences in the account.
|
|
599
549
|
|
|
@@ -609,14 +559,14 @@ class ResendApp(APIApplication):
|
|
|
609
559
|
Tags:
|
|
610
560
|
fetch, audience, management, api
|
|
611
561
|
"""
|
|
612
|
-
self.
|
|
562
|
+
api_key = await self.get_api_key()
|
|
613
563
|
try:
|
|
614
564
|
audience = resend.Audiences.get(id=audience_id)
|
|
615
565
|
return audience
|
|
616
566
|
except Exception as e:
|
|
617
567
|
raise ToolError(f"Failed to retrieve audience: {e}")
|
|
618
568
|
|
|
619
|
-
def remove_audience(self, audience_id: str) -> dict[str, Any]:
|
|
569
|
+
async def remove_audience(self, audience_id: str) -> dict[str, Any]:
|
|
620
570
|
"""
|
|
621
571
|
Deletes a specific audience from the Resend service using its unique identifier. This function wraps the Resend API's remove operation, returning the API's response. Unlike `remove_contact`, which targets individuals, this function removes the entire contact list defined by the audience ID.
|
|
622
572
|
|
|
@@ -632,14 +582,14 @@ class ResendApp(APIApplication):
|
|
|
632
582
|
Tags:
|
|
633
583
|
remove, audience, management, api
|
|
634
584
|
"""
|
|
635
|
-
self.
|
|
585
|
+
api_key = await self.get_api_key()
|
|
636
586
|
try:
|
|
637
587
|
response = resend.Audiences.remove(id=audience_id)
|
|
638
588
|
return response
|
|
639
589
|
except Exception as e:
|
|
640
590
|
raise ToolError(f"Failed to remove audience: {e}")
|
|
641
591
|
|
|
642
|
-
def list_audiences(self) -> list[dict[str, Any]]:
|
|
592
|
+
async def list_audiences(self) -> list[dict[str, Any]]:
|
|
643
593
|
"""
|
|
644
594
|
Retrieves a complete list of all audiences from the Resend account. It returns a list of dictionaries, with each containing the details of a specific audience. This function is distinct from `get_audience`, which fetches a single audience by its ID.
|
|
645
595
|
|
|
@@ -652,20 +602,15 @@ class ResendApp(APIApplication):
|
|
|
652
602
|
Tags:
|
|
653
603
|
list, audiences, management, important
|
|
654
604
|
"""
|
|
655
|
-
self.
|
|
605
|
+
api_key = await self.get_api_key()
|
|
656
606
|
try:
|
|
657
607
|
audiences = resend.Audiences.list()
|
|
658
608
|
return audiences
|
|
659
609
|
except Exception as e:
|
|
660
610
|
raise ToolError(f"Failed to list audiences: {e}")
|
|
661
611
|
|
|
662
|
-
def create_contact(
|
|
663
|
-
self,
|
|
664
|
-
audience_id: str,
|
|
665
|
-
email: str,
|
|
666
|
-
first_name: str | None = None,
|
|
667
|
-
last_name: str | None = None,
|
|
668
|
-
unsubscribed: bool = False,
|
|
612
|
+
async def create_contact(
|
|
613
|
+
self, audience_id: str, email: str, first_name: str | None = None, last_name: str | None = None, unsubscribed: bool = False
|
|
669
614
|
) -> dict[str, Any]:
|
|
670
615
|
"""
|
|
671
616
|
Creates a new contact with a given email, optional name, and subscription status, adding it to a specific audience. This function populates audience lists, differing from `update_contact` which modifies existing entries, and requires a valid `audience_id` to function.
|
|
@@ -686,12 +631,8 @@ class ResendApp(APIApplication):
|
|
|
686
631
|
Tags:
|
|
687
632
|
create, contact, management, important
|
|
688
633
|
"""
|
|
689
|
-
self.
|
|
690
|
-
params: resend.Contacts.CreateParams = {
|
|
691
|
-
"audience_id": audience_id,
|
|
692
|
-
"email": email,
|
|
693
|
-
"unsubscribed": unsubscribed,
|
|
694
|
-
}
|
|
634
|
+
api_key = await self.get_api_key()
|
|
635
|
+
params: resend.Contacts.CreateParams = {"audience_id": audience_id, "email": email, "unsubscribed": unsubscribed}
|
|
695
636
|
if first_name:
|
|
696
637
|
params["first_name"] = first_name
|
|
697
638
|
if last_name:
|
|
@@ -702,9 +643,7 @@ class ResendApp(APIApplication):
|
|
|
702
643
|
except Exception as e:
|
|
703
644
|
raise ToolError(f"Failed to create contact: {e}")
|
|
704
645
|
|
|
705
|
-
def get_contact(
|
|
706
|
-
self, audience_id: str, contact_id: str | None = None, email: str | None = None
|
|
707
|
-
) -> dict[str, Any]:
|
|
646
|
+
async def get_contact(self, audience_id: str, contact_id: str | None = None, email: str | None = None) -> dict[str, Any]:
|
|
708
647
|
"""
|
|
709
648
|
Fetches a single contact's details from a specified audience by its unique ID or email address. The function requires exactly one identifier for the lookup, raising an error if the identifier is missing, ambiguous, or if the API call fails.
|
|
710
649
|
|
|
@@ -722,7 +661,7 @@ class ResendApp(APIApplication):
|
|
|
722
661
|
Tags:
|
|
723
662
|
retrieve, contact, audience, management, api
|
|
724
663
|
"""
|
|
725
|
-
self.
|
|
664
|
+
api_key = await self.get_api_key()
|
|
726
665
|
if not (contact_id or email) or (contact_id and email):
|
|
727
666
|
raise ToolError("You must provide exactly one of 'contact_id' or 'email'.")
|
|
728
667
|
params = {"audience_id": audience_id}
|
|
@@ -736,7 +675,7 @@ class ResendApp(APIApplication):
|
|
|
736
675
|
except Exception as e:
|
|
737
676
|
raise ToolError(f"Failed to retrieve contact: {e}")
|
|
738
677
|
|
|
739
|
-
def update_contact(
|
|
678
|
+
async def update_contact(
|
|
740
679
|
self,
|
|
741
680
|
audience_id: str,
|
|
742
681
|
contact_id: str | None = None,
|
|
@@ -765,11 +704,9 @@ class ResendApp(APIApplication):
|
|
|
765
704
|
Tags:
|
|
766
705
|
update, contact, management
|
|
767
706
|
"""
|
|
768
|
-
self.
|
|
707
|
+
api_key = await self.get_api_key()
|
|
769
708
|
if not (contact_id or email) or (contact_id and email):
|
|
770
|
-
raise ToolError(
|
|
771
|
-
"You must provide exactly one of 'contact_id' or 'email' to identify the contact."
|
|
772
|
-
)
|
|
709
|
+
raise ToolError("You must provide exactly one of 'contact_id' or 'email' to identify the contact.")
|
|
773
710
|
params: resend.Contacts.UpdateParams = {"audience_id": audience_id}
|
|
774
711
|
if contact_id:
|
|
775
712
|
params["id"] = contact_id
|
|
@@ -781,19 +718,15 @@ class ResendApp(APIApplication):
|
|
|
781
718
|
params["last_name"] = last_name
|
|
782
719
|
if unsubscribed is not None:
|
|
783
720
|
params["unsubscribed"] = unsubscribed
|
|
784
|
-
if len(params) <= 2:
|
|
785
|
-
raise ToolError(
|
|
786
|
-
"At least one field to update (e.g., first_name, unsubscribed) must be provided."
|
|
787
|
-
)
|
|
721
|
+
if len(params) <= 2:
|
|
722
|
+
raise ToolError("At least one field to update (e.g., first_name, unsubscribed) must be provided.")
|
|
788
723
|
try:
|
|
789
724
|
response = resend.Contacts.update(params)
|
|
790
725
|
return response
|
|
791
726
|
except Exception as e:
|
|
792
727
|
raise ToolError(f"Failed to update contact: {e}")
|
|
793
728
|
|
|
794
|
-
def remove_contact(
|
|
795
|
-
self, audience_id: str, contact_id: str | None = None, email: str | None = None
|
|
796
|
-
) -> dict[str, Any]:
|
|
729
|
+
async def remove_contact(self, audience_id: str, contact_id: str | None = None, email: str | None = None) -> dict[str, Any]:
|
|
797
730
|
"""
|
|
798
731
|
Removes a contact from a specified audience. The contact must be identified by either its unique ID or email address, but not both. Raises an error if the identifier is missing, ambiguous, or if the API call to the Resend service fails.
|
|
799
732
|
|
|
@@ -811,7 +744,7 @@ class ResendApp(APIApplication):
|
|
|
811
744
|
Tags:
|
|
812
745
|
remove, contact-management, api-call
|
|
813
746
|
"""
|
|
814
|
-
self.
|
|
747
|
+
api_key = await self.get_api_key()
|
|
815
748
|
if not (contact_id or email) or (contact_id and email):
|
|
816
749
|
raise ToolError("You must provide exactly one of 'contact_id' or 'email'.")
|
|
817
750
|
params = {"audience_id": audience_id}
|
|
@@ -825,7 +758,7 @@ class ResendApp(APIApplication):
|
|
|
825
758
|
except Exception as e:
|
|
826
759
|
raise ToolError(f"Failed to remove contact: {e}")
|
|
827
760
|
|
|
828
|
-
def list_contacts(self, audience_id: str) -> list[dict[str, Any]]:
|
|
761
|
+
async def list_contacts(self, audience_id: str) -> list[dict[str, Any]]:
|
|
829
762
|
"""
|
|
830
763
|
Retrieves a complete list of contacts belonging to a specific audience, identified by its unique ID. This function returns all contacts within the audience, unlike `get_contact` which retrieves only a single contact by its ID or email.
|
|
831
764
|
|
|
@@ -841,7 +774,7 @@ class ResendApp(APIApplication):
|
|
|
841
774
|
Tags:
|
|
842
775
|
list, contacts, management, important
|
|
843
776
|
"""
|
|
844
|
-
self.
|
|
777
|
+
api_key = await self.get_api_key()
|
|
845
778
|
try:
|
|
846
779
|
contacts = resend.Contacts.list(audience_id=audience_id)
|
|
847
780
|
return contacts
|