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.
- package/package.json +26 -4
- package/src/index.d.ts +8 -0
- package/src/index.js +90 -0
- package/src/index.js.map +1 -0
- package/src/lib/actions/add-admins-to-group.d.ts +12 -0
- package/src/lib/actions/add-admins-to-group.js +45 -0
- package/src/lib/actions/add-admins-to-group.js.map +1 -0
- package/src/lib/actions/add-device.d.ts +11 -0
- package/src/lib/actions/add-device.js +40 -0
- package/src/lib/actions/add-device.js.map +1 -0
- package/src/lib/actions/add-members-to-group.d.ts +12 -0
- package/src/lib/actions/add-members-to-group.js +45 -0
- package/src/lib/actions/add-members-to-group.js.map +1 -0
- package/src/lib/actions/block-group.d.ts +11 -0
- package/src/lib/actions/block-group.js +37 -0
- package/src/lib/actions/block-group.js.map +1 -0
- package/src/lib/actions/create-group.d.ts +18 -0
- package/src/lib/actions/create-group.js +117 -0
- package/src/lib/actions/create-group.js.map +1 -0
- package/src/lib/actions/delete-group.d.ts +11 -0
- package/src/lib/actions/delete-group.js +37 -0
- package/src/lib/actions/delete-group.js.map +1 -0
- package/src/lib/actions/get-contact.d.ts +11 -0
- package/src/lib/actions/get-contact.js +37 -0
- package/src/lib/actions/get-contact.js.map +1 -0
- package/src/lib/actions/get-group.d.ts +11 -0
- package/src/lib/actions/get-group.js +37 -0
- package/src/lib/actions/get-group.js.map +1 -0
- package/src/lib/actions/get-qr-code-link.d.ts +11 -0
- package/src/lib/actions/get-qr-code-link.js +60 -0
- package/src/lib/actions/get-qr-code-link.js.map +1 -0
- package/src/lib/actions/join-group.d.ts +11 -0
- package/src/lib/actions/join-group.js +37 -0
- package/src/lib/actions/join-group.js.map +1 -0
- package/src/lib/actions/list-accounts.d.ts +8 -0
- package/src/lib/actions/list-accounts.js +23 -0
- package/src/lib/actions/list-accounts.js.map +1 -0
- package/src/lib/actions/list-attachments.d.ts +8 -0
- package/src/lib/actions/list-attachments.js +23 -0
- package/src/lib/actions/list-attachments.js.map +1 -0
- package/src/lib/actions/list-contacts.d.ts +10 -0
- package/src/lib/actions/list-contacts.js +32 -0
- package/src/lib/actions/list-contacts.js.map +1 -0
- package/src/lib/actions/list-devices.d.ts +10 -0
- package/src/lib/actions/list-devices.js +32 -0
- package/src/lib/actions/list-devices.js.map +1 -0
- package/src/lib/actions/list-groups.d.ts +10 -0
- package/src/lib/actions/list-groups.js +32 -0
- package/src/lib/actions/list-groups.js.map +1 -0
- package/src/lib/actions/list-identities.d.ts +10 -0
- package/src/lib/actions/list-identities.js +32 -0
- package/src/lib/actions/list-identities.js.map +1 -0
- package/src/lib/actions/quit-group.d.ts +11 -0
- package/src/lib/actions/quit-group.js +37 -0
- package/src/lib/actions/quit-group.js.map +1 -0
- package/src/lib/actions/receive-messages.d.ts +15 -0
- package/src/lib/actions/receive-messages.js +100 -0
- package/src/lib/actions/receive-messages.js.map +1 -0
- package/src/lib/actions/remote-delete-message.d.ts +12 -0
- package/src/lib/actions/remote-delete-message.js +46 -0
- package/src/lib/actions/remote-delete-message.js.map +1 -0
- package/src/lib/actions/remove-admins-from-group.d.ts +12 -0
- package/src/lib/actions/remove-admins-from-group.js +45 -0
- package/src/lib/actions/remove-admins-from-group.js.map +1 -0
- package/src/lib/actions/remove-device.d.ts +11 -0
- package/src/lib/actions/remove-device.js +37 -0
- package/src/lib/actions/remove-device.js.map +1 -0
- package/src/lib/actions/remove-members-from-group.d.ts +12 -0
- package/src/lib/actions/remove-members-from-group.js +45 -0
- package/src/lib/actions/remove-members-from-group.js.map +1 -0
- package/src/lib/actions/remove-reaction.d.ts +13 -0
- package/src/lib/actions/remove-reaction.js +52 -0
- package/src/lib/actions/remove-reaction.js.map +1 -0
- package/src/lib/actions/request-approval-message.d.ts +15 -0
- package/src/lib/actions/request-approval-message.js +184 -0
- package/src/lib/actions/request-approval-message.js.map +1 -0
- package/src/lib/actions/resume-approval-flow.d.ts +11 -0
- package/src/lib/actions/resume-approval-flow.js +181 -0
- package/src/lib/actions/resume-approval-flow.js.map +1 -0
- package/src/lib/actions/search-numbers.d.ts +11 -0
- package/src/lib/actions/search-numbers.js +42 -0
- package/src/lib/actions/search-numbers.js.map +1 -0
- package/src/lib/actions/send-message.d.ts +27 -0
- package/src/lib/actions/send-message.js +176 -0
- package/src/lib/actions/send-message.js.map +1 -0
- package/src/lib/actions/send-reaction.d.ts +14 -0
- package/src/lib/actions/send-reaction.js +58 -0
- package/src/lib/actions/send-reaction.js.map +1 -0
- package/src/lib/actions/send-receipt.d.ts +13 -0
- package/src/lib/actions/send-receipt.js +58 -0
- package/src/lib/actions/send-receipt.js.map +1 -0
- package/src/lib/actions/start-typing.d.ts +11 -0
- package/src/lib/actions/start-typing.js +40 -0
- package/src/lib/actions/start-typing.js.map +1 -0
- package/src/lib/actions/stop-typing.d.ts +11 -0
- package/src/lib/actions/stop-typing.js +40 -0
- package/src/lib/actions/stop-typing.js.map +1 -0
- package/src/lib/actions/sync-contacts.d.ts +10 -0
- package/src/lib/actions/sync-contacts.js +32 -0
- package/src/lib/actions/sync-contacts.js.map +1 -0
- package/src/lib/actions/update-account-settings.d.ts +12 -0
- package/src/lib/actions/update-account-settings.js +49 -0
- package/src/lib/actions/update-account-settings.js.map +1 -0
- package/src/lib/actions/update-contact.d.ts +13 -0
- package/src/lib/actions/update-contact.js +56 -0
- package/src/lib/actions/update-contact.js.map +1 -0
- package/src/lib/actions/update-group.d.ts +19 -0
- package/src/lib/actions/update-group.js +125 -0
- package/src/lib/actions/update-group.js.map +1 -0
- package/src/lib/actions/update-profile.d.ts +13 -0
- package/src/lib/actions/update-profile.js +56 -0
- package/src/lib/actions/update-profile.js.map +1 -0
- package/src/lib/common/api-client.d.ts +24 -0
- package/src/lib/common/api-client.js +103 -0
- package/src/lib/common/api-client.js.map +1 -0
- package/src/lib/common/auth.d.ts +8 -0
- package/src/lib/common/auth.js +68 -0
- package/src/lib/common/auth.js.map +1 -0
- package/src/lib/common/message-utils.d.ts +81 -0
- package/src/lib/common/message-utils.js +327 -0
- package/src/lib/common/message-utils.js.map +1 -0
- package/src/lib/common/types.d.ts +65 -0
- package/src/lib/common/types.js +3 -0
- package/src/lib/common/types.js.map +1 -0
- package/src/lib/common/utils.d.ts +23 -0
- package/src/lib/common/utils.js +105 -0
- package/src/lib/common/utils.js.map +1 -0
- package/src/lib/triggers/new-group-member.d.ts +50 -0
- package/src/lib/triggers/new-group-member.js +155 -0
- package/src/lib/triggers/new-group-member.js.map +1 -0
- package/src/lib/triggers/new-message-received.d.ts +58 -0
- package/src/lib/triggers/new-message-received.js +469 -0
- package/src/lib/triggers/new-message-received.js.map +1 -0
- package/project.json +0 -58
- package/src/index.ts +0 -87
- package/src/lib/actions/add-admins-to-group.ts +0 -50
- package/src/lib/actions/add-device.ts +0 -45
- package/src/lib/actions/add-members-to-group.ts +0 -50
- package/src/lib/actions/block-group.ts +0 -36
- package/src/lib/actions/create-group.ts +0 -139
- package/src/lib/actions/delete-group.ts +0 -36
- package/src/lib/actions/get-contact.ts +0 -42
- package/src/lib/actions/get-group.ts +0 -37
- package/src/lib/actions/get-qr-code-link.ts +0 -62
- package/src/lib/actions/join-group.ts +0 -36
- package/src/lib/actions/list-accounts.ts +0 -20
- package/src/lib/actions/list-attachments.ts +0 -20
- package/src/lib/actions/list-contacts.ts +0 -37
- package/src/lib/actions/list-devices.ts +0 -38
- package/src/lib/actions/list-groups.ts +0 -32
- package/src/lib/actions/list-identities.ts +0 -32
- package/src/lib/actions/quit-group.ts +0 -36
- package/src/lib/actions/receive-messages.ts +0 -108
- package/src/lib/actions/remote-delete-message.ts +0 -56
- package/src/lib/actions/remove-admins-from-group.ts +0 -50
- package/src/lib/actions/remove-device.ts +0 -36
- package/src/lib/actions/remove-members-from-group.ts +0 -50
- package/src/lib/actions/remove-reaction.ts +0 -59
- package/src/lib/actions/request-approval-message.ts +0 -215
- package/src/lib/actions/search-numbers.ts +0 -47
- package/src/lib/actions/send-message.ts +0 -189
- package/src/lib/actions/send-reaction.ts +0 -66
- package/src/lib/actions/send-receipt.ts +0 -65
- package/src/lib/actions/start-typing.ts +0 -45
- package/src/lib/actions/stop-typing.ts +0 -45
- package/src/lib/actions/sync-contacts.ts +0 -31
- package/src/lib/actions/update-account-settings.ts +0 -57
- package/src/lib/actions/update-contact.ts +0 -65
- package/src/lib/actions/update-group.ts +0 -145
- package/src/lib/actions/update-profile.ts +0 -65
- package/src/lib/common/api-client.ts +0 -150
- package/src/lib/common/auth.ts +0 -66
- package/src/lib/common/message-utils.ts +0 -449
- package/src/lib/common/types.ts +0 -73
- package/src/lib/common/utils.ts +0 -106
- package/src/lib/triggers/new-group-member.ts +0 -176
- package/src/lib/triggers/new-message-received.ts +0 -618
- package/tsconfig.json +0 -19
- package/tsconfig.lib.json +0 -11
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { createAction, Property } from '@activepieces/pieces-framework';
|
|
2
|
-
import { signalCliRestApiAuth } from '../common/auth';
|
|
3
|
-
import { SignalCliApiClient } from '../common/api-client';
|
|
4
|
-
import { GroupEntry } from '../common/types';
|
|
5
|
-
import { formatPhoneNumber } from '../common/utils';
|
|
6
|
-
|
|
7
|
-
export const listGroups = createAction({
|
|
8
|
-
auth: signalCliRestApiAuth,
|
|
9
|
-
name: 'listGroups',
|
|
10
|
-
displayName: 'List Groups',
|
|
11
|
-
description: 'List all Signal groups for a registered number',
|
|
12
|
-
props: {
|
|
13
|
-
number: Property.ShortText({
|
|
14
|
-
displayName: 'Phone Number',
|
|
15
|
-
description: 'Registered phone number in international format',
|
|
16
|
-
required: true,
|
|
17
|
-
}),
|
|
18
|
-
},
|
|
19
|
-
async run(context) {
|
|
20
|
-
const { number } = context.propsValue;
|
|
21
|
-
// Auth props are passed directly to API client
|
|
22
|
-
|
|
23
|
-
const apiClient = new SignalCliApiClient(context.auth.props);
|
|
24
|
-
const formattedNumber = formatPhoneNumber(number);
|
|
25
|
-
|
|
26
|
-
const response = await apiClient.get<GroupEntry[]>(
|
|
27
|
-
`/v1/groups/${encodeURIComponent(formattedNumber)}`
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
return response;
|
|
31
|
-
},
|
|
32
|
-
});
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { createAction, Property } from '@activepieces/pieces-framework';
|
|
2
|
-
import { signalCliRestApiAuth } from '../common/auth';
|
|
3
|
-
import { SignalCliApiClient } from '../common/api-client';
|
|
4
|
-
import { IdentityEntry } from '../common/types';
|
|
5
|
-
import { formatPhoneNumber } from '../common/utils';
|
|
6
|
-
|
|
7
|
-
export const listIdentities = createAction({
|
|
8
|
-
auth: signalCliRestApiAuth,
|
|
9
|
-
name: 'listIdentities',
|
|
10
|
-
displayName: 'List Identities',
|
|
11
|
-
description: 'List all identities for a registered number',
|
|
12
|
-
props: {
|
|
13
|
-
number: Property.ShortText({
|
|
14
|
-
displayName: 'Phone Number',
|
|
15
|
-
description: 'Registered phone number in international format',
|
|
16
|
-
required: true,
|
|
17
|
-
}),
|
|
18
|
-
},
|
|
19
|
-
async run(context) {
|
|
20
|
-
const { number } = context.propsValue;
|
|
21
|
-
// Auth props are passed directly to API client
|
|
22
|
-
|
|
23
|
-
const apiClient = new SignalCliApiClient(context.auth.props);
|
|
24
|
-
const formattedNumber = formatPhoneNumber(number);
|
|
25
|
-
|
|
26
|
-
const response = await apiClient.get<IdentityEntry[]>(
|
|
27
|
-
`/v1/identities/${encodeURIComponent(formattedNumber)}`
|
|
28
|
-
);
|
|
29
|
-
|
|
30
|
-
return response;
|
|
31
|
-
},
|
|
32
|
-
});
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { createAction, Property } from '@activepieces/pieces-framework';
|
|
2
|
-
import { signalCliRestApiAuth } from '../common/auth';
|
|
3
|
-
import { SignalCliApiClient } from '../common/api-client';
|
|
4
|
-
import { formatPhoneNumber } from '../common/utils';
|
|
5
|
-
|
|
6
|
-
export const quitGroup = createAction({
|
|
7
|
-
auth: signalCliRestApiAuth,
|
|
8
|
-
name: 'quitGroup',
|
|
9
|
-
displayName: 'Quit Group',
|
|
10
|
-
description: 'Quit a Signal group',
|
|
11
|
-
props: {
|
|
12
|
-
number: Property.ShortText({
|
|
13
|
-
displayName: 'Phone Number',
|
|
14
|
-
description: 'Registered phone number in international format',
|
|
15
|
-
required: true,
|
|
16
|
-
}),
|
|
17
|
-
groupid: Property.ShortText({
|
|
18
|
-
displayName: 'Group ID',
|
|
19
|
-
description: 'Group ID (base64 encoded)',
|
|
20
|
-
required: true,
|
|
21
|
-
}),
|
|
22
|
-
},
|
|
23
|
-
async run(context) {
|
|
24
|
-
const { number, groupid } = context.propsValue;
|
|
25
|
-
// Auth props are passed directly to API client
|
|
26
|
-
|
|
27
|
-
const apiClient = new SignalCliApiClient(context.auth.props);
|
|
28
|
-
const formattedNumber = formatPhoneNumber(number);
|
|
29
|
-
|
|
30
|
-
await apiClient.post(
|
|
31
|
-
`/v1/groups/${encodeURIComponent(formattedNumber)}/${encodeURIComponent(groupid)}/quit`
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
return { success: true };
|
|
35
|
-
},
|
|
36
|
-
});
|
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { createAction, Property } from '@activepieces/pieces-framework';
|
|
2
|
-
import { signalCliRestApiAuth } from '../common/auth';
|
|
3
|
-
import { formatPhoneNumber } from '../common/utils';
|
|
4
|
-
import {
|
|
5
|
-
tryWebSocketReceive,
|
|
6
|
-
tryHttpReceive,
|
|
7
|
-
tryResumeApprovalFlow,
|
|
8
|
-
SignalMessage,
|
|
9
|
-
} from '../common/message-utils';
|
|
10
|
-
|
|
11
|
-
export const receiveMessages = createAction({
|
|
12
|
-
auth: signalCliRestApiAuth,
|
|
13
|
-
name: 'receiveMessages',
|
|
14
|
-
displayName: 'Receive Messages',
|
|
15
|
-
description: 'Receive new messages from Signal. Automatically resumes approval flows if a message is a reaction to an approval request. Can be called manually, e.g., from a webhook or scheduler.',
|
|
16
|
-
props: {
|
|
17
|
-
number: Property.ShortText({
|
|
18
|
-
displayName: 'Phone Number',
|
|
19
|
-
description: 'Registered phone number in international format (e.g., +43123456789)',
|
|
20
|
-
required: true,
|
|
21
|
-
}),
|
|
22
|
-
timeout: Property.Number({
|
|
23
|
-
displayName: 'Timeout (seconds)',
|
|
24
|
-
description: 'Receive timeout in seconds (default: 1)',
|
|
25
|
-
required: false,
|
|
26
|
-
defaultValue: 1,
|
|
27
|
-
}),
|
|
28
|
-
ignore_attachments: Property.Checkbox({
|
|
29
|
-
displayName: 'Ignore Attachments',
|
|
30
|
-
description: 'Ignore attachments when receiving messages',
|
|
31
|
-
required: false,
|
|
32
|
-
defaultValue: false,
|
|
33
|
-
}),
|
|
34
|
-
ignore_stories: Property.Checkbox({
|
|
35
|
-
displayName: 'Ignore Stories',
|
|
36
|
-
description: 'Ignore stories when receiving messages',
|
|
37
|
-
required: false,
|
|
38
|
-
defaultValue: false,
|
|
39
|
-
}),
|
|
40
|
-
max_messages: Property.Number({
|
|
41
|
-
displayName: 'Max Messages',
|
|
42
|
-
description: 'Maximum number of messages to receive (default: unlimited)',
|
|
43
|
-
required: false,
|
|
44
|
-
}),
|
|
45
|
-
send_read_receipts: Property.Checkbox({
|
|
46
|
-
displayName: 'Send Read Receipts',
|
|
47
|
-
description: 'Automatically send read receipts when receiving messages',
|
|
48
|
-
required: false,
|
|
49
|
-
defaultValue: false,
|
|
50
|
-
}),
|
|
51
|
-
},
|
|
52
|
-
async run(context) {
|
|
53
|
-
const { baseUrl, useBasicAuth, basicAuthUsername, basicAuthPassword, mode = 'normal' } = context.auth.props;
|
|
54
|
-
const { number, timeout = 1, ignore_attachments = false, ignore_stories = false, max_messages, send_read_receipts = false } = context.propsValue;
|
|
55
|
-
|
|
56
|
-
const formattedNumber = formatPhoneNumber(number);
|
|
57
|
-
|
|
58
|
-
// Build query parameters
|
|
59
|
-
const queryParams = new URLSearchParams();
|
|
60
|
-
queryParams.append('timeout', timeout.toString());
|
|
61
|
-
queryParams.append('ignore_attachments', ignore_attachments.toString());
|
|
62
|
-
queryParams.append('ignore_stories', ignore_stories.toString());
|
|
63
|
-
if (max_messages) {
|
|
64
|
-
queryParams.append('max_messages', max_messages.toString());
|
|
65
|
-
}
|
|
66
|
-
queryParams.append('send_read_receipts', send_read_receipts.toString());
|
|
67
|
-
|
|
68
|
-
const baseUrlClean = baseUrl.replace(/\/$/, '');
|
|
69
|
-
const httpUrl = `${baseUrlClean}/v1/receive/${encodeURIComponent(formattedNumber)}?${queryParams.toString()}`;
|
|
70
|
-
|
|
71
|
-
// Build headers
|
|
72
|
-
const headers: Record<string, string> = {};
|
|
73
|
-
|
|
74
|
-
// Add Basic Auth header if configured
|
|
75
|
-
if (useBasicAuth && basicAuthUsername && basicAuthPassword) {
|
|
76
|
-
const credentials = Buffer.from(
|
|
77
|
-
`${basicAuthUsername}:${basicAuthPassword}`
|
|
78
|
-
).toString('base64');
|
|
79
|
-
headers['Authorization'] = `Basic ${credentials}`;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
// Use the configured mode to determine which method to use
|
|
83
|
-
let messages: SignalMessage[];
|
|
84
|
-
if (mode === 'json-rpc') {
|
|
85
|
-
// Use WebSocket for json-rpc mode
|
|
86
|
-
messages = await tryWebSocketReceive(httpUrl, headers, timeout, max_messages);
|
|
87
|
-
} else {
|
|
88
|
-
// Use HTTP GET for normal/native mode
|
|
89
|
-
messages = await tryHttpReceive(httpUrl, headers);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Process each message: try to resume approval flows if applicable
|
|
93
|
-
// Messages are still returned regardless of whether they triggered a resume
|
|
94
|
-
// Debug information is output via console.log (visible in Docker logs)
|
|
95
|
-
const apiUrl = context.server?.apiUrl || '';
|
|
96
|
-
|
|
97
|
-
for (const message of messages) {
|
|
98
|
-
// This will output debug info via console.log
|
|
99
|
-
await tryResumeApprovalFlow(message, context.store, apiUrl);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Return messages
|
|
103
|
-
return {
|
|
104
|
-
messages,
|
|
105
|
-
count: messages.length,
|
|
106
|
-
};
|
|
107
|
-
},
|
|
108
|
-
});
|
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { createAction, Property } from '@activepieces/pieces-framework';
|
|
2
|
-
import { signalCliRestApiAuth } from '../common/auth';
|
|
3
|
-
import { SignalCliApiClient } from '../common/api-client';
|
|
4
|
-
import { formatPhoneNumber } from '../common/utils';
|
|
5
|
-
|
|
6
|
-
interface RemoteDeleteRequest {
|
|
7
|
-
recipient: string;
|
|
8
|
-
timestamp: number;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
interface RemoteDeleteResponse {
|
|
12
|
-
timestamp: string;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const remoteDeleteMessage = createAction({
|
|
16
|
-
auth: signalCliRestApiAuth,
|
|
17
|
-
name: 'remoteDeleteMessage',
|
|
18
|
-
displayName: 'Remote Delete Message',
|
|
19
|
-
description: 'Delete a message remotely',
|
|
20
|
-
props: {
|
|
21
|
-
number: Property.ShortText({
|
|
22
|
-
displayName: 'Phone Number',
|
|
23
|
-
description: 'Registered phone number in international format',
|
|
24
|
-
required: true,
|
|
25
|
-
}),
|
|
26
|
-
recipient: Property.ShortText({
|
|
27
|
-
displayName: 'Recipient',
|
|
28
|
-
description: 'Phone number or group ID of the recipient',
|
|
29
|
-
required: true,
|
|
30
|
-
}),
|
|
31
|
-
timestamp: Property.Number({
|
|
32
|
-
displayName: 'Timestamp',
|
|
33
|
-
description: 'Timestamp of the message to delete',
|
|
34
|
-
required: true,
|
|
35
|
-
}),
|
|
36
|
-
},
|
|
37
|
-
async run(context) {
|
|
38
|
-
const { number, recipient, timestamp } = context.propsValue;
|
|
39
|
-
// Auth props are passed directly to API client
|
|
40
|
-
|
|
41
|
-
const apiClient = new SignalCliApiClient(context.auth.props);
|
|
42
|
-
const formattedNumber = formatPhoneNumber(number);
|
|
43
|
-
|
|
44
|
-
const requestBody: RemoteDeleteRequest = {
|
|
45
|
-
recipient,
|
|
46
|
-
timestamp,
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const response = await apiClient.delete<RemoteDeleteResponse>(
|
|
50
|
-
`/v1/remote-delete/${encodeURIComponent(formattedNumber)}`,
|
|
51
|
-
requestBody
|
|
52
|
-
);
|
|
53
|
-
|
|
54
|
-
return response;
|
|
55
|
-
},
|
|
56
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { createAction, Property } from '@activepieces/pieces-framework';
|
|
2
|
-
import { signalCliRestApiAuth } from '../common/auth';
|
|
3
|
-
import { SignalCliApiClient } from '../common/api-client';
|
|
4
|
-
import { formatPhoneNumber } from '../common/utils';
|
|
5
|
-
|
|
6
|
-
interface ChangeGroupAdminsRequest {
|
|
7
|
-
admins: string[];
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const removeAdminsFromGroup = createAction({
|
|
11
|
-
auth: signalCliRestApiAuth,
|
|
12
|
-
name: 'removeAdminsFromGroup',
|
|
13
|
-
displayName: 'Remove Admins from Group',
|
|
14
|
-
description: 'Remove one or more admins from a Signal group',
|
|
15
|
-
props: {
|
|
16
|
-
number: Property.ShortText({
|
|
17
|
-
displayName: 'Phone Number',
|
|
18
|
-
description: 'Registered phone number in international format',
|
|
19
|
-
required: true,
|
|
20
|
-
}),
|
|
21
|
-
groupid: Property.ShortText({
|
|
22
|
-
displayName: 'Group ID',
|
|
23
|
-
description: 'Group ID (base64 encoded)',
|
|
24
|
-
required: true,
|
|
25
|
-
}),
|
|
26
|
-
admins: Property.Array({
|
|
27
|
-
displayName: 'Admins',
|
|
28
|
-
description: 'Array of phone numbers to remove as admins',
|
|
29
|
-
required: true,
|
|
30
|
-
}),
|
|
31
|
-
},
|
|
32
|
-
async run(context) {
|
|
33
|
-
const { number, groupid, admins } = context.propsValue;
|
|
34
|
-
// Auth props are passed directly to API client
|
|
35
|
-
|
|
36
|
-
const apiClient = new SignalCliApiClient(context.auth.props);
|
|
37
|
-
const formattedNumber = formatPhoneNumber(number);
|
|
38
|
-
|
|
39
|
-
const requestBody: ChangeGroupAdminsRequest = {
|
|
40
|
-
admins: admins as string[],
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
await apiClient.delete(
|
|
44
|
-
`/v1/groups/${encodeURIComponent(formattedNumber)}/${encodeURIComponent(groupid)}/admins`,
|
|
45
|
-
requestBody
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
return { success: true };
|
|
49
|
-
},
|
|
50
|
-
});
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import { createAction, Property } from '@activepieces/pieces-framework';
|
|
2
|
-
import { signalCliRestApiAuth } from '../common/auth';
|
|
3
|
-
import { SignalCliApiClient } from '../common/api-client';
|
|
4
|
-
import { formatPhoneNumber } from '../common/utils';
|
|
5
|
-
|
|
6
|
-
export const removeDevice = createAction({
|
|
7
|
-
auth: signalCliRestApiAuth,
|
|
8
|
-
name: 'removeDevice',
|
|
9
|
-
displayName: 'Remove Device',
|
|
10
|
-
description: 'Remove a linked device from the primary account',
|
|
11
|
-
props: {
|
|
12
|
-
number: Property.ShortText({
|
|
13
|
-
displayName: 'Phone Number',
|
|
14
|
-
description: 'Registered phone number in international format',
|
|
15
|
-
required: true,
|
|
16
|
-
}),
|
|
17
|
-
deviceId: Property.Number({
|
|
18
|
-
displayName: 'Device ID',
|
|
19
|
-
description: 'Device ID from listDevices',
|
|
20
|
-
required: true,
|
|
21
|
-
}),
|
|
22
|
-
},
|
|
23
|
-
async run(context) {
|
|
24
|
-
const { number, deviceId } = context.propsValue;
|
|
25
|
-
// Auth props are passed directly to API client
|
|
26
|
-
|
|
27
|
-
const apiClient = new SignalCliApiClient(context.auth.props);
|
|
28
|
-
const formattedNumber = formatPhoneNumber(number);
|
|
29
|
-
|
|
30
|
-
await apiClient.delete(
|
|
31
|
-
`/v1/devices/${encodeURIComponent(formattedNumber)}/${deviceId}`
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
return { success: true };
|
|
35
|
-
},
|
|
36
|
-
});
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
import { createAction, Property } from '@activepieces/pieces-framework';
|
|
2
|
-
import { signalCliRestApiAuth } from '../common/auth';
|
|
3
|
-
import { SignalCliApiClient } from '../common/api-client';
|
|
4
|
-
import { formatPhoneNumber } from '../common/utils';
|
|
5
|
-
|
|
6
|
-
interface ChangeGroupMembersRequest {
|
|
7
|
-
members: string[];
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export const removeMembersFromGroup = createAction({
|
|
11
|
-
auth: signalCliRestApiAuth,
|
|
12
|
-
name: 'removeMembersFromGroup',
|
|
13
|
-
displayName: 'Remove Members from Group',
|
|
14
|
-
description: 'Remove one or more members from a Signal group',
|
|
15
|
-
props: {
|
|
16
|
-
number: Property.ShortText({
|
|
17
|
-
displayName: 'Phone Number',
|
|
18
|
-
description: 'Registered phone number in international format',
|
|
19
|
-
required: true,
|
|
20
|
-
}),
|
|
21
|
-
groupid: Property.ShortText({
|
|
22
|
-
displayName: 'Group ID',
|
|
23
|
-
description: 'Group ID (base64 encoded)',
|
|
24
|
-
required: true,
|
|
25
|
-
}),
|
|
26
|
-
members: Property.Array({
|
|
27
|
-
displayName: 'Members',
|
|
28
|
-
description: 'Array of phone numbers to remove',
|
|
29
|
-
required: true,
|
|
30
|
-
}),
|
|
31
|
-
},
|
|
32
|
-
async run(context) {
|
|
33
|
-
const { number, groupid, members } = context.propsValue;
|
|
34
|
-
// Auth props are passed directly to API client
|
|
35
|
-
|
|
36
|
-
const apiClient = new SignalCliApiClient(context.auth.props);
|
|
37
|
-
const formattedNumber = formatPhoneNumber(number);
|
|
38
|
-
|
|
39
|
-
const requestBody: ChangeGroupMembersRequest = {
|
|
40
|
-
members: members as string[],
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
await apiClient.delete(
|
|
44
|
-
`/v1/groups/${encodeURIComponent(formattedNumber)}/${encodeURIComponent(groupid)}/members`,
|
|
45
|
-
requestBody
|
|
46
|
-
);
|
|
47
|
-
|
|
48
|
-
return { success: true };
|
|
49
|
-
},
|
|
50
|
-
});
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { createAction, Property } from '@activepieces/pieces-framework';
|
|
2
|
-
import { signalCliRestApiAuth } from '../common/auth';
|
|
3
|
-
import { SignalCliApiClient } from '../common/api-client';
|
|
4
|
-
import { formatPhoneNumber } from '../common/utils';
|
|
5
|
-
|
|
6
|
-
interface ReactionRequest {
|
|
7
|
-
recipient: string;
|
|
8
|
-
target_author: string;
|
|
9
|
-
timestamp: number;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const removeReaction = createAction({
|
|
13
|
-
auth: signalCliRestApiAuth,
|
|
14
|
-
name: 'removeReaction',
|
|
15
|
-
displayName: 'Remove Reaction',
|
|
16
|
-
description: 'Remove a reaction from a message',
|
|
17
|
-
props: {
|
|
18
|
-
number: Property.ShortText({
|
|
19
|
-
displayName: 'Phone Number',
|
|
20
|
-
description: 'Registered phone number in international format',
|
|
21
|
-
required: true,
|
|
22
|
-
}),
|
|
23
|
-
recipient: Property.ShortText({
|
|
24
|
-
displayName: 'Recipient',
|
|
25
|
-
description: 'Phone number or group ID of the recipient',
|
|
26
|
-
required: true,
|
|
27
|
-
}),
|
|
28
|
-
target_author: Property.ShortText({
|
|
29
|
-
displayName: 'Target Author',
|
|
30
|
-
description: 'Phone number of the message author',
|
|
31
|
-
required: true,
|
|
32
|
-
}),
|
|
33
|
-
timestamp: Property.Number({
|
|
34
|
-
displayName: 'Timestamp',
|
|
35
|
-
description: 'Timestamp of the message',
|
|
36
|
-
required: true,
|
|
37
|
-
}),
|
|
38
|
-
},
|
|
39
|
-
async run(context) {
|
|
40
|
-
const { number, recipient, target_author, timestamp } = context.propsValue;
|
|
41
|
-
// Auth props are passed directly to API client
|
|
42
|
-
|
|
43
|
-
const apiClient = new SignalCliApiClient(context.auth.props);
|
|
44
|
-
const formattedNumber = formatPhoneNumber(number);
|
|
45
|
-
|
|
46
|
-
const requestBody: ReactionRequest = {
|
|
47
|
-
recipient,
|
|
48
|
-
target_author,
|
|
49
|
-
timestamp,
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
await apiClient.delete(
|
|
53
|
-
`/v1/reactions/${encodeURIComponent(formattedNumber)}`,
|
|
54
|
-
requestBody
|
|
55
|
-
);
|
|
56
|
-
|
|
57
|
-
return { success: true };
|
|
58
|
-
},
|
|
59
|
-
});
|
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
import { createAction, Property, StoreScope } from '@activepieces/pieces-framework';
|
|
2
|
-
import { signalCliRestApiAuth } from '../common/auth';
|
|
3
|
-
import { SignalCliApiClient } from '../common/api-client';
|
|
4
|
-
import { SendMessageV2Request, SendMessageResponse } from '../common/types';
|
|
5
|
-
import { formatPhoneNumber, commonProps } from '../common/utils';
|
|
6
|
-
import { ExecutionType, PauseType } from '@activepieces/shared';
|
|
7
|
-
import { assertNotNullOrUndefined } from '@activepieces/shared';
|
|
8
|
-
|
|
9
|
-
interface ApprovalMapping {
|
|
10
|
-
flowRunId: string;
|
|
11
|
-
requestId: string;
|
|
12
|
-
approveEmoji: string;
|
|
13
|
-
disapproveEmoji: string;
|
|
14
|
-
targetAuthor: string;
|
|
15
|
-
messageTimestamp: number;
|
|
16
|
-
timeoutSeconds: number;
|
|
17
|
-
createdAt: number;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export const requestApprovalMessage = createAction({
|
|
21
|
-
auth: signalCliRestApiAuth,
|
|
22
|
-
name: 'request_approval_message',
|
|
23
|
-
displayName: 'Request Approval (Signal)',
|
|
24
|
-
description: 'Send an approval message via Signal and wait for a reaction response. This action sends a message and pauses the flow until the recipient reacts with an approve or disapprove emoji.',
|
|
25
|
-
props: {
|
|
26
|
-
number: Property.ShortText({
|
|
27
|
-
displayName: 'Phone Number',
|
|
28
|
-
description: 'Registered phone number in international format (e.g., +43123456789). If not provided, uses the default number from the connection.',
|
|
29
|
-
required: false,
|
|
30
|
-
}),
|
|
31
|
-
recipients: commonProps.recipients,
|
|
32
|
-
message: commonProps.message,
|
|
33
|
-
approve_emoji: Property.ShortText({
|
|
34
|
-
displayName: 'Approve Emoji',
|
|
35
|
-
description: 'Emoji for approval (e.g., 👍)',
|
|
36
|
-
required: false,
|
|
37
|
-
defaultValue: '👍',
|
|
38
|
-
}),
|
|
39
|
-
disapprove_emoji: Property.ShortText({
|
|
40
|
-
displayName: 'Disapprove Emoji',
|
|
41
|
-
description: 'Emoji for disapproval (e.g., 👎)',
|
|
42
|
-
required: false,
|
|
43
|
-
defaultValue: '👎',
|
|
44
|
-
}),
|
|
45
|
-
timeout_seconds: Property.Number({
|
|
46
|
-
displayName: 'Timeout (seconds)',
|
|
47
|
-
description: 'Timeout in seconds after which the approval expires (default: 86400 = 24 hours)',
|
|
48
|
-
required: false,
|
|
49
|
-
defaultValue: 86400,
|
|
50
|
-
}),
|
|
51
|
-
},
|
|
52
|
-
async run(context) {
|
|
53
|
-
if (context.executionType === ExecutionType.BEGIN) {
|
|
54
|
-
const { number, recipients, message, approve_emoji = '👍', disapprove_emoji = '👎', timeout_seconds = 86400 } = context.propsValue;
|
|
55
|
-
|
|
56
|
-
assertNotNullOrUndefined(message, 'message');
|
|
57
|
-
assertNotNullOrUndefined(recipients, 'recipients');
|
|
58
|
-
|
|
59
|
-
const apiClient = new SignalCliApiClient(context.auth.props);
|
|
60
|
-
|
|
61
|
-
// Use number from props or fallback to default from connection
|
|
62
|
-
const phoneNumber = number || context.auth.props.defaultNumber;
|
|
63
|
-
if (!phoneNumber) {
|
|
64
|
-
throw new Error('Phone number is required. Please provide it in the action or set a default in the connection settings.');
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
const formattedNumber = formatPhoneNumber(phoneNumber);
|
|
68
|
-
|
|
69
|
-
// Generate resume URL to extract requestId
|
|
70
|
-
const resumeUrl = context.generateResumeUrl({
|
|
71
|
-
queryParams: { action: 'approve' },
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
// Extract requestId from URL: /v1/flow-runs/{flowRunId}/requests/{requestId}
|
|
75
|
-
const urlMatch = resumeUrl.match(/\/flow-runs\/[^/]+\/requests\/([^/?]+)/);
|
|
76
|
-
if (!urlMatch || !urlMatch[1]) {
|
|
77
|
-
throw new Error('Failed to extract requestId from resume URL');
|
|
78
|
-
}
|
|
79
|
-
const requestId = urlMatch[1];
|
|
80
|
-
|
|
81
|
-
// Prepare request body - send message exactly as user entered it
|
|
82
|
-
const requestBody: SendMessageV2Request = {
|
|
83
|
-
number: formattedNumber,
|
|
84
|
-
recipients: recipients as string[],
|
|
85
|
-
message: message || '',
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
// Send the message
|
|
89
|
-
const response = await apiClient.post<SendMessageResponse>('/v2/send', requestBody);
|
|
90
|
-
|
|
91
|
-
// Extract messageTimestamp from response
|
|
92
|
-
// Signal API returns timestamp in milliseconds as a string, convert to seconds (Unix timestamp)
|
|
93
|
-
const timestampMs = typeof response.timestamp === 'string'
|
|
94
|
-
? parseInt(response.timestamp, 10)
|
|
95
|
-
: Math.floor(response.timestamp);
|
|
96
|
-
const messageTimestamp = Math.floor(timestampMs / 1000); // Convert milliseconds to seconds
|
|
97
|
-
|
|
98
|
-
// targetAuthor is the phone number of the sender
|
|
99
|
-
const targetAuthor = formattedNumber;
|
|
100
|
-
const createdAt = Math.floor(Date.now() / 1000); // Unix timestamp in seconds
|
|
101
|
-
|
|
102
|
-
// Create store key
|
|
103
|
-
const storeKey = `approval:${messageTimestamp}:${targetAuthor}`;
|
|
104
|
-
|
|
105
|
-
// DEBUG: Log storing approval mapping
|
|
106
|
-
console.log('[RequestApprovalMessage] DEBUG - Storing approval mapping:', {
|
|
107
|
-
storeKey,
|
|
108
|
-
timestampMs,
|
|
109
|
-
messageTimestamp,
|
|
110
|
-
targetAuthor,
|
|
111
|
-
formattedNumber,
|
|
112
|
-
flowRunId: context.run.id,
|
|
113
|
-
requestId,
|
|
114
|
-
responseTimestamp: response.timestamp,
|
|
115
|
-
responseTimestampType: typeof response.timestamp
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
// Create mapping value
|
|
119
|
-
const mapping: ApprovalMapping = {
|
|
120
|
-
flowRunId: context.run.id,
|
|
121
|
-
requestId: requestId,
|
|
122
|
-
approveEmoji: approve_emoji,
|
|
123
|
-
disapproveEmoji: disapprove_emoji,
|
|
124
|
-
targetAuthor: targetAuthor,
|
|
125
|
-
messageTimestamp: messageTimestamp,
|
|
126
|
-
timeoutSeconds: timeout_seconds,
|
|
127
|
-
createdAt: createdAt,
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
// DEBUG: Log full mapping
|
|
131
|
-
console.log('[RequestApprovalMessage] DEBUG - Full mapping object:', mapping);
|
|
132
|
-
|
|
133
|
-
// Save mapping in Store (PROJECT-scoped)
|
|
134
|
-
await context.store.put(storeKey, mapping, StoreScope.PROJECT);
|
|
135
|
-
|
|
136
|
-
// DEBUG: Verify it was stored
|
|
137
|
-
const verifyMapping = await context.store.get<ApprovalMapping>(storeKey, StoreScope.PROJECT);
|
|
138
|
-
console.log('[RequestApprovalMessage] DEBUG - Verified stored mapping:', verifyMapping);
|
|
139
|
-
|
|
140
|
-
// Add key to approval keys list
|
|
141
|
-
const keysListKey = 'approval:keys';
|
|
142
|
-
const existingKeys = (await context.store.get<string[]>(keysListKey, StoreScope.PROJECT)) || [];
|
|
143
|
-
if (!existingKeys.includes(storeKey)) {
|
|
144
|
-
existingKeys.push(storeKey);
|
|
145
|
-
await context.store.put(keysListKey, existingKeys, StoreScope.PROJECT);
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Also save mapping from flowRunId to storeKey for easy lookup in RESUME phase
|
|
149
|
-
const flowRunMappingKey = `approval:flowRun:${context.run.id}`;
|
|
150
|
-
await context.store.put(flowRunMappingKey, storeKey, StoreScope.PROJECT);
|
|
151
|
-
|
|
152
|
-
const output = {
|
|
153
|
-
messageTimestamp,
|
|
154
|
-
targetAuthor,
|
|
155
|
-
flowRunId: context.run.id,
|
|
156
|
-
requestId,
|
|
157
|
-
debug: {
|
|
158
|
-
timestampMs,
|
|
159
|
-
messageTimestamp,
|
|
160
|
-
storeKey,
|
|
161
|
-
formattedNumber,
|
|
162
|
-
responseTimestamp: response.timestamp,
|
|
163
|
-
responseTimestampType: typeof response.timestamp,
|
|
164
|
-
approveEmoji: approve_emoji,
|
|
165
|
-
disapproveEmoji: disapprove_emoji,
|
|
166
|
-
timeoutSeconds: timeout_seconds,
|
|
167
|
-
createdAt,
|
|
168
|
-
mapping: mapping,
|
|
169
|
-
verifiedMapping: verifyMapping,
|
|
170
|
-
},
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
// Pause the flow and wait for approval
|
|
174
|
-
context.run.pause({
|
|
175
|
-
pauseMetadata: {
|
|
176
|
-
type: PauseType.WEBHOOK,
|
|
177
|
-
response: {},
|
|
178
|
-
},
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
return output;
|
|
182
|
-
} else {
|
|
183
|
-
// RESUME-Phase: Flow was resumed by Resume-Action
|
|
184
|
-
const action = context.resumePayload.queryParams['action'];
|
|
185
|
-
const approved = action === 'approve';
|
|
186
|
-
|
|
187
|
-
// Find the storeKey for this flowRunId
|
|
188
|
-
const flowRunMappingKey = `approval:flowRun:${context.run.id}`;
|
|
189
|
-
const storeKey = await context.store.get<string>(flowRunMappingKey, StoreScope.PROJECT);
|
|
190
|
-
|
|
191
|
-
if (storeKey) {
|
|
192
|
-
// Delete mapping from Store
|
|
193
|
-
await context.store.delete(storeKey, StoreScope.PROJECT);
|
|
194
|
-
|
|
195
|
-
// Delete flowRunId mapping
|
|
196
|
-
await context.store.delete(flowRunMappingKey, StoreScope.PROJECT);
|
|
197
|
-
|
|
198
|
-
// Remove key from approval keys list
|
|
199
|
-
const keysListKey = 'approval:keys';
|
|
200
|
-
const existingKeys = (await context.store.get<string[]>(keysListKey, StoreScope.PROJECT)) || [];
|
|
201
|
-
const updatedKeys = existingKeys.filter(key => key !== storeKey);
|
|
202
|
-
await context.store.put(keysListKey, updatedKeys, StoreScope.PROJECT);
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return {
|
|
206
|
-
approved,
|
|
207
|
-
debug: {
|
|
208
|
-
action,
|
|
209
|
-
storeKey: storeKey || null,
|
|
210
|
-
flowRunId: context.run.id,
|
|
211
|
-
},
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
},
|
|
215
|
-
});
|