Skip to content

Commit 3f98ada

Browse files
author
Eglė Šatūnaitė
authored
feat: expose reach endpoints for campaigns, automations, forms, limits (#80)
1 parent cc169a0 commit 3f98ada

4 files changed

Lines changed: 244 additions & 9 deletions

File tree

‎README.md‎

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ The Hostinger API node supports the following operations:
6262
- Create contacts in bulk, optionally tagging them on the way in
6363
- Filter contacts by subscription status, tag or search term
6464
- Manage custom contact fields and their choices
65+
- Check the remaining plan limits for the current period
66+
- Check the MX, SPF, DKIM and DMARC status of the profile domain
6567

6668
- **Email Marketing (Reach): Tags**
6769
- List, create, rename and delete tags
@@ -73,6 +75,21 @@ The Hostinger API node supports the following operations:
7375
- List the contacts a segment matches
7476
- Count the contacts a segment matches
7577

78+
- **Email Marketing (Reach): Automations**
79+
- List automations, filtered by status and ordered by creation date
80+
- Get a single automation with its contact journey counts
81+
- List the steps an automation runs
82+
83+
- **Email Marketing (Reach): Campaigns**
84+
- List campaigns, filtered by status and type
85+
- Get a single campaign with its setup and delivery progress
86+
- Get campaign performance: opens, clicks and unsubscribes
87+
88+
- **Email Marketing (Reach): Forms**
89+
- List signup forms
90+
- Get a single form with its template URL and the tags it applies
91+
- Delete a form
92+
7693
## Credentials
7794

7895
To use this node, you will need to authenticate with the Hostinger API.
@@ -108,6 +125,16 @@ Helpful link for beginners: [Try it out](https://docs.n8n.io/try-it-out/)
108125

109126
## Version history
110127

128+
- **v1.0.24**:
129+
- Added the Reach public API endpoints exposed since the previous release
130+
- Added `Reach Automations` resource: List Automations, Get Automation, List Automation Steps
131+
- Added `Reach Campaigns` resource: List Campaigns, Get Campaign, Get Campaign Statistics
132+
- Added `Reach Forms` resource: List Forms, Get Form, Delete Form
133+
- Added `Reach` operations: Get Profile Limits and Get Profile DNS Status
134+
135+
- **v1.0.23**:
136+
- Updated dependencies
137+
111138
- **v1.0.22**:
112139
- Added profile-scoped actions for Email Marketing (Reach), covering the endpoints the public API now exposes
113140
- Added `Reach` operations: List Profiles, List Profile Contacts, Get Profile Contact, Create Profile Contact, Create Contacts in Bulk, Update Profile Contact, Delete Profile Contact

‎nodes/hostingerApi/HostingerApi.node.ts‎

Lines changed: 214 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,10 @@ const resourceOptions: INodePropertyOptions[] = [
2020
{ name: 'Domain Forwarding', value: 'domainForwarding' },
2121
{ name: 'Domain WHOIS', value: 'whois' },
2222
{ name: 'Reach', value: 'reach' },
23+
{ name: 'Reach Automations', value: 'reachAutomations' },
24+
{ name: 'Reach Campaigns', value: 'reachCampaigns' },
2325
{ name: 'Reach Contact Fields', value: 'reachContactFields' },
26+
{ name: 'Reach Forms', value: 'reachForms' },
2427
{ name: 'Reach Segments', value: 'reachSegments' },
2528
{ name: 'Reach Tags', value: 'reachTags' },
2629
{ name: 'VPS', value: 'vps' },
@@ -411,6 +414,8 @@ export class HostingerApi implements INodeType {
411414
{ name: 'Delete Contact', value: 'deleteContact', action: 'Delete reach contact', description: 'Deprecated: use Delete Profile Contact to target an explicit profile' },
412415
{ name: 'Delete Profile Contact', value: 'deleteProfileContact', action: 'Delete reach profile contact' },
413416
{ name: 'Get Profile Contact', value: 'getProfileContact', action: 'Get reach profile contact' },
417+
{ name: 'Get Profile DNS Status', value: 'getProfileDnsStatus', action: 'Get reach profile domain DNS status' },
418+
{ name: 'Get Profile Limits', value: 'getProfileLimits', action: 'Get reach profile plan limits' },
414419
{ name: 'Get Segment', value: 'getSegment', action: 'Get reach segment', description: 'Deprecated: use Reach Segments to target an explicit profile' },
415420
{ name: 'Get Segment Contacts', value: 'getSegmentContacts', action: 'Get reach segment contacts', description: 'Deprecated: use Reach Segments to target an explicit profile' },
416421
{ name: 'List Contacts', value: 'listContacts', action: 'List reach contacts', description: 'Deprecated: use List Profile Contacts to target an explicit profile' },
@@ -487,6 +492,57 @@ export class HostingerApi implements INodeType {
487492
},
488493
},
489494
},
495+
{
496+
displayName: 'Operation',
497+
name: 'operation',
498+
type: 'options',
499+
noDataExpression: true,
500+
options: [
501+
{ name: 'Get Automation', value: 'getAutomation', action: 'Get reach automation' },
502+
{ name: 'List Automation Steps', value: 'listAutomationSteps', action: 'List reach automation steps' },
503+
{ name: 'List Automations', value: 'listAutomations', action: 'List reach automations' },
504+
],
505+
default: 'listAutomations',
506+
displayOptions: {
507+
show: {
508+
resource: ['reachAutomations']
509+
},
510+
},
511+
},
512+
{
513+
displayName: 'Operation',
514+
name: 'operation',
515+
type: 'options',
516+
noDataExpression: true,
517+
options: [
518+
{ name: 'Get Campaign', value: 'getCampaign', action: 'Get reach campaign' },
519+
{ name: 'Get Campaign Statistics', value: 'getCampaignStatistics', action: 'Get reach campaign statistics' },
520+
{ name: 'List Campaigns', value: 'listCampaigns', action: 'List reach campaigns' },
521+
],
522+
default: 'listCampaigns',
523+
displayOptions: {
524+
show: {
525+
resource: ['reachCampaigns']
526+
},
527+
},
528+
},
529+
{
530+
displayName: 'Operation',
531+
name: 'operation',
532+
type: 'options',
533+
noDataExpression: true,
534+
options: [
535+
{ name: 'Delete Form', value: 'deleteForm', action: 'Delete reach form' },
536+
{ name: 'Get Form', value: 'getForm', action: 'Get reach form' },
537+
{ name: 'List Forms', value: 'listForms', action: 'List reach forms' },
538+
],
539+
default: 'listForms',
540+
displayOptions: {
541+
show: {
542+
resource: ['reachForms']
543+
},
544+
},
545+
},
490546
{
491547
displayName: 'Virtual Machine ID',
492548
name: 'virtualMachineId',
@@ -1251,9 +1307,9 @@ export class HostingerApi implements INodeType {
12511307
required: true,
12521308
displayOptions: {
12531309
show: {
1254-
resource: ['reach', 'reachSegments'],
1310+
resource: ['reach', 'reachAutomations', 'reachCampaigns', 'reachForms', 'reachSegments'],
12551311
operation: [
1256-
'listContacts', 'listProfileContacts', 'listProfileSegments', 'listProfileSegmentContacts'
1312+
'listContacts', 'listProfileContacts', 'listProfileSegments', 'listProfileSegmentContacts', 'listAutomations', 'listCampaigns', 'listForms'
12571313
]
12581314
}
12591315
}
@@ -1266,8 +1322,8 @@ export class HostingerApi implements INodeType {
12661322
description: 'Number of results to return per page',
12671323
displayOptions: {
12681324
show: {
1269-
resource: ['reach', 'reachSegments'],
1270-
operation: ['listProfileContacts', 'listProfileSegments', 'listProfileSegmentContacts']
1325+
resource: ['reach', 'reachAutomations', 'reachCampaigns', 'reachForms', 'reachSegments'],
1326+
operation: ['listProfileContacts', 'listProfileSegments', 'listProfileSegmentContacts', 'listAutomations', 'listCampaigns', 'listForms']
12711327
}
12721328
}
12731329
},
@@ -1296,9 +1352,9 @@ export class HostingerApi implements INodeType {
12961352
description: 'UUID of the Reach profile. Use the List Profiles operation to look it up.',
12971353
displayOptions: {
12981354
show: {
1299-
resource: ['reach', 'reachContactFields', 'reachSegments', 'reachTags'],
1355+
resource: ['reach', 'reachAutomations', 'reachCampaigns', 'reachContactFields', 'reachForms', 'reachSegments', 'reachTags'],
13001356
operation: [
1301-
'listProfileContacts', 'createProfileContact', 'createProfileContactsBulk', 'getProfileContact', 'updateProfileContact', 'deleteProfileContact', 'listContactFields', 'createContactField', 'updateContactField', 'deleteContactField', 'listProfileSegments', 'createProfileSegment', 'getProfileSegment', 'updateProfileSegment', 'deleteProfileSegment', 'countProfileSegmentContacts', 'listProfileSegmentContacts', 'listTags', 'createTags', 'updateTag', 'deleteTag', 'assignTagToContact', 'assignTagToContacts', 'removeTagFromContact', 'removeTagFromContacts'
1357+
'listProfileContacts', 'createProfileContact', 'createProfileContactsBulk', 'getProfileContact', 'updateProfileContact', 'deleteProfileContact', 'getProfileDnsStatus', 'getProfileLimits', 'listContactFields', 'createContactField', 'updateContactField', 'deleteContactField', 'listProfileSegments', 'createProfileSegment', 'getProfileSegment', 'updateProfileSegment', 'deleteProfileSegment', 'countProfileSegmentContacts', 'listProfileSegmentContacts', 'listTags', 'createTags', 'updateTag', 'deleteTag', 'assignTagToContact', 'assignTagToContacts', 'removeTagFromContact', 'removeTagFromContacts', 'listAutomations', 'getAutomation', 'listAutomationSteps', 'listCampaigns', 'getCampaign', 'getCampaignStatistics', 'listForms', 'getForm', 'deleteForm'
13021358
]
13031359
}
13041360
}
@@ -1685,6 +1741,123 @@ export class HostingerApi implements INodeType {
16851741
operation: ['updateProfileSegment']
16861742
}
16871743
}
1744+
},
1745+
{
1746+
displayName: 'Automation UUID',
1747+
name: 'automationUuid',
1748+
type: 'string',
1749+
required: true,
1750+
default: '',
1751+
description: 'UUID of the automation',
1752+
displayOptions: {
1753+
show: {
1754+
resource: ['reachAutomations'],
1755+
operation: ['getAutomation', 'listAutomationSteps']
1756+
}
1757+
}
1758+
},
1759+
{
1760+
displayName: 'Status',
1761+
name: 'automationStatus',
1762+
type: 'options',
1763+
options: [
1764+
{ name: 'Active', value: 'active', },
1765+
{ name: 'All', value: '', },
1766+
{ name: 'Draft', value: 'draft', },
1767+
{ name: 'Paused', value: 'paused', },
1768+
],
1769+
default: '',
1770+
description: 'Filter automations by status. There is no completed status, an automation that has finished for every contact still reports as active.',
1771+
displayOptions: {
1772+
show: {
1773+
resource: ['reachAutomations'],
1774+
operation: ['listAutomations']
1775+
}
1776+
}
1777+
},
1778+
{
1779+
displayName: 'Sort Direction',
1780+
name: 'sortDirection',
1781+
type: 'options',
1782+
options: [
1783+
{ name: 'Newest First', value: 'desc', },
1784+
{ name: 'Oldest First', value: 'asc', },
1785+
],
1786+
default: 'desc',
1787+
description: 'Order the results by creation date',
1788+
displayOptions: {
1789+
show: {
1790+
resource: ['reachAutomations', 'reachCampaigns'],
1791+
operation: ['listAutomations', 'listCampaigns']
1792+
}
1793+
}
1794+
},
1795+
{
1796+
displayName: 'Campaign UUID',
1797+
name: 'campaignUuid',
1798+
type: 'string',
1799+
required: true,
1800+
default: '',
1801+
description: 'UUID of the campaign',
1802+
displayOptions: {
1803+
show: {
1804+
resource: ['reachCampaigns'],
1805+
operation: ['getCampaign', 'getCampaignStatistics']
1806+
}
1807+
}
1808+
},
1809+
{
1810+
displayName: 'Status',
1811+
name: 'campaignStatus',
1812+
type: 'options',
1813+
options: [
1814+
{ name: 'All', value: '', },
1815+
{ name: 'Draft', value: 'draft', },
1816+
{ name: 'Failed', value: 'failed', },
1817+
{ name: 'Scheduled', value: 'scheduled', },
1818+
{ name: 'Sending', value: 'sending', },
1819+
{ name: 'Sent', value: 'publish', },
1820+
],
1821+
default: '',
1822+
description: 'Filter campaigns by status. A fully sent campaign carries the publish status upstream.',
1823+
displayOptions: {
1824+
show: {
1825+
resource: ['reachCampaigns'],
1826+
operation: ['listCampaigns']
1827+
}
1828+
}
1829+
},
1830+
{
1831+
displayName: 'Type',
1832+
name: 'campaignType',
1833+
type: 'options',
1834+
options: [
1835+
{ name: 'Automation Email', value: 'automation', },
1836+
{ name: 'Campaign', value: 'campaign', },
1837+
{ name: 'Double Opt-In Confirmation', value: 'double_opt_in', },
1838+
],
1839+
default: 'campaign',
1840+
description: 'Which kind of emails to return',
1841+
displayOptions: {
1842+
show: {
1843+
resource: ['reachCampaigns'],
1844+
operation: ['listCampaigns']
1845+
}
1846+
}
1847+
},
1848+
{
1849+
displayName: 'Form UUID',
1850+
name: 'formUuid',
1851+
type: 'string',
1852+
required: true,
1853+
default: '',
1854+
description: 'UUID of the signup form',
1855+
displayOptions: {
1856+
show: {
1857+
resource: ['reachForms'],
1858+
operation: ['getForm', 'deleteForm']
1859+
}
1860+
}
16881861
}
16891862
]
16901863
};
@@ -2147,6 +2320,41 @@ export class HostingerApi implements INodeType {
21472320
case 'deleteProfileSegment': method = 'DELETE'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/segmentation/segments/${getPathParam('segmentUuid')}`; break;
21482321
case 'countProfileSegmentContacts': method = 'GET'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/segmentation/segments/${getPathParam('segmentUuid')}/count`; break;
21492322
case 'listProfileSegmentContacts': method = 'GET'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/segmentation/segments/${getPathParam('segmentUuid')}/contacts?page=${getParam('page')}&per_page=${getParam('perPage')}`; break;
2323+
//Reach - Profile plan and domain
2324+
case 'getProfileLimits': method = 'GET'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/limits`; break;
2325+
case 'getProfileDnsStatus': method = 'GET'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/domains/dns-status`; break;
2326+
//Reach - Automations
2327+
case 'listAutomations': {
2328+
let automationsEndpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/automations?page=${getParam('page')}&per_page=${getParam('perPage')}&sort_direction=${getParam('sortDirection')}`;
2329+
const automationStatus = this.getNodeParameter('automationStatus', i) as string;
2330+
2331+
if (automationStatus) {
2332+
automationsEndpoint += `&status=${automationStatus}`;
2333+
}
2334+
2335+
endpoint = automationsEndpoint;
2336+
break;
2337+
}
2338+
case 'getAutomation': method = 'GET'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/automations/${getPathParam('automationUuid')}`; break;
2339+
case 'listAutomationSteps': method = 'GET'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/automations/${getPathParam('automationUuid')}/steps`; break;
2340+
//Reach - Campaigns
2341+
case 'listCampaigns': {
2342+
let campaignsEndpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/campaigns?page=${getParam('page')}&per_page=${getParam('perPage')}&type=${getParam('campaignType')}&sort_direction=${getParam('sortDirection')}`;
2343+
const campaignStatus = this.getNodeParameter('campaignStatus', i) as string;
2344+
2345+
if (campaignStatus) {
2346+
campaignsEndpoint += `&status=${campaignStatus}`;
2347+
}
2348+
2349+
endpoint = campaignsEndpoint;
2350+
break;
2351+
}
2352+
case 'getCampaign': method = 'GET'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/campaigns/${getPathParam('campaignUuid')}`; break;
2353+
case 'getCampaignStatistics': method = 'GET'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/campaigns/${getPathParam('campaignUuid')}/statistics`; break;
2354+
//Reach - Forms
2355+
case 'listForms': method = 'GET'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/forms?page=${getParam('page')}&per_page=${getParam('perPage')}`; break;
2356+
case 'getForm': method = 'GET'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/forms/${getPathParam('formUuid')}`; break;
2357+
case 'deleteForm': method = 'DELETE'; endpoint = `/api/reach/v1/profiles/${getPathParam('profileUuid')}/forms/${getPathParam('formUuid')}`; break;
21502358

21512359
default: throw new ApplicationError(`Unsupported operation: ${operation}`);
21522360
}

‎package-lock.json‎

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "n8n-nodes-hostinger-api",
3-
"version": "1.0.23",
3+
"version": "1.0.24",
44
"description": "Hostinger API n8n Node",
55
"keywords": [
66
"n8n-community-node-package"

0 commit comments

Comments
 (0)