n8n-nodes-simgate 0.1.0

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.
Files changed (32) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +111 -0
  3. package/dist/credentials/SimGateApi.credentials.d.ts +10 -0
  4. package/dist/credentials/SimGateApi.credentials.js +53 -0
  5. package/dist/credentials/SimGateApi.credentials.js.map +1 -0
  6. package/dist/icons/simgate.dark.svg +6 -0
  7. package/dist/icons/simgate.svg +6 -0
  8. package/dist/nodes/SimGate/SimGate.node.d.ts +9 -0
  9. package/dist/nodes/SimGate/SimGate.node.js +89 -0
  10. package/dist/nodes/SimGate/SimGate.node.js.map +1 -0
  11. package/dist/nodes/SimGate/SimGate.node.json +18 -0
  12. package/dist/nodes/SimGate/SimGateTrigger.node.d.ts +12 -0
  13. package/dist/nodes/SimGate/SimGateTrigger.node.js +180 -0
  14. package/dist/nodes/SimGate/SimGateTrigger.node.js.map +1 -0
  15. package/dist/nodes/SimGate/SimGateTrigger.node.json +18 -0
  16. package/dist/nodes/SimGate/resources/account/index.d.ts +2 -0
  17. package/dist/nodes/SimGate/resources/account/index.js +31 -0
  18. package/dist/nodes/SimGate/resources/account/index.js.map +1 -0
  19. package/dist/nodes/SimGate/resources/device/index.d.ts +2 -0
  20. package/dist/nodes/SimGate/resources/device/index.js +77 -0
  21. package/dist/nodes/SimGate/resources/device/index.js.map +1 -0
  22. package/dist/nodes/SimGate/resources/message/get.d.ts +2 -0
  23. package/dist/nodes/SimGate/resources/message/get.js +19 -0
  24. package/dist/nodes/SimGate/resources/message/get.js.map +1 -0
  25. package/dist/nodes/SimGate/resources/message/index.d.ts +2 -0
  26. package/dist/nodes/SimGate/resources/message/index.js +47 -0
  27. package/dist/nodes/SimGate/resources/message/index.js.map +1 -0
  28. package/dist/nodes/SimGate/resources/message/send.d.ts +2 -0
  29. package/dist/nodes/SimGate/resources/message/send.js +52 -0
  30. package/dist/nodes/SimGate/resources/message/send.js.map +1 -0
  31. package/dist/package.json +63 -0
  32. package/package.json +63 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SimGate
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,111 @@
1
+ # n8n-nodes-simgate
2
+
3
+ Send and receive SMS from n8n through your own phone, using [SimGate](https://simgate.app).
4
+
5
+ SimGate turns an Android phone into an SMS gateway. Your messages go out from your own number and your own SIM — no sender IDs, no per-message pricing, no third party holding the number.
6
+
7
+ This package adds two nodes:
8
+
9
+ - **SimGate** — send an SMS, check a message's status, list your phones, read your quota.
10
+ - **SimGate Trigger** — start a workflow when your phone receives an SMS or a call.
11
+
12
+ [Installation](#installation) · [Credentials](#credentials) · [Operations](#operations) · [SimGate Trigger](#simgate-trigger) · [Compatibility](#compatibility)
13
+
14
+ ## Installation
15
+
16
+ ### n8n Cloud
17
+
18
+ Search for `SimGate` in the nodes panel and add it to your canvas.
19
+
20
+ ### Self-hosted
21
+
22
+ Go to **Settings → Community nodes → Install**, enter `n8n-nodes-simgate`, and confirm.
23
+
24
+ ## Credentials
25
+
26
+ You need a SimGate account with at least one phone registered.
27
+
28
+ 1. In the [SimGate dashboard](https://simgate.app/dashboard), open **API** and create an API key.
29
+ 2. In n8n, create a new **SimGate API** credential and paste the key.
30
+ 3. Leave **Base URL** as `https://api.simgate.app` unless you self-host the backend.
31
+ 4. Leave **Webhook Signing Secret** empty. The SimGate Trigger captures it automatically when it registers; fill it in only if you set the webhook up by hand in the dashboard.
32
+
33
+ Use **Test** in the credential dialog to confirm the key works — it reads your account usage.
34
+
35
+ ## Operations
36
+
37
+ ### Message
38
+
39
+ | Operation | What it does |
40
+ | --- | --- |
41
+ | Send | Sends an SMS from one of your phones |
42
+ | Get | Returns the current delivery status of a message you sent |
43
+
44
+ **Send** takes a device, a recipient number in international format, and the message text. Turn on **Test Mode** to draw from your test quota instead of your SMS quota.
45
+
46
+ The response looks like this:
47
+
48
+ ```json
49
+ {
50
+ "success": true,
51
+ "messageId": "6f2b1c1e-2b9a-4f1a-9a1e-3a5d6c8b7e40",
52
+ "queued": false,
53
+ "connectionStatus": "online",
54
+ "message": "SMS command accepted by device."
55
+ }
56
+ ```
57
+
58
+ If the phone is briefly offline, SimGate queues the message and retries automatically. The node still succeeds, but the item carries `"queued": true`. Use **Message → Get** with the `messageId` to poll for the final state.
59
+
60
+ ### Device
61
+
62
+ | Operation | What it does |
63
+ | --- | --- |
64
+ | Get Many | Lists every phone registered to your account |
65
+ | Get | Returns one phone |
66
+ | Get Status | Returns whether a phone is online right now |
67
+
68
+ ### Account
69
+
70
+ | Operation | What it does |
71
+ | --- | --- |
72
+ | Get Usage | Returns your plan, billing period, and remaining inbound and outbound quota |
73
+
74
+ ## SimGate Trigger
75
+
76
+ The trigger registers itself. Add the node, choose your events, and activate the workflow — SimGate is pointed at this workflow's URL and the signing secret is stored with it. Deactivating the workflow releases the webhook again.
77
+
78
+ SimGate delivers to one endpoint per account. If your account already sends webhooks somewhere else, activation stops with a clear error instead of taking the slot over — turn the existing webhook off in the SimGate dashboard first.
79
+
80
+ Every delivery is verified with HMAC-SHA256 over `timestamp.body`, and anything older than five minutes is rejected as a replay. You do not need to fill in the credential's **Webhook Signing Secret** unless you configured the webhook by hand in the dashboard.
81
+
82
+ An `sms.received` event arrives as:
83
+
84
+ ```json
85
+ {
86
+ "id": "3f8f0b16-84e3-4a37-9b0e-53b0d2d1d1a1",
87
+ "type": "sms.received",
88
+ "createdAt": "2026-08-20T09:12:44.001Z",
89
+ "data": {
90
+ "deviceId": "android-5q15b182f2704gbz",
91
+ "from": "+391234567890",
92
+ "body": "Yes, 3pm works",
93
+ "receivedAt": "2026-08-20T09:12:43.880Z"
94
+ }
95
+ }
96
+ ```
97
+
98
+ Call events (`call.incoming`, `call.answered`, `call.ended`) use the same envelope, with `callId`, `direction`, and — on `call.ended` — `durationSeconds`.
99
+
100
+ ## Compatibility
101
+
102
+ Requires n8n 1.0 or later and Node.js 20.19 or later. Tested against the SimGate API v1.
103
+
104
+ ## Resources
105
+
106
+ - [SimGate documentation](https://simgate.app/integrations/n8n)
107
+ - [n8n community nodes documentation](https://docs.n8n.io/integrations/community-nodes/)
108
+
109
+ ## License
110
+
111
+ [MIT](LICENSE.md)
@@ -0,0 +1,10 @@
1
+ import type { IAuthenticateGeneric, Icon, ICredentialTestRequest, ICredentialType, INodeProperties } from 'n8n-workflow';
2
+ export declare class SimGateApi implements ICredentialType {
3
+ name: string;
4
+ displayName: string;
5
+ icon: Icon;
6
+ documentationUrl: string;
7
+ properties: INodeProperties[];
8
+ authenticate: IAuthenticateGeneric;
9
+ test: ICredentialTestRequest;
10
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SimGateApi = void 0;
4
+ class SimGateApi {
5
+ constructor() {
6
+ this.name = 'simGateApi';
7
+ this.displayName = 'SimGate API';
8
+ this.icon = { light: 'file:../icons/simgate.svg', dark: 'file:../icons/simgate.dark.svg' };
9
+ this.documentationUrl = 'https://github.com/simgate-dev/n8n-nodes-simgate?tab=readme-ov-file#credentials';
10
+ this.properties = [
11
+ {
12
+ displayName: 'API Key',
13
+ name: 'apiKey',
14
+ type: 'string',
15
+ typeOptions: { password: true },
16
+ required: true,
17
+ default: '',
18
+ description: 'Create one in the SimGate dashboard under API',
19
+ },
20
+ {
21
+ displayName: 'Webhook Signing Secret',
22
+ name: 'signingSecret',
23
+ type: 'string',
24
+ typeOptions: { password: true },
25
+ default: '',
26
+ description: 'Leave empty. The SimGate Trigger captures this automatically when it registers its webhook. Set it only when the webhook was configured by hand in the SimGate dashboard.',
27
+ },
28
+ {
29
+ displayName: 'Base URL',
30
+ name: 'baseUrl',
31
+ type: 'string',
32
+ default: 'https://api.simgate.app',
33
+ description: 'Change this only if you run a self-hosted SimGate backend',
34
+ },
35
+ ];
36
+ this.authenticate = {
37
+ type: 'generic',
38
+ properties: {
39
+ headers: {
40
+ 'x-api-key': '={{$credentials.apiKey}}',
41
+ },
42
+ },
43
+ };
44
+ this.test = {
45
+ request: {
46
+ baseURL: '={{$credentials.baseUrl}}',
47
+ url: '/v1/usage',
48
+ },
49
+ };
50
+ }
51
+ }
52
+ exports.SimGateApi = SimGateApi;
53
+ //# sourceMappingURL=SimGateApi.credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SimGateApi.credentials.js","sourceRoot":"","sources":["../../credentials/SimGateApi.credentials.ts"],"names":[],"mappings":";;;AAQA,MAAa,UAAU;IAAvB;QACC,SAAI,GAAG,YAAY,CAAC;QAEpB,gBAAW,GAAG,aAAa,CAAC;QAE5B,SAAI,GAAS,EAAE,KAAK,EAAE,2BAA2B,EAAE,IAAI,EAAE,gCAAgC,EAAE,CAAC;QAE5F,qBAAgB,GAAG,iFAAiF,CAAC;QAErG,eAAU,GAAsB;YAC/B;gBACC,WAAW,EAAE,SAAS;gBACtB,IAAI,EAAE,QAAQ;gBACd,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,QAAQ,EAAE,IAAI;gBACd,OAAO,EAAE,EAAE;gBACX,WAAW,EAAE,+CAA+C;aAC5D;YACD;gBACC,WAAW,EAAE,wBAAwB;gBACrC,IAAI,EAAE,eAAe;gBACrB,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE;gBAC/B,OAAO,EAAE,EAAE;gBACX,WAAW,EACV,2KAA2K;aAC5K;YACD;gBACC,WAAW,EAAE,UAAU;gBACvB,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,QAAQ;gBACd,OAAO,EAAE,yBAAyB;gBAClC,WAAW,EAAE,2DAA2D;aACxE;SACD,CAAC;QAEF,iBAAY,GAAyB;YACpC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE;gBACX,OAAO,EAAE;oBACR,WAAW,EAAE,0BAA0B;iBACvC;aACD;SACD,CAAC;QAEF,SAAI,GAA2B;YAC9B,OAAO,EAAE;gBACR,OAAO,EAAE,2BAA2B;gBACpC,GAAG,EAAE,WAAW;aAChB;SACD,CAAC;IACH,CAAC;CAAA;AApDD,gCAoDC"}
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" fill="none">
2
+ <path d="M11 9a5 5 0 0 1 5-5h17.7a5 5 0 0 1 3.54 1.46l9.3 9.3A5 5 0 0 1 48 18.3V51a5 5 0 0 1-5 5H16a5 5 0 0 1-5-5V9Z" fill="#FF7093"/>
3
+ <rect x="19" y="26" width="22" height="19" rx="3.5" fill="#1A1416"/>
4
+ <path d="M19 32.5h22M19 38.5h22M26.5 26v19M33.5 26v19" stroke="#FF7093" stroke-width="1.7" stroke-linecap="round"/>
5
+ <path d="M35.5 12.5a7.5 7.5 0 0 1 0 8M40 9.5a13 13 0 0 1 0 14" stroke="#1A1416" stroke-width="2.6" stroke-linecap="round"/>
6
+ </svg>
@@ -0,0 +1,6 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" fill="none">
2
+ <path d="M11 9a5 5 0 0 1 5-5h17.7a5 5 0 0 1 3.54 1.46l9.3 9.3A5 5 0 0 1 48 18.3V51a5 5 0 0 1-5 5H16a5 5 0 0 1-5-5V9Z" fill="#D2325C"/>
3
+ <rect x="19" y="26" width="22" height="19" rx="3.5" fill="#FFFFFF"/>
4
+ <path d="M19 32.5h22M19 38.5h22M26.5 26v19M33.5 26v19" stroke="#D2325C" stroke-width="1.7" stroke-linecap="round"/>
5
+ <path d="M35.5 12.5a7.5 7.5 0 0 1 0 8M40 9.5a13 13 0 0 1 0 14" stroke="#FFFFFF" stroke-width="2.6" stroke-linecap="round"/>
6
+ </svg>
@@ -0,0 +1,9 @@
1
+ import { type ILoadOptionsFunctions, type INodePropertyOptions, type INodeType, type INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class SimGate implements INodeType {
3
+ description: INodeTypeDescription;
4
+ methods: {
5
+ loadOptions: {
6
+ getDevices(this: ILoadOptionsFunctions): Promise<INodePropertyOptions[]>;
7
+ };
8
+ };
9
+ }
@@ -0,0 +1,89 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SimGate = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const account_1 = require("./resources/account");
6
+ const device_1 = require("./resources/device");
7
+ const message_1 = require("./resources/message");
8
+ class SimGate {
9
+ constructor() {
10
+ this.description = {
11
+ displayName: 'SimGate',
12
+ name: 'simGate',
13
+ icon: { light: 'file:../../icons/simgate.svg', dark: 'file:../../icons/simgate.dark.svg' },
14
+ group: ['output'],
15
+ version: 1,
16
+ subtitle: '={{$parameter["operation"] + ": " + $parameter["resource"]}}',
17
+ description: 'Send SMS from your own phone number with SimGate',
18
+ defaults: {
19
+ name: 'SimGate',
20
+ },
21
+ usableAsTool: true,
22
+ inputs: [n8n_workflow_1.NodeConnectionTypes.Main],
23
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
24
+ credentials: [
25
+ {
26
+ name: 'simGateApi',
27
+ required: true,
28
+ },
29
+ ],
30
+ requestDefaults: {
31
+ baseURL: '={{$credentials.baseUrl}}/v1',
32
+ headers: {
33
+ Accept: 'application/json',
34
+ 'Content-Type': 'application/json',
35
+ },
36
+ },
37
+ properties: [
38
+ {
39
+ displayName: 'Resource',
40
+ name: 'resource',
41
+ type: 'options',
42
+ noDataExpression: true,
43
+ options: [
44
+ {
45
+ name: 'Account',
46
+ value: 'account',
47
+ },
48
+ {
49
+ name: 'Device',
50
+ value: 'device',
51
+ },
52
+ {
53
+ name: 'Message',
54
+ value: 'message',
55
+ },
56
+ ],
57
+ default: 'message',
58
+ },
59
+ ...account_1.accountDescription,
60
+ ...device_1.deviceDescription,
61
+ ...message_1.messageDescription,
62
+ ],
63
+ };
64
+ this.methods = {
65
+ loadOptions: {
66
+ async getDevices() {
67
+ var _a;
68
+ const credentials = await this.getCredentials('simGateApi');
69
+ const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'simGateApi', {
70
+ method: 'GET',
71
+ url: `${credentials.baseUrl}/v1/devices`,
72
+ json: true,
73
+ }));
74
+ return ((_a = response.devices) !== null && _a !== void 0 ? _a : []).map((device) => {
75
+ var _a;
76
+ return ({
77
+ name: device.deviceName
78
+ ? `${device.deviceName} (${(_a = device.connectionStatus) !== null && _a !== void 0 ? _a : 'unknown'})`
79
+ : device.deviceId,
80
+ value: device.deviceId,
81
+ });
82
+ });
83
+ },
84
+ },
85
+ };
86
+ }
87
+ }
88
+ exports.SimGate = SimGate;
89
+ //# sourceMappingURL=SimGate.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SimGate.node.js","sourceRoot":"","sources":["../../../nodes/SimGate/SimGate.node.ts"],"names":[],"mappings":";;;AAAA,+CAMsB;AACtB,iDAAyD;AACzD,+CAAuD;AACvD,iDAAyD;AAQzD,MAAa,OAAO;IAApB;QACC,gBAAW,GAAyB;YACnC,WAAW,EAAE,SAAS;YACtB,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,EAAE,KAAK,EAAE,8BAA8B,EAAE,IAAI,EAAE,mCAAmC,EAAE;YAC1F,KAAK,EAAE,CAAC,QAAQ,CAAC;YACjB,OAAO,EAAE,CAAC;YACV,QAAQ,EAAE,8DAA8D;YACxE,WAAW,EAAE,kDAAkD;YAC/D,QAAQ,EAAE;gBACT,IAAI,EAAE,SAAS;aACf;YACD,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,CAAC,kCAAmB,CAAC,IAAI,CAAC;YAClC,OAAO,EAAE,CAAC,kCAAmB,CAAC,IAAI,CAAC;YACnC,WAAW,EAAE;gBACZ;oBACC,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE,IAAI;iBACd;aACD;YACD,eAAe,EAAE;gBAChB,OAAO,EAAE,8BAA8B;gBACvC,OAAO,EAAE;oBACR,MAAM,EAAE,kBAAkB;oBAC1B,cAAc,EAAE,kBAAkB;iBAClC;aACD;YACD,UAAU,EAAE;gBACX;oBACC,WAAW,EAAE,UAAU;oBACvB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,SAAS;oBACf,gBAAgB,EAAE,IAAI;oBACtB,OAAO,EAAE;wBACR;4BACC,IAAI,EAAE,SAAS;4BACf,KAAK,EAAE,SAAS;yBAChB;wBACD;4BACC,IAAI,EAAE,QAAQ;4BACd,KAAK,EAAE,QAAQ;yBACf;wBACD;4BACC,IAAI,EAAE,SAAS;4BACf,KAAK,EAAE,SAAS;yBAChB;qBACD;oBACD,OAAO,EAAE,SAAS;iBAClB;gBACD,GAAG,4BAAkB;gBACrB,GAAG,0BAAiB;gBACpB,GAAG,4BAAkB;aACrB;SACD,CAAC;QAEF,YAAO,GAAG;YACT,WAAW,EAAE;gBACZ,KAAK,CAAC,UAAU;;oBACf,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;oBAC5D,MAAM,QAAQ,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,6BAA6B,CAAC,IAAI,CACtE,IAAI,EACJ,YAAY,EACZ;wBACC,MAAM,EAAE,KAAK;wBACb,GAAG,EAAE,GAAG,WAAW,CAAC,OAAiB,aAAa;wBAClD,IAAI,EAAE,IAAI;qBACV,CACD,CAAkC,CAAC;oBAEpC,OAAO,CAAC,MAAA,QAAQ,CAAC,OAAO,mCAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;;wBAAC,OAAA,CAAC;4BAChD,IAAI,EAAE,MAAM,CAAC,UAAU;gCACtB,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,KAAK,MAAA,MAAM,CAAC,gBAAgB,mCAAI,SAAS,GAAG;gCAClE,CAAC,CAAC,MAAM,CAAC,QAAQ;4BAClB,KAAK,EAAE,MAAM,CAAC,QAAQ;yBACtB,CAAC,CAAA;qBAAA,CAAC,CAAC;gBACL,CAAC;aACD;SACD,CAAC;IACH,CAAC;CAAA;AA/ED,0BA+EC"}
@@ -0,0 +1,18 @@
1
+ {
2
+ "node": "n8n-nodes-simgate.simGate",
3
+ "nodeVersion": "1.0",
4
+ "codexVersion": "1.0",
5
+ "categories": ["Communication", "Utility"],
6
+ "resources": {
7
+ "credentialDocumentation": [
8
+ {
9
+ "url": "https://github.com/simgate-dev/n8n-nodes-simgate?tab=readme-ov-file#credentials"
10
+ }
11
+ ],
12
+ "primaryDocumentation": [
13
+ {
14
+ "url": "https://github.com/simgate-dev/n8n-nodes-simgate?tab=readme-ov-file"
15
+ }
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,12 @@
1
+ import { type IHookFunctions, type INodeType, type INodeTypeDescription, type IWebhookFunctions, type IWebhookResponseData } from 'n8n-workflow';
2
+ export declare class SimGateTrigger implements INodeType {
3
+ description: INodeTypeDescription;
4
+ webhookMethods: {
5
+ default: {
6
+ checkExists(this: IHookFunctions): Promise<boolean>;
7
+ create(this: IHookFunctions): Promise<boolean>;
8
+ delete(this: IHookFunctions): Promise<boolean>;
9
+ };
10
+ };
11
+ webhook(this: IWebhookFunctions): Promise<IWebhookResponseData>;
12
+ }
@@ -0,0 +1,180 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SimGateTrigger = void 0;
4
+ const node_crypto_1 = require("node:crypto");
5
+ const n8n_workflow_1 = require("n8n-workflow");
6
+ const TIMESTAMP_TOLERANCE_SECONDS = 300;
7
+ class SimGateTrigger {
8
+ constructor() {
9
+ this.description = {
10
+ displayName: 'SimGate Trigger',
11
+ name: 'simGateTrigger',
12
+ icon: { light: 'file:../../icons/simgate.svg', dark: 'file:../../icons/simgate.dark.svg' },
13
+ group: ['trigger'],
14
+ version: 1,
15
+ subtitle: '={{$parameter["events"].join(", ")}}',
16
+ description: 'Starts a workflow when your phone receives an SMS or a call',
17
+ defaults: {
18
+ name: 'SimGate Trigger',
19
+ },
20
+ inputs: [],
21
+ outputs: [n8n_workflow_1.NodeConnectionTypes.Main],
22
+ credentials: [
23
+ {
24
+ name: 'simGateApi',
25
+ required: true,
26
+ },
27
+ ],
28
+ webhooks: [
29
+ {
30
+ name: 'default',
31
+ httpMethod: 'POST',
32
+ responseMode: 'onReceived',
33
+ path: 'webhook',
34
+ },
35
+ ],
36
+ properties: [
37
+ {
38
+ displayName: 'Events',
39
+ name: 'events',
40
+ type: 'multiOptions',
41
+ options: [
42
+ {
43
+ name: 'Call Answered',
44
+ value: 'call.answered',
45
+ description: 'An incoming call was answered on the phone',
46
+ },
47
+ {
48
+ name: 'Call Ended',
49
+ value: 'call.ended',
50
+ description: 'A call finished, including its duration',
51
+ },
52
+ {
53
+ name: 'Call Incoming',
54
+ value: 'call.incoming',
55
+ description: 'The phone started ringing',
56
+ },
57
+ {
58
+ name: 'SMS Received',
59
+ value: 'sms.received',
60
+ description: 'The phone received a text message',
61
+ },
62
+ ],
63
+ default: ['sms.received'],
64
+ required: true,
65
+ description: 'Which SimGate events should start this workflow',
66
+ },
67
+ ],
68
+ };
69
+ this.webhookMethods = {
70
+ default: {
71
+ async checkExists() {
72
+ const credentials = await this.getCredentials('simGateApi');
73
+ const webhookUrl = this.getNodeWebhookUrl('default');
74
+ const response = (await this.helpers.httpRequestWithAuthentication.call(this, 'simGateApi', {
75
+ method: 'GET',
76
+ url: `${credentials.baseUrl}/v1/webhooks/integration`,
77
+ qs: { url: webhookUrl },
78
+ json: true,
79
+ }));
80
+ return response.matches === true;
81
+ },
82
+ async create() {
83
+ var _a;
84
+ const credentials = await this.getCredentials('simGateApi');
85
+ const webhookUrl = this.getNodeWebhookUrl('default');
86
+ let response;
87
+ try {
88
+ response = (await this.helpers.httpRequestWithAuthentication.call(this, 'simGateApi', {
89
+ method: 'POST',
90
+ url: `${credentials.baseUrl}/v1/webhooks/integration`,
91
+ body: { url: webhookUrl },
92
+ json: true,
93
+ }));
94
+ }
95
+ catch (error) {
96
+ const status = error.statusCode;
97
+ const httpCode = error.httpCode;
98
+ if (status === 409 || httpCode === '409') {
99
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'This SimGate account already sends webhooks somewhere else. Turn that webhook off in the SimGate dashboard, then activate this workflow again.');
100
+ }
101
+ throw new n8n_workflow_1.NodeApiError(this.getNode(), error);
102
+ }
103
+ const webhookData = this.getWorkflowStaticData('node');
104
+ webhookData.signingSecret = response.signingSecret;
105
+ webhookData.webhookUrl = (_a = response.url) !== null && _a !== void 0 ? _a : webhookUrl;
106
+ return true;
107
+ },
108
+ async delete() {
109
+ var _a;
110
+ const credentials = await this.getCredentials('simGateApi');
111
+ const webhookData = this.getWorkflowStaticData('node');
112
+ const webhookUrl = (_a = webhookData.webhookUrl) !== null && _a !== void 0 ? _a : this.getNodeWebhookUrl('default');
113
+ try {
114
+ await this.helpers.httpRequestWithAuthentication.call(this, 'simGateApi', {
115
+ method: 'DELETE',
116
+ url: `${credentials.baseUrl}/v1/webhooks/integration`,
117
+ body: { url: webhookUrl },
118
+ json: true,
119
+ });
120
+ }
121
+ catch (error) {
122
+ this.logger.warn(`SimGate Trigger could not release the webhook for ${webhookUrl}: ${error.message}`);
123
+ return false;
124
+ }
125
+ delete webhookData.signingSecret;
126
+ delete webhookData.webhookUrl;
127
+ return true;
128
+ },
129
+ },
130
+ };
131
+ }
132
+ async webhook() {
133
+ var _a, _b, _c, _d;
134
+ const request = this.getRequestObject();
135
+ const headers = this.getHeaderData();
136
+ const credentials = await this.getCredentials('simGateApi');
137
+ const events = this.getNodeParameter('events', []);
138
+ if (!request.rawBody) {
139
+ await request.readRawBody();
140
+ }
141
+ if (!request.rawBody) {
142
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Could not read the raw request body, so the SimGate signature cannot be verified');
143
+ }
144
+ const body = request.rawBody.toString('utf8');
145
+ const webhookData = this.getWorkflowStaticData('node');
146
+ const signingSecret = (_b = (_a = webhookData.signingSecret) !== null && _a !== void 0 ? _a : credentials.signingSecret) !== null && _b !== void 0 ? _b : '';
147
+ if (signingSecret !== '') {
148
+ const timestamp = (_c = headers['x-simgate-timestamp']) !== null && _c !== void 0 ? _c : '';
149
+ const signature = (_d = headers['x-simgate-signature']) !== null && _d !== void 0 ? _d : '';
150
+ const expected = `v1=${(0, node_crypto_1.createHmac)('sha256', signingSecret)
151
+ .update(`${timestamp}.${body}`, 'utf8')
152
+ .digest('hex')}`;
153
+ const expectedBuffer = Buffer.from(expected, 'utf8');
154
+ const receivedBuffer = Buffer.from(signature, 'utf8');
155
+ if (expectedBuffer.length !== receivedBuffer.length ||
156
+ !(0, node_crypto_1.timingSafeEqual)(expectedBuffer, receivedBuffer)) {
157
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'Invalid SimGate webhook signature');
158
+ }
159
+ const age = Math.abs(Date.now() / 1000 - Number(timestamp));
160
+ if (!Number.isFinite(age) || age > TIMESTAMP_TOLERANCE_SECONDS) {
161
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'SimGate webhook timestamp is outside the allowed tolerance, so it was rejected as a replay');
162
+ }
163
+ }
164
+ let event;
165
+ try {
166
+ event = JSON.parse(body);
167
+ }
168
+ catch {
169
+ throw new n8n_workflow_1.NodeOperationError(this.getNode(), 'SimGate webhook body is not valid JSON');
170
+ }
171
+ if (event.type === undefined || !events.includes(event.type)) {
172
+ return { webhookResponse: { received: true, ignored: true } };
173
+ }
174
+ return {
175
+ workflowData: [this.helpers.returnJsonArray([event])],
176
+ };
177
+ }
178
+ }
179
+ exports.SimGateTrigger = SimGateTrigger;
180
+ //# sourceMappingURL=SimGateTrigger.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SimGateTrigger.node.js","sourceRoot":"","sources":["../../../nodes/SimGate/SimGateTrigger.node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ {
2
+ "node": "n8n-nodes-simgate.simGateTrigger",
3
+ "nodeVersion": "1.0",
4
+ "codexVersion": "1.0",
5
+ "categories": ["Communication", "Utility"],
6
+ "resources": {
7
+ "credentialDocumentation": [
8
+ {
9
+ "url": "https://github.com/simgate-dev/n8n-nodes-simgate?tab=readme-ov-file#credentials"
10
+ }
11
+ ],
12
+ "primaryDocumentation": [
13
+ {
14
+ "url": "https://github.com/simgate-dev/n8n-nodes-simgate?tab=readme-ov-file#simgate-trigger"
15
+ }
16
+ ]
17
+ }
18
+ }
@@ -0,0 +1,2 @@
1
+ import type { INodeProperties } from 'n8n-workflow';
2
+ export declare const accountDescription: INodeProperties[];
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.accountDescription = void 0;
4
+ const showOnlyForAccount = {
5
+ resource: ['account'],
6
+ };
7
+ exports.accountDescription = [
8
+ {
9
+ displayName: 'Operation',
10
+ name: 'operation',
11
+ type: 'options',
12
+ noDataExpression: true,
13
+ displayOptions: { show: showOnlyForAccount },
14
+ options: [
15
+ {
16
+ name: 'Get Usage',
17
+ value: 'getUsage',
18
+ action: 'Get account usage',
19
+ description: 'Retrieve your plan and remaining SMS quota',
20
+ routing: {
21
+ request: {
22
+ method: 'GET',
23
+ url: '/usage',
24
+ },
25
+ },
26
+ },
27
+ ],
28
+ default: 'getUsage',
29
+ },
30
+ ];
31
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../nodes/SimGate/resources/account/index.ts"],"names":[],"mappings":";;;AAEA,MAAM,kBAAkB,GAAG;IAC1B,QAAQ,EAAE,CAAC,SAAS,CAAC;CACrB,CAAC;AAEW,QAAA,kBAAkB,GAAsB;IACpD;QACC,WAAW,EAAE,WAAW;QACxB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,SAAS;QACf,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE;QAC5C,OAAO,EAAE;YACR;gBACC,IAAI,EAAE,WAAW;gBACjB,KAAK,EAAE,UAAU;gBACjB,MAAM,EAAE,mBAAmB;gBAC3B,WAAW,EAAE,4CAA4C;gBACzD,OAAO,EAAE;oBACR,OAAO,EAAE;wBACR,MAAM,EAAE,KAAK;wBACb,GAAG,EAAE,QAAQ;qBACb;iBACD;aACD;SACD;QACD,OAAO,EAAE,UAAU;KACnB;CACD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { INodeProperties } from 'n8n-workflow';
2
+ export declare const deviceDescription: INodeProperties[];
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.deviceDescription = void 0;
4
+ const showOnlyForDevices = {
5
+ resource: ['device'],
6
+ };
7
+ const showOnlyForSingleDevice = {
8
+ operation: ['get', 'getStatus'],
9
+ resource: ['device'],
10
+ };
11
+ exports.deviceDescription = [
12
+ {
13
+ displayName: 'Operation',
14
+ name: 'operation',
15
+ type: 'options',
16
+ noDataExpression: true,
17
+ displayOptions: { show: showOnlyForDevices },
18
+ options: [
19
+ {
20
+ name: 'Get',
21
+ value: 'get',
22
+ action: 'Get a device',
23
+ description: 'Retrieve a single registered phone',
24
+ routing: {
25
+ request: {
26
+ method: 'GET',
27
+ url: '=/devices/{{$parameter.deviceId}}',
28
+ },
29
+ },
30
+ },
31
+ {
32
+ name: 'Get Many',
33
+ value: 'getAll',
34
+ action: 'Get many devices',
35
+ description: 'Retrieve every phone registered to your account',
36
+ routing: {
37
+ request: {
38
+ method: 'GET',
39
+ url: '/devices',
40
+ },
41
+ output: {
42
+ postReceive: [
43
+ {
44
+ type: 'rootProperty',
45
+ properties: { property: 'devices' },
46
+ },
47
+ ],
48
+ },
49
+ },
50
+ },
51
+ {
52
+ name: 'Get Status',
53
+ value: 'getStatus',
54
+ action: 'Get a device status',
55
+ description: 'Check whether a phone is currently online',
56
+ routing: {
57
+ request: {
58
+ method: 'GET',
59
+ url: '=/devices/{{$parameter.deviceId}}/status',
60
+ },
61
+ },
62
+ },
63
+ ],
64
+ default: 'getAll',
65
+ },
66
+ {
67
+ displayName: 'Device Name or ID',
68
+ name: 'deviceId',
69
+ type: 'options',
70
+ typeOptions: { loadOptionsMethod: 'getDevices' },
71
+ displayOptions: { show: showOnlyForSingleDevice },
72
+ default: '',
73
+ required: true,
74
+ description: 'The phone to look up. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
75
+ },
76
+ ];
77
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../nodes/SimGate/resources/device/index.ts"],"names":[],"mappings":";;;AAEA,MAAM,kBAAkB,GAAG;IAC1B,QAAQ,EAAE,CAAC,QAAQ,CAAC;CACpB,CAAC;AAEF,MAAM,uBAAuB,GAAG;IAC/B,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC;IAC/B,QAAQ,EAAE,CAAC,QAAQ,CAAC;CACpB,CAAC;AAEW,QAAA,iBAAiB,GAAsB;IACnD;QACC,WAAW,EAAE,WAAW;QACxB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,SAAS;QACf,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,EAAE,IAAI,EAAE,kBAAkB,EAAE;QAC5C,OAAO,EAAE;YACR;gBACC,IAAI,EAAE,KAAK;gBACX,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,cAAc;gBACtB,WAAW,EAAE,oCAAoC;gBACjD,OAAO,EAAE;oBACR,OAAO,EAAE;wBACR,MAAM,EAAE,KAAK;wBACb,GAAG,EAAE,mCAAmC;qBACxC;iBACD;aACD;YACD;gBACC,IAAI,EAAE,UAAU;gBAChB,KAAK,EAAE,QAAQ;gBACf,MAAM,EAAE,kBAAkB;gBAC1B,WAAW,EAAE,iDAAiD;gBAC9D,OAAO,EAAE;oBACR,OAAO,EAAE;wBACR,MAAM,EAAE,KAAK;wBACb,GAAG,EAAE,UAAU;qBACf;oBACD,MAAM,EAAE;wBACP,WAAW,EAAE;4BACZ;gCACC,IAAI,EAAE,cAAc;gCACpB,UAAU,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE;6BACnC;yBACD;qBACD;iBACD;aACD;YACD;gBACC,IAAI,EAAE,YAAY;gBAClB,KAAK,EAAE,WAAW;gBAClB,MAAM,EAAE,qBAAqB;gBAC7B,WAAW,EAAE,2CAA2C;gBACxD,OAAO,EAAE;oBACR,OAAO,EAAE;wBACR,MAAM,EAAE,KAAK;wBACb,GAAG,EAAE,0CAA0C;qBAC/C;iBACD;aACD;SACD;QACD,OAAO,EAAE,QAAQ;KACjB;IACD;QACC,WAAW,EAAE,mBAAmB;QAChC,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,EAAE,iBAAiB,EAAE,YAAY,EAAE;QAChD,cAAc,EAAE,EAAE,IAAI,EAAE,uBAAuB,EAAE;QACjD,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,IAAI;QACd,WAAW,EACV,uIAAuI;KACxI;CACD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { INodeProperties } from 'n8n-workflow';
2
+ export declare const messageGetDescription: INodeProperties[];
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.messageGetDescription = void 0;
4
+ const showOnlyForMessageGet = {
5
+ operation: ['get'],
6
+ resource: ['message'],
7
+ };
8
+ exports.messageGetDescription = [
9
+ {
10
+ displayName: 'Message ID',
11
+ name: 'messageId',
12
+ type: 'string',
13
+ displayOptions: { show: showOnlyForMessageGet },
14
+ default: '',
15
+ required: true,
16
+ description: 'The ID returned by a previous Send operation',
17
+ },
18
+ ];
19
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.js","sourceRoot":"","sources":["../../../../../nodes/SimGate/resources/message/get.ts"],"names":[],"mappings":";;;AAEA,MAAM,qBAAqB,GAAG;IAC7B,SAAS,EAAE,CAAC,KAAK,CAAC;IAClB,QAAQ,EAAE,CAAC,SAAS,CAAC;CACrB,CAAC;AAEW,QAAA,qBAAqB,GAAsB;IACvD;QACC,WAAW,EAAE,YAAY;QACzB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,QAAQ;QACd,cAAc,EAAE,EAAE,IAAI,EAAE,qBAAqB,EAAE;QAC/C,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,8CAA8C;KAC3D;CACD,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { INodeProperties } from 'n8n-workflow';
2
+ export declare const messageDescription: INodeProperties[];
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.messageDescription = void 0;
4
+ const get_1 = require("./get");
5
+ const send_1 = require("./send");
6
+ const showOnlyForMessages = {
7
+ resource: ['message'],
8
+ };
9
+ exports.messageDescription = [
10
+ {
11
+ displayName: 'Operation',
12
+ name: 'operation',
13
+ type: 'options',
14
+ noDataExpression: true,
15
+ displayOptions: { show: showOnlyForMessages },
16
+ options: [
17
+ {
18
+ name: 'Get',
19
+ value: 'get',
20
+ action: 'Get a message',
21
+ description: 'Retrieve the delivery status of a sent message',
22
+ routing: {
23
+ request: {
24
+ method: 'GET',
25
+ url: '=/messages/{{$parameter.messageId}}',
26
+ },
27
+ },
28
+ },
29
+ {
30
+ name: 'Send',
31
+ value: 'send',
32
+ action: 'Send an SMS',
33
+ description: 'Send an SMS from one of your phones',
34
+ routing: {
35
+ request: {
36
+ method: 'POST',
37
+ url: '/sms/send',
38
+ },
39
+ },
40
+ },
41
+ ],
42
+ default: 'send',
43
+ },
44
+ ...get_1.messageGetDescription,
45
+ ...send_1.messageSendDescription,
46
+ ];
47
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../nodes/SimGate/resources/message/index.ts"],"names":[],"mappings":";;;AACA,+BAA8C;AAC9C,iCAAgD;AAEhD,MAAM,mBAAmB,GAAG;IAC3B,QAAQ,EAAE,CAAC,SAAS,CAAC;CACrB,CAAC;AAEW,QAAA,kBAAkB,GAAsB;IACpD;QACC,WAAW,EAAE,WAAW;QACxB,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,SAAS;QACf,gBAAgB,EAAE,IAAI;QACtB,cAAc,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE;QAC7C,OAAO,EAAE;YACR;gBACC,IAAI,EAAE,KAAK;gBACX,KAAK,EAAE,KAAK;gBACZ,MAAM,EAAE,eAAe;gBACvB,WAAW,EAAE,gDAAgD;gBAC7D,OAAO,EAAE;oBACR,OAAO,EAAE;wBACR,MAAM,EAAE,KAAK;wBACb,GAAG,EAAE,qCAAqC;qBAC1C;iBACD;aACD;YACD;gBACC,IAAI,EAAE,MAAM;gBACZ,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,aAAa;gBACrB,WAAW,EAAE,qCAAqC;gBAClD,OAAO,EAAE;oBACR,OAAO,EAAE;wBACR,MAAM,EAAE,MAAM;wBACd,GAAG,EAAE,WAAW;qBAChB;iBACD;aACD;SACD;QACD,OAAO,EAAE,MAAM;KACf;IACD,GAAG,2BAAqB;IACxB,GAAG,6BAAsB;CACzB,CAAC"}
@@ -0,0 +1,2 @@
1
+ import type { INodeProperties } from 'n8n-workflow';
2
+ export declare const messageSendDescription: INodeProperties[];
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.messageSendDescription = void 0;
4
+ const showOnlyForMessageSend = {
5
+ operation: ['send'],
6
+ resource: ['message'],
7
+ };
8
+ exports.messageSendDescription = [
9
+ {
10
+ displayName: 'Device Name or ID',
11
+ name: 'deviceId',
12
+ type: 'options',
13
+ typeOptions: { loadOptionsMethod: 'getDevices' },
14
+ displayOptions: { show: showOnlyForMessageSend },
15
+ default: '',
16
+ required: true,
17
+ description: 'The phone that sends the SMS. Choose from the list, or specify an ID using an <a href="https://docs.n8n.io/code/expressions/">expression</a>.',
18
+ routing: { send: { type: 'body', property: 'deviceId' } },
19
+ },
20
+ {
21
+ displayName: 'To',
22
+ name: 'phoneNumber',
23
+ type: 'string',
24
+ displayOptions: { show: showOnlyForMessageSend },
25
+ default: '',
26
+ required: true,
27
+ placeholder: '+391234567890',
28
+ description: 'Recipient phone number in international format',
29
+ routing: { send: { type: 'body', property: 'phoneNumber' } },
30
+ },
31
+ {
32
+ displayName: 'Message',
33
+ name: 'message',
34
+ type: 'string',
35
+ typeOptions: { rows: 4 },
36
+ displayOptions: { show: showOnlyForMessageSend },
37
+ default: '',
38
+ required: true,
39
+ description: 'Text of the SMS to send',
40
+ routing: { send: { type: 'body', property: 'message' } },
41
+ },
42
+ {
43
+ displayName: 'Test Mode',
44
+ name: 'test',
45
+ type: 'boolean',
46
+ displayOptions: { show: showOnlyForMessageSend },
47
+ default: false,
48
+ description: 'Whether to count this message against your test quota instead of your SMS quota',
49
+ routing: { send: { type: 'body', property: 'test' } },
50
+ },
51
+ ];
52
+ //# sourceMappingURL=send.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../../../../nodes/SimGate/resources/message/send.ts"],"names":[],"mappings":";;;AAEA,MAAM,sBAAsB,GAAG;IAC9B,SAAS,EAAE,CAAC,MAAM,CAAC;IACnB,QAAQ,EAAE,CAAC,SAAS,CAAC;CACrB,CAAC;AAEW,QAAA,sBAAsB,GAAsB;IACxD;QACC,WAAW,EAAE,mBAAmB;QAChC,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,EAAE,iBAAiB,EAAE,YAAY,EAAE;QAChD,cAAc,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE;QAChD,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,IAAI;QACd,WAAW,EACV,+IAA+I;QAChJ,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE;KACzD;IACD;QACC,WAAW,EAAE,IAAI;QACjB,IAAI,EAAE,aAAa;QACnB,IAAI,EAAE,QAAQ;QACd,cAAc,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE;QAChD,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,eAAe;QAC5B,WAAW,EAAE,gDAAgD;QAC7D,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,EAAE;KAC5D;IACD;QACC,WAAW,EAAE,SAAS;QACtB,IAAI,EAAE,SAAS;QACf,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;QACxB,cAAc,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE;QAChD,OAAO,EAAE,EAAE;QACX,QAAQ,EAAE,IAAI;QACd,WAAW,EAAE,yBAAyB;QACtC,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,EAAE;KACxD;IACD;QACC,WAAW,EAAE,WAAW;QACxB,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,SAAS;QACf,cAAc,EAAE,EAAE,IAAI,EAAE,sBAAsB,EAAE;QAChD,OAAO,EAAE,KAAK;QACd,WAAW,EACV,iFAAiF;QAClF,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE;KACrD;CACD,CAAC"}
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "n8n-nodes-simgate",
3
+ "version": "0.1.0",
4
+ "description": "Send and receive SMS through your own phone with SimGate",
5
+ "license": "MIT",
6
+ "homepage": "https://simgate.app",
7
+ "keywords": [
8
+ "n8n-community-node-package",
9
+ "n8n",
10
+ "simgate",
11
+ "sms",
12
+ "sms-gateway",
13
+ "android"
14
+ ],
15
+ "author": {
16
+ "name": "Nikola",
17
+ "email": "nikola@viametrics.com"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/simgate-dev/n8n-nodes-simgate.git"
22
+ },
23
+ "engines": {
24
+ "node": ">=22.22"
25
+ },
26
+ "scripts": {
27
+ "build": "n8n-node build",
28
+ "build:watch": "tsc --watch",
29
+ "dev": "n8n-node dev",
30
+ "lint": "n8n-node lint",
31
+ "lint:fix": "n8n-node lint --fix",
32
+ "release": "n8n-node release",
33
+ "prepublishOnly": "n8n-node prerelease"
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "!dist/tsconfig.tsbuildinfo"
38
+ ],
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "n8n": {
43
+ "n8nNodesApiVersion": 1,
44
+ "strict": true,
45
+ "credentials": [
46
+ "dist/credentials/SimGateApi.credentials.js"
47
+ ],
48
+ "nodes": [
49
+ "dist/nodes/SimGate/SimGate.node.js",
50
+ "dist/nodes/SimGate/SimGateTrigger.node.js"
51
+ ]
52
+ },
53
+ "devDependencies": {
54
+ "@n8n/node-cli": "^0.44.4",
55
+ "eslint": "9.32.0",
56
+ "prettier": "3.6.2",
57
+ "release-it": "^19.0.4",
58
+ "typescript": "5.9.2"
59
+ },
60
+ "peerDependencies": {
61
+ "n8n-workflow": "*"
62
+ }
63
+ }
package/package.json ADDED
@@ -0,0 +1,63 @@
1
+ {
2
+ "name": "n8n-nodes-simgate",
3
+ "version": "0.1.0",
4
+ "description": "Send and receive SMS through your own phone with SimGate",
5
+ "license": "MIT",
6
+ "homepage": "https://simgate.app",
7
+ "keywords": [
8
+ "n8n-community-node-package",
9
+ "n8n",
10
+ "simgate",
11
+ "sms",
12
+ "sms-gateway",
13
+ "android"
14
+ ],
15
+ "author": {
16
+ "name": "Nikola",
17
+ "email": "nikola@viametrics.com"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/simgate-dev/n8n-nodes-simgate.git"
22
+ },
23
+ "engines": {
24
+ "node": ">=22.22"
25
+ },
26
+ "scripts": {
27
+ "build": "n8n-node build",
28
+ "build:watch": "tsc --watch",
29
+ "dev": "n8n-node dev",
30
+ "lint": "n8n-node lint",
31
+ "lint:fix": "n8n-node lint --fix",
32
+ "release": "n8n-node release",
33
+ "prepublishOnly": "n8n-node prerelease"
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "!dist/tsconfig.tsbuildinfo"
38
+ ],
39
+ "publishConfig": {
40
+ "access": "public"
41
+ },
42
+ "n8n": {
43
+ "n8nNodesApiVersion": 1,
44
+ "strict": true,
45
+ "credentials": [
46
+ "dist/credentials/SimGateApi.credentials.js"
47
+ ],
48
+ "nodes": [
49
+ "dist/nodes/SimGate/SimGate.node.js",
50
+ "dist/nodes/SimGate/SimGateTrigger.node.js"
51
+ ]
52
+ },
53
+ "devDependencies": {
54
+ "@n8n/node-cli": "^0.44.4",
55
+ "eslint": "9.32.0",
56
+ "prettier": "3.6.2",
57
+ "release-it": "^19.0.4",
58
+ "typescript": "5.9.2"
59
+ },
60
+ "peerDependencies": {
61
+ "n8n-workflow": "*"
62
+ }
63
+ }