Skip to content

Commit de16337

Browse files
authored
feat: Added Reach endpoints (#10)
1 parent 317b577 commit de16337

File tree

4 files changed

+215
-13
lines changed

4 files changed

+215
-13
lines changed

README.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# n8n-nodes-hostinger-api
22

3-
This is an n8n community node. It lets you use Hostinger VPS API in your n8n workflows.
3+
This is an n8n community node. It lets you use Hostinger API in your n8n workflows.
44

5-
Hostinger VPS API allows you to manage your virtual private servers, automate provisioning, monitor resources, and perform various administrative actions programmatically.
5+
Hostinger API allows you to manage your virtual private servers, domains, billing, email marketing, and more. Automate provisioning, monitor resources, and perform various administrative actions programmatically.
66

77
[n8n](https://n8n.io/) is a [fair-code licensed](https://docs.n8n.io/reference/license/) workflow automation platform.
88

@@ -20,7 +20,7 @@ Follow the [installation guide](https://docs.n8n.io/integrations/community-nodes
2020

2121
## Operations
2222

23-
The Hostinger VPS node supports the following operations:
23+
The Hostinger API node supports the following operations:
2424

2525
- **Server Management**
2626
- List VPS instances
@@ -56,6 +56,13 @@ The Hostinger VPS node supports the following operations:
5656
- View catalog and pricing
5757
- Manage payment methods and subscriptions
5858

59+
- **Email Marketing (Reach)**
60+
- List and manage email contacts
61+
- Create new contacts with custom fields
62+
- Delete contacts by UUID
63+
- Manage contact groups
64+
- Filter contacts by subscription status
65+
5966
## Credentials
6067

6168
To use this node, you will need to authenticate with the Hostinger API.
@@ -74,10 +81,10 @@ No known version incompatibilities at this time.
7481

7582
## Usage
7683

77-
1. **Add the Hostinger VPS node** to your workflow.
78-
2. **Select the desired operation** (e.g., Start VPS, Get Status).
79-
3. **Provide required parameters**, such as VPS ID, action type, etc.
80-
4. **Execute the workflow** and automate your VPS management tasks.
84+
1. **Add the Hostinger API node** to your workflow.
85+
2. **Select the desired operation** (e.g., Start VPS, Create Contact, Check Domain).
86+
3. **Provide required parameters**, such as VPS ID, contact details, domain name, etc.
87+
4. **Execute the workflow** and automate your Hostinger management tasks.
8188

8289
For more complex workflows, combine this node with standard n8n nodes such as HTTP Request, Function, and Set.
8390

@@ -91,6 +98,9 @@ Helpful link for beginners: [Try it out](https://docs.n8n.io/try-it-out/)
9198

9299
## Version history
93100

101+
- **v1.0.5**:
102+
- Added Email Marketing (Reach) endpoints
103+
94104
- **v1.0.4**:
95105
- Added Purchase VM Method
96106
- Added Billing methods

nodes/hostingerApi/HostingerApi.node.ts

Lines changed: 195 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,11 @@ export class HostingerApi implements INodeType {
3636
name: 'category',
3737
type: 'options',
3838
options: [
39-
{ name: 'VPS', value: 'vps' },
39+
{ name: 'Billing', value: 'billing' },
4040
{ name: 'DNS', value: 'dns' },
4141
{ name: 'Domains', value: 'domains' },
42-
{ name: 'Billing', value: 'billing' },
42+
{ name: 'Reach', value: 'reach' },
43+
{ name: 'VPS', value: 'vps' },
4344
],
4445
default: 'vps',
4546
},
@@ -423,6 +424,23 @@ export class HostingerApi implements INodeType {
423424
},
424425
},
425426
},
427+
{
428+
displayName: 'Reach Action',
429+
name: 'reachAction',
430+
type: 'options',
431+
options: [
432+
{ name: 'List Contacts', value: 'listContacts' },
433+
{ name: 'Create Contact', value: 'createContact' },
434+
{ name: 'Delete Contact', value: 'deleteContact' },
435+
{ name: 'List Contact Groups', value: 'listContactGroups' },
436+
],
437+
default: 'listContacts',
438+
displayOptions: {
439+
show: {
440+
category: ['reach']
441+
},
442+
},
443+
},
426444
{
427445
displayName: 'Virtual Machine ID',
428446
name: 'virtualMachineId',
@@ -707,6 +725,132 @@ export class HostingerApi implements INodeType {
707725
}
708726
}
709727
},
728+
{
729+
displayName: 'Email',
730+
name: 'contactEmail',
731+
type: 'string',
732+
default: '',
733+
description: 'Email address for the contact',
734+
required: true,
735+
displayOptions: {
736+
show: {
737+
category: ['reach'],
738+
reachAction: ['createContact']
739+
}
740+
}
741+
},
742+
{
743+
displayName: 'Name',
744+
name: 'contactName',
745+
type: 'string',
746+
default: '',
747+
description: 'First name of the contact',
748+
displayOptions: {
749+
show: {
750+
category: ['reach'],
751+
reachAction: ['createContact']
752+
}
753+
}
754+
},
755+
{
756+
displayName: 'Surname',
757+
name: 'contactSurname',
758+
type: 'string',
759+
default: '',
760+
description: 'Last name of the contact',
761+
displayOptions: {
762+
show: {
763+
category: ['reach'],
764+
reachAction: ['createContact']
765+
}
766+
}
767+
},
768+
{
769+
displayName: 'Group UUIDs',
770+
name: 'contactGroupUuids',
771+
type: 'string',
772+
default: '',
773+
description: 'Comma-separated list of group UUIDs to assign the contact to',
774+
displayOptions: {
775+
show: {
776+
category: ['reach'],
777+
reachAction: ['createContact']
778+
}
779+
}
780+
},
781+
{
782+
displayName: 'Note',
783+
name: 'contactNote',
784+
type: 'string',
785+
default: '',
786+
description: 'Note about the contact (max 75 characters)',
787+
displayOptions: {
788+
show: {
789+
category: ['reach'],
790+
reachAction: ['createContact']
791+
}
792+
}
793+
},
794+
795+
796+
{
797+
displayName: 'Contact UUID',
798+
name: 'contactUuid',
799+
type: 'string',
800+
default: '',
801+
description: 'UUID of the contact to delete',
802+
displayOptions: {
803+
show: {
804+
category: ['reach'],
805+
reachAction: ['deleteContact']
806+
}
807+
}
808+
},
809+
{
810+
displayName: 'Group UUID',
811+
name: 'groupUuid',
812+
type: 'string',
813+
default: '',
814+
description: 'Filter contacts by group UUID',
815+
displayOptions: {
816+
show: {
817+
category: ['reach'],
818+
reachAction: ['listContacts']
819+
}
820+
}
821+
},
822+
{
823+
displayName: 'Subscription Status',
824+
name: 'subscriptionStatus',
825+
type: 'options',
826+
options: [
827+
{ name: 'All', value: '' },
828+
{ name: 'Subscribed', value: 'subscribed' },
829+
{ name: 'Unsubscribed', value: 'unsubscribed' },
830+
],
831+
default: '',
832+
description: 'Filter contacts by subscription status (leave as "All" to see all contacts)',
833+
displayOptions: {
834+
show: {
835+
category: ['reach'],
836+
reachAction: ['listContacts']
837+
}
838+
}
839+
},
840+
{
841+
displayName: 'Page',
842+
name: 'page',
843+
type: 'number',
844+
default: 1,
845+
description: 'Page number for pagination',
846+
required: true,
847+
displayOptions: {
848+
show: {
849+
category: ['reach'],
850+
reachAction: ['listContacts']
851+
}
852+
}
853+
},
710854
]
711855
};
712856

@@ -732,6 +876,9 @@ export class HostingerApi implements INodeType {
732876
case 'billing':
733877
action = this.getNodeParameter('billingAction', i) as string;
734878
break;
879+
case 'reach':
880+
action = this.getNodeParameter('reachAction', i) as string;
881+
break;
735882
default:
736883
throw new ApplicationError(`Unknown category: ${category}`);
737884
}
@@ -742,7 +889,35 @@ export class HostingerApi implements INodeType {
742889
let requestBody: IDataObject | undefined;
743890

744891
try {
745-
requestBody = JSON.parse(this.getNodeParameter('requestBody', i) as string);
892+
// For Reach createContact, build request body from individual fields
893+
if (category === 'reach' && action === 'createContact') {
894+
const contactEmail = this.getNodeParameter('contactEmail', i) as string;
895+
const contactName = this.getNodeParameter('contactName', i) as string;
896+
const contactSurname = this.getNodeParameter('contactSurname', i) as string;
897+
const contactGroupUuids = this.getNodeParameter('contactGroupUuids', i) as string;
898+
const contactNote = this.getNodeParameter('contactNote', i) as string;
899+
900+
const contactData: IDataObject = {
901+
email: contactEmail
902+
};
903+
904+
if (contactName) contactData.name = contactName;
905+
if (contactSurname) contactData.surname = contactSurname;
906+
if (contactNote) contactData.note = contactNote;
907+
908+
// Handle group UUIDs - convert comma-separated string to array
909+
if (contactGroupUuids) {
910+
const groupUuids = contactGroupUuids.split(',').map(uuid => uuid.trim()).filter(uuid => uuid);
911+
if (groupUuids.length > 0) {
912+
contactData.group_uuids = groupUuids;
913+
}
914+
}
915+
916+
requestBody = contactData;
917+
} else {
918+
// For other actions, use the request body field
919+
requestBody = JSON.parse(this.getNodeParameter('requestBody', i) as string);
920+
}
746921
} catch (e) {}
747922

748923
switch (action) {
@@ -849,6 +1024,23 @@ export class HostingerApi implements INodeType {
8491024
case 'getPaymentList': method = 'GET'; endpoint = '/api/billing/v1/payment-methods'; break;
8501025
case 'deleteSubscription': method = 'DELETE'; endpoint = `/api/billing/v1/subscriptions/${getParam('subscriptionId')}`; break;
8511026
case 'getSubscriptionList': method = 'GET'; endpoint = '/api/billing/v1/subscriptions'; break;
1027+
//Reach
1028+
case 'listContacts':
1029+
let contactsEndpoint = `/api/reach/v1/contacts?page=${getParam('page')}`;
1030+
const groupUuid = this.getNodeParameter('groupUuid', i) as string;
1031+
const subscriptionStatus = this.getNodeParameter('subscriptionStatus', i) as string;
1032+
1033+
if (groupUuid) {
1034+
contactsEndpoint += `&group_uuid=${groupUuid}`;
1035+
}
1036+
if (subscriptionStatus) {
1037+
contactsEndpoint += `&subscription_status=${subscriptionStatus}`;
1038+
}
1039+
endpoint = contactsEndpoint;
1040+
break;
1041+
case 'createContact': method = 'POST'; endpoint = '/api/reach/v1/contacts'; break;
1042+
case 'deleteContact': method = 'DELETE'; endpoint = `/api/reach/v1/contacts/${getParam('contactUuid')}`; break;
1043+
case 'listContactGroups': endpoint = '/api/reach/v1/contacts/groups'; break;
8521044

8531045
default: throw new ApplicationError(`Unsupported action: ${action}`);
8541046
}

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.4",
3+
"version": "1.0.5",
44
"description": "Hostinger API n8n Node",
55
"keywords": [
66
"n8n-community-node-package"

0 commit comments

Comments
 (0)