@agent-comm/piece-agent-comms 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@agent-comm/piece-agent-comms",
3
+ "version": "0.1.0",
4
+ "description": "Agent Comms — voice-agent communications. Triggers on calls, appointments and chats; place outbound calls, upsert contacts and send SMS.",
5
+ "type": "commonjs",
6
+ "main": "./src/index.js",
7
+ "types": "./src/index.d.ts",
8
+ "files": [
9
+ "src"
10
+ ],
11
+ "scripts": {
12
+ "build": "tsc"
13
+ },
14
+ "dependencies": {
15
+ "@activepieces/pieces-common": "0.12.4",
16
+ "@activepieces/pieces-framework": "0.30.0",
17
+ "@activepieces/shared": "0.92.0",
18
+ "tslib": "2.6.2"
19
+ },
20
+ "devDependencies": {
21
+ "typescript": "5.4.5"
22
+ }
23
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export declare const agentComms: import("@activepieces/pieces-framework").Piece<import("@activepieces/pieces-framework").SecretTextProperty<true>>;
package/src/index.js ADDED
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.agentComms = void 0;
4
+ const pieces_framework_1 = require("@activepieces/pieces-framework");
5
+ const shared_1 = require("@activepieces/shared");
6
+ const auth_1 = require("./lib/auth");
7
+ const call_completed_1 = require("./lib/triggers/call-completed");
8
+ const appointment_created_1 = require("./lib/triggers/appointment-created");
9
+ const chat_completed_1 = require("./lib/triggers/chat-completed");
10
+ const make_outbound_call_1 = require("./lib/actions/make-outbound-call");
11
+ const upsert_contact_1 = require("./lib/actions/upsert-contact");
12
+ const send_sms_1 = require("./lib/actions/send-sms");
13
+ // Agent Comms — voice-agent communications. Neutral white-label name (NOT the platform's brand) so
14
+ // resellers' customers never see who powers it. One opaque API key per workspace scopes every
15
+ // trigger and action to that org server-side; the piece itself holds no org identity.
16
+ // TODO before install: upload a neutral logo to the agent-comms-logo.png path below.
17
+ exports.agentComms = (0, pieces_framework_1.createPiece)({
18
+ displayName: 'Agent Comms',
19
+ description: 'Agent communications. Trigger flows on completed calls, new appointments and finished chats; place outbound calls, upsert CRM contacts, and send SMS.',
20
+ auth: auth_1.bellvoxAuth,
21
+ minimumSupportedRelease: '0.36.1',
22
+ logoUrl: 'https://ajhcthysvaaqunjvqlgy.supabase.co/storage/v1/object/public/public/agent-comms-logo.png',
23
+ categories: [shared_1.PieceCategory.COMMUNICATION, shared_1.PieceCategory.SALES_AND_CRM],
24
+ authors: ['agent-comms'],
25
+ triggers: [call_completed_1.callCompleted, appointment_created_1.appointmentCreated, chat_completed_1.chatCompleted],
26
+ actions: [make_outbound_call_1.makeOutboundCall, upsert_contact_1.upsertContact, send_sms_1.sendSms],
27
+ });
package/src/index.ts ADDED
@@ -0,0 +1,26 @@
1
+ import { createPiece } from '@activepieces/pieces-framework';
2
+ import { PieceCategory } from '@activepieces/shared';
3
+ import { bellvoxAuth } from './lib/auth';
4
+ import { callCompleted } from './lib/triggers/call-completed';
5
+ import { appointmentCreated } from './lib/triggers/appointment-created';
6
+ import { chatCompleted } from './lib/triggers/chat-completed';
7
+ import { makeOutboundCall } from './lib/actions/make-outbound-call';
8
+ import { upsertContact } from './lib/actions/upsert-contact';
9
+ import { sendSms } from './lib/actions/send-sms';
10
+
11
+ // Agent Comms — voice-agent communications. Neutral white-label name (NOT the platform's brand) so
12
+ // resellers' customers never see who powers it. One opaque API key per workspace scopes every
13
+ // trigger and action to that org server-side; the piece itself holds no org identity.
14
+ // TODO before install: upload a neutral logo to the agent-comms-logo.png path below.
15
+ export const agentComms = createPiece({
16
+ displayName: 'Agent Comms',
17
+ description:
18
+ 'Agent communications. Trigger flows on completed calls, new appointments and finished chats; place outbound calls, upsert CRM contacts, and send SMS.',
19
+ auth: bellvoxAuth,
20
+ minimumSupportedRelease: '0.36.1',
21
+ logoUrl: 'https://ajhcthysvaaqunjvqlgy.supabase.co/storage/v1/object/public/public/agent-comms-logo.png',
22
+ categories: [PieceCategory.COMMUNICATION, PieceCategory.SALES_AND_CRM],
23
+ authors: ['agent-comms'],
24
+ triggers: [callCompleted, appointmentCreated, chatCompleted],
25
+ actions: [makeOutboundCall, upsertContact, sendSms],
26
+ });
@@ -0,0 +1,4 @@
1
+ export declare const makeOutboundCall: import("@activepieces/pieces-framework").IAction<import("@activepieces/pieces-framework").SecretTextProperty<true>, {
2
+ assistant_id: import("@activepieces/pieces-framework").ShortTextProperty<true>;
3
+ to_number: import("@activepieces/pieces-framework").ShortTextProperty<true>;
4
+ }>;
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeOutboundCall = void 0;
4
+ const pieces_framework_1 = require("@activepieces/pieces-framework");
5
+ const pieces_common_1 = require("@activepieces/pieces-common");
6
+ const auth_1 = require("../auth");
7
+ const common_1 = require("../common");
8
+ // Place an outbound AI call. The edge fn verifies the assistant belongs to the key's org
9
+ // before dialing — we never trust the assistant_id alone.
10
+ exports.makeOutboundCall = (0, pieces_framework_1.createAction)({
11
+ auth: auth_1.bellvoxAuth,
12
+ name: 'make_outbound_call',
13
+ displayName: 'Make Outbound Call',
14
+ description: 'Have a Bellvox assistant place an outbound phone call.',
15
+ props: {
16
+ assistant_id: pieces_framework_1.Property.ShortText({
17
+ displayName: 'Assistant ID',
18
+ description: 'The Bellvox assistant that should place the call.',
19
+ required: true,
20
+ }),
21
+ to_number: pieces_framework_1.Property.ShortText({
22
+ displayName: 'To Number',
23
+ description: 'Destination phone number in E.164 format, e.g. +15557654321.',
24
+ required: true,
25
+ }),
26
+ },
27
+ async run(context) {
28
+ const res = await pieces_common_1.httpClient.sendRequest({
29
+ method: pieces_common_1.HttpMethod.POST,
30
+ url: `${common_1.BELLVOX_API}/ap-actions?do=make_outbound_call`,
31
+ headers: { 'x-bellvox-key': (0, common_1.authKey)(context.auth) },
32
+ body: {
33
+ assistant_id: context.propsValue.assistant_id,
34
+ to_number: context.propsValue.to_number,
35
+ },
36
+ });
37
+ return res.body;
38
+ },
39
+ });
@@ -0,0 +1,37 @@
1
+ import { createAction, Property } from '@activepieces/pieces-framework';
2
+ import { httpClient, HttpMethod } from '@activepieces/pieces-common';
3
+ import { bellvoxAuth } from '../auth';
4
+ import { BELLVOX_API, authKey } from '../common';
5
+
6
+ // Place an outbound AI call. The edge fn verifies the assistant belongs to the key's org
7
+ // before dialing — we never trust the assistant_id alone.
8
+ export const makeOutboundCall = createAction({
9
+ auth: bellvoxAuth,
10
+ name: 'make_outbound_call',
11
+ displayName: 'Make Outbound Call',
12
+ description: 'Have a Bellvox assistant place an outbound phone call.',
13
+ props: {
14
+ assistant_id: Property.ShortText({
15
+ displayName: 'Assistant ID',
16
+ description: 'The Bellvox assistant that should place the call.',
17
+ required: true,
18
+ }),
19
+ to_number: Property.ShortText({
20
+ displayName: 'To Number',
21
+ description: 'Destination phone number in E.164 format, e.g. +15557654321.',
22
+ required: true,
23
+ }),
24
+ },
25
+ async run(context) {
26
+ const res = await httpClient.sendRequest({
27
+ method: HttpMethod.POST,
28
+ url: `${BELLVOX_API}/ap-actions?do=make_outbound_call`,
29
+ headers: { 'x-bellvox-key': authKey(context.auth) },
30
+ body: {
31
+ assistant_id: context.propsValue.assistant_id,
32
+ to_number: context.propsValue.to_number,
33
+ },
34
+ });
35
+ return res.body;
36
+ },
37
+ });
@@ -0,0 +1,4 @@
1
+ export declare const sendSms: import("@activepieces/pieces-framework").IAction<import("@activepieces/pieces-framework").SecretTextProperty<true>, {
2
+ to: import("@activepieces/pieces-framework").ShortTextProperty<true>;
3
+ body: import("@activepieces/pieces-framework").LongTextProperty<true>;
4
+ }>;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sendSms = void 0;
4
+ const pieces_framework_1 = require("@activepieces/pieces-framework");
5
+ const pieces_common_1 = require("@activepieces/pieces-common");
6
+ const auth_1 = require("../auth");
7
+ const common_1 = require("../common");
8
+ // Send an SMS from the org's active number. Sender selection + carrier auth happen server-side.
9
+ exports.sendSms = (0, pieces_framework_1.createAction)({
10
+ auth: auth_1.bellvoxAuth,
11
+ name: 'send_sms',
12
+ displayName: 'Send SMS',
13
+ description: 'Send a text message from your Bellvox number.',
14
+ props: {
15
+ to: pieces_framework_1.Property.ShortText({
16
+ displayName: 'To',
17
+ description: 'Destination phone number in E.164 format, e.g. +15557654321.',
18
+ required: true,
19
+ }),
20
+ body: pieces_framework_1.Property.LongText({
21
+ displayName: 'Message',
22
+ description: 'The text message body.',
23
+ required: true,
24
+ }),
25
+ },
26
+ async run(context) {
27
+ const res = await pieces_common_1.httpClient.sendRequest({
28
+ method: pieces_common_1.HttpMethod.POST,
29
+ url: `${common_1.BELLVOX_API}/ap-actions?do=send_sms`,
30
+ headers: { 'x-bellvox-key': (0, common_1.authKey)(context.auth) },
31
+ body: {
32
+ to: context.propsValue.to,
33
+ body: context.propsValue.body,
34
+ },
35
+ });
36
+ return res.body;
37
+ },
38
+ });
@@ -0,0 +1,36 @@
1
+ import { createAction, Property } from '@activepieces/pieces-framework';
2
+ import { httpClient, HttpMethod } from '@activepieces/pieces-common';
3
+ import { bellvoxAuth } from '../auth';
4
+ import { BELLVOX_API, authKey } from '../common';
5
+
6
+ // Send an SMS from the org's active number. Sender selection + carrier auth happen server-side.
7
+ export const sendSms = createAction({
8
+ auth: bellvoxAuth,
9
+ name: 'send_sms',
10
+ displayName: 'Send SMS',
11
+ description: 'Send a text message from your Bellvox number.',
12
+ props: {
13
+ to: Property.ShortText({
14
+ displayName: 'To',
15
+ description: 'Destination phone number in E.164 format, e.g. +15557654321.',
16
+ required: true,
17
+ }),
18
+ body: Property.LongText({
19
+ displayName: 'Message',
20
+ description: 'The text message body.',
21
+ required: true,
22
+ }),
23
+ },
24
+ async run(context) {
25
+ const res = await httpClient.sendRequest({
26
+ method: HttpMethod.POST,
27
+ url: `${BELLVOX_API}/ap-actions?do=send_sms`,
28
+ headers: { 'x-bellvox-key': authKey(context.auth) },
29
+ body: {
30
+ to: context.propsValue.to,
31
+ body: context.propsValue.body,
32
+ },
33
+ });
34
+ return res.body;
35
+ },
36
+ });
@@ -0,0 +1,7 @@
1
+ export declare const upsertContact: import("@activepieces/pieces-framework").IAction<import("@activepieces/pieces-framework").SecretTextProperty<true>, {
2
+ name: import("@activepieces/pieces-framework").ShortTextProperty<false>;
3
+ phone: import("@activepieces/pieces-framework").ShortTextProperty<false>;
4
+ email: import("@activepieces/pieces-framework").ShortTextProperty<false>;
5
+ status: import("@activepieces/pieces-framework").ShortTextProperty<false>;
6
+ tags: import("@activepieces/pieces-framework").ArrayProperty<false>;
7
+ }>;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.upsertContact = void 0;
4
+ const pieces_framework_1 = require("@activepieces/pieces-framework");
5
+ const pieces_common_1 = require("@activepieces/pieces-common");
6
+ const auth_1 = require("../auth");
7
+ const common_1 = require("../common");
8
+ // Create or update a CRM contact in the key's org. org_id is derived server-side from the key.
9
+ exports.upsertContact = (0, pieces_framework_1.createAction)({
10
+ auth: auth_1.bellvoxAuth,
11
+ name: 'upsert_contact',
12
+ displayName: 'Upsert Contact',
13
+ description: 'Create or update a contact in the Bellvox CRM.',
14
+ props: {
15
+ name: pieces_framework_1.Property.ShortText({
16
+ displayName: 'Name',
17
+ required: false,
18
+ }),
19
+ phone: pieces_framework_1.Property.ShortText({
20
+ displayName: 'Phone',
21
+ description: 'Phone number in E.164 format. Used as the match key for upserts.',
22
+ required: false,
23
+ }),
24
+ email: pieces_framework_1.Property.ShortText({
25
+ displayName: 'Email',
26
+ required: false,
27
+ }),
28
+ status: pieces_framework_1.Property.ShortText({
29
+ displayName: 'Status',
30
+ description: "Pipeline status, e.g. 'lead', 'customer'. Defaults to 'lead' on the server.",
31
+ required: false,
32
+ }),
33
+ tags: pieces_framework_1.Property.Array({
34
+ displayName: 'Tags',
35
+ required: false,
36
+ }),
37
+ },
38
+ async run(context) {
39
+ const res = await pieces_common_1.httpClient.sendRequest({
40
+ method: pieces_common_1.HttpMethod.POST,
41
+ url: `${common_1.BELLVOX_API}/ap-actions?do=upsert_contact`,
42
+ headers: { 'x-bellvox-key': (0, common_1.authKey)(context.auth) },
43
+ body: {
44
+ name: context.propsValue.name,
45
+ phone: context.propsValue.phone,
46
+ email: context.propsValue.email,
47
+ status: context.propsValue.status,
48
+ tags: context.propsValue.tags,
49
+ },
50
+ });
51
+ return res.body;
52
+ },
53
+ });
@@ -0,0 +1,51 @@
1
+ import { createAction, Property } from '@activepieces/pieces-framework';
2
+ import { httpClient, HttpMethod } from '@activepieces/pieces-common';
3
+ import { bellvoxAuth } from '../auth';
4
+ import { BELLVOX_API, authKey } from '../common';
5
+
6
+ // Create or update a CRM contact in the key's org. org_id is derived server-side from the key.
7
+ export const upsertContact = createAction({
8
+ auth: bellvoxAuth,
9
+ name: 'upsert_contact',
10
+ displayName: 'Upsert Contact',
11
+ description: 'Create or update a contact in the Bellvox CRM.',
12
+ props: {
13
+ name: Property.ShortText({
14
+ displayName: 'Name',
15
+ required: false,
16
+ }),
17
+ phone: Property.ShortText({
18
+ displayName: 'Phone',
19
+ description: 'Phone number in E.164 format. Used as the match key for upserts.',
20
+ required: false,
21
+ }),
22
+ email: Property.ShortText({
23
+ displayName: 'Email',
24
+ required: false,
25
+ }),
26
+ status: Property.ShortText({
27
+ displayName: 'Status',
28
+ description: "Pipeline status, e.g. 'lead', 'customer'. Defaults to 'lead' on the server.",
29
+ required: false,
30
+ }),
31
+ tags: Property.Array({
32
+ displayName: 'Tags',
33
+ required: false,
34
+ }),
35
+ },
36
+ async run(context) {
37
+ const res = await httpClient.sendRequest({
38
+ method: HttpMethod.POST,
39
+ url: `${BELLVOX_API}/ap-actions?do=upsert_contact`,
40
+ headers: { 'x-bellvox-key': authKey(context.auth) },
41
+ body: {
42
+ name: context.propsValue.name,
43
+ phone: context.propsValue.phone,
44
+ email: context.propsValue.email,
45
+ status: context.propsValue.status,
46
+ tags: context.propsValue.tags,
47
+ },
48
+ });
49
+ return res.body;
50
+ },
51
+ });
@@ -0,0 +1 @@
1
+ export declare const bellvoxAuth: import("@activepieces/pieces-framework").SecretTextProperty<true>;
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.bellvoxAuth = void 0;
4
+ const pieces_framework_1 = require("@activepieces/pieces-framework");
5
+ const pieces_common_1 = require("@activepieces/pieces-common");
6
+ const common_1 = require("./common");
7
+ const MARKDOWN = `
8
+ Paste your **API Key** to connect.
9
+
10
+ 1. Sign in to your workspace.
11
+ 2. Open the **Automations** page and click **Generate key** (or **Regenerate**).
12
+ 3. Copy the \`bvx_…\` key shown once and paste it here.
13
+
14
+ The key scopes every flow to *your* workspace only.
15
+ `;
16
+ // Secret API key. validate() round-trips the key against ap-credentials?action=whoami:
17
+ // a 200 with { ok:true, org_id } means the key resolves to a real org; anything else is invalid.
18
+ // NOTE: the wire header (x-bellvox-key) + endpoints are the fixed server contract — not shown to
19
+ // users — so they stay; only the displayed labels/copy are brand-neutral ("Agent Comms").
20
+ exports.bellvoxAuth = pieces_framework_1.PieceAuth.SecretText({
21
+ displayName: 'API Key',
22
+ description: MARKDOWN,
23
+ required: true,
24
+ validate: async ({ auth }) => {
25
+ try {
26
+ const res = await pieces_common_1.httpClient.sendRequest({
27
+ method: pieces_common_1.HttpMethod.GET,
28
+ url: `${common_1.BELLVOX_API}/ap-credentials?action=whoami`,
29
+ // In a SecretText validate the arg is { auth }, where `auth` is the raw secret string.
30
+ headers: { 'x-bellvox-key': auth },
31
+ });
32
+ if (res.status === 200 && res.body?.ok && res.body?.org_id) {
33
+ return { valid: true };
34
+ }
35
+ return { valid: false, error: 'That API key was not recognized.' };
36
+ }
37
+ catch (e) {
38
+ return {
39
+ valid: false,
40
+ error: 'Could not validate the API key. Check the key and try again.',
41
+ };
42
+ }
43
+ },
44
+ });
@@ -0,0 +1,42 @@
1
+ import { PieceAuth } from '@activepieces/pieces-framework';
2
+ import { httpClient, HttpMethod } from '@activepieces/pieces-common';
3
+ import { BELLVOX_API } from './common';
4
+
5
+ const MARKDOWN = `
6
+ Paste your **API Key** to connect.
7
+
8
+ 1. Sign in to your workspace.
9
+ 2. Open the **Automations** page and click **Generate key** (or **Regenerate**).
10
+ 3. Copy the \`bvx_…\` key shown once and paste it here.
11
+
12
+ The key scopes every flow to *your* workspace only.
13
+ `;
14
+
15
+ // Secret API key. validate() round-trips the key against ap-credentials?action=whoami:
16
+ // a 200 with { ok:true, org_id } means the key resolves to a real org; anything else is invalid.
17
+ // NOTE: the wire header (x-bellvox-key) + endpoints are the fixed server contract — not shown to
18
+ // users — so they stay; only the displayed labels/copy are brand-neutral ("Agent Comms").
19
+ export const bellvoxAuth = PieceAuth.SecretText({
20
+ displayName: 'API Key',
21
+ description: MARKDOWN,
22
+ required: true,
23
+ validate: async ({ auth }) => {
24
+ try {
25
+ const res = await httpClient.sendRequest<{ ok?: boolean; org_id?: string }>({
26
+ method: HttpMethod.GET,
27
+ url: `${BELLVOX_API}/ap-credentials?action=whoami`,
28
+ // In a SecretText validate the arg is { auth }, where `auth` is the raw secret string.
29
+ headers: { 'x-bellvox-key': auth },
30
+ });
31
+ if (res.status === 200 && res.body?.ok && res.body?.org_id) {
32
+ return { valid: true };
33
+ }
34
+ return { valid: false, error: 'That API key was not recognized.' };
35
+ } catch (e) {
36
+ return {
37
+ valid: false,
38
+ error: 'Could not validate the API key. Check the key and try again.',
39
+ };
40
+ }
41
+ },
42
+ });
@@ -0,0 +1,2 @@
1
+ export declare const BELLVOX_API = "https://ajhcthysvaaqunjvqlgy.supabase.co/functions/v1";
2
+ export declare function authKey(auth: unknown): string;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.authKey = exports.BELLVOX_API = void 0;
4
+ // Shared constants for the Bellvox piece.
5
+ //
6
+ // Every action/trigger talks to Bellvox's Supabase edge functions. Auth is a single opaque
7
+ // API key ("bvx_..." + 40 hex) presented in the x-bellvox-key header. The edge function
8
+ // resolves that key -> the caller's org and scopes everything to it (the key is the ONLY
9
+ // source of org identity — request bodies never carry an org/assistant we trust blindly).
10
+ exports.BELLVOX_API = 'https://ajhcthysvaaqunjvqlgy.supabase.co/functions/v1';
11
+ // AP resolves SecretText auth to the raw "bvx_..." string at runtime, but the framework types it as
12
+ // a { type, secret_text } connection object. Read it defensively so the x-bellvox-key header is the
13
+ // plain key string whichever shape a given AP version hands the action/trigger.
14
+ function authKey(auth) {
15
+ if (auth && typeof auth === 'object' && 'secret_text' in auth) {
16
+ return String(auth.secret_text);
17
+ }
18
+ return String(auth ?? '');
19
+ }
20
+ exports.authKey = authKey;
@@ -0,0 +1,17 @@
1
+ // Shared constants for the Bellvox piece.
2
+ //
3
+ // Every action/trigger talks to Bellvox's Supabase edge functions. Auth is a single opaque
4
+ // API key ("bvx_..." + 40 hex) presented in the x-bellvox-key header. The edge function
5
+ // resolves that key -> the caller's org and scopes everything to it (the key is the ONLY
6
+ // source of org identity — request bodies never carry an org/assistant we trust blindly).
7
+ export const BELLVOX_API = 'https://ajhcthysvaaqunjvqlgy.supabase.co/functions/v1';
8
+
9
+ // AP resolves SecretText auth to the raw "bvx_..." string at runtime, but the framework types it as
10
+ // a { type, secret_text } connection object. Read it defensively so the x-bellvox-key header is the
11
+ // plain key string whichever shape a given AP version hands the action/trigger.
12
+ export function authKey(auth: unknown): string {
13
+ if (auth && typeof auth === 'object' && 'secret_text' in auth) {
14
+ return String((auth as { secret_text: unknown }).secret_text);
15
+ }
16
+ return String(auth ?? '');
17
+ }
@@ -0,0 +1,2 @@
1
+ import { TriggerStrategy } from '@activepieces/pieces-framework';
2
+ export declare const appointmentCreated: import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.WEBHOOK, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}> | import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.POLLING, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}> | import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.MANUAL, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}> | import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.APP_WEBHOOK, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}>;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.appointmentCreated = void 0;
4
+ const pieces_framework_1 = require("@activepieces/pieces-framework");
5
+ const pieces_common_1 = require("@activepieces/pieces-common");
6
+ const auth_1 = require("../auth");
7
+ const common_1 = require("../common");
8
+ // Fires when a Bellvox assistant books an appointment. Registration is identical to the other
9
+ // triggers — only the trigger_event differs, which is what Bellvox uses to route fan-out.
10
+ exports.appointmentCreated = (0, pieces_framework_1.createTrigger)({
11
+ auth: auth_1.bellvoxAuth,
12
+ name: 'appointment_created',
13
+ displayName: 'Appointment Created',
14
+ description: 'Fires when a Bellvox assistant books a new appointment.',
15
+ props: {},
16
+ type: pieces_framework_1.TriggerStrategy.WEBHOOK,
17
+ sampleData: {
18
+ appointment_id: 'b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e',
19
+ assistant_id: 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d',
20
+ assistant_name: 'Front Desk',
21
+ call_id: '8f3c2b1a-0d4e-4a9b-9c1f-2e6d7a8b9c0d',
22
+ contact_name: 'Jane Doe',
23
+ contact_phone: '+15557654321',
24
+ contact_email: 'jane.doe@example.com',
25
+ title: 'Consultation',
26
+ notes: 'New patient, prefers mornings.',
27
+ starts_at: '2026-06-29T14:00:00.000Z',
28
+ ends_at: '2026-06-29T14:30:00.000Z',
29
+ status: 'scheduled',
30
+ created_at: '2026-06-24T15:06:30.000Z',
31
+ },
32
+ async onEnable(context) {
33
+ const res = await pieces_common_1.httpClient.sendRequest({
34
+ method: pieces_common_1.HttpMethod.POST,
35
+ url: `${common_1.BELLVOX_API}/ap-credentials?action=register-webhook`,
36
+ headers: { 'x-bellvox-key': (0, common_1.authKey)(context.auth) },
37
+ body: {
38
+ event: 'appointment_created',
39
+ webhook_url: context.webhookUrl,
40
+ flow_name: 'Appointment Created',
41
+ },
42
+ });
43
+ await context.store.put('_bellvox_flow_id', res.body.id);
44
+ },
45
+ async onDisable(context) {
46
+ const id = await context.store.get('_bellvox_flow_id');
47
+ if (id) {
48
+ await pieces_common_1.httpClient.sendRequest({
49
+ method: pieces_common_1.HttpMethod.POST,
50
+ url: `${common_1.BELLVOX_API}/ap-credentials?action=unregister-webhook&id=${encodeURIComponent(id)}`,
51
+ headers: { 'x-bellvox-key': (0, common_1.authKey)(context.auth) },
52
+ });
53
+ }
54
+ },
55
+ async run(context) {
56
+ return [context.payload.body];
57
+ },
58
+ });
@@ -0,0 +1,56 @@
1
+ import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
2
+ import { httpClient, HttpMethod } from '@activepieces/pieces-common';
3
+ import { bellvoxAuth } from '../auth';
4
+ import { BELLVOX_API, authKey } from '../common';
5
+
6
+ // Fires when a Bellvox assistant books an appointment. Registration is identical to the other
7
+ // triggers — only the trigger_event differs, which is what Bellvox uses to route fan-out.
8
+ export const appointmentCreated = createTrigger({
9
+ auth: bellvoxAuth,
10
+ name: 'appointment_created',
11
+ displayName: 'Appointment Created',
12
+ description: 'Fires when a Bellvox assistant books a new appointment.',
13
+ props: {},
14
+ type: TriggerStrategy.WEBHOOK,
15
+ sampleData: {
16
+ appointment_id: 'b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e',
17
+ assistant_id: 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d',
18
+ assistant_name: 'Front Desk',
19
+ call_id: '8f3c2b1a-0d4e-4a9b-9c1f-2e6d7a8b9c0d',
20
+ contact_name: 'Jane Doe',
21
+ contact_phone: '+15557654321',
22
+ contact_email: 'jane.doe@example.com',
23
+ title: 'Consultation',
24
+ notes: 'New patient, prefers mornings.',
25
+ starts_at: '2026-06-29T14:00:00.000Z',
26
+ ends_at: '2026-06-29T14:30:00.000Z',
27
+ status: 'scheduled',
28
+ created_at: '2026-06-24T15:06:30.000Z',
29
+ },
30
+ async onEnable(context) {
31
+ const res = await httpClient.sendRequest<{ id: string }>({
32
+ method: HttpMethod.POST,
33
+ url: `${BELLVOX_API}/ap-credentials?action=register-webhook`,
34
+ headers: { 'x-bellvox-key': authKey(context.auth) },
35
+ body: {
36
+ event: 'appointment_created',
37
+ webhook_url: context.webhookUrl,
38
+ flow_name: 'Appointment Created',
39
+ },
40
+ });
41
+ await context.store.put('_bellvox_flow_id', res.body.id);
42
+ },
43
+ async onDisable(context) {
44
+ const id = await context.store.get<string>('_bellvox_flow_id');
45
+ if (id) {
46
+ await httpClient.sendRequest({
47
+ method: HttpMethod.POST,
48
+ url: `${BELLVOX_API}/ap-credentials?action=unregister-webhook&id=${encodeURIComponent(id)}`,
49
+ headers: { 'x-bellvox-key': authKey(context.auth) },
50
+ });
51
+ }
52
+ },
53
+ async run(context) {
54
+ return [context.payload.body];
55
+ },
56
+ });
@@ -0,0 +1,2 @@
1
+ import { TriggerStrategy } from '@activepieces/pieces-framework';
2
+ export declare const callCompleted: import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.WEBHOOK, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}> | import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.POLLING, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}> | import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.MANUAL, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}> | import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.APP_WEBHOOK, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}>;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.callCompleted = void 0;
4
+ const pieces_framework_1 = require("@activepieces/pieces-framework");
5
+ const pieces_common_1 = require("@activepieces/pieces-common");
6
+ const auth_1 = require("../auth");
7
+ const common_1 = require("../common");
8
+ // Bellvox delivers a webhook to AP when a phone call wraps up. onEnable registers AP's
9
+ // generated webhook URL with Bellvox (keyed to the caller's org via the API key); Bellvox
10
+ // then POSTs the payload here on every completed call. We stash the returned flow row id so
11
+ // onDisable can unregister precisely.
12
+ exports.callCompleted = (0, pieces_framework_1.createTrigger)({
13
+ auth: auth_1.bellvoxAuth,
14
+ name: 'call_completed',
15
+ displayName: 'Call Completed',
16
+ description: 'Fires when a Bellvox voice call finishes (with transcript, summary and extracted data).',
17
+ props: {},
18
+ type: pieces_framework_1.TriggerStrategy.WEBHOOK,
19
+ sampleData: {
20
+ call_id: '8f3c2b1a-0d4e-4a9b-9c1f-2e6d7a8b9c0d',
21
+ assistant_id: 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d',
22
+ assistant_name: 'Front Desk',
23
+ from_number: '+15551230001',
24
+ to_number: '+15557654321',
25
+ direction: 'inbound',
26
+ number: '+15557654321',
27
+ duration_sec: 142,
28
+ transcript: 'Assistant: Thanks for calling Acme Clinic, how can I help?\nCaller: I need to reschedule my appointment...',
29
+ summary: 'Caller asked to reschedule their Thursday appointment to next Monday.',
30
+ extracted_data: {
31
+ patient_name: 'Jane Doe',
32
+ reason: 'reschedule',
33
+ requested_date: '2026-06-29',
34
+ },
35
+ recording_url: 'https://ajhcthysvaaqunjvqlgy.supabase.co/storage/v1/object/recordings/8f3c2b1a.mp3',
36
+ started_at: '2026-06-24T15:04:00.000Z',
37
+ ended_at: '2026-06-24T15:06:22.000Z',
38
+ status: 'completed',
39
+ },
40
+ async onEnable(context) {
41
+ const res = await pieces_common_1.httpClient.sendRequest({
42
+ method: pieces_common_1.HttpMethod.POST,
43
+ url: `${common_1.BELLVOX_API}/ap-credentials?action=register-webhook`,
44
+ headers: { 'x-bellvox-key': (0, common_1.authKey)(context.auth) },
45
+ body: {
46
+ event: 'call_completed',
47
+ webhook_url: context.webhookUrl,
48
+ flow_name: 'Call Completed',
49
+ },
50
+ });
51
+ await context.store.put('_bellvox_flow_id', res.body.id);
52
+ },
53
+ async onDisable(context) {
54
+ const id = await context.store.get('_bellvox_flow_id');
55
+ if (id) {
56
+ await pieces_common_1.httpClient.sendRequest({
57
+ method: pieces_common_1.HttpMethod.POST,
58
+ url: `${common_1.BELLVOX_API}/ap-credentials?action=unregister-webhook&id=${encodeURIComponent(id)}`,
59
+ headers: { 'x-bellvox-key': (0, common_1.authKey)(context.auth) },
60
+ });
61
+ }
62
+ },
63
+ async run(context) {
64
+ return [context.payload.body];
65
+ },
66
+ });
@@ -0,0 +1,65 @@
1
+ import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
2
+ import { httpClient, HttpMethod } from '@activepieces/pieces-common';
3
+ import { bellvoxAuth } from '../auth';
4
+ import { BELLVOX_API, authKey } from '../common';
5
+
6
+ // Bellvox delivers a webhook to AP when a phone call wraps up. onEnable registers AP's
7
+ // generated webhook URL with Bellvox (keyed to the caller's org via the API key); Bellvox
8
+ // then POSTs the payload here on every completed call. We stash the returned flow row id so
9
+ // onDisable can unregister precisely.
10
+ export const callCompleted = createTrigger({
11
+ auth: bellvoxAuth,
12
+ name: 'call_completed',
13
+ displayName: 'Call Completed',
14
+ description: 'Fires when a Bellvox voice call finishes (with transcript, summary and extracted data).',
15
+ props: {},
16
+ type: TriggerStrategy.WEBHOOK,
17
+ sampleData: {
18
+ call_id: '8f3c2b1a-0d4e-4a9b-9c1f-2e6d7a8b9c0d',
19
+ assistant_id: 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d',
20
+ assistant_name: 'Front Desk',
21
+ from_number: '+15551230001',
22
+ to_number: '+15557654321',
23
+ direction: 'inbound',
24
+ number: '+15557654321',
25
+ duration_sec: 142,
26
+ transcript:
27
+ 'Assistant: Thanks for calling Acme Clinic, how can I help?\nCaller: I need to reschedule my appointment...',
28
+ summary: 'Caller asked to reschedule their Thursday appointment to next Monday.',
29
+ extracted_data: {
30
+ patient_name: 'Jane Doe',
31
+ reason: 'reschedule',
32
+ requested_date: '2026-06-29',
33
+ },
34
+ recording_url: 'https://ajhcthysvaaqunjvqlgy.supabase.co/storage/v1/object/recordings/8f3c2b1a.mp3',
35
+ started_at: '2026-06-24T15:04:00.000Z',
36
+ ended_at: '2026-06-24T15:06:22.000Z',
37
+ status: 'completed',
38
+ },
39
+ async onEnable(context) {
40
+ const res = await httpClient.sendRequest<{ id: string }>({
41
+ method: HttpMethod.POST,
42
+ url: `${BELLVOX_API}/ap-credentials?action=register-webhook`,
43
+ headers: { 'x-bellvox-key': authKey(context.auth) },
44
+ body: {
45
+ event: 'call_completed',
46
+ webhook_url: context.webhookUrl,
47
+ flow_name: 'Call Completed',
48
+ },
49
+ });
50
+ await context.store.put('_bellvox_flow_id', res.body.id);
51
+ },
52
+ async onDisable(context) {
53
+ const id = await context.store.get<string>('_bellvox_flow_id');
54
+ if (id) {
55
+ await httpClient.sendRequest({
56
+ method: HttpMethod.POST,
57
+ url: `${BELLVOX_API}/ap-credentials?action=unregister-webhook&id=${encodeURIComponent(id)}`,
58
+ headers: { 'x-bellvox-key': authKey(context.auth) },
59
+ });
60
+ }
61
+ },
62
+ async run(context) {
63
+ return [context.payload.body];
64
+ },
65
+ });
@@ -0,0 +1,2 @@
1
+ import { TriggerStrategy } from '@activepieces/pieces-framework';
2
+ export declare const chatCompleted: import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.WEBHOOK, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}> | import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.POLLING, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}> | import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.MANUAL, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}> | import("@activepieces/pieces-framework").ITrigger<TriggerStrategy.APP_WEBHOOK, import("@activepieces/pieces-framework").SecretTextProperty<true>, {}>;
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.chatCompleted = void 0;
4
+ const pieces_framework_1 = require("@activepieces/pieces-framework");
5
+ const pieces_common_1 = require("@activepieces/pieces-common");
6
+ const auth_1 = require("../auth");
7
+ const common_1 = require("../common");
8
+ // Fires when a Bellvox web-chat conversation ends. Same registration handshake as the other
9
+ // triggers; trigger_event = chat_completed.
10
+ exports.chatCompleted = (0, pieces_framework_1.createTrigger)({
11
+ auth: auth_1.bellvoxAuth,
12
+ name: 'chat_completed',
13
+ displayName: 'Chat Completed',
14
+ description: 'Fires when a Bellvox web-chat conversation ends (with transcript and summary).',
15
+ props: {},
16
+ type: pieces_framework_1.TriggerStrategy.WEBHOOK,
17
+ sampleData: {
18
+ chat_id: 'c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f',
19
+ assistant_id: 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d',
20
+ assistant_name: 'Website Concierge',
21
+ visitor_id: 'v_9f8e7d6c',
22
+ contact_name: 'Jane Doe',
23
+ contact_email: 'jane.doe@example.com',
24
+ message_count: 8,
25
+ transcript: 'Visitor: Do you carry CPAP supplies?\nAssistant: Yes — we stock masks, tubing and filters...',
26
+ summary: 'Visitor asked about CPAP supplies and store hours; provided email for follow-up.',
27
+ extracted_data: { intent: 'product_inquiry', product: 'CPAP supplies' },
28
+ started_at: '2026-06-24T15:00:00.000Z',
29
+ ended_at: '2026-06-24T15:03:40.000Z',
30
+ status: 'completed',
31
+ },
32
+ async onEnable(context) {
33
+ const res = await pieces_common_1.httpClient.sendRequest({
34
+ method: pieces_common_1.HttpMethod.POST,
35
+ url: `${common_1.BELLVOX_API}/ap-credentials?action=register-webhook`,
36
+ headers: { 'x-bellvox-key': (0, common_1.authKey)(context.auth) },
37
+ body: {
38
+ event: 'chat_completed',
39
+ webhook_url: context.webhookUrl,
40
+ flow_name: 'Chat Completed',
41
+ },
42
+ });
43
+ await context.store.put('_bellvox_flow_id', res.body.id);
44
+ },
45
+ async onDisable(context) {
46
+ const id = await context.store.get('_bellvox_flow_id');
47
+ if (id) {
48
+ await pieces_common_1.httpClient.sendRequest({
49
+ method: pieces_common_1.HttpMethod.POST,
50
+ url: `${common_1.BELLVOX_API}/ap-credentials?action=unregister-webhook&id=${encodeURIComponent(id)}`,
51
+ headers: { 'x-bellvox-key': (0, common_1.authKey)(context.auth) },
52
+ });
53
+ }
54
+ },
55
+ async run(context) {
56
+ return [context.payload.body];
57
+ },
58
+ });
@@ -0,0 +1,57 @@
1
+ import { createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
2
+ import { httpClient, HttpMethod } from '@activepieces/pieces-common';
3
+ import { bellvoxAuth } from '../auth';
4
+ import { BELLVOX_API, authKey } from '../common';
5
+
6
+ // Fires when a Bellvox web-chat conversation ends. Same registration handshake as the other
7
+ // triggers; trigger_event = chat_completed.
8
+ export const chatCompleted = createTrigger({
9
+ auth: bellvoxAuth,
10
+ name: 'chat_completed',
11
+ displayName: 'Chat Completed',
12
+ description: 'Fires when a Bellvox web-chat conversation ends (with transcript and summary).',
13
+ props: {},
14
+ type: TriggerStrategy.WEBHOOK,
15
+ sampleData: {
16
+ chat_id: 'c3d4e5f6-a7b8-4c9d-0e1f-2a3b4c5d6e7f',
17
+ assistant_id: 'a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d',
18
+ assistant_name: 'Website Concierge',
19
+ visitor_id: 'v_9f8e7d6c',
20
+ contact_name: 'Jane Doe',
21
+ contact_email: 'jane.doe@example.com',
22
+ message_count: 8,
23
+ transcript:
24
+ 'Visitor: Do you carry CPAP supplies?\nAssistant: Yes — we stock masks, tubing and filters...',
25
+ summary: 'Visitor asked about CPAP supplies and store hours; provided email for follow-up.',
26
+ extracted_data: { intent: 'product_inquiry', product: 'CPAP supplies' },
27
+ started_at: '2026-06-24T15:00:00.000Z',
28
+ ended_at: '2026-06-24T15:03:40.000Z',
29
+ status: 'completed',
30
+ },
31
+ async onEnable(context) {
32
+ const res = await httpClient.sendRequest<{ id: string }>({
33
+ method: HttpMethod.POST,
34
+ url: `${BELLVOX_API}/ap-credentials?action=register-webhook`,
35
+ headers: { 'x-bellvox-key': authKey(context.auth) },
36
+ body: {
37
+ event: 'chat_completed',
38
+ webhook_url: context.webhookUrl,
39
+ flow_name: 'Chat Completed',
40
+ },
41
+ });
42
+ await context.store.put('_bellvox_flow_id', res.body.id);
43
+ },
44
+ async onDisable(context) {
45
+ const id = await context.store.get<string>('_bellvox_flow_id');
46
+ if (id) {
47
+ await httpClient.sendRequest({
48
+ method: HttpMethod.POST,
49
+ url: `${BELLVOX_API}/ap-credentials?action=unregister-webhook&id=${encodeURIComponent(id)}`,
50
+ headers: { 'x-bellvox-key': authKey(context.auth) },
51
+ });
52
+ }
53
+ },
54
+ async run(context) {
55
+ return [context.payload.body];
56
+ },
57
+ });