universal-mcp-applications 0.1.18__py3-none-any.whl → 0.1.19__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/ahrefs/README.md +3 -3
- universal_mcp/applications/airtable/README.md +3 -3
- universal_mcp/applications/asana/README.md +3 -3
- universal_mcp/applications/aws_s3/README.md +29 -0
- universal_mcp/applications/bill/README.md +249 -0
- universal_mcp/applications/calendly/README.md +45 -45
- universal_mcp/applications/canva/README.md +35 -35
- universal_mcp/applications/clickup/README.md +4 -4
- universal_mcp/applications/contentful/README.md +1 -2
- universal_mcp/applications/crustdata/README.md +3 -3
- universal_mcp/applications/domain_checker/README.md +2 -2
- universal_mcp/applications/e2b/README.md +4 -4
- universal_mcp/applications/elevenlabs/README.md +3 -77
- universal_mcp/applications/exa/README.md +7 -7
- universal_mcp/applications/falai/README.md +13 -12
- universal_mcp/applications/figma/README.md +3 -3
- universal_mcp/applications/file_system/README.md +13 -0
- universal_mcp/applications/firecrawl/README.md +9 -9
- universal_mcp/applications/fireflies/README.md +14 -14
- universal_mcp/applications/fpl/README.md +12 -12
- universal_mcp/applications/fpl/app.py +5 -5
- universal_mcp/applications/github/README.md +10 -10
- universal_mcp/applications/google_calendar/README.md +10 -10
- universal_mcp/applications/google_docs/README.md +14 -14
- universal_mcp/applications/google_drive/README.md +54 -57
- universal_mcp/applications/google_gemini/README.md +3 -14
- universal_mcp/applications/google_mail/README.md +20 -20
- universal_mcp/applications/google_searchconsole/README.md +10 -10
- universal_mcp/applications/google_sheet/README.md +25 -25
- universal_mcp/applications/google_sheet/app.py +1 -1
- universal_mcp/applications/http_tools/README.md +5 -5
- universal_mcp/applications/hubspot/__init__.py +1 -1
- universal_mcp/applications/hubspot/api_segments/__init__.py +0 -0
- universal_mcp/applications/hubspot/api_segments/api_segment_base.py +25 -0
- universal_mcp/applications/hubspot/api_segments/crm_api.py +7337 -0
- universal_mcp/applications/hubspot/api_segments/marketing_api.py +1467 -0
- universal_mcp/applications/hubspot/app.py +74 -146
- universal_mcp/applications/klaviyo/README.md +0 -36
- universal_mcp/applications/linkedin/README.md +4 -4
- universal_mcp/applications/mailchimp/README.md +3 -3
- universal_mcp/applications/ms_teams/README.md +31 -31
- universal_mcp/applications/neon/README.md +3 -3
- universal_mcp/applications/openai/README.md +18 -17
- universal_mcp/applications/outlook/README.md +9 -9
- universal_mcp/applications/perplexity/README.md +4 -4
- universal_mcp/applications/posthog/README.md +128 -127
- universal_mcp/applications/reddit/README.md +21 -124
- universal_mcp/applications/replicate/README.md +10 -10
- universal_mcp/applications/resend/README.md +29 -29
- universal_mcp/applications/scraper/README.md +4 -4
- universal_mcp/applications/semrush/README.md +3 -0
- universal_mcp/applications/serpapi/README.md +3 -3
- universal_mcp/applications/sharepoint/README.md +17 -0
- universal_mcp/applications/shortcut/README.md +3 -3
- universal_mcp/applications/slack/README.md +23 -0
- universal_mcp/applications/spotify/README.md +3 -3
- universal_mcp/applications/supabase/README.md +3 -3
- universal_mcp/applications/tavily/README.md +4 -4
- universal_mcp/applications/twilio/README.md +15 -0
- universal_mcp/applications/twitter/README.md +92 -89
- universal_mcp/applications/twitter/app.py +11 -11
- universal_mcp/applications/unipile/README.md +17 -17
- universal_mcp/applications/whatsapp/README.md +12 -12
- universal_mcp/applications/whatsapp/app.py +13 -13
- universal_mcp/applications/whatsapp_business/README.md +23 -23
- universal_mcp/applications/youtube/README.md +46 -46
- universal_mcp/applications/youtube/app.py +7 -1
- universal_mcp/applications/zenquotes/README.md +1 -1
- {universal_mcp_applications-0.1.18.dist-info → universal_mcp_applications-0.1.19.dist-info}/METADATA +2 -89
- {universal_mcp_applications-0.1.18.dist-info → universal_mcp_applications-0.1.19.dist-info}/RECORD +72 -67
- {universal_mcp_applications-0.1.18.dist-info → universal_mcp_applications-0.1.19.dist-info}/WHEEL +0 -0
- {universal_mcp_applications-0.1.18.dist-info → universal_mcp_applications-0.1.19.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,1467 @@
|
|
|
1
|
+
from typing import Any, List, Optional
|
|
2
|
+
from .api_segment_base import APISegmentBase
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class MarketingApi(APISegmentBase):
|
|
6
|
+
|
|
7
|
+
def __init__(self, main_app_client: Any):
|
|
8
|
+
super().__init__(main_app_client)
|
|
9
|
+
|
|
10
|
+
def get_marketing_campaigns(
|
|
11
|
+
self,
|
|
12
|
+
sort: Optional[str] = None,
|
|
13
|
+
after: Optional[str] = None,
|
|
14
|
+
limit: Optional[int] = None,
|
|
15
|
+
name: Optional[str] = None,
|
|
16
|
+
properties: Optional[List[str]] = None,
|
|
17
|
+
) -> dict[str, Any]:
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
Retrieves a list of marketing campaigns with optional filtering by name, sorting, and limiting results.
|
|
21
|
+
|
|
22
|
+
Args:
|
|
23
|
+
sort (string): Optional query parameter to specify sorting criteria for the returned campaigns, allowing sorting by one or more fields in ascending or descending order.
|
|
24
|
+
after (string): Optional parameter to specify a string value for filtering campaigns that occur after a certain point in time.
|
|
25
|
+
limit (integer): The maximum number of campaign records to return in the response.
|
|
26
|
+
name (string): Optional string parameter to filter campaigns by name.
|
|
27
|
+
properties (array): An optional array of campaign property names to include in the response for filtering or detailed retrieval.
|
|
28
|
+
|
|
29
|
+
Returns:
|
|
30
|
+
dict[str, Any]: successful operation
|
|
31
|
+
|
|
32
|
+
Raises:
|
|
33
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
34
|
+
|
|
35
|
+
Tags:
|
|
36
|
+
Search
|
|
37
|
+
"""
|
|
38
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns"
|
|
39
|
+
query_params = {
|
|
40
|
+
k: v
|
|
41
|
+
for k, v in [
|
|
42
|
+
("sort", sort),
|
|
43
|
+
("after", after),
|
|
44
|
+
("limit", limit),
|
|
45
|
+
("name", name),
|
|
46
|
+
("properties", properties),
|
|
47
|
+
]
|
|
48
|
+
if v is not None
|
|
49
|
+
}
|
|
50
|
+
response = self._get(url, params=query_params)
|
|
51
|
+
return self._handle_response(response)
|
|
52
|
+
|
|
53
|
+
def create_marketing_campaigns(self, properties: dict[str, str]) -> dict[str, Any]:
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
Creates a new marketing campaign using the provided JSON data and returns a status message upon successful creation.
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
properties (object): properties
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
dict[str, Any]: successful operation
|
|
63
|
+
|
|
64
|
+
Raises:
|
|
65
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
66
|
+
|
|
67
|
+
Tags:
|
|
68
|
+
Basic
|
|
69
|
+
"""
|
|
70
|
+
request_body_data = None
|
|
71
|
+
request_body_data = {"properties": properties}
|
|
72
|
+
request_body_data = {
|
|
73
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
74
|
+
}
|
|
75
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns"
|
|
76
|
+
query_params = {}
|
|
77
|
+
response = self._post(
|
|
78
|
+
url,
|
|
79
|
+
data=request_body_data,
|
|
80
|
+
params=query_params,
|
|
81
|
+
content_type="application/json",
|
|
82
|
+
)
|
|
83
|
+
return self._handle_response(response)
|
|
84
|
+
|
|
85
|
+
def batch_read_campaigns_post(
|
|
86
|
+
self,
|
|
87
|
+
inputs: List[dict[str, Any]],
|
|
88
|
+
startDate: Optional[str] = None,
|
|
89
|
+
endDate: Optional[str] = None,
|
|
90
|
+
properties: Optional[List[str]] = None,
|
|
91
|
+
) -> dict[str, Any]:
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
Retrieves a batch of campaign data from the marketing API, filtering by optional start and end dates and specifying properties to include, using JSON-formatted request body.
|
|
95
|
+
|
|
96
|
+
Args:
|
|
97
|
+
inputs (array): inputs
|
|
98
|
+
startDate (string): Optional string parameter to specify the start date for filtering campaigns in the batch read operation.
|
|
99
|
+
endDate (string): Optional query parameter specifying the end date to filter campaigns up to that date in string format.
|
|
100
|
+
properties (array): Optional array of properties to include in the response for the batch read operation.
|
|
101
|
+
|
|
102
|
+
Returns:
|
|
103
|
+
dict[str, Any]: successful operation
|
|
104
|
+
|
|
105
|
+
Raises:
|
|
106
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
107
|
+
|
|
108
|
+
Tags:
|
|
109
|
+
Batch
|
|
110
|
+
"""
|
|
111
|
+
request_body_data = None
|
|
112
|
+
request_body_data = {"inputs": inputs}
|
|
113
|
+
request_body_data = {
|
|
114
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
115
|
+
}
|
|
116
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/batch/read"
|
|
117
|
+
query_params = {
|
|
118
|
+
k: v
|
|
119
|
+
for k, v in [
|
|
120
|
+
("startDate", startDate),
|
|
121
|
+
("endDate", endDate),
|
|
122
|
+
("properties", properties),
|
|
123
|
+
]
|
|
124
|
+
if v is not None
|
|
125
|
+
}
|
|
126
|
+
response = self._post(
|
|
127
|
+
url,
|
|
128
|
+
data=request_body_data,
|
|
129
|
+
params=query_params,
|
|
130
|
+
content_type="application/json",
|
|
131
|
+
)
|
|
132
|
+
return self._handle_response(response)
|
|
133
|
+
|
|
134
|
+
def update_campaigns_batch(self, inputs: List[dict[str, Any]]) -> dict[str, Any]:
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
Updates multiple marketing campaigns in a batch using the POST method, requiring a JSON body and authentication via OAuth2 or private apps with "marketing.campaigns.read" permissions.
|
|
138
|
+
|
|
139
|
+
Args:
|
|
140
|
+
inputs (array): inputs
|
|
141
|
+
|
|
142
|
+
Returns:
|
|
143
|
+
dict[str, Any]: successful operation
|
|
144
|
+
|
|
145
|
+
Raises:
|
|
146
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
147
|
+
|
|
148
|
+
Tags:
|
|
149
|
+
Batch
|
|
150
|
+
"""
|
|
151
|
+
request_body_data = None
|
|
152
|
+
request_body_data = {"inputs": inputs}
|
|
153
|
+
request_body_data = {
|
|
154
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
155
|
+
}
|
|
156
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/batch/update"
|
|
157
|
+
query_params = {}
|
|
158
|
+
response = self._post(
|
|
159
|
+
url,
|
|
160
|
+
data=request_body_data,
|
|
161
|
+
params=query_params,
|
|
162
|
+
content_type="application/json",
|
|
163
|
+
)
|
|
164
|
+
return self._handle_response(response)
|
|
165
|
+
|
|
166
|
+
def get_campaign_metrics(
|
|
167
|
+
self,
|
|
168
|
+
campaignGuid: str,
|
|
169
|
+
startDate: Optional[str] = None,
|
|
170
|
+
endDate: Optional[str] = None,
|
|
171
|
+
) -> dict[str, Any]:
|
|
172
|
+
"""
|
|
173
|
+
|
|
174
|
+
Retrieves campaign metrics for a specified campaign GUID, optionally filtering by start and end dates.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
campaignGuid (string): campaignGuid
|
|
178
|
+
startDate (string): The optional startDate query parameter specifies the beginning date for retrieving campaign metrics in the report.
|
|
179
|
+
endDate (string): Optional date parameter specifying the end date for fetching campaign metrics, formatted as a string.
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
dict[str, Any]: successful operation
|
|
183
|
+
|
|
184
|
+
Raises:
|
|
185
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
186
|
+
|
|
187
|
+
Tags:
|
|
188
|
+
Reports
|
|
189
|
+
"""
|
|
190
|
+
if campaignGuid is None:
|
|
191
|
+
raise ValueError("Missing required parameter 'campaignGuid'.")
|
|
192
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/{campaignGuid}/reports/metrics"
|
|
193
|
+
query_params = {
|
|
194
|
+
k: v
|
|
195
|
+
for k, v in [("startDate", startDate), ("endDate", endDate)]
|
|
196
|
+
if v is not None
|
|
197
|
+
}
|
|
198
|
+
response = self._get(url, params=query_params)
|
|
199
|
+
return self._handle_response(response)
|
|
200
|
+
|
|
201
|
+
def get_campaign_asset_by_type(
|
|
202
|
+
self,
|
|
203
|
+
campaignGuid: str,
|
|
204
|
+
assetType: str,
|
|
205
|
+
after: Optional[str] = None,
|
|
206
|
+
limit: Optional[str] = None,
|
|
207
|
+
startDate: Optional[str] = None,
|
|
208
|
+
endDate: Optional[str] = None,
|
|
209
|
+
) -> dict[str, Any]:
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
Retrieves assets of a specified type for a given marketing campaign, supporting optional filtering by date range and pagination.
|
|
213
|
+
|
|
214
|
+
Args:
|
|
215
|
+
campaignGuid (string): campaignGuid
|
|
216
|
+
assetType (string): assetType
|
|
217
|
+
after (string): An optional string parameter used to specify a cursor for pagination, indicating the starting point for retrieving assets after a specific position.
|
|
218
|
+
limit (string): Optional string parameter to specify the maximum number of items to return in the response.
|
|
219
|
+
startDate (string): Optional start date filter for retrieving campaign assets, specified in string format.
|
|
220
|
+
endDate (string): Optional date string to specify the end date for filtering campaign assets.
|
|
221
|
+
|
|
222
|
+
Returns:
|
|
223
|
+
dict[str, Any]: successful operation
|
|
224
|
+
|
|
225
|
+
Raises:
|
|
226
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
227
|
+
|
|
228
|
+
Tags:
|
|
229
|
+
Asset
|
|
230
|
+
"""
|
|
231
|
+
if campaignGuid is None:
|
|
232
|
+
raise ValueError("Missing required parameter 'campaignGuid'.")
|
|
233
|
+
if assetType is None:
|
|
234
|
+
raise ValueError("Missing required parameter 'assetType'.")
|
|
235
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/{campaignGuid}/assets/{assetType}"
|
|
236
|
+
query_params = {
|
|
237
|
+
k: v
|
|
238
|
+
for k, v in [
|
|
239
|
+
("after", after),
|
|
240
|
+
("limit", limit),
|
|
241
|
+
("startDate", startDate),
|
|
242
|
+
("endDate", endDate),
|
|
243
|
+
]
|
|
244
|
+
if v is not None
|
|
245
|
+
}
|
|
246
|
+
response = self._get(url, params=query_params)
|
|
247
|
+
return self._handle_response(response)
|
|
248
|
+
|
|
249
|
+
def archive_campaigns_batch(self, inputs: List[dict[str, Any]]) -> Any:
|
|
250
|
+
"""
|
|
251
|
+
|
|
252
|
+
Archives a batch of marketing campaigns using the HubSpot API, requiring a JSON request body and returning a 204 status upon successful completion.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
inputs (array): inputs
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
Any: No content
|
|
259
|
+
|
|
260
|
+
Raises:
|
|
261
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
262
|
+
|
|
263
|
+
Tags:
|
|
264
|
+
Batch
|
|
265
|
+
"""
|
|
266
|
+
request_body_data = None
|
|
267
|
+
request_body_data = {"inputs": inputs}
|
|
268
|
+
request_body_data = {
|
|
269
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
270
|
+
}
|
|
271
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/batch/archive"
|
|
272
|
+
query_params = {}
|
|
273
|
+
response = self._post(
|
|
274
|
+
url,
|
|
275
|
+
data=request_body_data,
|
|
276
|
+
params=query_params,
|
|
277
|
+
content_type="application/json",
|
|
278
|
+
)
|
|
279
|
+
return self._handle_response(response)
|
|
280
|
+
|
|
281
|
+
def update_campaign_asset(
|
|
282
|
+
self, campaignGuid: str, assetType: str, assetId: str
|
|
283
|
+
) -> Any:
|
|
284
|
+
"""
|
|
285
|
+
|
|
286
|
+
Updates a specific asset of a given type within a marketing campaign identified by campaignGuid.
|
|
287
|
+
|
|
288
|
+
Args:
|
|
289
|
+
campaignGuid (string): campaignGuid
|
|
290
|
+
assetType (string): assetType
|
|
291
|
+
assetId (string): assetId
|
|
292
|
+
|
|
293
|
+
Returns:
|
|
294
|
+
Any: No content
|
|
295
|
+
|
|
296
|
+
Raises:
|
|
297
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
298
|
+
|
|
299
|
+
Tags:
|
|
300
|
+
Asset
|
|
301
|
+
"""
|
|
302
|
+
if campaignGuid is None:
|
|
303
|
+
raise ValueError("Missing required parameter 'campaignGuid'.")
|
|
304
|
+
if assetType is None:
|
|
305
|
+
raise ValueError("Missing required parameter 'assetType'.")
|
|
306
|
+
if assetId is None:
|
|
307
|
+
raise ValueError("Missing required parameter 'assetId'.")
|
|
308
|
+
request_body_data = None
|
|
309
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/{campaignGuid}/assets/{assetType}/{assetId}"
|
|
310
|
+
query_params = {}
|
|
311
|
+
response = self._put(
|
|
312
|
+
url,
|
|
313
|
+
data=request_body_data,
|
|
314
|
+
params=query_params,
|
|
315
|
+
content_type="application/json",
|
|
316
|
+
)
|
|
317
|
+
return self._handle_response(response)
|
|
318
|
+
|
|
319
|
+
def delete_campaign_asset_by_id(
|
|
320
|
+
self, campaignGuid: str, assetType: str, assetId: str
|
|
321
|
+
) -> Any:
|
|
322
|
+
"""
|
|
323
|
+
|
|
324
|
+
Deletes a specific asset from a marketing campaign using the provided campaign GUID, asset type, and asset ID.
|
|
325
|
+
|
|
326
|
+
Args:
|
|
327
|
+
campaignGuid (string): campaignGuid
|
|
328
|
+
assetType (string): assetType
|
|
329
|
+
assetId (string): assetId
|
|
330
|
+
|
|
331
|
+
Returns:
|
|
332
|
+
Any: No content
|
|
333
|
+
|
|
334
|
+
Raises:
|
|
335
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
336
|
+
|
|
337
|
+
Tags:
|
|
338
|
+
Asset
|
|
339
|
+
"""
|
|
340
|
+
if campaignGuid is None:
|
|
341
|
+
raise ValueError("Missing required parameter 'campaignGuid'.")
|
|
342
|
+
if assetType is None:
|
|
343
|
+
raise ValueError("Missing required parameter 'assetType'.")
|
|
344
|
+
if assetId is None:
|
|
345
|
+
raise ValueError("Missing required parameter 'assetId'.")
|
|
346
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/{campaignGuid}/assets/{assetType}/{assetId}"
|
|
347
|
+
query_params = {}
|
|
348
|
+
response = self._delete(url, params=query_params)
|
|
349
|
+
return self._handle_response(response)
|
|
350
|
+
|
|
351
|
+
def get_campaign_revenue_report(
|
|
352
|
+
self,
|
|
353
|
+
campaignGuid: str,
|
|
354
|
+
attributionModel: Optional[str] = None,
|
|
355
|
+
startDate: Optional[str] = None,
|
|
356
|
+
endDate: Optional[str] = None,
|
|
357
|
+
) -> dict[str, Any]:
|
|
358
|
+
"""
|
|
359
|
+
|
|
360
|
+
Retrieves revenue reports for a specific marketing campaign using the provided campaign GUID, with optional filtering by attribution model and date range.
|
|
361
|
+
|
|
362
|
+
Args:
|
|
363
|
+
campaignGuid (string): campaignGuid
|
|
364
|
+
attributionModel (string): Specifies the attribution model to use for calculating revenue in the report, determining which marketing channels or touchpoints receive credit for conversions.
|
|
365
|
+
startDate (string): The startDate query parameter specifies the optional beginning date to filter the revenue report data for the campaign.
|
|
366
|
+
endDate (string): The endDate query parameter specifies the optional end date to filter the revenue report data for the campaign.
|
|
367
|
+
|
|
368
|
+
Returns:
|
|
369
|
+
dict[str, Any]: successful operation
|
|
370
|
+
|
|
371
|
+
Raises:
|
|
372
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
373
|
+
|
|
374
|
+
Tags:
|
|
375
|
+
Reports
|
|
376
|
+
"""
|
|
377
|
+
if campaignGuid is None:
|
|
378
|
+
raise ValueError("Missing required parameter 'campaignGuid'.")
|
|
379
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/{campaignGuid}/reports/revenue"
|
|
380
|
+
query_params = {
|
|
381
|
+
k: v
|
|
382
|
+
for k, v in [
|
|
383
|
+
("attributionModel", attributionModel),
|
|
384
|
+
("startDate", startDate),
|
|
385
|
+
("endDate", endDate),
|
|
386
|
+
]
|
|
387
|
+
if v is not None
|
|
388
|
+
}
|
|
389
|
+
response = self._get(url, params=query_params)
|
|
390
|
+
return self._handle_response(response)
|
|
391
|
+
|
|
392
|
+
def create_campaigns_batch(self, inputs: List[dict[str, Any]]) -> dict[str, Any]:
|
|
393
|
+
"""
|
|
394
|
+
|
|
395
|
+
Creates multiple marketing campaigns in a single operation using the "POST" method, accepting a JSON body with campaign details and returning a status message upon successful creation.
|
|
396
|
+
|
|
397
|
+
Args:
|
|
398
|
+
inputs (array): inputs
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
dict[str, Any]: successful operation
|
|
402
|
+
|
|
403
|
+
Raises:
|
|
404
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
405
|
+
|
|
406
|
+
Tags:
|
|
407
|
+
Batch
|
|
408
|
+
"""
|
|
409
|
+
request_body_data = None
|
|
410
|
+
request_body_data = {"inputs": inputs}
|
|
411
|
+
request_body_data = {
|
|
412
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
413
|
+
}
|
|
414
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/batch/create"
|
|
415
|
+
query_params = {}
|
|
416
|
+
response = self._post(
|
|
417
|
+
url,
|
|
418
|
+
data=request_body_data,
|
|
419
|
+
params=query_params,
|
|
420
|
+
content_type="application/json",
|
|
421
|
+
)
|
|
422
|
+
return self._handle_response(response)
|
|
423
|
+
|
|
424
|
+
def get_campaign_budget_totals(self, campaignGuid: str) -> dict[str, Any]:
|
|
425
|
+
"""
|
|
426
|
+
|
|
427
|
+
Retrieves the total budget details for a marketing campaign using the campaign's GUID.
|
|
428
|
+
|
|
429
|
+
Args:
|
|
430
|
+
campaignGuid (string): campaignGuid
|
|
431
|
+
|
|
432
|
+
Returns:
|
|
433
|
+
dict[str, Any]: successful operation
|
|
434
|
+
|
|
435
|
+
Raises:
|
|
436
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
437
|
+
|
|
438
|
+
Tags:
|
|
439
|
+
Budget
|
|
440
|
+
"""
|
|
441
|
+
if campaignGuid is None:
|
|
442
|
+
raise ValueError("Missing required parameter 'campaignGuid'.")
|
|
443
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/{campaignGuid}/budget/totals"
|
|
444
|
+
query_params = {}
|
|
445
|
+
response = self._get(url, params=query_params)
|
|
446
|
+
return self._handle_response(response)
|
|
447
|
+
|
|
448
|
+
def get_campaign_by_guid(
|
|
449
|
+
self,
|
|
450
|
+
campaignGuid: str,
|
|
451
|
+
startDate: Optional[str] = None,
|
|
452
|
+
endDate: Optional[str] = None,
|
|
453
|
+
properties: Optional[List[str]] = None,
|
|
454
|
+
) -> dict[str, Any]:
|
|
455
|
+
"""
|
|
456
|
+
|
|
457
|
+
Retrieves detailed information about a specific marketing campaign identified by its campaignGuid, optionally filtered by date range and selected properties.
|
|
458
|
+
|
|
459
|
+
Args:
|
|
460
|
+
campaignGuid (string): campaignGuid
|
|
461
|
+
startDate (string): The optional startDate query parameter specifies the beginning date to filter campaign data for the GET /marketing/v3/campaigns/{campaignGuid} operation.
|
|
462
|
+
endDate (string): Optional date parameter to filter campaigns by end date, specified in ISO 8601 format.
|
|
463
|
+
properties (array): Optional array of properties to include in the response for the specified campaign.
|
|
464
|
+
|
|
465
|
+
Returns:
|
|
466
|
+
dict[str, Any]: successful operation
|
|
467
|
+
|
|
468
|
+
Raises:
|
|
469
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
470
|
+
|
|
471
|
+
Tags:
|
|
472
|
+
Basic
|
|
473
|
+
"""
|
|
474
|
+
if campaignGuid is None:
|
|
475
|
+
raise ValueError("Missing required parameter 'campaignGuid'.")
|
|
476
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/{campaignGuid}"
|
|
477
|
+
query_params = {
|
|
478
|
+
k: v
|
|
479
|
+
for k, v in [
|
|
480
|
+
("startDate", startDate),
|
|
481
|
+
("endDate", endDate),
|
|
482
|
+
("properties", properties),
|
|
483
|
+
]
|
|
484
|
+
if v is not None
|
|
485
|
+
}
|
|
486
|
+
response = self._get(url, params=query_params)
|
|
487
|
+
return self._handle_response(response)
|
|
488
|
+
|
|
489
|
+
def delete_campaign_by_guid(self, campaignGuid: str) -> Any:
|
|
490
|
+
"""
|
|
491
|
+
|
|
492
|
+
Deletes a marketing campaign using the provided campaign GUID and returns a 204 No Content response.
|
|
493
|
+
|
|
494
|
+
Args:
|
|
495
|
+
campaignGuid (string): campaignGuid
|
|
496
|
+
|
|
497
|
+
Returns:
|
|
498
|
+
Any: No content
|
|
499
|
+
|
|
500
|
+
Raises:
|
|
501
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
502
|
+
|
|
503
|
+
Tags:
|
|
504
|
+
Basic
|
|
505
|
+
"""
|
|
506
|
+
if campaignGuid is None:
|
|
507
|
+
raise ValueError("Missing required parameter 'campaignGuid'.")
|
|
508
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/{campaignGuid}"
|
|
509
|
+
query_params = {}
|
|
510
|
+
response = self._delete(url, params=query_params)
|
|
511
|
+
return self._handle_response(response)
|
|
512
|
+
|
|
513
|
+
def patch_campaign_by_guid(
|
|
514
|
+
self, campaignGuid: str, properties: dict[str, str]
|
|
515
|
+
) -> dict[str, Any]:
|
|
516
|
+
"""
|
|
517
|
+
|
|
518
|
+
Updates specified properties of a marketing campaign identified by the campaignGuid using a JSON patch document.
|
|
519
|
+
|
|
520
|
+
Args:
|
|
521
|
+
campaignGuid (string): campaignGuid
|
|
522
|
+
properties (object): properties
|
|
523
|
+
|
|
524
|
+
Returns:
|
|
525
|
+
dict[str, Any]: successful operation
|
|
526
|
+
|
|
527
|
+
Raises:
|
|
528
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
529
|
+
|
|
530
|
+
Tags:
|
|
531
|
+
Basic
|
|
532
|
+
"""
|
|
533
|
+
if campaignGuid is None:
|
|
534
|
+
raise ValueError("Missing required parameter 'campaignGuid'.")
|
|
535
|
+
request_body_data = None
|
|
536
|
+
request_body_data = {"properties": properties}
|
|
537
|
+
request_body_data = {
|
|
538
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
539
|
+
}
|
|
540
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/{campaignGuid}"
|
|
541
|
+
query_params = {}
|
|
542
|
+
response = self._patch(url, data=request_body_data, params=query_params)
|
|
543
|
+
return self._handle_response(response)
|
|
544
|
+
|
|
545
|
+
def get_campaign_contacts_report_by_type(
|
|
546
|
+
self,
|
|
547
|
+
campaignGuid: str,
|
|
548
|
+
contactType: str,
|
|
549
|
+
startDate: Optional[str] = None,
|
|
550
|
+
endDate: Optional[str] = None,
|
|
551
|
+
limit: Optional[int] = None,
|
|
552
|
+
after: Optional[str] = None,
|
|
553
|
+
) -> dict[str, Any]:
|
|
554
|
+
"""
|
|
555
|
+
|
|
556
|
+
Retrieves a report of contacts of a specified type for a marketing campaign, allowing optional filtering by start and end dates and pagination.
|
|
557
|
+
|
|
558
|
+
Args:
|
|
559
|
+
campaignGuid (string): campaignGuid
|
|
560
|
+
contactType (string): contactType
|
|
561
|
+
startDate (string): Optional query parameter specifying the start date for filtering reports in the format of a string, allowing users to narrow down the data based on a specific date range.
|
|
562
|
+
endDate (string): Optional query parameter to specify the end date for filtering the campaign contact report data.
|
|
563
|
+
limit (integer): The "limit" parameter, an optional integer, specifies the maximum number of records to return in the response for the contacts report.
|
|
564
|
+
after (string): Optional string parameter to specify a filter for retrieving contacts after a specific date or identifier.
|
|
565
|
+
|
|
566
|
+
Returns:
|
|
567
|
+
dict[str, Any]: successful operation
|
|
568
|
+
|
|
569
|
+
Raises:
|
|
570
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
571
|
+
|
|
572
|
+
Tags:
|
|
573
|
+
Reports
|
|
574
|
+
"""
|
|
575
|
+
if campaignGuid is None:
|
|
576
|
+
raise ValueError("Missing required parameter 'campaignGuid'.")
|
|
577
|
+
if contactType is None:
|
|
578
|
+
raise ValueError("Missing required parameter 'contactType'.")
|
|
579
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/campaigns/{campaignGuid}/reports/contacts/{contactType}"
|
|
580
|
+
query_params = {
|
|
581
|
+
k: v
|
|
582
|
+
for k, v in [
|
|
583
|
+
("startDate", startDate),
|
|
584
|
+
("endDate", endDate),
|
|
585
|
+
("limit", limit),
|
|
586
|
+
("after", after),
|
|
587
|
+
]
|
|
588
|
+
if v is not None
|
|
589
|
+
}
|
|
590
|
+
response = self._get(url, params=query_params)
|
|
591
|
+
return self._handle_response(response)
|
|
592
|
+
|
|
593
|
+
def list_email_statistics(
|
|
594
|
+
self,
|
|
595
|
+
startTimestamp: Optional[str] = None,
|
|
596
|
+
endTimestamp: Optional[str] = None,
|
|
597
|
+
emailIds: Optional[List[int]] = None,
|
|
598
|
+
property: Optional[str] = None,
|
|
599
|
+
) -> dict[str, Any]:
|
|
600
|
+
"""
|
|
601
|
+
|
|
602
|
+
Retrieves email statistics for a specified time range and optional email IDs and properties using the GET method.
|
|
603
|
+
|
|
604
|
+
Args:
|
|
605
|
+
startTimestamp (string): Optional query parameter to specify the start timestamp for filtering email statistics.
|
|
606
|
+
endTimestamp (string): Optional end timestamp in string format to filter email statistics up to a specific point in time.
|
|
607
|
+
emailIds (array): Optional array of email IDs to filter statistics; allows retrieving specific email campaign statistics.
|
|
608
|
+
property (string): An optional string parameter used in the query to specify additional properties for filtering or customizing the email statistics list.
|
|
609
|
+
|
|
610
|
+
Returns:
|
|
611
|
+
dict[str, Any]: successful operation
|
|
612
|
+
|
|
613
|
+
Raises:
|
|
614
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
615
|
+
|
|
616
|
+
Tags:
|
|
617
|
+
Statistics
|
|
618
|
+
"""
|
|
619
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/statistics/list"
|
|
620
|
+
query_params = {
|
|
621
|
+
k: v
|
|
622
|
+
for k, v in [
|
|
623
|
+
("startTimestamp", startTimestamp),
|
|
624
|
+
("endTimestamp", endTimestamp),
|
|
625
|
+
("emailIds", emailIds),
|
|
626
|
+
("property", property),
|
|
627
|
+
]
|
|
628
|
+
if v is not None
|
|
629
|
+
}
|
|
630
|
+
response = self._get(url, params=query_params)
|
|
631
|
+
return self._handle_response(response)
|
|
632
|
+
|
|
633
|
+
def create_ab_test_email_variation(
|
|
634
|
+
self, variationName: str, contentId: str
|
|
635
|
+
) -> dict[str, Any]:
|
|
636
|
+
"""
|
|
637
|
+
|
|
638
|
+
Creates a variation for an A/B test email using the POST method and returns a successful creation status.
|
|
639
|
+
|
|
640
|
+
Args:
|
|
641
|
+
variationName (string): variationName
|
|
642
|
+
contentId (string): ID of the object to test. Example: '7'.
|
|
643
|
+
|
|
644
|
+
Returns:
|
|
645
|
+
dict[str, Any]: successful operation
|
|
646
|
+
|
|
647
|
+
Raises:
|
|
648
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
649
|
+
|
|
650
|
+
Tags:
|
|
651
|
+
Public_VNext_Emails
|
|
652
|
+
"""
|
|
653
|
+
request_body_data = None
|
|
654
|
+
request_body_data = {"variationName": variationName, "contentId": contentId}
|
|
655
|
+
request_body_data = {
|
|
656
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
657
|
+
}
|
|
658
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/ab-test/create-variation"
|
|
659
|
+
query_params = {}
|
|
660
|
+
response = self._post(
|
|
661
|
+
url,
|
|
662
|
+
data=request_body_data,
|
|
663
|
+
params=query_params,
|
|
664
|
+
content_type="application/json",
|
|
665
|
+
)
|
|
666
|
+
return self._handle_response(response)
|
|
667
|
+
|
|
668
|
+
def get_email_statistics_histogram(
|
|
669
|
+
self,
|
|
670
|
+
interval: Optional[str] = None,
|
|
671
|
+
startTimestamp: Optional[str] = None,
|
|
672
|
+
endTimestamp: Optional[str] = None,
|
|
673
|
+
emailIds: Optional[List[int]] = None,
|
|
674
|
+
) -> dict[str, Any]:
|
|
675
|
+
"""
|
|
676
|
+
|
|
677
|
+
Retrieves histogram statistics for marketing emails filtered by optional parameters such as interval, time range, and specific email IDs.
|
|
678
|
+
|
|
679
|
+
Args:
|
|
680
|
+
interval (string): The "interval" parameter specifies the time interval for dividing email statistics into buckets, with options including YEAR, QUARTER, MONTH, WEEK, DAY, HOUR, QUARTER_HOUR, MINUTE, and SECOND.
|
|
681
|
+
startTimestamp (string): The optional query parameter specifying the start timestamp to filter email statistics in the histogram data.
|
|
682
|
+
endTimestamp (string): Optional end timestamp for the histogram data, specified as a string.
|
|
683
|
+
emailIds (array): Optional query parameter to specify one or more email IDs for which to retrieve histogram statistics.
|
|
684
|
+
|
|
685
|
+
Returns:
|
|
686
|
+
dict[str, Any]: successful operation
|
|
687
|
+
|
|
688
|
+
Raises:
|
|
689
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
690
|
+
|
|
691
|
+
Tags:
|
|
692
|
+
Statistics
|
|
693
|
+
"""
|
|
694
|
+
url = (
|
|
695
|
+
f"{self.main_app_client.base_url}/marketing/v3/emails/statistics/histogram"
|
|
696
|
+
)
|
|
697
|
+
query_params = {
|
|
698
|
+
k: v
|
|
699
|
+
for k, v in [
|
|
700
|
+
("interval", interval),
|
|
701
|
+
("startTimestamp", startTimestamp),
|
|
702
|
+
("endTimestamp", endTimestamp),
|
|
703
|
+
("emailIds", emailIds),
|
|
704
|
+
]
|
|
705
|
+
if v is not None
|
|
706
|
+
}
|
|
707
|
+
response = self._get(url, params=query_params)
|
|
708
|
+
return self._handle_response(response)
|
|
709
|
+
|
|
710
|
+
def get_email_ab_test_variation(self, emailId: str) -> dict[str, Any]:
|
|
711
|
+
"""
|
|
712
|
+
|
|
713
|
+
Retrieves the variation for an A/B test associated with a specific email by its ID using the GET method.
|
|
714
|
+
|
|
715
|
+
Args:
|
|
716
|
+
emailId (string): emailId
|
|
717
|
+
|
|
718
|
+
Returns:
|
|
719
|
+
dict[str, Any]: successful operation
|
|
720
|
+
|
|
721
|
+
Raises:
|
|
722
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
723
|
+
|
|
724
|
+
Tags:
|
|
725
|
+
Marketing Emails
|
|
726
|
+
"""
|
|
727
|
+
if emailId is None:
|
|
728
|
+
raise ValueError("Missing required parameter 'emailId'.")
|
|
729
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/{emailId}/ab-test/get-variation"
|
|
730
|
+
query_params = {}
|
|
731
|
+
response = self._get(url, params=query_params)
|
|
732
|
+
return self._handle_response(response)
|
|
733
|
+
|
|
734
|
+
def reset_email_draft_by_id(self, emailId: str) -> Any:
|
|
735
|
+
"""
|
|
736
|
+
|
|
737
|
+
Resets the draft status of an email using the specified email ID.
|
|
738
|
+
|
|
739
|
+
Args:
|
|
740
|
+
emailId (string): emailId
|
|
741
|
+
|
|
742
|
+
Returns:
|
|
743
|
+
Any: No content
|
|
744
|
+
|
|
745
|
+
Raises:
|
|
746
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
747
|
+
|
|
748
|
+
Tags:
|
|
749
|
+
Marketing Emails
|
|
750
|
+
"""
|
|
751
|
+
if emailId is None:
|
|
752
|
+
raise ValueError("Missing required parameter 'emailId'.")
|
|
753
|
+
request_body_data = None
|
|
754
|
+
url = (
|
|
755
|
+
f"{self.main_app_client.base_url}/marketing/v3/emails/{emailId}/draft/reset"
|
|
756
|
+
)
|
|
757
|
+
query_params = {}
|
|
758
|
+
response = self._post(
|
|
759
|
+
url,
|
|
760
|
+
data=request_body_data,
|
|
761
|
+
params=query_params,
|
|
762
|
+
content_type="application/json",
|
|
763
|
+
)
|
|
764
|
+
return self._handle_response(response)
|
|
765
|
+
|
|
766
|
+
def restore_email_revision_to_draft(
|
|
767
|
+
self, emailId: str, revisionId: str
|
|
768
|
+
) -> dict[str, Any]:
|
|
769
|
+
"""
|
|
770
|
+
|
|
771
|
+
Restores a specified email revision to draft status by email ID and revision ID.
|
|
772
|
+
|
|
773
|
+
Args:
|
|
774
|
+
emailId (string): emailId
|
|
775
|
+
revisionId (string): revisionId
|
|
776
|
+
|
|
777
|
+
Returns:
|
|
778
|
+
dict[str, Any]: successful operation
|
|
779
|
+
|
|
780
|
+
Raises:
|
|
781
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
782
|
+
|
|
783
|
+
Tags:
|
|
784
|
+
Marketing Emails
|
|
785
|
+
"""
|
|
786
|
+
if emailId is None:
|
|
787
|
+
raise ValueError("Missing required parameter 'emailId'.")
|
|
788
|
+
if revisionId is None:
|
|
789
|
+
raise ValueError("Missing required parameter 'revisionId'.")
|
|
790
|
+
request_body_data = None
|
|
791
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/{emailId}/revisions/{revisionId}/restore-to-draft"
|
|
792
|
+
query_params = {}
|
|
793
|
+
response = self._post(
|
|
794
|
+
url,
|
|
795
|
+
data=request_body_data,
|
|
796
|
+
params=query_params,
|
|
797
|
+
content_type="application/json",
|
|
798
|
+
)
|
|
799
|
+
return self._handle_response(response)
|
|
800
|
+
|
|
801
|
+
def get_email_draft_by_id(self, emailId: str) -> dict[str, Any]:
|
|
802
|
+
"""
|
|
803
|
+
|
|
804
|
+
Retrieves the draft of an email with the specified `{emailId}` using the marketing API.
|
|
805
|
+
|
|
806
|
+
Args:
|
|
807
|
+
emailId (string): emailId
|
|
808
|
+
|
|
809
|
+
Returns:
|
|
810
|
+
dict[str, Any]: successful operation
|
|
811
|
+
|
|
812
|
+
Raises:
|
|
813
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
814
|
+
|
|
815
|
+
Tags:
|
|
816
|
+
Marketing Emails
|
|
817
|
+
"""
|
|
818
|
+
if emailId is None:
|
|
819
|
+
raise ValueError("Missing required parameter 'emailId'.")
|
|
820
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/{emailId}/draft"
|
|
821
|
+
query_params = {}
|
|
822
|
+
response = self._get(url, params=query_params)
|
|
823
|
+
return self._handle_response(response)
|
|
824
|
+
|
|
825
|
+
def update_email_draft_by_id(
|
|
826
|
+
self,
|
|
827
|
+
emailId: str,
|
|
828
|
+
rssData: Optional[dict[str, Any]] = None,
|
|
829
|
+
subject: Optional[str] = None,
|
|
830
|
+
testing: Optional[dict[str, Any]] = None,
|
|
831
|
+
publishDate: Optional[str] = None,
|
|
832
|
+
language: Optional[str] = None,
|
|
833
|
+
businessUnitId: Optional[str] = None,
|
|
834
|
+
content: Optional[dict[str, Any]] = None,
|
|
835
|
+
webversion: Optional[dict[str, Any]] = None,
|
|
836
|
+
archived: Optional[bool] = None,
|
|
837
|
+
subscriptionDetails: Optional[dict[str, Any]] = None,
|
|
838
|
+
activeDomain: Optional[str] = None,
|
|
839
|
+
name: Optional[str] = None,
|
|
840
|
+
campaign: Optional[str] = None,
|
|
841
|
+
from_: Optional[dict[str, Any]] = None,
|
|
842
|
+
state: Optional[str] = None,
|
|
843
|
+
to: Optional[dict[str, Any]] = None,
|
|
844
|
+
subcategory: Optional[str] = None,
|
|
845
|
+
sendOnPublish: Optional[bool] = None,
|
|
846
|
+
) -> dict[str, Any]:
|
|
847
|
+
"""
|
|
848
|
+
|
|
849
|
+
Updates a draft email identified by the specified emailId using the provided JSON data.
|
|
850
|
+
|
|
851
|
+
Args:
|
|
852
|
+
emailId (string): emailId
|
|
853
|
+
rssData (object): RSS related data if it is a blog or rss email.
|
|
854
|
+
subject (string): The subject of the email. Example: 'My subject'.
|
|
855
|
+
testing (object): AB testing related data. This property is only returned for AB type emails.
|
|
856
|
+
publishDate (string): The date and time the email is scheduled for, in ISO8601 representation. This is only used in local time or scheduled emails. Example: '2023-11-30T18:44:20.387Z'.
|
|
857
|
+
language (string): language
|
|
858
|
+
businessUnitId (string): businessUnitId
|
|
859
|
+
content (object): Data structure representing the content of the email. Example: {'flexAreas': {'main': {'boxed': False, 'isSingleColumnFullWidth': False, 'sections': [{'columns': [{'id': 'column_1606761806181_0', 'widgets': ['module_160676180617911'], 'width': 12}], 'id': 'section_1606761806181', 'style': {'backgroundColor': '', 'backgroundType': 'CONTENT'}}, {'columns': [{'id': 'column-0-1', 'widgets': ['module-0-1-1'], 'width': 12}], 'id': 'section-0', 'style': {'backgroundType': 'CONTENT', 'paddingBottom': '40px', 'paddingTop': '40px'}}, {'columns': [{'id': 'column-1-1', 'widgets': ['module-1-1-1'], 'width': 12}], 'id': 'section-1', 'style': {'backgroundColor': '', 'backgroundType': 'CONTENT', 'paddingBottom': '0px', 'paddingTop': '0px'}}]}}, 'plainTextVersion': 'This is custom! View in browser ({{view_as_page_url}})
|
|
860
|
+
|
|
861
|
+
Hello {{ contact.firstname }},
|
|
862
|
+
|
|
863
|
+
Plain text emails have minimal formatting so your reader can really focus on what you have to say. Introduce yourself and explain why you’re reaching out.
|
|
864
|
+
|
|
865
|
+
Every email should try to lead the reader to some kind of action. Use this space to describe why the reader should want to click on the link below. Put the link on its own line to really draw their eye to it.
|
|
866
|
+
|
|
867
|
+
Link text
|
|
868
|
+
|
|
869
|
+
Now it’s time to wrap up your email. Before your signature, thank the recipient for reading. You can also invite them to send this email to any of their colleagues who might be interested.
|
|
870
|
+
|
|
871
|
+
All the best,
|
|
872
|
+
|
|
873
|
+
Your full name
|
|
874
|
+
|
|
875
|
+
Your job title
|
|
876
|
+
|
|
877
|
+
Other contact information
|
|
878
|
+
|
|
879
|
+
{{site_settings.company_name}}, {{site_settings.company_street_address_1}}, {{site_settings.company_street_address_2}}, {{site_settings.company_city}}, {{site_settings.company_state}} {{site_settings.company_zip}}, {{site_settings.company_country}}, {{site_settings.company_phone}}
|
|
880
|
+
|
|
881
|
+
Unsubscribe ({{unsubscribe_link_all}})
|
|
882
|
+
|
|
883
|
+
Manage preferences ({{unsubscribe_link}})', 'styleSettings': {}, 'widgets': {'module-0-1-1': {'body': {'css_class': 'dnd-module', 'html': '<p style="margin-bottom:10px;">Hello {{ contact.firstname }},<br><br>Plain text emails have minimal formatting so your reader can really focus on what you have to say. Introduce yourself and explain why you’re reaching out.</p><p style="margin-bottom:10px;">Every email should try to lead the reader to some kind of action. Use this space to describe why the reader should want to click on the link below. Put the link on its own line to really draw their eye to it.</p><p style="margin-bottom:10px;"><a target="_blank" rel="noopener">Link text</a></p><p style="margin-bottom:10px;">Now it’s time to wrap up your email. Before your signature, thank the recipient for reading. You can also invite them to send this email to any of their colleagues who might be interested.</p><p style="margin-bottom:10px;">All the best,<br>Your full name<br>Your job title<br>Other contact information</p>', 'i18nKey': 'richText.plainText', 'path': '@hubspot/rich_text', 'schema_version': 2}, 'child_css': {}, 'css': {}, 'id': 'module-0-1-1', 'module_id': 1155639, 'name': 'module-0-1-1', 'order': 2, 'styles': {}, 'type': 'module'}, 'module-1-1-1': {'body': {'align': 'center', 'css_class': 'dnd-module', 'font': {'color': '#23496d', 'font': 'Arial, sans-serif', 'size': {'units': 'px', 'value': 12}}, 'link_font': {'color': '#00a4bd', 'font': 'Helvetica,Arial,sans-serif', 'size': {'units': 'px', 'value': 12}, 'styles': {'bold': False, 'italic': False, 'underline': True}}, 'path': '@hubspot/email_footer', 'schema_version': 2, 'unsubscribe_link_type': 'both'}, 'child_css': {}, 'css': {}, 'id': 'module-1-1-1', 'module_id': 2869621, 'name': 'module-1-1-1', 'order': 3, 'styles': {}, 'type': 'module'}, 'module_160676180617911': {'body': {'font': {'color': '#00a4bd', 'font': 'Arial, sans-serif', 'size': {'units': 'px', 'value': 12}, 'styles': {'bold': False, 'italic': False, 'underline': True}}, 'hs_enable_module_padding': False, 'hs_wrapper_css': {}}, 'child_css': {}, 'css': {}, 'id': 'module_160676180617911', 'module_id': 2794854, 'name': 'module_160676180617911', 'styles': {}, 'type': 'module'}, 'preview_text': {'body': {'value': ''}, 'child_css': {}, 'css': {}, 'id': 'preview_text', 'label': 'Preview Text <span class=help-text>This will be used as the preview text that displays in some email clients</span>', 'name': 'preview_text', 'order': 0, 'styles': {}, 'type': 'text'}}}.
|
|
884
|
+
webversion (object): webversion Example: {'expiresAt': '2020-11-30T18:44:20.387Z', 'metaDescription': '', 'redirectToPageId': 0, 'redirectToUrl': 'http://www.example.org'}.
|
|
885
|
+
archived (boolean): Determines if the email is archived or not. Example: False.
|
|
886
|
+
subscriptionDetails (object): Data structure representing the subscription fields of the email. Example: {'officeLocationId': '5449392956'}.
|
|
887
|
+
activeDomain (string): The active domain of the email. Example: 'test.hs-sites.com'.
|
|
888
|
+
name (string): The name of the email, as displayed on the email dashboard. Example: 'My subject'.
|
|
889
|
+
campaign (string): The ID of the campaign this email is associated to. Example: '1b7f51a6-33c1-44d6-ba28-fe81f655dced'.
|
|
890
|
+
from_ (object): Data structure representing the from fields on the email. Example: {'fromName': 'Bruce Wayne', 'replyTo': 'test@hubspot.com'}.
|
|
891
|
+
state (string): The email state. Example: 'DRAFT'.
|
|
892
|
+
to (object): Data structure representing the to fields of the email. Example: {'contactIds': {}, 'contactLists': {'exclude': [1], 'include': [5]}, 'suppressGraymail': True}.
|
|
893
|
+
subcategory (string): The email subcategory. Example: 'batch'.
|
|
894
|
+
sendOnPublish (boolean): Determines whether the email will be sent immediately on publish. Example: True.
|
|
895
|
+
|
|
896
|
+
Returns:
|
|
897
|
+
dict[str, Any]: successful operation
|
|
898
|
+
|
|
899
|
+
Raises:
|
|
900
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
901
|
+
|
|
902
|
+
Tags:
|
|
903
|
+
Marketing Emails
|
|
904
|
+
"""
|
|
905
|
+
if emailId is None:
|
|
906
|
+
raise ValueError("Missing required parameter 'emailId'.")
|
|
907
|
+
request_body_data = None
|
|
908
|
+
request_body_data = {
|
|
909
|
+
"rssData": rssData,
|
|
910
|
+
"subject": subject,
|
|
911
|
+
"testing": testing,
|
|
912
|
+
"publishDate": publishDate,
|
|
913
|
+
"language": language,
|
|
914
|
+
"businessUnitId": businessUnitId,
|
|
915
|
+
"content": content,
|
|
916
|
+
"webversion": webversion,
|
|
917
|
+
"archived": archived,
|
|
918
|
+
"subscriptionDetails": subscriptionDetails,
|
|
919
|
+
"activeDomain": activeDomain,
|
|
920
|
+
"name": name,
|
|
921
|
+
"campaign": campaign,
|
|
922
|
+
"from": from_,
|
|
923
|
+
"state": state,
|
|
924
|
+
"to": to,
|
|
925
|
+
"subcategory": subcategory,
|
|
926
|
+
"sendOnPublish": sendOnPublish,
|
|
927
|
+
}
|
|
928
|
+
request_body_data = {
|
|
929
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
930
|
+
}
|
|
931
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/{emailId}/draft"
|
|
932
|
+
query_params = {}
|
|
933
|
+
response = self._patch(url, data=request_body_data, params=query_params)
|
|
934
|
+
return self._handle_response(response)
|
|
935
|
+
|
|
936
|
+
def get_email_revisions(
|
|
937
|
+
self,
|
|
938
|
+
emailId: str,
|
|
939
|
+
after: Optional[str] = None,
|
|
940
|
+
before: Optional[str] = None,
|
|
941
|
+
limit: Optional[int] = None,
|
|
942
|
+
) -> dict[str, Any]:
|
|
943
|
+
"""
|
|
944
|
+
|
|
945
|
+
Get a list of revisions for a specified marketing email, optionally filtered by date range and limited in number.
|
|
946
|
+
|
|
947
|
+
Args:
|
|
948
|
+
emailId (string): emailId
|
|
949
|
+
after (string): The "after" query parameter specifies a cursor or token to retrieve email revisions created after a certain point, enabling pagination of results.
|
|
950
|
+
before (string): Filter the email revisions to include only those created before the specified timestamp or identifier.
|
|
951
|
+
limit (integer): The "limit" parameter specifies the maximum number of revisions to return in the response when retrieving revisions for a specific email.
|
|
952
|
+
|
|
953
|
+
Returns:
|
|
954
|
+
dict[str, Any]: successful operation
|
|
955
|
+
|
|
956
|
+
Raises:
|
|
957
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
958
|
+
|
|
959
|
+
Tags:
|
|
960
|
+
Marketing Emails
|
|
961
|
+
"""
|
|
962
|
+
if emailId is None:
|
|
963
|
+
raise ValueError("Missing required parameter 'emailId'.")
|
|
964
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/{emailId}/revisions"
|
|
965
|
+
query_params = {
|
|
966
|
+
k: v
|
|
967
|
+
for k, v in [("after", after), ("before", before), ("limit", limit)]
|
|
968
|
+
if v is not None
|
|
969
|
+
}
|
|
970
|
+
response = self._get(url, params=query_params)
|
|
971
|
+
return self._handle_response(response)
|
|
972
|
+
|
|
973
|
+
def get_email_revision_by_id(self, emailId: str, revisionId: str) -> dict[str, Any]:
|
|
974
|
+
"""
|
|
975
|
+
|
|
976
|
+
Retrieves a specific revision of an email identified by the provided email ID and revision ID using the GET method.
|
|
977
|
+
|
|
978
|
+
Args:
|
|
979
|
+
emailId (string): emailId
|
|
980
|
+
revisionId (string): revisionId
|
|
981
|
+
|
|
982
|
+
Returns:
|
|
983
|
+
dict[str, Any]: successful operation
|
|
984
|
+
|
|
985
|
+
Raises:
|
|
986
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
987
|
+
|
|
988
|
+
Tags:
|
|
989
|
+
Marketing Emails
|
|
990
|
+
"""
|
|
991
|
+
if emailId is None:
|
|
992
|
+
raise ValueError("Missing required parameter 'emailId'.")
|
|
993
|
+
if revisionId is None:
|
|
994
|
+
raise ValueError("Missing required parameter 'revisionId'.")
|
|
995
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/{emailId}/revisions/{revisionId}"
|
|
996
|
+
query_params = {}
|
|
997
|
+
response = self._get(url, params=query_params)
|
|
998
|
+
return self._handle_response(response)
|
|
999
|
+
|
|
1000
|
+
def clone_email(self, id: str, cloneName: Optional[str] = None) -> dict[str, Any]:
|
|
1001
|
+
"""
|
|
1002
|
+
|
|
1003
|
+
Clones a marketing email using the POST method at the "/marketing/v3/emails/clone" endpoint, creating a duplicate email with the same properties as the original but with a unique ID.
|
|
1004
|
+
|
|
1005
|
+
Args:
|
|
1006
|
+
id (string): ID of the email to be cloned.
|
|
1007
|
+
cloneName (string): Name of the cloned email.
|
|
1008
|
+
|
|
1009
|
+
Returns:
|
|
1010
|
+
dict[str, Any]: successful operation
|
|
1011
|
+
|
|
1012
|
+
Raises:
|
|
1013
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
1014
|
+
|
|
1015
|
+
Tags:
|
|
1016
|
+
Public_VNext_Emails
|
|
1017
|
+
"""
|
|
1018
|
+
request_body_data = None
|
|
1019
|
+
request_body_data = {"cloneName": cloneName, "id": id}
|
|
1020
|
+
request_body_data = {
|
|
1021
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
1022
|
+
}
|
|
1023
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/clone"
|
|
1024
|
+
query_params = {}
|
|
1025
|
+
response = self._post(
|
|
1026
|
+
url,
|
|
1027
|
+
data=request_body_data,
|
|
1028
|
+
params=query_params,
|
|
1029
|
+
content_type="application/json",
|
|
1030
|
+
)
|
|
1031
|
+
return self._handle_response(response)
|
|
1032
|
+
|
|
1033
|
+
def list_marketing_emails(
|
|
1034
|
+
self,
|
|
1035
|
+
createdAt: Optional[str] = None,
|
|
1036
|
+
createdAfter: Optional[str] = None,
|
|
1037
|
+
createdBefore: Optional[str] = None,
|
|
1038
|
+
updatedAt: Optional[str] = None,
|
|
1039
|
+
updatedAfter: Optional[str] = None,
|
|
1040
|
+
updatedBefore: Optional[str] = None,
|
|
1041
|
+
sort: Optional[List[str]] = None,
|
|
1042
|
+
after: Optional[str] = None,
|
|
1043
|
+
limit: Optional[int] = None,
|
|
1044
|
+
includeStats: Optional[bool] = None,
|
|
1045
|
+
type: Optional[str] = None,
|
|
1046
|
+
isPublished: Optional[bool] = None,
|
|
1047
|
+
includedProperties: Optional[List[str]] = None,
|
|
1048
|
+
archived: Optional[bool] = None,
|
|
1049
|
+
) -> dict[str, Any]:
|
|
1050
|
+
"""
|
|
1051
|
+
|
|
1052
|
+
Retrieves a list of marketing emails with optional filtering, sorting, pagination, and inclusion of statistics.
|
|
1053
|
+
|
|
1054
|
+
Args:
|
|
1055
|
+
createdAt (string): Optional query parameter specifying the creation date of emails to filter results, formatted as a string.
|
|
1056
|
+
createdAfter (string): Filter emails created after a specific date and time, specified in ISO 8601 format.
|
|
1057
|
+
createdBefore (string): Filter results to include only emails created before the specified date and time.
|
|
1058
|
+
updatedAt (string): Filter emails to include only those updated at or after the specified date and time.
|
|
1059
|
+
updatedAfter (string): Filter emails to include only those updated after the specified date and time.
|
|
1060
|
+
updatedBefore (string): Optional query parameter to filter emails updated before a specified date and time.
|
|
1061
|
+
sort (array): Specifies an array of fields to sort the email results by, allowing clients to customize the order of returned data.
|
|
1062
|
+
after (string): Optional string parameter to filter emails by retrieving only those sent after the specified date or time.
|
|
1063
|
+
limit (integer): Specifies the maximum number of email records to return in the response.
|
|
1064
|
+
includeStats (boolean): Indicates whether to include email statistics in the response; defaults to false if not specified.
|
|
1065
|
+
type (string): Optional query parameter to filter emails by type, with possible values including various email categories such as AB_EMAIL, BATCH_EMAIL, and others.
|
|
1066
|
+
isPublished (boolean): Indicates whether to include only published emails in the response; accepts boolean values (true or false).
|
|
1067
|
+
includedProperties (array): Optional array parameter to specify additional properties to include in the response for the GET operation at "/marketing/v3/emails/".
|
|
1068
|
+
archived (boolean): Filter emails by their archived status; set to true to return only archived emails, or false to exclude archived emails.
|
|
1069
|
+
|
|
1070
|
+
Returns:
|
|
1071
|
+
dict[str, Any]: successful operation
|
|
1072
|
+
|
|
1073
|
+
Raises:
|
|
1074
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
1075
|
+
|
|
1076
|
+
Tags:
|
|
1077
|
+
Marketing Emails
|
|
1078
|
+
"""
|
|
1079
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/"
|
|
1080
|
+
query_params = {
|
|
1081
|
+
k: v
|
|
1082
|
+
for k, v in [
|
|
1083
|
+
("createdAt", createdAt),
|
|
1084
|
+
("createdAfter", createdAfter),
|
|
1085
|
+
("createdBefore", createdBefore),
|
|
1086
|
+
("updatedAt", updatedAt),
|
|
1087
|
+
("updatedAfter", updatedAfter),
|
|
1088
|
+
("updatedBefore", updatedBefore),
|
|
1089
|
+
("sort", sort),
|
|
1090
|
+
("after", after),
|
|
1091
|
+
("limit", limit),
|
|
1092
|
+
("includeStats", includeStats),
|
|
1093
|
+
("type", type),
|
|
1094
|
+
("isPublished", isPublished),
|
|
1095
|
+
("includedProperties", includedProperties),
|
|
1096
|
+
("archived", archived),
|
|
1097
|
+
]
|
|
1098
|
+
if v is not None
|
|
1099
|
+
}
|
|
1100
|
+
response = self._get(url, params=query_params)
|
|
1101
|
+
return self._handle_response(response)
|
|
1102
|
+
|
|
1103
|
+
def create_email_marketing_campaign(
|
|
1104
|
+
self,
|
|
1105
|
+
name: str,
|
|
1106
|
+
feedbackSurveyId: Optional[str] = None,
|
|
1107
|
+
rssData: Optional[dict[str, Any]] = None,
|
|
1108
|
+
subject: Optional[str] = None,
|
|
1109
|
+
testing: Optional[dict[str, Any]] = None,
|
|
1110
|
+
publishDate: Optional[str] = None,
|
|
1111
|
+
language: Optional[str] = None,
|
|
1112
|
+
businessUnitId: Optional[str] = None,
|
|
1113
|
+
content: Optional[dict[str, Any]] = None,
|
|
1114
|
+
webversion: Optional[dict[str, Any]] = None,
|
|
1115
|
+
archived: Optional[bool] = None,
|
|
1116
|
+
subscriptionDetails: Optional[dict[str, Any]] = None,
|
|
1117
|
+
activeDomain: Optional[str] = None,
|
|
1118
|
+
campaign: Optional[str] = None,
|
|
1119
|
+
from_: Optional[dict[str, Any]] = None,
|
|
1120
|
+
state: Optional[str] = None,
|
|
1121
|
+
to: Optional[dict[str, Any]] = None,
|
|
1122
|
+
subcategory: Optional[str] = None,
|
|
1123
|
+
sendOnPublish: Optional[bool] = None,
|
|
1124
|
+
) -> dict[str, Any]:
|
|
1125
|
+
"""
|
|
1126
|
+
|
|
1127
|
+
Creates a new email resource in the marketing system using the provided JSON data and returns a success response upon creation.
|
|
1128
|
+
|
|
1129
|
+
Args:
|
|
1130
|
+
name (string): The name of the email, as displayed on the email dashboard. Example: 'My subject'.
|
|
1131
|
+
feedbackSurveyId (string): The ID of the feedback survey linked to the email.
|
|
1132
|
+
rssData (object): RSS related data if it is a blog or rss email.
|
|
1133
|
+
subject (string): The subject of the email. Example: 'My subject'.
|
|
1134
|
+
testing (object): AB testing related data. This property is only returned for AB type emails.
|
|
1135
|
+
publishDate (string): The date and time the email is scheduled for, in ISO8601 representation. This is only used in local time or scheduled emails. Example: '2023-11-30T18:44:20.387Z'.
|
|
1136
|
+
language (string): language
|
|
1137
|
+
businessUnitId (string): businessUnitId
|
|
1138
|
+
content (object): Data structure representing the content of the email. Example: {'flexAreas': {'main': {'boxed': False, 'isSingleColumnFullWidth': False, 'sections': [{'columns': [{'id': 'column_1606761806181_0', 'widgets': ['module_160676180617911'], 'width': 12}], 'id': 'section_1606761806181', 'style': {'backgroundColor': '', 'backgroundType': 'CONTENT'}}, {'columns': [{'id': 'column-0-1', 'widgets': ['module-0-1-1'], 'width': 12}], 'id': 'section-0', 'style': {'backgroundType': 'CONTENT', 'paddingBottom': '40px', 'paddingTop': '40px'}}, {'columns': [{'id': 'column-1-1', 'widgets': ['module-1-1-1'], 'width': 12}], 'id': 'section-1', 'style': {'backgroundColor': '', 'backgroundType': 'CONTENT', 'paddingBottom': '0px', 'paddingTop': '0px'}}]}}, 'plainTextVersion': 'This is custom! View in browser ({{view_as_page_url}})
|
|
1139
|
+
|
|
1140
|
+
Hello {{ contact.firstname }},
|
|
1141
|
+
|
|
1142
|
+
Plain text emails have minimal formatting so your reader can really focus on what you have to say. Introduce yourself and explain why you’re reaching out.
|
|
1143
|
+
|
|
1144
|
+
Every email should try to lead the reader to some kind of action. Use this space to describe why the reader should want to click on the link below. Put the link on its own line to really draw their eye to it.
|
|
1145
|
+
|
|
1146
|
+
Link text
|
|
1147
|
+
|
|
1148
|
+
Now it’s time to wrap up your email. Before your signature, thank the recipient for reading. You can also invite them to send this email to any of their colleagues who might be interested.
|
|
1149
|
+
|
|
1150
|
+
All the best,
|
|
1151
|
+
|
|
1152
|
+
Your full name
|
|
1153
|
+
|
|
1154
|
+
Your job title
|
|
1155
|
+
|
|
1156
|
+
Other contact information
|
|
1157
|
+
|
|
1158
|
+
{{site_settings.company_name}}, {{site_settings.company_street_address_1}}, {{site_settings.company_street_address_2}}, {{site_settings.company_city}}, {{site_settings.company_state}} {{site_settings.company_zip}}, {{site_settings.company_country}}, {{site_settings.company_phone}}
|
|
1159
|
+
|
|
1160
|
+
Unsubscribe ({{unsubscribe_link_all}})
|
|
1161
|
+
|
|
1162
|
+
Manage preferences ({{unsubscribe_link}})', 'styleSettings': {}, 'widgets': {'module-0-1-1': {'body': {'css_class': 'dnd-module', 'html': '<p style="margin-bottom:10px;">Hello {{ contact.firstname }},<br><br>Plain text emails have minimal formatting so your reader can really focus on what you have to say. Introduce yourself and explain why you’re reaching out.</p><p style="margin-bottom:10px;">Every email should try to lead the reader to some kind of action. Use this space to describe why the reader should want to click on the link below. Put the link on its own line to really draw their eye to it.</p><p style="margin-bottom:10px;"><a target="_blank" rel="noopener">Link text</a></p><p style="margin-bottom:10px;">Now it’s time to wrap up your email. Before your signature, thank the recipient for reading. You can also invite them to send this email to any of their colleagues who might be interested.</p><p style="margin-bottom:10px;">All the best,<br>Your full name<br>Your job title<br>Other contact information</p>', 'i18nKey': 'richText.plainText', 'path': '@hubspot/rich_text', 'schema_version': 2}, 'child_css': {}, 'css': {}, 'id': 'module-0-1-1', 'module_id': 1155639, 'name': 'module-0-1-1', 'order': 2, 'styles': {}, 'type': 'module'}, 'module-1-1-1': {'body': {'align': 'center', 'css_class': 'dnd-module', 'font': {'color': '#23496d', 'font': 'Arial, sans-serif', 'size': {'units': 'px', 'value': 12}}, 'link_font': {'color': '#00a4bd', 'font': 'Helvetica,Arial,sans-serif', 'size': {'units': 'px', 'value': 12}, 'styles': {'bold': False, 'italic': False, 'underline': True}}, 'path': '@hubspot/email_footer', 'schema_version': 2, 'unsubscribe_link_type': 'both'}, 'child_css': {}, 'css': {}, 'id': 'module-1-1-1', 'module_id': 2869621, 'name': 'module-1-1-1', 'order': 3, 'styles': {}, 'type': 'module'}, 'module_160676180617911': {'body': {'font': {'color': '#00a4bd', 'font': 'Arial, sans-serif', 'size': {'units': 'px', 'value': 12}, 'styles': {'bold': False, 'italic': False, 'underline': True}}, 'hs_enable_module_padding': False, 'hs_wrapper_css': {}}, 'child_css': {}, 'css': {}, 'id': 'module_160676180617911', 'module_id': 2794854, 'name': 'module_160676180617911', 'styles': {}, 'type': 'module'}, 'preview_text': {'body': {'value': ''}, 'child_css': {}, 'css': {}, 'id': 'preview_text', 'label': 'Preview Text <span class=help-text>This will be used as the preview text that displays in some email clients</span>', 'name': 'preview_text', 'order': 0, 'styles': {}, 'type': 'text'}}}.
|
|
1163
|
+
webversion (object): webversion Example: {'expiresAt': '2020-11-30T18:44:20.387Z', 'metaDescription': '', 'redirectToPageId': 0, 'redirectToUrl': 'http://www.example.org'}.
|
|
1164
|
+
archived (boolean): Determines if the email is archived or not. Example: False.
|
|
1165
|
+
subscriptionDetails (object): Data structure representing the subscription fields of the email. Example: {'officeLocationId': '5449392956'}.
|
|
1166
|
+
activeDomain (string): The active domain of the email. Example: 'test.hs-sites.com'.
|
|
1167
|
+
campaign (string): The ID of the campaign this email is associated to. Example: '1b7f51a6-33c1-44d6-ba28-fe81f655dced'.
|
|
1168
|
+
from_ (object): Data structure representing the from fields on the email. Example: {'fromName': 'Bruce Wayne', 'replyTo': 'test@hubspot.com'}.
|
|
1169
|
+
state (string): The email state. Example: 'DRAFT'.
|
|
1170
|
+
to (object): Data structure representing the to fields of the email. Example: {'contactIds': {}, 'contactLists': {'exclude': [1], 'include': [5]}, 'suppressGraymail': True}.
|
|
1171
|
+
subcategory (string): The email subcategory. Example: 'batch'.
|
|
1172
|
+
sendOnPublish (boolean): Determines whether the email will be sent immediately on publish. Example: True.
|
|
1173
|
+
|
|
1174
|
+
Returns:
|
|
1175
|
+
dict[str, Any]: successful operation
|
|
1176
|
+
|
|
1177
|
+
Raises:
|
|
1178
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
1179
|
+
|
|
1180
|
+
Tags:
|
|
1181
|
+
Marketing Emails
|
|
1182
|
+
"""
|
|
1183
|
+
request_body_data = None
|
|
1184
|
+
request_body_data = {
|
|
1185
|
+
"feedbackSurveyId": feedbackSurveyId,
|
|
1186
|
+
"rssData": rssData,
|
|
1187
|
+
"subject": subject,
|
|
1188
|
+
"testing": testing,
|
|
1189
|
+
"publishDate": publishDate,
|
|
1190
|
+
"language": language,
|
|
1191
|
+
"businessUnitId": businessUnitId,
|
|
1192
|
+
"content": content,
|
|
1193
|
+
"webversion": webversion,
|
|
1194
|
+
"archived": archived,
|
|
1195
|
+
"subscriptionDetails": subscriptionDetails,
|
|
1196
|
+
"activeDomain": activeDomain,
|
|
1197
|
+
"name": name,
|
|
1198
|
+
"campaign": campaign,
|
|
1199
|
+
"from": from_,
|
|
1200
|
+
"state": state,
|
|
1201
|
+
"to": to,
|
|
1202
|
+
"subcategory": subcategory,
|
|
1203
|
+
"sendOnPublish": sendOnPublish,
|
|
1204
|
+
}
|
|
1205
|
+
request_body_data = {
|
|
1206
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
1207
|
+
}
|
|
1208
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/"
|
|
1209
|
+
query_params = {}
|
|
1210
|
+
response = self._post(
|
|
1211
|
+
url,
|
|
1212
|
+
data=request_body_data,
|
|
1213
|
+
params=query_params,
|
|
1214
|
+
content_type="application/json",
|
|
1215
|
+
)
|
|
1216
|
+
return self._handle_response(response)
|
|
1217
|
+
|
|
1218
|
+
def restore_email_revision(self, emailId: str, revisionId: str) -> Any:
|
|
1219
|
+
"""
|
|
1220
|
+
|
|
1221
|
+
Restores a specific email revision using the provided email ID and revision ID via the POST method.
|
|
1222
|
+
|
|
1223
|
+
Args:
|
|
1224
|
+
emailId (string): emailId
|
|
1225
|
+
revisionId (string): revisionId
|
|
1226
|
+
|
|
1227
|
+
Returns:
|
|
1228
|
+
Any: No content
|
|
1229
|
+
|
|
1230
|
+
Raises:
|
|
1231
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
1232
|
+
|
|
1233
|
+
Tags:
|
|
1234
|
+
Marketing Emails
|
|
1235
|
+
"""
|
|
1236
|
+
if emailId is None:
|
|
1237
|
+
raise ValueError("Missing required parameter 'emailId'.")
|
|
1238
|
+
if revisionId is None:
|
|
1239
|
+
raise ValueError("Missing required parameter 'revisionId'.")
|
|
1240
|
+
request_body_data = None
|
|
1241
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/{emailId}/revisions/{revisionId}/restore"
|
|
1242
|
+
query_params = {}
|
|
1243
|
+
response = self._post(
|
|
1244
|
+
url,
|
|
1245
|
+
data=request_body_data,
|
|
1246
|
+
params=query_params,
|
|
1247
|
+
content_type="application/json",
|
|
1248
|
+
)
|
|
1249
|
+
return self._handle_response(response)
|
|
1250
|
+
|
|
1251
|
+
def get_email_by_id_marketing(
|
|
1252
|
+
self,
|
|
1253
|
+
emailId: str,
|
|
1254
|
+
includeStats: Optional[bool] = None,
|
|
1255
|
+
includedProperties: Optional[List[str]] = None,
|
|
1256
|
+
archived: Optional[bool] = None,
|
|
1257
|
+
) -> dict[str, Any]:
|
|
1258
|
+
"""
|
|
1259
|
+
|
|
1260
|
+
Retrieves detailed information about a specific email by its ID, optionally including statistics, selected properties, and archived status.
|
|
1261
|
+
|
|
1262
|
+
Args:
|
|
1263
|
+
emailId (string): emailId
|
|
1264
|
+
includeStats (boolean): Optionally includes email statistics in the response when set to true.
|
|
1265
|
+
includedProperties (array): An optional array parameter to specify which email properties should be included in the response, allowing customization of the returned data.
|
|
1266
|
+
archived (boolean): Optional boolean parameter to indicate whether to include archived emails in the response.
|
|
1267
|
+
|
|
1268
|
+
Returns:
|
|
1269
|
+
dict[str, Any]: successful operation
|
|
1270
|
+
|
|
1271
|
+
Raises:
|
|
1272
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
1273
|
+
|
|
1274
|
+
Tags:
|
|
1275
|
+
Marketing Emails
|
|
1276
|
+
"""
|
|
1277
|
+
if emailId is None:
|
|
1278
|
+
raise ValueError("Missing required parameter 'emailId'.")
|
|
1279
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/{emailId}"
|
|
1280
|
+
query_params = {
|
|
1281
|
+
k: v
|
|
1282
|
+
for k, v in [
|
|
1283
|
+
("includeStats", includeStats),
|
|
1284
|
+
("includedProperties", includedProperties),
|
|
1285
|
+
("archived", archived),
|
|
1286
|
+
]
|
|
1287
|
+
if v is not None
|
|
1288
|
+
}
|
|
1289
|
+
response = self._get(url, params=query_params)
|
|
1290
|
+
return self._handle_response(response)
|
|
1291
|
+
|
|
1292
|
+
def delete_email_by_id_marketing(
|
|
1293
|
+
self, emailId: str, archived: Optional[bool] = None
|
|
1294
|
+
) -> Any:
|
|
1295
|
+
"""
|
|
1296
|
+
|
|
1297
|
+
Deletes the specified marketing email by its emailId, optionally archiving it, and returns a 204 No Content status on success.
|
|
1298
|
+
|
|
1299
|
+
Args:
|
|
1300
|
+
emailId (string): emailId
|
|
1301
|
+
archived (boolean): Optional boolean parameter to indicate whether archived emails should be considered during the deletion operation.
|
|
1302
|
+
|
|
1303
|
+
Returns:
|
|
1304
|
+
Any: No content
|
|
1305
|
+
|
|
1306
|
+
Raises:
|
|
1307
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
1308
|
+
|
|
1309
|
+
Tags:
|
|
1310
|
+
Marketing Emails
|
|
1311
|
+
"""
|
|
1312
|
+
if emailId is None:
|
|
1313
|
+
raise ValueError("Missing required parameter 'emailId'.")
|
|
1314
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/{emailId}"
|
|
1315
|
+
query_params = {k: v for k, v in [("archived", archived)] if v is not None}
|
|
1316
|
+
response = self._delete(url, params=query_params)
|
|
1317
|
+
return self._handle_response(response)
|
|
1318
|
+
|
|
1319
|
+
def patch_email_by_id(
|
|
1320
|
+
self,
|
|
1321
|
+
emailId: str,
|
|
1322
|
+
archived: Optional[bool] = None,
|
|
1323
|
+
rssData: Optional[dict[str, Any]] = None,
|
|
1324
|
+
subject: Optional[str] = None,
|
|
1325
|
+
testing: Optional[dict[str, Any]] = None,
|
|
1326
|
+
publishDate: Optional[str] = None,
|
|
1327
|
+
language: Optional[str] = None,
|
|
1328
|
+
businessUnitId: Optional[str] = None,
|
|
1329
|
+
content: Optional[dict[str, Any]] = None,
|
|
1330
|
+
webversion: Optional[dict[str, Any]] = None,
|
|
1331
|
+
archived_body: Optional[bool] = None,
|
|
1332
|
+
subscriptionDetails: Optional[dict[str, Any]] = None,
|
|
1333
|
+
activeDomain: Optional[str] = None,
|
|
1334
|
+
name: Optional[str] = None,
|
|
1335
|
+
campaign: Optional[str] = None,
|
|
1336
|
+
from_: Optional[dict[str, Any]] = None,
|
|
1337
|
+
state: Optional[str] = None,
|
|
1338
|
+
to: Optional[dict[str, Any]] = None,
|
|
1339
|
+
subcategory: Optional[str] = None,
|
|
1340
|
+
sendOnPublish: Optional[bool] = None,
|
|
1341
|
+
) -> dict[str, Any]:
|
|
1342
|
+
"""
|
|
1343
|
+
|
|
1344
|
+
Updates an email resource identified by `{emailId}` with partial modifications using JSON in the request body and optionally sets its archived status.
|
|
1345
|
+
|
|
1346
|
+
Args:
|
|
1347
|
+
emailId (string): emailId
|
|
1348
|
+
archived (boolean): Indicates whether the email should be marked as archived, with true meaning archived and false meaning not archived, during the PATCH operation.
|
|
1349
|
+
rssData (object): RSS related data if it is a blog or rss email.
|
|
1350
|
+
subject (string): The subject of the email. Example: 'My subject'.
|
|
1351
|
+
testing (object): AB testing related data. This property is only returned for AB type emails.
|
|
1352
|
+
publishDate (string): The date and time the email is scheduled for, in ISO8601 representation. This is only used in local time or scheduled emails. Example: '2023-11-30T18:44:20.387Z'.
|
|
1353
|
+
language (string): language
|
|
1354
|
+
businessUnitId (string): businessUnitId
|
|
1355
|
+
content (object): Data structure representing the content of the email. Example: {'flexAreas': {'main': {'boxed': False, 'isSingleColumnFullWidth': False, 'sections': [{'columns': [{'id': 'column_1606761806181_0', 'widgets': ['module_160676180617911'], 'width': 12}], 'id': 'section_1606761806181', 'style': {'backgroundColor': '', 'backgroundType': 'CONTENT'}}, {'columns': [{'id': 'column-0-1', 'widgets': ['module-0-1-1'], 'width': 12}], 'id': 'section-0', 'style': {'backgroundType': 'CONTENT', 'paddingBottom': '40px', 'paddingTop': '40px'}}, {'columns': [{'id': 'column-1-1', 'widgets': ['module-1-1-1'], 'width': 12}], 'id': 'section-1', 'style': {'backgroundColor': '', 'backgroundType': 'CONTENT', 'paddingBottom': '0px', 'paddingTop': '0px'}}]}}, 'plainTextVersion': 'This is custom! View in browser ({{view_as_page_url}})
|
|
1356
|
+
|
|
1357
|
+
Hello {{ contact.firstname }},
|
|
1358
|
+
|
|
1359
|
+
Plain text emails have minimal formatting so your reader can really focus on what you have to say. Introduce yourself and explain why you’re reaching out.
|
|
1360
|
+
|
|
1361
|
+
Every email should try to lead the reader to some kind of action. Use this space to describe why the reader should want to click on the link below. Put the link on its own line to really draw their eye to it.
|
|
1362
|
+
|
|
1363
|
+
Link text
|
|
1364
|
+
|
|
1365
|
+
Now it’s time to wrap up your email. Before your signature, thank the recipient for reading. You can also invite them to send this email to any of their colleagues who might be interested.
|
|
1366
|
+
|
|
1367
|
+
All the best,
|
|
1368
|
+
|
|
1369
|
+
Your full name
|
|
1370
|
+
|
|
1371
|
+
Your job title
|
|
1372
|
+
|
|
1373
|
+
Other contact information
|
|
1374
|
+
|
|
1375
|
+
{{site_settings.company_name}}, {{site_settings.company_street_address_1}}, {{site_settings.company_street_address_2}}, {{site_settings.company_city}}, {{site_settings.company_state}} {{site_settings.company_zip}}, {{site_settings.company_country}}, {{site_settings.company_phone}}
|
|
1376
|
+
|
|
1377
|
+
Unsubscribe ({{unsubscribe_link_all}})
|
|
1378
|
+
|
|
1379
|
+
Manage preferences ({{unsubscribe_link}})', 'styleSettings': {}, 'widgets': {'module-0-1-1': {'body': {'css_class': 'dnd-module', 'html': '<p style="margin-bottom:10px;">Hello {{ contact.firstname }},<br><br>Plain text emails have minimal formatting so your reader can really focus on what you have to say. Introduce yourself and explain why you’re reaching out.</p><p style="margin-bottom:10px;">Every email should try to lead the reader to some kind of action. Use this space to describe why the reader should want to click on the link below. Put the link on its own line to really draw their eye to it.</p><p style="margin-bottom:10px;"><a target="_blank" rel="noopener">Link text</a></p><p style="margin-bottom:10px;">Now it’s time to wrap up your email. Before your signature, thank the recipient for reading. You can also invite them to send this email to any of their colleagues who might be interested.</p><p style="margin-bottom:10px;">All the best,<br>Your full name<br>Your job title<br>Other contact information</p>', 'i18nKey': 'richText.plainText', 'path': '@hubspot/rich_text', 'schema_version': 2}, 'child_css': {}, 'css': {}, 'id': 'module-0-1-1', 'module_id': 1155639, 'name': 'module-0-1-1', 'order': 2, 'styles': {}, 'type': 'module'}, 'module-1-1-1': {'body': {'align': 'center', 'css_class': 'dnd-module', 'font': {'color': '#23496d', 'font': 'Arial, sans-serif', 'size': {'units': 'px', 'value': 12}}, 'link_font': {'color': '#00a4bd', 'font': 'Helvetica,Arial,sans-serif', 'size': {'units': 'px', 'value': 12}, 'styles': {'bold': False, 'italic': False, 'underline': True}}, 'path': '@hubspot/email_footer', 'schema_version': 2, 'unsubscribe_link_type': 'both'}, 'child_css': {}, 'css': {}, 'id': 'module-1-1-1', 'module_id': 2869621, 'name': 'module-1-1-1', 'order': 3, 'styles': {}, 'type': 'module'}, 'module_160676180617911': {'body': {'font': {'color': '#00a4bd', 'font': 'Arial, sans-serif', 'size': {'units': 'px', 'value': 12}, 'styles': {'bold': False, 'italic': False, 'underline': True}}, 'hs_enable_module_padding': False, 'hs_wrapper_css': {}}, 'child_css': {}, 'css': {}, 'id': 'module_160676180617911', 'module_id': 2794854, 'name': 'module_160676180617911', 'styles': {}, 'type': 'module'}, 'preview_text': {'body': {'value': ''}, 'child_css': {}, 'css': {}, 'id': 'preview_text', 'label': 'Preview Text <span class=help-text>This will be used as the preview text that displays in some email clients</span>', 'name': 'preview_text', 'order': 0, 'styles': {}, 'type': 'text'}}}.
|
|
1380
|
+
webversion (object): webversion Example: {'expiresAt': '2020-11-30T18:44:20.387Z', 'metaDescription': '', 'redirectToPageId': 0, 'redirectToUrl': 'http://www.example.org'}.
|
|
1381
|
+
archived_body (boolean): Determines if the email is archived or not. Example: False.
|
|
1382
|
+
subscriptionDetails (object): Data structure representing the subscription fields of the email. Example: {'officeLocationId': '5449392956'}.
|
|
1383
|
+
activeDomain (string): The active domain of the email. Example: 'test.hs-sites.com'.
|
|
1384
|
+
name (string): The name of the email, as displayed on the email dashboard. Example: 'My subject'.
|
|
1385
|
+
campaign (string): The ID of the campaign this email is associated to. Example: '1b7f51a6-33c1-44d6-ba28-fe81f655dced'.
|
|
1386
|
+
from_ (object): Data structure representing the from fields on the email. Example: {'fromName': 'Bruce Wayne', 'replyTo': 'test@hubspot.com'}.
|
|
1387
|
+
state (string): The email state. Example: 'DRAFT'.
|
|
1388
|
+
to (object): Data structure representing the to fields of the email. Example: {'contactIds': {}, 'contactLists': {'exclude': [1], 'include': [5]}, 'suppressGraymail': True}.
|
|
1389
|
+
subcategory (string): The email subcategory. Example: 'batch'.
|
|
1390
|
+
sendOnPublish (boolean): Determines whether the email will be sent immediately on publish. Example: True.
|
|
1391
|
+
|
|
1392
|
+
Returns:
|
|
1393
|
+
dict[str, Any]: successful operation
|
|
1394
|
+
|
|
1395
|
+
Raises:
|
|
1396
|
+
HTTPStatusError: Raised when the API request fails with detailed error information including status code and response body.
|
|
1397
|
+
|
|
1398
|
+
Tags:
|
|
1399
|
+
Marketing Emails
|
|
1400
|
+
"""
|
|
1401
|
+
if emailId is None:
|
|
1402
|
+
raise ValueError("Missing required parameter 'emailId'.")
|
|
1403
|
+
request_body_data = None
|
|
1404
|
+
request_body_data = {
|
|
1405
|
+
"rssData": rssData,
|
|
1406
|
+
"subject": subject,
|
|
1407
|
+
"testing": testing,
|
|
1408
|
+
"publishDate": publishDate,
|
|
1409
|
+
"language": language,
|
|
1410
|
+
"businessUnitId": businessUnitId,
|
|
1411
|
+
"content": content,
|
|
1412
|
+
"webversion": webversion,
|
|
1413
|
+
"archived": archived_body,
|
|
1414
|
+
"subscriptionDetails": subscriptionDetails,
|
|
1415
|
+
"activeDomain": activeDomain,
|
|
1416
|
+
"name": name,
|
|
1417
|
+
"campaign": campaign,
|
|
1418
|
+
"from": from_,
|
|
1419
|
+
"state": state,
|
|
1420
|
+
"to": to,
|
|
1421
|
+
"subcategory": subcategory,
|
|
1422
|
+
"sendOnPublish": sendOnPublish,
|
|
1423
|
+
}
|
|
1424
|
+
request_body_data = {
|
|
1425
|
+
k: v for k, v in request_body_data.items() if v is not None
|
|
1426
|
+
}
|
|
1427
|
+
url = f"{self.main_app_client.base_url}/marketing/v3/emails/{emailId}"
|
|
1428
|
+
query_params = {k: v for k, v in [("archived", archived)] if v is not None}
|
|
1429
|
+
response = self._patch(url, data=request_body_data, params=query_params)
|
|
1430
|
+
return self._handle_response(response)
|
|
1431
|
+
|
|
1432
|
+
def list_tools(self):
|
|
1433
|
+
return [
|
|
1434
|
+
self.get_marketing_campaigns,
|
|
1435
|
+
self.create_marketing_campaigns,
|
|
1436
|
+
self.batch_read_campaigns_post,
|
|
1437
|
+
self.update_campaigns_batch,
|
|
1438
|
+
self.get_campaign_metrics,
|
|
1439
|
+
self.get_campaign_asset_by_type,
|
|
1440
|
+
self.archive_campaigns_batch,
|
|
1441
|
+
self.update_campaign_asset,
|
|
1442
|
+
self.delete_campaign_asset_by_id,
|
|
1443
|
+
self.get_campaign_revenue_report,
|
|
1444
|
+
self.create_campaigns_batch,
|
|
1445
|
+
self.get_campaign_budget_totals,
|
|
1446
|
+
self.get_campaign_by_guid,
|
|
1447
|
+
self.delete_campaign_by_guid,
|
|
1448
|
+
self.patch_campaign_by_guid,
|
|
1449
|
+
self.get_campaign_contacts_report_by_type,
|
|
1450
|
+
self.list_email_statistics,
|
|
1451
|
+
self.create_ab_test_email_variation,
|
|
1452
|
+
self.get_email_statistics_histogram,
|
|
1453
|
+
self.get_email_ab_test_variation,
|
|
1454
|
+
self.reset_email_draft_by_id,
|
|
1455
|
+
self.restore_email_revision_to_draft,
|
|
1456
|
+
self.get_email_draft_by_id,
|
|
1457
|
+
self.update_email_draft_by_id,
|
|
1458
|
+
self.get_email_revisions,
|
|
1459
|
+
self.get_email_revision_by_id,
|
|
1460
|
+
self.clone_email,
|
|
1461
|
+
self.list_marketing_emails,
|
|
1462
|
+
self.create_email_marketing_campaign,
|
|
1463
|
+
self.restore_email_revision,
|
|
1464
|
+
self.get_email_by_id_marketing,
|
|
1465
|
+
self.delete_email_by_id_marketing,
|
|
1466
|
+
self.patch_email_by_id,
|
|
1467
|
+
]
|