n8n-nodes-nashir 0.2.2 → 0.3.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.
package/README.md CHANGED
@@ -1,6 +1,8 @@
1
1
  # n8n-nodes-nashir
2
2
 
3
- n8n community nodes for [nashir.ai](https://nashir.ai) — publish to Facebook, Instagram, TikTok, LinkedIn, YouTube, WhatsApp and Telegram.
3
+ n8n community nodes for [nashir.ai](https://nashir.ai) — publish to Facebook, Instagram, TikTok, LinkedIn, YouTube, WhatsApp and Telegram, and manage AI-driven conversations.
4
+
5
+ > Requires nashir.ai API v0.3.0+ for conversation management operations.
4
6
 
5
7
  ## Installation
6
8
 
@@ -12,34 +14,97 @@ n8n-nodes-nashir
12
14
 
13
15
  ## Nodes
14
16
 
15
- - **Nashir Facebook** — Publish posts and reels
16
- - **Nashir Instagram** — Publish feed posts, reels, and stories
17
- - **Nashir TikTok** Publish video and photo posts (Direct Post API)
18
- - **Nashir LinkedIn** — Publish posts and articles
19
- - **Nashir YouTube** Upload and schedule videos
20
- - **Nashir WhatsApp** Send messages via WhatsApp Business
21
- - **Nashir Telegram** Send messages and media to Telegram channels/groups
17
+ ### Nashir WhatsApp
18
+
19
+ | Operation | Description |
20
+ |-----------|-------------|
21
+ | Send Message | Send text, template, or media message to a phone number |
22
+ | Reply to Message | Reply to a specific message by ID |
23
+ | Get Messages | Retrieve recent WhatsApp messages |
24
+ | Mark as Read | Mark a message as read |
25
+ | **Get Conversation History** | Fetch the last N messages for a phone number |
26
+ | **Get AI Status** | Check if AI auto-reply is active or paused for a conversation |
27
+ | **Set AI Status** | Pause or resume AI auto-reply for a conversation |
28
+ | **Save Message to Inbox** | Store an external message in nashir.ai (ingest) |
29
+ | **Get Contact** | Fetch contact details by phone number |
30
+
31
+ ### Nashir Contact
32
+
33
+ | Operation | Description |
34
+ |-----------|-------------|
35
+ | Get Contact | Fetch contact details by phone number |
36
+ | **Update Contact Tags** | Add tags to a contact (idempotent, comma-separated) |
37
+
38
+ ### Nashir Facebook
39
+ Publish posts and reels.
40
+
41
+ ### Nashir Instagram
42
+ Publish feed posts, reels, and stories.
43
+
44
+ ### Nashir TikTok
45
+ Publish video and photo posts (Direct Post API).
46
+
47
+ ### Nashir LinkedIn
48
+ Publish posts and articles.
49
+
50
+ ### Nashir YouTube
51
+ Upload and schedule videos.
52
+
53
+ ### Nashir Telegram
54
+ Send messages and media to Telegram channels/groups.
22
55
 
23
56
  ## Credentials
24
57
 
25
58
  Create a **Nashir API** credential with your API key from [nashir.ai/settings](https://nashir.ai/settings).
26
59
 
60
+ The credential supports an optional **Base URL** field (default: `https://nashir.ai`) — override this for self-hosted or staging environments.
61
+
62
+ ## Example: Conversation History Lookup
63
+
64
+ This workflow fetches the last 10 messages for an inbound WhatsApp number and passes them to an AI node:
65
+
66
+ 1. **Webhook** — receives a WhatsApp message (phone in `body.phone`)
67
+ 2. **Nashir WhatsApp** → *Get Conversation History*
68
+ - Phone: `={{ $json.body.phone }}`
69
+ - Limit: `10`
70
+ 3. **AI Agent** — receives the message array as context
71
+ 4. **Nashir WhatsApp** → *Set AI Status* (pause while agent replies)
72
+ - Phone: `={{ $json.body.phone }}`
73
+ - Action: `pause`
74
+ - Reason: `Human-in-the-loop`
75
+
27
76
  ---
28
77
 
29
78
  ## Changelog
30
79
 
80
+ ### 0.3.0 — Apr 2026
81
+
82
+ **New WhatsApp operations**
83
+
84
+ - **Get Conversation History** — fetch last N messages for a phone (`GET /api/v1/conversations/:phone/messages?limit=N`)
85
+ - **Get AI Status** — check if AI is paused/active for a conversation (`GET /api/v1/conversations/:phone/ai-status`)
86
+ - **Set AI Status** — pause or resume AI auto-reply with optional reason (`POST /api/v1/conversations/:phone/ai-toggle`)
87
+ - **Save Message to Inbox** — store external messages in nashir.ai with role, media type, and `is_from_ai` flag (`POST /api/v1/messages/ingest`)
88
+ - **Get Contact** — fetch contact details by phone number (`GET /api/v1/contacts/:phone`)
89
+
90
+ **New Contact node**
91
+
92
+ - **Update Contact Tags** — add tags to a contact, idempotent, comma-separated input (`POST /api/v1/contacts/:phone/tags`)
93
+
94
+ **Improvements**
95
+
96
+ - Configurable Base URL in credentials (default `https://nashir.ai`, override for dev/staging)
97
+ - Friendly error messages: 401/403 → clear auth error, 404 → context-aware not-found message
98
+ - Full TypeScript types for all response shapes
99
+
31
100
  ### 0.2.2 — Apr 2026
32
101
 
33
102
  **TikTok node — full Direct Post API compliance update**
34
103
 
35
104
  - `privacy_level` now required field with 3 options: Public to Everyone, Friends Only, Only Me
36
- - Interactions renamed to "Allow Comments / Allow Duet / Allow Stitch" (all default `false` per TikTok guidelines) — mapped to `disable_comment / disable_duet / disable_stitch` in the API
105
+ - Interactions renamed to "Allow Comments / Allow Duet / Allow Stitch" (all default `false` per TikTok guidelines)
37
106
  - `brand_content_toggle` renamed to **Content Disclosure** in UI
38
- - `brand_organic_toggle` (Your Brand) and `brand_branded_content_toggle` (Branded Content / Paid Partnership) shown conditionally when Content Disclosure is enabled
39
107
  - Removed `FOLLOWER_OF_CREATOR` privacy option (not supported by Direct Post API)
40
- - Node description updated: "Privacy Level is required. Interactions are off by default per TikTok guidelines. Content Disclosure must have at least one option selected if enabled."
41
- - All fields map directly to nashir.ai `tiktok_options` object
42
- - Prepared for TikTok Direct Post API audit approval
43
108
 
44
109
  ### 0.2.1 — Mar 2026
45
110
 
@@ -0,0 +1,6 @@
1
+ import { IExecuteFunctions, INodeExecutionData, INodeType, INodeTypeDescription } from 'n8n-workflow';
2
+ export declare class NashirContact implements INodeType {
3
+ description: INodeTypeDescription;
4
+ execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]>;
5
+ }
6
+ //# sourceMappingURL=NashirContact.node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NashirContact.node.d.ts","sourceRoot":"","sources":["../../../nodes/NashirContact/NashirContact.node.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,iBAAiB,EACjB,kBAAkB,EAClB,SAAS,EACT,oBAAoB,EACpB,MAAM,cAAc,CAAC;AAItB,qBAAa,aAAc,YAAW,SAAS;IAC9C,WAAW,EAAE,oBAAoB,CAiD/B;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CAwCvE"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NashirContact = void 0;
4
+ const api_1 = require("../shared/api");
5
+ class NashirContact {
6
+ constructor() {
7
+ this.description = {
8
+ displayName: 'Nashir Contact',
9
+ name: 'nashirContact',
10
+ icon: 'file:nashir.svg',
11
+ group: ['transform'],
12
+ version: 1,
13
+ subtitle: '={{$parameter["operation"]}}',
14
+ description: 'Manage contacts in nashir.ai',
15
+ defaults: { name: 'Nashir Contact', color: '#6366f1' },
16
+ inputs: ['main'],
17
+ outputs: ['main'],
18
+ credentials: [{ name: 'nashirApi', required: true }],
19
+ properties: [
20
+ {
21
+ displayName: 'Operation',
22
+ name: 'operation',
23
+ type: 'options',
24
+ noDataExpression: true,
25
+ options: [
26
+ { name: 'Get Contact', value: 'getContact', action: 'Get contact details' },
27
+ { name: 'Update Contact Tags', value: 'updateTags', action: 'Add tags to a contact' },
28
+ ],
29
+ default: 'getContact',
30
+ },
31
+ // ── Shared: phone ────────────────────────────────────────────────────────
32
+ {
33
+ displayName: 'Phone Number',
34
+ name: 'phone',
35
+ type: 'string',
36
+ default: '',
37
+ required: true,
38
+ placeholder: '+1234567890',
39
+ description: 'Phone number of the contact in international format',
40
+ displayOptions: { show: { operation: ['getContact', 'updateTags'] } },
41
+ },
42
+ // ── Update Tags fields ───────────────────────────────────────────────────
43
+ {
44
+ displayName: 'Tags',
45
+ name: 'tags',
46
+ type: 'string',
47
+ default: '',
48
+ required: true,
49
+ placeholder: 'vip, arabic, lead',
50
+ description: 'Comma-separated list of tags to apply to the contact (idempotent)',
51
+ displayOptions: { show: { operation: ['updateTags'] } },
52
+ },
53
+ ],
54
+ };
55
+ }
56
+ async execute() {
57
+ const items = this.getInputData();
58
+ const returnData = [];
59
+ for (let i = 0; i < items.length; i++) {
60
+ try {
61
+ const operation = this.getNodeParameter('operation', i);
62
+ let responseData;
63
+ if (operation === 'getContact') {
64
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i));
65
+ responseData = await (0, api_1.nashirApiRequest)(this, 'GET', `/contacts/${phone}`);
66
+ }
67
+ else if (operation === 'updateTags') {
68
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i));
69
+ const tagsRaw = this.getNodeParameter('tags', i);
70
+ const tags = tagsRaw
71
+ .split(',')
72
+ .map((t) => t.trim())
73
+ .filter(Boolean);
74
+ responseData = await (0, api_1.nashirApiRequest)(this, 'POST', `/contacts/${phone}/tags`, { tags });
75
+ }
76
+ else {
77
+ throw new Error(`Unknown operation: ${operation}`);
78
+ }
79
+ const rows = Array.isArray(responseData) ? responseData : [responseData];
80
+ returnData.push(...rows.map((d) => ({ json: d, pairedItem: i })));
81
+ }
82
+ catch (error) {
83
+ if (this.continueOnFail()) {
84
+ returnData.push({ json: { error: error.message }, pairedItem: i });
85
+ continue;
86
+ }
87
+ throw error;
88
+ }
89
+ }
90
+ return [returnData];
91
+ }
92
+ }
93
+ exports.NashirContact = NashirContact;
94
+ //# sourceMappingURL=NashirContact.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"NashirContact.node.js","sourceRoot":"","sources":["../../../nodes/NashirContact/NashirContact.node.ts"],"names":[],"mappings":";;;AAQA,uCAAiD;AAEjD,MAAa,aAAa;IAA1B;QACC,gBAAW,GAAyB;YACnC,WAAW,EAAE,gBAAgB;YAC7B,IAAI,EAAE,eAAe;YACrB,IAAI,EAAE,iBAAiB;YACvB,KAAK,EAAE,CAAC,WAAW,CAAC;YACpB,OAAO,EAAE,CAAC;YACV,QAAQ,EAAE,8BAA8B;YACxC,WAAW,EAAE,8BAA8B;YAC3C,QAAQ,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,SAAS,EAAE;YACtD,MAAM,EAAE,CAAC,MAAM,CAAC;YAChB,OAAO,EAAE,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACpD,UAAU,EAAE;gBACX;oBACC,WAAW,EAAE,WAAW;oBACxB,IAAI,EAAE,WAAW;oBACjB,IAAI,EAAE,SAAS;oBACf,gBAAgB,EAAE,IAAI;oBACtB,OAAO,EAAE;wBACR,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,qBAAqB,EAAE;wBAC3E,EAAE,IAAI,EAAE,qBAAqB,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,uBAAuB,EAAE;qBACrF;oBACD,OAAO,EAAE,YAAY;iBACrB;gBAED,4EAA4E;gBAC5E;oBACC,WAAW,EAAE,cAAc;oBAC3B,IAAI,EAAE,OAAO;oBACb,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,EAAE;oBACX,QAAQ,EAAE,IAAI;oBACd,WAAW,EAAE,aAAa;oBAC1B,WAAW,EAAE,qDAAqD;oBAClE,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC,EAAE,EAAE;iBACrE;gBAED,4EAA4E;gBAC5E;oBACC,WAAW,EAAE,MAAM;oBACnB,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,EAAE;oBACX,QAAQ,EAAE,IAAI;oBACd,WAAW,EAAE,mBAAmB;oBAChC,WAAW,EAAE,mEAAmE;oBAChF,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,YAAY,CAAC,EAAE,EAAE;iBACvD;aACD;SACD,CAAC;IA0CH,CAAC;IAxCA,KAAK,CAAC,OAAO;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,MAAM,UAAU,GAAyB,EAAE,CAAC;QAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC;gBACJ,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAW,CAAC;gBAClE,IAAI,YAAyC,CAAC;gBAE9C,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;oBAChC,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAW,CAAC,CAAC;oBAC9E,YAAY,GAAG,MAAM,IAAA,sBAAgB,EAAC,IAAI,EAAE,KAAK,EAAE,aAAa,KAAK,EAAE,CAAC,CAAC;gBAE1E,CAAC;qBAAM,IAAI,SAAS,KAAK,YAAY,EAAE,CAAC;oBACvC,MAAM,KAAK,GAAG,kBAAkB,CAAC,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAW,CAAC,CAAC;oBAC9E,MAAM,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,CAAC,CAAW,CAAC;oBAC3D,MAAM,IAAI,GAAG,OAAO;yBAClB,KAAK,CAAC,GAAG,CAAC;yBACV,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;yBACpB,MAAM,CAAC,OAAO,CAAC,CAAC;oBAClB,YAAY,GAAG,MAAM,IAAA,sBAAgB,EAAC,IAAI,EAAE,MAAM,EAAE,aAAa,KAAK,OAAO,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;gBAE1F,CAAC;qBAAM,CAAC;oBACP,MAAM,IAAI,KAAK,CAAC,sBAAsB,SAAS,EAAE,CAAC,CAAC;gBACpD,CAAC;gBAED,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;gBACzE,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YAEnE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;oBAC3B,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,EAAG,KAAe,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;oBAC9E,SAAS;gBACV,CAAC;gBACD,MAAM,KAAK,CAAC;YACb,CAAC;QACF,CAAC;QAED,OAAO,CAAC,UAAU,CAAC,CAAC;IACrB,CAAC;CACD;AA5FD,sCA4FC"}
@@ -0,0 +1,5 @@
1
+ <svg viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="60" height="60" rx="12" fill="#7C3AED"/>
3
+ <path d="M8 30L50 10L37 52L28 33L8 30Z" fill="white"/>
4
+ <path d="M28 33L37 24" stroke="#7C3AED" stroke-width="3" stroke-linecap="round"/>
5
+ </svg>
@@ -1 +1 @@
1
- {"version":3,"file":"NashirWhatsApp.node.d.ts","sourceRoot":"","sources":["../../../nodes/NashirWhatsApp/NashirWhatsApp.node.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,SAAS,EACT,oBAAoB,EACpB,MAAM,cAAc,CAAC;AAItB,qBAAa,cAAe,YAAW,SAAS;IAC/C,WAAW,EAAE,oBAAoB,CAwG/B;IAEF,OAAO;;uCAE4B,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;;MAIxF;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CAsDvE"}
1
+ {"version":3,"file":"NashirWhatsApp.node.d.ts","sourceRoot":"","sources":["../../../nodes/NashirWhatsApp/NashirWhatsApp.node.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,iBAAiB,EACjB,qBAAqB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,SAAS,EACT,oBAAoB,EACpB,MAAM,cAAc,CAAC;AAItB,qBAAa,cAAe,YAAW,SAAS;IAC/C,WAAW,EAAE,oBAAoB,CA0O/B;IAEF,OAAO;;uCAE4B,qBAAqB,GAAG,OAAO,CAAC,oBAAoB,EAAE,CAAC;;MAIxF;IAEI,OAAO,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC;CAwGvE"}
@@ -23,10 +23,15 @@ class NashirWhatsApp {
23
23
  type: 'options',
24
24
  noDataExpression: true,
25
25
  options: [
26
+ { name: 'Get AI Status', value: 'getAiStatus', action: 'Get AI status for a conversation' },
27
+ { name: 'Get Contact', value: 'getContact', action: 'Get contact details' },
28
+ { name: 'Get Conversation History', value: 'getConversationHistory', action: 'Get conversation history for a phone number' },
26
29
  { name: 'Get Messages', value: 'getMessages', action: 'Get messages' },
27
30
  { name: 'Mark as Read', value: 'markRead', action: 'Mark message as read' },
28
31
  { name: 'Reply to Message', value: 'replyMessage', action: 'Reply to a message' },
32
+ { name: 'Save Message to Inbox', value: 'saveMessage', action: 'Save a message to the inbox' },
29
33
  { name: 'Send Message', value: 'sendMessage', action: 'Send a message' },
34
+ { name: 'Set AI Status', value: 'setAiStatus', action: 'Pause or resume AI auto-reply' },
30
35
  ],
31
36
  default: 'sendMessage',
32
37
  },
@@ -100,6 +105,121 @@ class NashirWhatsApp {
100
105
  required: true,
101
106
  displayOptions: { show: { operation: ['replyMessage'] } },
102
107
  },
108
+ // ── Conversation History fields ──────────────────────────────────────────
109
+ {
110
+ displayName: 'Phone Number',
111
+ name: 'phone',
112
+ type: 'string',
113
+ default: '',
114
+ required: true,
115
+ placeholder: '+1234567890',
116
+ description: 'Phone number in international format',
117
+ displayOptions: {
118
+ show: {
119
+ operation: [
120
+ 'getConversationHistory',
121
+ 'getAiStatus',
122
+ 'setAiStatus',
123
+ 'getContact',
124
+ ],
125
+ },
126
+ },
127
+ },
128
+ {
129
+ displayName: 'Limit',
130
+ name: 'limit',
131
+ type: 'number',
132
+ default: 20,
133
+ description: 'Number of messages to return (most recent first)',
134
+ displayOptions: { show: { operation: ['getConversationHistory'] } },
135
+ },
136
+ // ── Set AI Status fields ────────────────────────────────────────────────
137
+ {
138
+ displayName: 'Action',
139
+ name: 'aiAction',
140
+ type: 'options',
141
+ options: [
142
+ { name: 'Pause', value: 'pause' },
143
+ { name: 'Resume', value: 'resume' },
144
+ ],
145
+ default: 'pause',
146
+ required: true,
147
+ description: 'Pause or resume AI auto-reply for this conversation',
148
+ displayOptions: { show: { operation: ['setAiStatus'] } },
149
+ },
150
+ {
151
+ displayName: 'Reason',
152
+ name: 'reason',
153
+ type: 'string',
154
+ default: '',
155
+ description: 'Optional reason for pausing (e.g. "Human takeover")',
156
+ displayOptions: { show: { operation: ['setAiStatus'] } },
157
+ },
158
+ // ── Save Message to Inbox fields ────────────────────────────────────────
159
+ {
160
+ displayName: 'Phone Number',
161
+ name: 'ingestPhone',
162
+ type: 'string',
163
+ default: '',
164
+ required: true,
165
+ placeholder: '+1234567890',
166
+ description: 'Phone number of the contact',
167
+ displayOptions: { show: { operation: ['saveMessage'] } },
168
+ },
169
+ {
170
+ displayName: 'Role',
171
+ name: 'role',
172
+ type: 'options',
173
+ options: [
174
+ { name: 'User (Inbound)', value: 'user' },
175
+ { name: 'Assistant (Outbound)', value: 'assistant' },
176
+ ],
177
+ default: 'user',
178
+ required: true,
179
+ description: 'Whether this message is from the user or the AI assistant',
180
+ displayOptions: { show: { operation: ['saveMessage'] } },
181
+ },
182
+ {
183
+ displayName: 'Message Content',
184
+ name: 'messageContent',
185
+ type: 'string',
186
+ typeOptions: { rows: 3 },
187
+ default: '',
188
+ required: true,
189
+ description: 'Text content of the message',
190
+ displayOptions: { show: { operation: ['saveMessage'] } },
191
+ },
192
+ {
193
+ displayName: 'Media Type',
194
+ name: 'mediaType',
195
+ type: 'options',
196
+ options: [
197
+ { name: 'None', value: '' },
198
+ { name: 'Image', value: 'image' },
199
+ { name: 'Video', value: 'video' },
200
+ { name: 'Audio', value: 'audio' },
201
+ { name: 'Document', value: 'document' },
202
+ ],
203
+ default: '',
204
+ description: 'Optional media type if the message contains media',
205
+ displayOptions: { show: { operation: ['saveMessage'] } },
206
+ },
207
+ {
208
+ displayName: 'Media URL',
209
+ name: 'mediaUrl',
210
+ type: 'string',
211
+ default: '',
212
+ description: 'URL of the media file (required if Media Type is set)',
213
+ displayOptions: { show: { operation: ['saveMessage'] } },
214
+ },
215
+ {
216
+ displayName: 'Is From AI',
217
+ name: 'isFromAi',
218
+ type: 'boolean',
219
+ default: true,
220
+ description: 'Whether this message was generated by the AI',
221
+ displayOptions: { show: { operation: ['saveMessage'] } },
222
+ },
103
223
  ],
104
224
  };
105
225
  this.methods = {
@@ -142,13 +262,54 @@ class NashirWhatsApp {
142
262
  const accountId = this.getNodeParameter('account', i);
143
263
  const messageId = this.getNodeParameter('messageId', i);
144
264
  const replyText = this.getNodeParameter('replyText', i);
145
- responseData = await (0, api_1.nashirApiRequest)(this, 'POST', `/messages/${messageId}/reply`, { message: replyText, account_id: accountId });
265
+ responseData = await (0, api_1.nashirApiRequest)(this, 'POST', `/messages/${messageId}/reply`, {
266
+ message: replyText,
267
+ account_id: accountId,
268
+ });
146
269
  }
147
- else {
148
- // markRead
270
+ else if (operation === 'markRead') {
149
271
  const messageId = this.getNodeParameter('messageId', i);
150
272
  responseData = await (0, api_1.nashirApiRequest)(this, 'PATCH', `/messages/${messageId}/read`);
151
273
  }
274
+ else if (operation === 'getConversationHistory') {
275
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i));
276
+ const limit = this.getNodeParameter('limit', i, 20);
277
+ responseData = await (0, api_1.nashirApiRequest)(this, 'GET', `/conversations/${phone}/messages`, undefined, { limit });
278
+ }
279
+ else if (operation === 'getAiStatus') {
280
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i));
281
+ responseData = await (0, api_1.nashirApiRequest)(this, 'GET', `/conversations/${phone}/ai-status`);
282
+ }
283
+ else if (operation === 'setAiStatus') {
284
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i));
285
+ const action = this.getNodeParameter('aiAction', i);
286
+ const reason = this.getNodeParameter('reason', i, '');
287
+ const body = { action };
288
+ if (reason)
289
+ body.reason = reason;
290
+ responseData = await (0, api_1.nashirApiRequest)(this, 'POST', `/conversations/${phone}/ai-toggle`, body);
291
+ }
292
+ else if (operation === 'saveMessage') {
293
+ const phone = this.getNodeParameter('ingestPhone', i);
294
+ const role = this.getNodeParameter('role', i);
295
+ const content = this.getNodeParameter('messageContent', i);
296
+ const mediaType = this.getNodeParameter('mediaType', i, '');
297
+ const mediaUrl = this.getNodeParameter('mediaUrl', i, '');
298
+ const isFromAi = this.getNodeParameter('isFromAi', i, true);
299
+ const body = { phone, role, content, is_from_ai: isFromAi };
300
+ if (mediaType)
301
+ body.media_type = mediaType;
302
+ if (mediaUrl)
303
+ body.media_url = mediaUrl;
304
+ responseData = await (0, api_1.nashirApiRequest)(this, 'POST', '/messages/ingest', body);
305
+ }
306
+ else if (operation === 'getContact') {
307
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i));
308
+ responseData = await (0, api_1.nashirApiRequest)(this, 'GET', `/contacts/${phone}`);
309
+ }
310
+ else {
311
+ throw new Error(`Unknown operation: ${operation}`);
312
+ }
152
313
  const rows = Array.isArray(responseData) ? responseData : [responseData];
153
314
  returnData.push(...rows.map((d) => ({ json: d, pairedItem: i })));
154
315
  }
@@ -1 +1 @@
1
- {"version":3,"file":"NashirWhatsApp.node.js","sourceRoot":"","sources":["../../../nodes/NashirWhatsApp/NashirWhatsApp.node.ts"],"names":[],"mappings":";;;AAUA,uCAAmF;AAEnF,MAAa,cAAc;IAA3B;QACC,gBAAW,GAAyB;YACnC,WAAW,EAAE,iBAAiB;YAC9B,IAAI,EAAE,gBAAgB;YACtB,IAAI,EAAE,iBAAiB;YACvB,KAAK,EAAE,CAAC,WAAW,CAAC;YACpB,OAAO,EAAE,CAAC;YACV,QAAQ,EAAE,8BAA8B;YACxC,WAAW,EAAE,iDAAiD;YAC9D,QAAQ,EAAE,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,SAAS,EAAE;YACvD,MAAM,EAAE,CAAC,MAAM,CAAC;YAChB,OAAO,EAAE,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACpD,UAAU,EAAE;gBACX;oBACC,WAAW,EAAE,WAAW;oBACxB,IAAI,EAAE,WAAW;oBACjB,IAAI,EAAE,SAAS;oBACf,gBAAgB,EAAE,IAAI;oBACtB,OAAO,EAAE;wBACR,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,cAAc,EAAE;wBACtE,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,sBAAsB,EAAE;wBAC3E,EAAE,IAAI,EAAE,kBAAkB,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,oBAAoB,EAAE;wBACjF,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,gBAAgB,EAAE;qBACxE;oBACD,OAAO,EAAE,aAAa;iBACtB;gBAED,2EAA2E;gBAC3E;oBACC,WAAW,EAAE,SAAS;oBACtB,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,SAAS;oBACf,WAAW,EAAE,EAAE,iBAAiB,EAAE,sBAAsB,EAAE;oBAC1D,OAAO,EAAE,EAAE;oBACX,QAAQ,EAAE,IAAI;oBACd,WAAW,EAAE,sCAAsC;oBACnD,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,aAAa,EAAE,cAAc,CAAC,EAAE,EAAE;iBACxE;gBAED;oBACC,WAAW,EAAE,mBAAmB;oBAChC,IAAI,EAAE,IAAI;oBACV,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,EAAE;oBACX,QAAQ,EAAE,IAAI;oBACd,WAAW,EAAE,aAAa;oBAC1B,WAAW,EAAE,gDAAgD;oBAC7D,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE;iBACxD;gBAED;oBACC,WAAW,EAAE,cAAc;oBAC3B,IAAI,EAAE,aAAa;oBACnB,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE;wBACR,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;wBAC/B,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE;wBACvC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE;qBACjC;oBACD,OAAO,EAAE,MAAM;oBACf,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,aAAa,CAAC,EAAE,EAAE;iBACxD;gBAED;oBACC,WAAW,EAAE,SAAS;oBACtB,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;oBACxB,OAAO,EAAE,EAAE;oBACX,QAAQ,EAAE,IAAI;oBACd,WAAW,EAAE,sBAAsB;oBACnC,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,aAAa,CAAC,EAAE,WAAW,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,EAAE;iBAC3F;gBAED;oBACC,WAAW,EAAE,uBAAuB;oBACpC,IAAI,EAAE,oBAAoB;oBAC1B,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,MAAM;oBACf,QAAQ,EAAE,IAAI;oBACd,WAAW,EAAE,uDAAuD;oBACpE,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,aAAa,CAAC,EAAE,WAAW,EAAE,CAAC,OAAO,CAAC,EAAE,EAAE;iBAChF;gBAED,2EAA2E;gBAC3E;oBACC,WAAW,EAAE,YAAY;oBACzB,IAAI,EAAE,WAAW;oBACjB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,EAAE;oBACX,QAAQ,EAAE,IAAI;oBACd,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,cAAc,EAAE,UAAU,CAAC,EAAE,EAAE;iBACrE;gBAED;oBACC,WAAW,EAAE,YAAY;oBACzB,IAAI,EAAE,WAAW;oBACjB,IAAI,EAAE,QAAQ;oBACd,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE;oBACxB,OAAO,EAAE,EAAE;oBACX,QAAQ,EAAE,IAAI;oBACd,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,CAAC,cAAc,CAAC,EAAE,EAAE;iBACzD;aACD;SACD,CAAC;QAEF,YAAO,GAAG;YACT,WAAW,EAAE;gBACZ,KAAK,CAAC,oBAAoB;oBACzB,OAAO,IAAA,kBAAY,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;gBACvC,CAAC;aACD;SACD,CAAC;IAwDH,CAAC;IAtDA,KAAK,CAAC,OAAO;QACZ,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;QAClC,MAAM,UAAU,GAAyB,EAAE,CAAC;QAE5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC;gBACJ,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAW,CAAC;gBAClE,IAAI,YAAyC,CAAC;gBAE9C,IAAI,SAAS,KAAK,aAAa,EAAE,CAAC;oBACjC,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAW,CAAC;oBAChE,MAAM,EAAE,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC,CAAW,CAAC;oBACpD,MAAM,WAAW,GAAG,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,CAAC,CAAW,CAAC;oBAEtE,MAAM,IAAI,GAAgB;wBACzB,UAAU,EAAE,SAAS;wBACrB,EAAE;wBACF,YAAY,EAAE,WAAW;qBACzB,CAAC;oBAEF,IAAI,WAAW,KAAK,MAAM,IAAI,WAAW,KAAK,UAAU,EAAE,CAAC;wBAC1D,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAW,CAAC;oBAC9D,CAAC;yBAAM,CAAC;wBACP,MAAM,UAAU,GAAG,IAAI,CAAC,gBAAgB,CAAC,oBAAoB,EAAE,CAAC,EAAE,MAAM,CAAW,CAAC;wBACpF,IAAI,CAAC,SAAS,GAAG,MAAM,IAAA,wBAAkB,EAAC,IAAI,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC;oBAChE,CAAC;oBAED,YAAY,GAAG,MAAM,IAAA,sBAAgB,EAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC;gBACxE,CAAC;qBAAM,IAAI,SAAS,KAAK,aAAa,EAAE,CAAC;oBACxC,YAAY,GAAG,MAAM,IAAA,sBAAgB,EAAC,IAAI,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;gBACtG,CAAC;qBAAM,IAAI,SAAS,KAAK,cAAc,EAAE,CAAC;oBACzC,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAW,CAAC;oBAChE,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAW,CAAC;oBAClE,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAW,CAAC;oBAClE,YAAY,GAAG,MAAM,IAAA,sBAAgB,EAAC,IAAI,EAAE,MAAM,EAAE,aAAa,SAAS,QAAQ,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;gBACpI,CAAC;qBAAM,CAAC;oBACP,WAAW;oBACX,MAAM,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,EAAE,CAAC,CAAW,CAAC;oBAClE,YAAY,GAAG,MAAM,IAAA,sBAAgB,EAAC,IAAI,EAAE,OAAO,EAAE,aAAa,SAAS,OAAO,CAAC,CAAC;gBACrF,CAAC;gBAED,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;gBACzE,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACnE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,IAAI,IAAI,CAAC,cAAc,EAAE,EAAE,CAAC;oBAC3B,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,EAAE,KAAK,EAAG,KAAe,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;oBAC9E,SAAS;gBACV,CAAC;gBACD,MAAM,KAAK,CAAC;YACb,CAAC;QACF,CAAC;QAED,OAAO,CAAC,UAAU,CAAC,CAAC;IACrB,CAAC;CACD;AAzKD,wCAyKC"}
1
+ {"version":3,"file":"NashirWhatsApp.node.js","sourceRoot":"","sources":["../../../nodes/NashirWhatsApp/NashirWhatsApp.node.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,7 @@ type AnyContext = IExecuteFunctions | ILoadOptionsFunctions;
3
3
  /**
4
4
  * Make an authenticated request to the Nashir API.
5
5
  */
6
- export declare function nashirApiRequest(ctx: IExecuteFunctions, method: string, endpoint: string, body?: IDataObject, qs?: IDataObject): Promise<IDataObject>;
6
+ export declare function nashirApiRequest(ctx: IExecuteFunctions, method: string, endpoint: string, body?: IDataObject, qs?: IDataObject): Promise<IDataObject | IDataObject[]>;
7
7
  /**
8
8
  * Upload a binary item to /api/v1/upload and return the public URL.
9
9
  */
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../nodes/shared/api.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,EACX,iBAAiB,EAEjB,qBAAqB,EACrB,oBAAoB,EACpB,MAAM,cAAc,CAAC;AAEtB,KAAK,UAAU,GAAG,iBAAiB,GAAG,qBAAqB,CAAC;AAE5D;;GAEG;AACH,wBAAsB,gBAAgB,CACrC,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,WAAW,EAClB,EAAE,CAAC,EAAE,WAAW,GACd,OAAO,CAAC,WAAW,CAAC,CAuBtB;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACvC,GAAG,EAAE,iBAAiB,EACtB,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,MAAM,GACxB,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CACjC,GAAG,EAAE,UAAU,EACf,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAC1B,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAiCjC"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../nodes/shared/api.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,WAAW,EACX,iBAAiB,EAEjB,qBAAqB,EACrB,oBAAoB,EACpB,MAAM,cAAc,CAAC;AAEtB,KAAK,UAAU,GAAG,iBAAiB,GAAG,qBAAqB,CAAC;AAkC5D;;GAEG;AACH,wBAAsB,gBAAgB,CACrC,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,IAAI,CAAC,EAAE,WAAW,EAClB,EAAE,CAAC,EAAE,WAAW,GACd,OAAO,CAAC,WAAW,GAAG,WAAW,EAAE,CAAC,CAuBtC;AAED;;GAEG;AACH,wBAAsB,kBAAkB,CACvC,GAAG,EAAE,iBAAiB,EACtB,SAAS,EAAE,MAAM,EACjB,kBAAkB,EAAE,MAAM,GACxB,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAED;;;GAGG;AACH,wBAAsB,YAAY,CACjC,GAAG,EAAE,UAAU,EACf,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAC1B,OAAO,CAAC,oBAAoB,EAAE,CAAC,CAqCjC"}
@@ -3,6 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.nashirApiRequest = nashirApiRequest;
4
4
  exports.nashirUploadBinary = nashirUploadBinary;
5
5
  exports.loadAccounts = loadAccounts;
6
+ function throwFriendlyError(error, endpoint) {
7
+ var _a, _b;
8
+ const status = (_a = error.statusCode) !== null && _a !== void 0 ? _a : (_b = error.response) === null || _b === void 0 ? void 0 : _b.statusCode;
9
+ if (status === 401 || status === 403) {
10
+ throw new Error('Authentication failed: your Nashir API key is invalid or does not have permission for this action. ' +
11
+ 'Check your credentials at nashir.ai → Settings → API.');
12
+ }
13
+ if (status === 404) {
14
+ // Give a context-aware message based on the endpoint path
15
+ if (endpoint.includes('/contacts/')) {
16
+ throw new Error(`Contact not found. Verify the phone number is registered in nashir.ai.`);
17
+ }
18
+ if (endpoint.includes('/conversations/')) {
19
+ throw new Error(`Conversation not found for this phone number.`);
20
+ }
21
+ throw new Error(`Resource not found (404): ${endpoint}`);
22
+ }
23
+ throw error;
24
+ }
6
25
  /**
7
26
  * Make an authenticated request to the Nashir API.
8
27
  */
@@ -26,7 +45,7 @@ async function nashirApiRequest(ctx, method, endpoint, body, qs) {
26
45
  return await ctx.helpers.request(options);
27
46
  }
28
47
  catch (error) {
29
- throw error;
48
+ throwFriendlyError(error, endpoint);
30
49
  }
31
50
  }
32
51
  /**
@@ -56,11 +75,11 @@ async function nashirUploadBinary(ctx, itemIndex, binaryPropertyName) {
56
75
  json: true,
57
76
  };
58
77
  try {
59
- const response = await ctx.helpers.request(options);
78
+ const response = (await ctx.helpers.request(options));
60
79
  return response.url;
61
80
  }
62
81
  catch (error) {
63
- throw error;
82
+ throwFriendlyError(error, '/upload');
64
83
  }
65
84
  }
66
85
  /**
@@ -82,7 +101,7 @@ async function loadAccounts(ctx, platform) {
82
101
  json: true,
83
102
  };
84
103
  try {
85
- const response = await ctx.helpers.request(options);
104
+ const response = (await ctx.helpers.request(options));
86
105
  let accounts = Array.isArray(response)
87
106
  ? response
88
107
  : ((_a = response.data) !== null && _a !== void 0 ? _a : []);
@@ -92,7 +111,11 @@ async function loadAccounts(ctx, platform) {
92
111
  }
93
112
  return accounts.map((account) => ({
94
113
  value: String(account.id),
95
- name: (account.pageName || account.page_name || account.account_name || account.name || String(account.id)),
114
+ name: (account.pageName ||
115
+ account.page_name ||
116
+ account.account_name ||
117
+ account.name ||
118
+ String(account.id)),
96
119
  }));
97
120
  }
98
121
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../nodes/shared/api.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../nodes/shared/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ import {
2
+ IDataObject,
3
+ IExecuteFunctions,
4
+ INodeExecutionData,
5
+ INodeType,
6
+ INodeTypeDescription,
7
+ } from 'n8n-workflow';
8
+
9
+ import { nashirApiRequest } from '../shared/api';
10
+
11
+ export class NashirContact implements INodeType {
12
+ description: INodeTypeDescription = {
13
+ displayName: 'Nashir Contact',
14
+ name: 'nashirContact',
15
+ icon: 'file:nashir.svg',
16
+ group: ['transform'],
17
+ version: 1,
18
+ subtitle: '={{$parameter["operation"]}}',
19
+ description: 'Manage contacts in nashir.ai',
20
+ defaults: { name: 'Nashir Contact', color: '#6366f1' },
21
+ inputs: ['main'],
22
+ outputs: ['main'],
23
+ credentials: [{ name: 'nashirApi', required: true }],
24
+ properties: [
25
+ {
26
+ displayName: 'Operation',
27
+ name: 'operation',
28
+ type: 'options',
29
+ noDataExpression: true,
30
+ options: [
31
+ { name: 'Get Contact', value: 'getContact', action: 'Get contact details' },
32
+ { name: 'Update Contact Tags', value: 'updateTags', action: 'Add tags to a contact' },
33
+ ],
34
+ default: 'getContact',
35
+ },
36
+
37
+ // ── Shared: phone ────────────────────────────────────────────────────────
38
+ {
39
+ displayName: 'Phone Number',
40
+ name: 'phone',
41
+ type: 'string',
42
+ default: '',
43
+ required: true,
44
+ placeholder: '+1234567890',
45
+ description: 'Phone number of the contact in international format',
46
+ displayOptions: { show: { operation: ['getContact', 'updateTags'] } },
47
+ },
48
+
49
+ // ── Update Tags fields ───────────────────────────────────────────────────
50
+ {
51
+ displayName: 'Tags',
52
+ name: 'tags',
53
+ type: 'string',
54
+ default: '',
55
+ required: true,
56
+ placeholder: 'vip, arabic, lead',
57
+ description: 'Comma-separated list of tags to apply to the contact (idempotent)',
58
+ displayOptions: { show: { operation: ['updateTags'] } },
59
+ },
60
+ ],
61
+ };
62
+
63
+ async execute(this: IExecuteFunctions): Promise<INodeExecutionData[][]> {
64
+ const items = this.getInputData();
65
+ const returnData: INodeExecutionData[] = [];
66
+
67
+ for (let i = 0; i < items.length; i++) {
68
+ try {
69
+ const operation = this.getNodeParameter('operation', i) as string;
70
+ let responseData: IDataObject | IDataObject[];
71
+
72
+ if (operation === 'getContact') {
73
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i) as string);
74
+ responseData = await nashirApiRequest(this, 'GET', `/contacts/${phone}`);
75
+
76
+ } else if (operation === 'updateTags') {
77
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i) as string);
78
+ const tagsRaw = this.getNodeParameter('tags', i) as string;
79
+ const tags = tagsRaw
80
+ .split(',')
81
+ .map((t) => t.trim())
82
+ .filter(Boolean);
83
+ responseData = await nashirApiRequest(this, 'POST', `/contacts/${phone}/tags`, { tags });
84
+
85
+ } else {
86
+ throw new Error(`Unknown operation: ${operation}`);
87
+ }
88
+
89
+ const rows = Array.isArray(responseData) ? responseData : [responseData];
90
+ returnData.push(...rows.map((d) => ({ json: d, pairedItem: i })));
91
+
92
+ } catch (error) {
93
+ if (this.continueOnFail()) {
94
+ returnData.push({ json: { error: (error as Error).message }, pairedItem: i });
95
+ continue;
96
+ }
97
+ throw error;
98
+ }
99
+ }
100
+
101
+ return [returnData];
102
+ }
103
+ }
@@ -0,0 +1,5 @@
1
+ <svg viewBox="0 0 60 60" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <rect width="60" height="60" rx="12" fill="#7C3AED"/>
3
+ <path d="M8 30L50 10L37 52L28 33L8 30Z" fill="white"/>
4
+ <path d="M28 33L37 24" stroke="#7C3AED" stroke-width="3" stroke-linecap="round"/>
5
+ </svg>
@@ -30,10 +30,15 @@ export class NashirWhatsApp implements INodeType {
30
30
  type: 'options',
31
31
  noDataExpression: true,
32
32
  options: [
33
+ { name: 'Get AI Status', value: 'getAiStatus', action: 'Get AI status for a conversation' },
34
+ { name: 'Get Contact', value: 'getContact', action: 'Get contact details' },
35
+ { name: 'Get Conversation History', value: 'getConversationHistory', action: 'Get conversation history for a phone number' },
33
36
  { name: 'Get Messages', value: 'getMessages', action: 'Get messages' },
34
37
  { name: 'Mark as Read', value: 'markRead', action: 'Mark message as read' },
35
38
  { name: 'Reply to Message', value: 'replyMessage', action: 'Reply to a message' },
39
+ { name: 'Save Message to Inbox', value: 'saveMessage', action: 'Save a message to the inbox' },
36
40
  { name: 'Send Message', value: 'sendMessage', action: 'Send a message' },
41
+ { name: 'Set AI Status', value: 'setAiStatus', action: 'Pause or resume AI auto-reply' },
37
42
  ],
38
43
  default: 'sendMessage',
39
44
  },
@@ -114,6 +119,131 @@ export class NashirWhatsApp implements INodeType {
114
119
  required: true,
115
120
  displayOptions: { show: { operation: ['replyMessage'] } },
116
121
  },
122
+
123
+ // ── Conversation History fields ──────────────────────────────────────────
124
+ {
125
+ displayName: 'Phone Number',
126
+ name: 'phone',
127
+ type: 'string',
128
+ default: '',
129
+ required: true,
130
+ placeholder: '+1234567890',
131
+ description: 'Phone number in international format',
132
+ displayOptions: {
133
+ show: {
134
+ operation: [
135
+ 'getConversationHistory',
136
+ 'getAiStatus',
137
+ 'setAiStatus',
138
+ 'getContact',
139
+ ],
140
+ },
141
+ },
142
+ },
143
+
144
+ {
145
+ displayName: 'Limit',
146
+ name: 'limit',
147
+ type: 'number',
148
+ default: 20,
149
+ description: 'Number of messages to return (most recent first)',
150
+ displayOptions: { show: { operation: ['getConversationHistory'] } },
151
+ },
152
+
153
+ // ── Set AI Status fields ────────────────────────────────────────────────
154
+ {
155
+ displayName: 'Action',
156
+ name: 'aiAction',
157
+ type: 'options',
158
+ options: [
159
+ { name: 'Pause', value: 'pause' },
160
+ { name: 'Resume', value: 'resume' },
161
+ ],
162
+ default: 'pause',
163
+ required: true,
164
+ description: 'Pause or resume AI auto-reply for this conversation',
165
+ displayOptions: { show: { operation: ['setAiStatus'] } },
166
+ },
167
+
168
+ {
169
+ displayName: 'Reason',
170
+ name: 'reason',
171
+ type: 'string',
172
+ default: '',
173
+ description: 'Optional reason for pausing (e.g. "Human takeover")',
174
+ displayOptions: { show: { operation: ['setAiStatus'] } },
175
+ },
176
+
177
+ // ── Save Message to Inbox fields ────────────────────────────────────────
178
+ {
179
+ displayName: 'Phone Number',
180
+ name: 'ingestPhone',
181
+ type: 'string',
182
+ default: '',
183
+ required: true,
184
+ placeholder: '+1234567890',
185
+ description: 'Phone number of the contact',
186
+ displayOptions: { show: { operation: ['saveMessage'] } },
187
+ },
188
+
189
+ {
190
+ displayName: 'Role',
191
+ name: 'role',
192
+ type: 'options',
193
+ options: [
194
+ { name: 'User (Inbound)', value: 'user' },
195
+ { name: 'Assistant (Outbound)', value: 'assistant' },
196
+ ],
197
+ default: 'user',
198
+ required: true,
199
+ description: 'Whether this message is from the user or the AI assistant',
200
+ displayOptions: { show: { operation: ['saveMessage'] } },
201
+ },
202
+
203
+ {
204
+ displayName: 'Message Content',
205
+ name: 'messageContent',
206
+ type: 'string',
207
+ typeOptions: { rows: 3 },
208
+ default: '',
209
+ required: true,
210
+ description: 'Text content of the message',
211
+ displayOptions: { show: { operation: ['saveMessage'] } },
212
+ },
213
+
214
+ {
215
+ displayName: 'Media Type',
216
+ name: 'mediaType',
217
+ type: 'options',
218
+ options: [
219
+ { name: 'None', value: '' },
220
+ { name: 'Image', value: 'image' },
221
+ { name: 'Video', value: 'video' },
222
+ { name: 'Audio', value: 'audio' },
223
+ { name: 'Document', value: 'document' },
224
+ ],
225
+ default: '',
226
+ description: 'Optional media type if the message contains media',
227
+ displayOptions: { show: { operation: ['saveMessage'] } },
228
+ },
229
+
230
+ {
231
+ displayName: 'Media URL',
232
+ name: 'mediaUrl',
233
+ type: 'string',
234
+ default: '',
235
+ description: 'URL of the media file (required if Media Type is set)',
236
+ displayOptions: { show: { operation: ['saveMessage'] } },
237
+ },
238
+
239
+ {
240
+ displayName: 'Is From AI',
241
+ name: 'isFromAi',
242
+ type: 'boolean',
243
+ default: true,
244
+ description: 'Whether this message was generated by the AI',
245
+ displayOptions: { show: { operation: ['saveMessage'] } },
246
+ },
117
247
  ],
118
248
  };
119
249
 
@@ -153,21 +283,71 @@ export class NashirWhatsApp implements INodeType {
153
283
  }
154
284
 
155
285
  responseData = await nashirApiRequest(this, 'POST', '/messages', body);
286
+
156
287
  } else if (operation === 'getMessages') {
157
288
  responseData = await nashirApiRequest(this, 'GET', '/messages', undefined, { platform: 'whatsapp' });
289
+
158
290
  } else if (operation === 'replyMessage') {
159
291
  const accountId = this.getNodeParameter('account', i) as string;
160
292
  const messageId = this.getNodeParameter('messageId', i) as string;
161
293
  const replyText = this.getNodeParameter('replyText', i) as string;
162
- responseData = await nashirApiRequest(this, 'POST', `/messages/${messageId}/reply`, { message: replyText, account_id: accountId });
163
- } else {
164
- // markRead
294
+ responseData = await nashirApiRequest(this, 'POST', `/messages/${messageId}/reply`, {
295
+ message: replyText,
296
+ account_id: accountId,
297
+ });
298
+
299
+ } else if (operation === 'markRead') {
165
300
  const messageId = this.getNodeParameter('messageId', i) as string;
166
301
  responseData = await nashirApiRequest(this, 'PATCH', `/messages/${messageId}/read`);
302
+
303
+ } else if (operation === 'getConversationHistory') {
304
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i) as string);
305
+ const limit = this.getNodeParameter('limit', i, 20) as number;
306
+ responseData = await nashirApiRequest(
307
+ this,
308
+ 'GET',
309
+ `/conversations/${phone}/messages`,
310
+ undefined,
311
+ { limit },
312
+ );
313
+
314
+ } else if (operation === 'getAiStatus') {
315
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i) as string);
316
+ responseData = await nashirApiRequest(this, 'GET', `/conversations/${phone}/ai-status`);
317
+
318
+ } else if (operation === 'setAiStatus') {
319
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i) as string);
320
+ const action = this.getNodeParameter('aiAction', i) as string;
321
+ const reason = this.getNodeParameter('reason', i, '') as string;
322
+ const body: IDataObject = { action };
323
+ if (reason) body.reason = reason;
324
+ responseData = await nashirApiRequest(this, 'POST', `/conversations/${phone}/ai-toggle`, body);
325
+
326
+ } else if (operation === 'saveMessage') {
327
+ const phone = this.getNodeParameter('ingestPhone', i) as string;
328
+ const role = this.getNodeParameter('role', i) as string;
329
+ const content = this.getNodeParameter('messageContent', i) as string;
330
+ const mediaType = this.getNodeParameter('mediaType', i, '') as string;
331
+ const mediaUrl = this.getNodeParameter('mediaUrl', i, '') as string;
332
+ const isFromAi = this.getNodeParameter('isFromAi', i, true) as boolean;
333
+
334
+ const body: IDataObject = { phone, role, content, is_from_ai: isFromAi };
335
+ if (mediaType) body.media_type = mediaType;
336
+ if (mediaUrl) body.media_url = mediaUrl;
337
+
338
+ responseData = await nashirApiRequest(this, 'POST', '/messages/ingest', body);
339
+
340
+ } else if (operation === 'getContact') {
341
+ const phone = encodeURIComponent(this.getNodeParameter('phone', i) as string);
342
+ responseData = await nashirApiRequest(this, 'GET', `/contacts/${phone}`);
343
+
344
+ } else {
345
+ throw new Error(`Unknown operation: ${operation}`);
167
346
  }
168
347
 
169
348
  const rows = Array.isArray(responseData) ? responseData : [responseData];
170
349
  returnData.push(...rows.map((d) => ({ json: d, pairedItem: i })));
350
+
171
351
  } catch (error) {
172
352
  if (this.continueOnFail()) {
173
353
  returnData.push({ json: { error: (error as Error).message }, pairedItem: i });
@@ -8,6 +8,38 @@ import {
8
8
 
9
9
  type AnyContext = IExecuteFunctions | ILoadOptionsFunctions;
10
10
 
11
+ /** Shape of error objects thrown by ctx.helpers.request */
12
+ interface RequestError extends Error {
13
+ statusCode?: number;
14
+ response?: { statusCode?: number; body?: IDataObject | string };
15
+ }
16
+
17
+ function throwFriendlyError(error: RequestError, endpoint: string): never {
18
+ const status =
19
+ error.statusCode ??
20
+ (error.response as { statusCode?: number } | undefined)?.statusCode;
21
+
22
+ if (status === 401 || status === 403) {
23
+ throw new Error(
24
+ 'Authentication failed: your Nashir API key is invalid or does not have permission for this action. ' +
25
+ 'Check your credentials at nashir.ai → Settings → API.',
26
+ );
27
+ }
28
+
29
+ if (status === 404) {
30
+ // Give a context-aware message based on the endpoint path
31
+ if (endpoint.includes('/contacts/')) {
32
+ throw new Error(`Contact not found. Verify the phone number is registered in nashir.ai.`);
33
+ }
34
+ if (endpoint.includes('/conversations/')) {
35
+ throw new Error(`Conversation not found for this phone number.`);
36
+ }
37
+ throw new Error(`Resource not found (404): ${endpoint}`);
38
+ }
39
+
40
+ throw error;
41
+ }
42
+
11
43
  /**
12
44
  * Make an authenticated request to the Nashir API.
13
45
  */
@@ -17,7 +49,7 @@ export async function nashirApiRequest(
17
49
  endpoint: string,
18
50
  body?: IDataObject,
19
51
  qs?: IDataObject,
20
- ): Promise<IDataObject> {
52
+ ): Promise<IDataObject | IDataObject[]> {
21
53
  const credentials = await ctx.getCredentials('nashirApi');
22
54
  const baseUrl = ((credentials.baseUrl as string) || 'https://nashir.ai').replace(/\/$/, '');
23
55
  const apiKey = credentials.apiKey as string;
@@ -38,7 +70,7 @@ export async function nashirApiRequest(
38
70
  try {
39
71
  return await ctx.helpers.request(options);
40
72
  } catch (error) {
41
- throw error;
73
+ throwFriendlyError(error as RequestError, endpoint);
42
74
  }
43
75
  }
44
76
 
@@ -76,10 +108,10 @@ export async function nashirUploadBinary(
76
108
  };
77
109
 
78
110
  try {
79
- const response = await ctx.helpers.request(options) as IDataObject;
111
+ const response = (await ctx.helpers.request(options)) as IDataObject;
80
112
  return response.url as string;
81
113
  } catch (error) {
82
- throw error;
114
+ throwFriendlyError(error as RequestError, '/upload');
83
115
  }
84
116
  }
85
117
 
@@ -106,7 +138,7 @@ export async function loadAccounts(
106
138
  };
107
139
 
108
140
  try {
109
- const response = await ctx.helpers.request(options) as IDataObject | IDataObject[];
141
+ const response = (await ctx.helpers.request(options)) as IDataObject | IDataObject[];
110
142
  let accounts: IDataObject[] = Array.isArray(response)
111
143
  ? response
112
144
  : ((response.data as IDataObject[]) ?? []);
@@ -118,7 +150,11 @@ export async function loadAccounts(
118
150
 
119
151
  return accounts.map((account) => ({
120
152
  value: String(account.id),
121
- name: (account.pageName || account.page_name || account.account_name || account.name || String(account.id)) as string,
153
+ name: (account.pageName ||
154
+ account.page_name ||
155
+ account.account_name ||
156
+ account.name ||
157
+ String(account.id)) as string,
122
158
  }));
123
159
  } catch {
124
160
  return [];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "n8n-nodes-nashir",
3
- "version": "0.2.2",
4
- "description": "n8n community nodes for nashir.ai — publish to Facebook, Instagram, TikTok, LinkedIn, YouTube, WhatsApp and Telegram",
3
+ "version": "0.3.0",
4
+ "description": "n8n community nodes for nashir.ai — publish to Facebook, Instagram, TikTok, LinkedIn, YouTube, WhatsApp and Telegram, plus AI conversation management",
5
5
  "keywords": [
6
6
  "n8n-community-node-package",
7
7
  "nashir",
@@ -12,7 +12,10 @@
12
12
  "linkedin",
13
13
  "youtube",
14
14
  "whatsapp",
15
- "telegram"
15
+ "telegram",
16
+ "ai",
17
+ "chatbot",
18
+ "conversation-history"
16
19
  ],
17
20
  "license": "MIT",
18
21
  "homepage": "https://nashir.ai",
@@ -48,7 +51,8 @@
48
51
  "dist/nodes/NashirLinkedIn/NashirLinkedIn.node.js",
49
52
  "dist/nodes/NashirYouTube/NashirYouTube.node.js",
50
53
  "dist/nodes/NashirWhatsApp/NashirWhatsApp.node.js",
51
- "dist/nodes/NashirTelegram/NashirTelegram.node.js"
54
+ "dist/nodes/NashirTelegram/NashirTelegram.node.js",
55
+ "dist/nodes/NashirContact/NashirContact.node.js"
52
56
  ]
53
57
  },
54
58
  "devDependencies": {