piece-signal-cli-rest-api 0.2.0 → 0.2.1

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 (179) hide show
  1. package/package.json +26 -4
  2. package/src/index.d.ts +8 -0
  3. package/src/index.js +90 -0
  4. package/src/index.js.map +1 -0
  5. package/src/lib/actions/add-admins-to-group.d.ts +12 -0
  6. package/src/lib/actions/add-admins-to-group.js +45 -0
  7. package/src/lib/actions/add-admins-to-group.js.map +1 -0
  8. package/src/lib/actions/add-device.d.ts +11 -0
  9. package/src/lib/actions/add-device.js +40 -0
  10. package/src/lib/actions/add-device.js.map +1 -0
  11. package/src/lib/actions/add-members-to-group.d.ts +12 -0
  12. package/src/lib/actions/add-members-to-group.js +45 -0
  13. package/src/lib/actions/add-members-to-group.js.map +1 -0
  14. package/src/lib/actions/block-group.d.ts +11 -0
  15. package/src/lib/actions/block-group.js +37 -0
  16. package/src/lib/actions/block-group.js.map +1 -0
  17. package/src/lib/actions/create-group.d.ts +18 -0
  18. package/src/lib/actions/create-group.js +117 -0
  19. package/src/lib/actions/create-group.js.map +1 -0
  20. package/src/lib/actions/delete-group.d.ts +11 -0
  21. package/src/lib/actions/delete-group.js +37 -0
  22. package/src/lib/actions/delete-group.js.map +1 -0
  23. package/src/lib/actions/get-contact.d.ts +11 -0
  24. package/src/lib/actions/get-contact.js +37 -0
  25. package/src/lib/actions/get-contact.js.map +1 -0
  26. package/src/lib/actions/get-group.d.ts +11 -0
  27. package/src/lib/actions/get-group.js +37 -0
  28. package/src/lib/actions/get-group.js.map +1 -0
  29. package/src/lib/actions/get-qr-code-link.d.ts +11 -0
  30. package/src/lib/actions/get-qr-code-link.js +60 -0
  31. package/src/lib/actions/get-qr-code-link.js.map +1 -0
  32. package/src/lib/actions/join-group.d.ts +11 -0
  33. package/src/lib/actions/join-group.js +37 -0
  34. package/src/lib/actions/join-group.js.map +1 -0
  35. package/src/lib/actions/list-accounts.d.ts +8 -0
  36. package/src/lib/actions/list-accounts.js +23 -0
  37. package/src/lib/actions/list-accounts.js.map +1 -0
  38. package/src/lib/actions/list-attachments.d.ts +8 -0
  39. package/src/lib/actions/list-attachments.js +23 -0
  40. package/src/lib/actions/list-attachments.js.map +1 -0
  41. package/src/lib/actions/list-contacts.d.ts +10 -0
  42. package/src/lib/actions/list-contacts.js +32 -0
  43. package/src/lib/actions/list-contacts.js.map +1 -0
  44. package/src/lib/actions/list-devices.d.ts +10 -0
  45. package/src/lib/actions/list-devices.js +32 -0
  46. package/src/lib/actions/list-devices.js.map +1 -0
  47. package/src/lib/actions/list-groups.d.ts +10 -0
  48. package/src/lib/actions/list-groups.js +32 -0
  49. package/src/lib/actions/list-groups.js.map +1 -0
  50. package/src/lib/actions/list-identities.d.ts +10 -0
  51. package/src/lib/actions/list-identities.js +32 -0
  52. package/src/lib/actions/list-identities.js.map +1 -0
  53. package/src/lib/actions/quit-group.d.ts +11 -0
  54. package/src/lib/actions/quit-group.js +37 -0
  55. package/src/lib/actions/quit-group.js.map +1 -0
  56. package/src/lib/actions/receive-messages.d.ts +15 -0
  57. package/src/lib/actions/receive-messages.js +100 -0
  58. package/src/lib/actions/receive-messages.js.map +1 -0
  59. package/src/lib/actions/remote-delete-message.d.ts +12 -0
  60. package/src/lib/actions/remote-delete-message.js +46 -0
  61. package/src/lib/actions/remote-delete-message.js.map +1 -0
  62. package/src/lib/actions/remove-admins-from-group.d.ts +12 -0
  63. package/src/lib/actions/remove-admins-from-group.js +45 -0
  64. package/src/lib/actions/remove-admins-from-group.js.map +1 -0
  65. package/src/lib/actions/remove-device.d.ts +11 -0
  66. package/src/lib/actions/remove-device.js +37 -0
  67. package/src/lib/actions/remove-device.js.map +1 -0
  68. package/src/lib/actions/remove-members-from-group.d.ts +12 -0
  69. package/src/lib/actions/remove-members-from-group.js +45 -0
  70. package/src/lib/actions/remove-members-from-group.js.map +1 -0
  71. package/src/lib/actions/remove-reaction.d.ts +13 -0
  72. package/src/lib/actions/remove-reaction.js +52 -0
  73. package/src/lib/actions/remove-reaction.js.map +1 -0
  74. package/src/lib/actions/request-approval-message.d.ts +15 -0
  75. package/src/lib/actions/request-approval-message.js +184 -0
  76. package/src/lib/actions/request-approval-message.js.map +1 -0
  77. package/src/lib/actions/resume-approval-flow.d.ts +11 -0
  78. package/src/lib/actions/resume-approval-flow.js +181 -0
  79. package/src/lib/actions/resume-approval-flow.js.map +1 -0
  80. package/src/lib/actions/search-numbers.d.ts +11 -0
  81. package/src/lib/actions/search-numbers.js +42 -0
  82. package/src/lib/actions/search-numbers.js.map +1 -0
  83. package/src/lib/actions/send-message.d.ts +27 -0
  84. package/src/lib/actions/send-message.js +176 -0
  85. package/src/lib/actions/send-message.js.map +1 -0
  86. package/src/lib/actions/send-reaction.d.ts +14 -0
  87. package/src/lib/actions/send-reaction.js +58 -0
  88. package/src/lib/actions/send-reaction.js.map +1 -0
  89. package/src/lib/actions/send-receipt.d.ts +13 -0
  90. package/src/lib/actions/send-receipt.js +58 -0
  91. package/src/lib/actions/send-receipt.js.map +1 -0
  92. package/src/lib/actions/start-typing.d.ts +11 -0
  93. package/src/lib/actions/start-typing.js +40 -0
  94. package/src/lib/actions/start-typing.js.map +1 -0
  95. package/src/lib/actions/stop-typing.d.ts +11 -0
  96. package/src/lib/actions/stop-typing.js +40 -0
  97. package/src/lib/actions/stop-typing.js.map +1 -0
  98. package/src/lib/actions/sync-contacts.d.ts +10 -0
  99. package/src/lib/actions/sync-contacts.js +32 -0
  100. package/src/lib/actions/sync-contacts.js.map +1 -0
  101. package/src/lib/actions/update-account-settings.d.ts +12 -0
  102. package/src/lib/actions/update-account-settings.js +49 -0
  103. package/src/lib/actions/update-account-settings.js.map +1 -0
  104. package/src/lib/actions/update-contact.d.ts +13 -0
  105. package/src/lib/actions/update-contact.js +56 -0
  106. package/src/lib/actions/update-contact.js.map +1 -0
  107. package/src/lib/actions/update-group.d.ts +19 -0
  108. package/src/lib/actions/update-group.js +125 -0
  109. package/src/lib/actions/update-group.js.map +1 -0
  110. package/src/lib/actions/update-profile.d.ts +13 -0
  111. package/src/lib/actions/update-profile.js +56 -0
  112. package/src/lib/actions/update-profile.js.map +1 -0
  113. package/src/lib/common/api-client.d.ts +24 -0
  114. package/src/lib/common/api-client.js +103 -0
  115. package/src/lib/common/api-client.js.map +1 -0
  116. package/src/lib/common/auth.d.ts +8 -0
  117. package/src/lib/common/auth.js +68 -0
  118. package/src/lib/common/auth.js.map +1 -0
  119. package/src/lib/common/message-utils.d.ts +81 -0
  120. package/src/lib/common/message-utils.js +327 -0
  121. package/src/lib/common/message-utils.js.map +1 -0
  122. package/src/lib/common/types.d.ts +65 -0
  123. package/src/lib/common/types.js +3 -0
  124. package/src/lib/common/types.js.map +1 -0
  125. package/src/lib/common/utils.d.ts +23 -0
  126. package/src/lib/common/utils.js +105 -0
  127. package/src/lib/common/utils.js.map +1 -0
  128. package/src/lib/triggers/new-group-member.d.ts +50 -0
  129. package/src/lib/triggers/new-group-member.js +155 -0
  130. package/src/lib/triggers/new-group-member.js.map +1 -0
  131. package/src/lib/triggers/new-message-received.d.ts +58 -0
  132. package/src/lib/triggers/new-message-received.js +469 -0
  133. package/src/lib/triggers/new-message-received.js.map +1 -0
  134. package/project.json +0 -58
  135. package/src/index.ts +0 -87
  136. package/src/lib/actions/add-admins-to-group.ts +0 -50
  137. package/src/lib/actions/add-device.ts +0 -45
  138. package/src/lib/actions/add-members-to-group.ts +0 -50
  139. package/src/lib/actions/block-group.ts +0 -36
  140. package/src/lib/actions/create-group.ts +0 -139
  141. package/src/lib/actions/delete-group.ts +0 -36
  142. package/src/lib/actions/get-contact.ts +0 -42
  143. package/src/lib/actions/get-group.ts +0 -37
  144. package/src/lib/actions/get-qr-code-link.ts +0 -62
  145. package/src/lib/actions/join-group.ts +0 -36
  146. package/src/lib/actions/list-accounts.ts +0 -20
  147. package/src/lib/actions/list-attachments.ts +0 -20
  148. package/src/lib/actions/list-contacts.ts +0 -37
  149. package/src/lib/actions/list-devices.ts +0 -38
  150. package/src/lib/actions/list-groups.ts +0 -32
  151. package/src/lib/actions/list-identities.ts +0 -32
  152. package/src/lib/actions/quit-group.ts +0 -36
  153. package/src/lib/actions/receive-messages.ts +0 -108
  154. package/src/lib/actions/remote-delete-message.ts +0 -56
  155. package/src/lib/actions/remove-admins-from-group.ts +0 -50
  156. package/src/lib/actions/remove-device.ts +0 -36
  157. package/src/lib/actions/remove-members-from-group.ts +0 -50
  158. package/src/lib/actions/remove-reaction.ts +0 -59
  159. package/src/lib/actions/request-approval-message.ts +0 -215
  160. package/src/lib/actions/search-numbers.ts +0 -47
  161. package/src/lib/actions/send-message.ts +0 -189
  162. package/src/lib/actions/send-reaction.ts +0 -66
  163. package/src/lib/actions/send-receipt.ts +0 -65
  164. package/src/lib/actions/start-typing.ts +0 -45
  165. package/src/lib/actions/stop-typing.ts +0 -45
  166. package/src/lib/actions/sync-contacts.ts +0 -31
  167. package/src/lib/actions/update-account-settings.ts +0 -57
  168. package/src/lib/actions/update-contact.ts +0 -65
  169. package/src/lib/actions/update-group.ts +0 -145
  170. package/src/lib/actions/update-profile.ts +0 -65
  171. package/src/lib/common/api-client.ts +0 -150
  172. package/src/lib/common/auth.ts +0 -66
  173. package/src/lib/common/message-utils.ts +0 -449
  174. package/src/lib/common/types.ts +0 -73
  175. package/src/lib/common/utils.ts +0 -106
  176. package/src/lib/triggers/new-group-member.ts +0 -176
  177. package/src/lib/triggers/new-message-received.ts +0 -618
  178. package/tsconfig.json +0 -19
  179. package/tsconfig.lib.json +0 -11
@@ -1,449 +0,0 @@
1
- import { StoreScope } from '@activepieces/pieces-framework';
2
- import { HttpMethod, httpClient } from '@activepieces/pieces-common';
3
- import WebSocket from 'ws';
4
-
5
- export interface SignalMessage {
6
- envelope: {
7
- source: string;
8
- sourceNumber?: string;
9
- sourceUuid?: string;
10
- sourceName?: string;
11
- sourceDevice: number;
12
- timestamp: number;
13
- timestampISO?: string;
14
- dataMessage?: {
15
- message?: string;
16
- timestamp: number;
17
- expiresInSeconds?: number;
18
- attachments?: Array<{
19
- id: string;
20
- contentType: string;
21
- size: number;
22
- fileName?: string;
23
- width?: number;
24
- height?: number;
25
- voiceNote?: boolean;
26
- caption?: string;
27
- }>;
28
- mentions?: Array<{
29
- start: number;
30
- length: number;
31
- recipient: string;
32
- }>;
33
- groupInfo?: {
34
- groupId: string;
35
- type: string;
36
- members?: string[];
37
- name?: string;
38
- avatarId?: number;
39
- };
40
- quote?: {
41
- id: number;
42
- author: string;
43
- text?: string;
44
- };
45
- preview?: Array<{
46
- url: string;
47
- title: string;
48
- description?: string;
49
- }>;
50
- sticker?: {
51
- packId: string;
52
- stickerId: number;
53
- };
54
- reaction?: {
55
- emoji: string;
56
- targetAuthor: string;
57
- targetTimestamp: number;
58
- };
59
- viewOnce?: boolean;
60
- };
61
- syncMessage?: {
62
- sentMessage?: {
63
- destination: string;
64
- timestamp: number;
65
- message?: string;
66
- };
67
- };
68
- receipt?: {
69
- type: number;
70
- timestamp: number;
71
- timestamps: number[];
72
- };
73
- typing?: {
74
- action: number;
75
- timestamp: number;
76
- };
77
- };
78
- account: string;
79
- }
80
-
81
- interface ApprovalMapping {
82
- flowRunId: string;
83
- requestId: string;
84
- approveEmoji: string;
85
- disapproveEmoji: string;
86
- targetAuthor: string;
87
- messageTimestamp: number;
88
- timeoutSeconds: number;
89
- createdAt: number;
90
- }
91
-
92
- // Function to automatically resume approval flows
93
- export async function tryResumeApprovalFlow(
94
- message: SignalMessage,
95
- store: any,
96
- apiUrl: string
97
- ): Promise<{ resumed: boolean; action?: string }> {
98
- console.log('[ReceiveMessages] DEBUG - Processing message:', {
99
- hasReaction: !!message.envelope?.dataMessage?.reaction,
100
- });
101
-
102
- // Check if it's a reaction
103
- if (!message.envelope?.dataMessage?.reaction) {
104
- return { resumed: false };
105
- }
106
-
107
- console.log('[ReceiveMessages] DEBUG - Reaction detected');
108
- const reaction = message.envelope.dataMessage.reaction;
109
- // Convert targetTimestamp from milliseconds to seconds (Unix timestamp)
110
- // Note: targetTimestamp in SignalMessage interface might be targetSentTimestamp in actual data
111
- const targetTimestampMs = (reaction as any).targetSentTimestamp || reaction.targetTimestamp;
112
- const targetTimestamp = Math.floor(targetTimestampMs / 1000);
113
- const targetAuthor = reaction.targetAuthor;
114
- const reactionEmoji = reaction.emoji;
115
-
116
- console.log('[ReceiveMessages] DEBUG - Reaction data:', {
117
- targetSentTimestampOriginal: targetTimestampMs,
118
- targetTimestamp,
119
- targetAuthor,
120
- reactionEmoji,
121
- });
122
-
123
- // Cleanup expired approvals
124
- const keysListKey = 'approval:keys';
125
- const existingKeys = (await store.get<string[]>(keysListKey, StoreScope.PROJECT)) || [];
126
- const currentTimestamp = Math.floor(Date.now() / 1000);
127
- const validKeys: string[] = [];
128
- const keysToDelete: string[] = [];
129
-
130
- console.log('[ReceiveMessages] DEBUG - Store info:', {
131
- existingKeysCount: existingKeys.length,
132
- existingKeys: existingKeys,
133
- currentTimestamp,
134
- });
135
-
136
- for (const key of existingKeys) {
137
- const mapping = await store.get<ApprovalMapping>(key, StoreScope.PROJECT);
138
- if (mapping) {
139
- // Check if expired
140
- if (currentTimestamp - mapping.createdAt > mapping.timeoutSeconds) {
141
- // Expired - delete it and flowRunId mapping
142
- await store.delete(key, StoreScope.PROJECT);
143
- const flowRunMappingKey = `approval:flowRun:${mapping.flowRunId}`;
144
- await store.delete(flowRunMappingKey, StoreScope.PROJECT);
145
- keysToDelete.push(key);
146
- } else {
147
- validKeys.push(key);
148
- }
149
- } else {
150
- // Mapping not found - remove from list
151
- keysToDelete.push(key);
152
- }
153
- }
154
-
155
- // Update keys list if any were deleted
156
- if (keysToDelete.length > 0) {
157
- await store.put(keysListKey, validKeys, StoreScope.PROJECT);
158
- }
159
-
160
- console.log('[ReceiveMessages] DEBUG - Cleanup result:', {
161
- keysDeleted: keysToDelete.length,
162
- validKeysCount: validKeys.length,
163
- });
164
-
165
- // Look up the specific approval mapping
166
- const storeKey = `approval:${targetTimestamp}:${targetAuthor}`;
167
-
168
- console.log('[ReceiveMessages] DEBUG - Store lookup:', {
169
- storeKey,
170
- existingKeysCount: existingKeys.length,
171
- });
172
-
173
- const mapping = await store.get<ApprovalMapping>(storeKey, StoreScope.PROJECT);
174
-
175
- if (!mapping) {
176
- // Not an approval message
177
- console.log('[ReceiveMessages] DEBUG - No mapping found:', {
178
- reason: 'not_an_approval_message',
179
- searchedKey: storeKey,
180
- });
181
- return { resumed: false };
182
- }
183
-
184
- console.log('[ReceiveMessages] DEBUG - Mapping found:', {
185
- flowRunId: mapping.flowRunId,
186
- requestId: mapping.requestId,
187
- approveEmoji: mapping.approveEmoji,
188
- disapproveEmoji: mapping.disapproveEmoji,
189
- messageTimestamp: mapping.messageTimestamp,
190
- createdAt: mapping.createdAt,
191
- timeoutSeconds: mapping.timeoutSeconds,
192
- });
193
-
194
- // Check if expired
195
- const ageInSeconds = currentTimestamp - mapping.createdAt;
196
- const isExpired = ageInSeconds > mapping.timeoutSeconds;
197
-
198
- console.log('[ReceiveMessages] DEBUG - Expiration check:', {
199
- currentTimestamp,
200
- createdAt: mapping.createdAt,
201
- ageInSeconds,
202
- timeoutSeconds: mapping.timeoutSeconds,
203
- isExpired,
204
- });
205
-
206
- if (isExpired) {
207
- // Expired - delete and return
208
- await store.delete(storeKey, StoreScope.PROJECT);
209
- const flowRunMappingKey = `approval:flowRun:${mapping.flowRunId}`;
210
- await store.delete(flowRunMappingKey, StoreScope.PROJECT);
211
- const updatedKeys = validKeys.filter(key => key !== storeKey);
212
- await store.put(keysListKey, updatedKeys, StoreScope.PROJECT);
213
- console.log('[ReceiveMessages] DEBUG - Approval expired');
214
- return { resumed: false };
215
- }
216
-
217
- // Check emoji and determine action
218
- let action: string;
219
-
220
- console.log('[ReceiveMessages] DEBUG - Emoji check:', {
221
- receivedEmoji: reactionEmoji,
222
- expectedApproveEmoji: mapping.approveEmoji,
223
- expectedDisapproveEmoji: mapping.disapproveEmoji,
224
- });
225
-
226
- if (reactionEmoji === mapping.approveEmoji) {
227
- action = 'approve';
228
- console.log('[ReceiveMessages] DEBUG - Emoji matched: approve');
229
- } else if (reactionEmoji === mapping.disapproveEmoji) {
230
- action = 'disapprove';
231
- console.log('[ReceiveMessages] DEBUG - Emoji matched: disapprove');
232
- } else {
233
- // Invalid emoji - not an approval reaction
234
- console.log('[ReceiveMessages] DEBUG - Invalid emoji:', {
235
- reason: 'invalid_emoji',
236
- receivedEmoji: reactionEmoji,
237
- });
238
- return { resumed: false };
239
- }
240
-
241
- // Make HTTP request to resume the flow
242
- const resumeUrl = `${apiUrl}v1/flow-runs/${mapping.flowRunId}/requests/${mapping.requestId}?action=${action}`;
243
-
244
- console.log('[ReceiveMessages] DEBUG - Attempting resume:', {
245
- resumeUrl,
246
- apiUrl,
247
- flowRunId: mapping.flowRunId,
248
- requestId: mapping.requestId,
249
- action,
250
- });
251
-
252
- try {
253
- const response = await httpClient.sendRequest({
254
- method: HttpMethod.POST,
255
- url: resumeUrl,
256
- headers: {
257
- 'Content-Type': 'application/json',
258
- },
259
- });
260
-
261
- console.log('[ReceiveMessages] DEBUG - Resume successful:', {
262
- flowRunId: mapping.flowRunId,
263
- action,
264
- responseStatus: response.status,
265
- responseBody: response.body,
266
- });
267
-
268
- // Delete mapping from Store (cleanup)
269
- await store.delete(storeKey, StoreScope.PROJECT);
270
-
271
- // Delete flowRunId mapping
272
- const flowRunMappingKey = `approval:flowRun:${mapping.flowRunId}`;
273
- await store.delete(flowRunMappingKey, StoreScope.PROJECT);
274
-
275
- // Remove key from approval keys list
276
- const finalKeys = validKeys.filter(key => key !== storeKey);
277
- await store.put(keysListKey, finalKeys, StoreScope.PROJECT);
278
-
279
- console.log('[ReceiveMessages] DEBUG - Cleanup completed');
280
-
281
- return { resumed: true, action };
282
- } catch (error) {
283
- // If resume fails, log but don't throw - message will still be returned
284
- console.error('[ReceiveMessages] DEBUG - Resume failed:', {
285
- error: error instanceof Error ? error.message : String(error),
286
- errorStack: error instanceof Error ? error.stack : undefined,
287
- resumeUrl,
288
- flowRunId: mapping.flowRunId,
289
- reason: 'resume_failed',
290
- });
291
- return { resumed: false };
292
- }
293
- }
294
-
295
- // WebSocket receive function (for json-rpc mode)
296
- export async function tryWebSocketReceive(
297
- httpUrl: string,
298
- headers: Record<string, string>,
299
- timeout: number,
300
- max_messages?: number
301
- ): Promise<SignalMessage[]> {
302
- const wsUrl = httpUrl.replace(/^http:/, 'ws:').replace(/^https:/, 'wss:');
303
- const wsHeaders: Record<string, string> = {
304
- ...headers,
305
- 'Connection': 'Upgrade',
306
- 'Upgrade': 'websocket',
307
- };
308
-
309
- return new Promise((resolve, reject) => {
310
- const messages: SignalMessage[] = [];
311
- let messageCount = 0;
312
- const maxMessagesToCollect = max_messages || Infinity;
313
- const timeoutMs = timeout * 1000;
314
- let resolved = false;
315
-
316
- const resolveOnce = (result: SignalMessage[]) => {
317
- if (!resolved) {
318
- resolved = true;
319
- resolve(result);
320
- }
321
- };
322
-
323
- const rejectOnce = (error: Error) => {
324
- if (!resolved) {
325
- resolved = true;
326
- reject(error);
327
- }
328
- };
329
-
330
- const processMessages = () => {
331
- // Filter messages that have dataMessage (actual message content)
332
- return messages.filter((msg) => msg.envelope?.dataMessage);
333
- };
334
-
335
- const ws = new WebSocket(wsUrl, {
336
- headers: wsHeaders,
337
- });
338
-
339
- const timeoutId = setTimeout(() => {
340
- if (!resolved) {
341
- ws.close();
342
- resolveOnce(processMessages());
343
- }
344
- }, timeoutMs);
345
-
346
- ws.on('open', () => {
347
- // WebSocket connection opened successfully
348
- // The server will send messages as they arrive
349
- });
350
-
351
- ws.on('message', (data: WebSocket.Data) => {
352
- try {
353
- const messageText = data.toString();
354
-
355
- // Check if it's an error message
356
- if (messageText.includes('"error"') || messageText.includes('"Msg"')) {
357
- try {
358
- const errorObj = JSON.parse(messageText);
359
- if (errorObj.error || errorObj.Msg) {
360
- clearTimeout(timeoutId);
361
- ws.close();
362
- // If it's a "no messages" type error, return empty array
363
- if (errorObj.Msg && errorObj.Msg.includes('No new messages')) {
364
- resolveOnce([]);
365
- } else {
366
- rejectOnce(new Error(errorObj.error || errorObj.Msg));
367
- }
368
- return;
369
- }
370
- } catch {
371
- // Not a JSON error, continue processing
372
- }
373
- }
374
-
375
- // Try to parse as JSON message
376
- try {
377
- const message: SignalMessage = JSON.parse(messageText);
378
- messages.push(message);
379
- messageCount++;
380
-
381
- // If we've reached max_messages, close the connection
382
- if (messageCount >= maxMessagesToCollect) {
383
- clearTimeout(timeoutId);
384
- ws.close();
385
- resolveOnce(processMessages());
386
- }
387
- } catch (parseError) {
388
- // If parsing fails, ignore this message
389
- // The server might send non-JSON data
390
- }
391
- } catch (error) {
392
- // Ignore individual message errors
393
- }
394
- });
395
-
396
- ws.on('error', (error) => {
397
- clearTimeout(timeoutId);
398
- ws.close();
399
- // Reject to trigger fallback to HTTP GET
400
- rejectOnce(error);
401
- });
402
-
403
- ws.on('close', () => {
404
- clearTimeout(timeoutId);
405
- // If we haven't resolved yet, resolve with collected messages
406
- if (!resolved) {
407
- resolveOnce(processMessages());
408
- }
409
- });
410
- });
411
- }
412
-
413
- // HTTP GET receive function (for normal/native mode)
414
- export async function tryHttpReceive(
415
- httpUrl: string,
416
- headers: Record<string, string>
417
- ): Promise<SignalMessage[]> {
418
- try {
419
- const response = await httpClient.sendRequest<SignalMessage[] | string>({
420
- method: HttpMethod.GET,
421
- url: httpUrl,
422
- headers,
423
- });
424
-
425
- // The API returns either a JSON array of messages or a JSON string
426
- let messages: SignalMessage[] = [];
427
- if (typeof response.body === 'string') {
428
- try {
429
- messages = JSON.parse(response.body);
430
- } catch {
431
- // If parsing fails, try to parse as array
432
- messages = [];
433
- }
434
- } else if (Array.isArray(response.body)) {
435
- messages = response.body;
436
- } else {
437
- messages = [];
438
- }
439
-
440
- // Filter messages that have dataMessage (actual message content)
441
- return messages.filter((msg) => msg.envelope?.dataMessage);
442
- } catch (error) {
443
- // If no messages are available, return empty array
444
- if (error instanceof Error && error.message.includes('No new messages')) {
445
- return [];
446
- }
447
- throw error;
448
- }
449
- }
@@ -1,73 +0,0 @@
1
- export interface SendMessageV2Request {
2
- number: string;
3
- recipients: string[];
4
- message: string;
5
- base64_attachments?: string[];
6
- sticker?: string;
7
- mentions?: MessageMention[];
8
- quote_timestamp?: number;
9
- quote_author?: string;
10
- quote_message?: string;
11
- quote_mentions?: MessageMention[];
12
- text_mode?: 'normal' | 'styled';
13
- edit_timestamp?: number;
14
- notify_self?: boolean;
15
- link_preview?: LinkPreviewType;
16
- view_once?: boolean;
17
- }
18
-
19
- export interface MessageMention {
20
- start: number;
21
- length: number;
22
- recipient: string;
23
- }
24
-
25
- export interface LinkPreviewType {
26
- url: string;
27
- title: string;
28
- description?: string;
29
- base64_thumbnail?: string;
30
- }
31
-
32
- export interface GroupEntry {
33
- id: string;
34
- name: string;
35
- description?: string;
36
- members: string[];
37
- admins: string[];
38
- blocked: boolean;
39
- permissions?: GroupPermissions;
40
- group_link?: string;
41
- expiration_time?: number;
42
- pending_requests?: string[];
43
- pending_invites?: string[];
44
- }
45
-
46
- export interface GroupPermissions {
47
- add_members: 'every-member' | 'only-admins';
48
- edit_group: 'every-member' | 'only-admins';
49
- send_messages: 'every-member' | 'only-admins';
50
- }
51
-
52
- export interface ContactEntry {
53
- number: string;
54
- name?: string;
55
- expiration_in_seconds?: number;
56
- }
57
-
58
- export interface IdentityEntry {
59
- number: string;
60
- trust_level: string;
61
- added: string;
62
- safety_number: string;
63
- }
64
-
65
- export interface SendMessageResponse {
66
- timestamp: string;
67
- }
68
-
69
- export interface ErrorResponse {
70
- error: string;
71
- challenge_tokens?: string[];
72
- account?: string;
73
- }
@@ -1,106 +0,0 @@
1
- import { Property, ApFile } from '@activepieces/pieces-framework';
2
- import mime from 'mime-types';
3
-
4
- export const commonProps = {
5
- number: Property.ShortText({
6
- displayName: 'Phone Number',
7
- description: 'Registered phone number in international format (e.g., +43123456789). If not provided, uses the default number from the connection.',
8
- required: false,
9
- }),
10
- recipients: Property.Array({
11
- displayName: 'Recipients',
12
- description: 'Array of phone numbers or group IDs',
13
- required: true,
14
- }),
15
- message: Property.LongText({
16
- displayName: 'Message',
17
- description: 'Message text to send',
18
- required: true,
19
- }),
20
- };
21
-
22
- /**
23
- * Gets the phone number from props or connection default
24
- */
25
- export function getPhoneNumber(
26
- numberFromProps: string | undefined,
27
- defaultNumberFromConnection: string | undefined
28
- ): string {
29
- const phoneNumber = numberFromProps || defaultNumberFromConnection;
30
- if (!phoneNumber) {
31
- throw new Error('Phone number is required. Please provide it in the action or set a default in the connection settings.');
32
- }
33
- return formatPhoneNumber(phoneNumber);
34
- }
35
-
36
- export function validatePhoneNumber(number: string): boolean {
37
- // Basic validation for international phone number format
38
- // Should start with + and contain only digits after that
39
- return /^\+[1-9]\d{1,14}$/.test(number);
40
- }
41
-
42
- export function formatPhoneNumber(number: string): string {
43
- // Remove any spaces, dashes, or parentheses
44
- const cleaned = number.replace(/[\s\-\(\)]/g, '');
45
- // Ensure it starts with +
46
- if (!cleaned.startsWith('+')) {
47
- return '+' + cleaned;
48
- }
49
- return cleaned;
50
- }
51
-
52
- /**
53
- * Converts a file data URL or base64 string to a format suitable for the API
54
- * Supports:
55
- * - Base64 strings (with or without data URL prefix)
56
- * - Data URLs (data:mime/type;base64,base64data)
57
- * - File data URLs with filename (data:mime/type;filename=name;base64,base64data)
58
- */
59
- export function normalizeBase64Attachment(
60
- attachment: string
61
- ): string {
62
- // If it's already a plain base64 string, return as is
63
- if (!attachment.includes(',')) {
64
- return attachment;
65
- }
66
-
67
- // If it's a data URL, extract the base64 part
68
- if (attachment.startsWith('data:')) {
69
- const parts = attachment.split(',');
70
- if (parts.length === 2) {
71
- // Extract mime type and other metadata from the first part
72
- const header = parts[0];
73
- const base64Data = parts[1];
74
-
75
- // Check if it has filename
76
- if (header.includes('filename=')) {
77
- // Format: data:mime/type;filename=name;base64,data
78
- return attachment;
79
- } else if (header.includes('base64')) {
80
- // Format: data:mime/type;base64,data
81
- return attachment;
82
- } else {
83
- // Just base64 data, add data URL prefix
84
- const mimeType = header.replace('data:', '').split(';')[0] || 'application/octet-stream';
85
- return `data:${mimeType};base64,${base64Data}`;
86
- }
87
- }
88
- }
89
-
90
- return attachment;
91
- }
92
-
93
- /**
94
- * Converts file data to base64 string
95
- */
96
- export async function fileToBase64(file: File | Blob): Promise<string> {
97
- return new Promise((resolve, reject) => {
98
- const reader = new FileReader();
99
- reader.onload = () => {
100
- const result = reader.result as string;
101
- resolve(result);
102
- };
103
- reader.onerror = reject;
104
- reader.readAsDataURL(file);
105
- });
106
- }