Add Activepieces integration for workflow automation
- Add Activepieces fork with SmoothSchedule custom piece - Create integrations app with Activepieces service layer - Add embed token endpoint for iframe integration - Create Automations page with embedded workflow builder - Add sidebar visibility fix for embed mode - Add list inactive customers endpoint to Public API - Include SmoothSchedule triggers: event created/updated/cancelled - Include SmoothSchedule actions: create/update/cancel events, list resources/services/customers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { guideliteAuth } from '../common/auth';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { makeRequest } from '../common/client';
|
||||
import { assistantIdDropdown } from '../common/props';
|
||||
|
||||
export const sendAPrompt = createAction({
|
||||
auth: guideliteAuth,
|
||||
name: 'sendAPrompt',
|
||||
displayName: 'Send a Prompt',
|
||||
description: 'Send a message to a Guidelite Assistant',
|
||||
props: {
|
||||
assistantId: assistantIdDropdown,
|
||||
message: Property.LongText({
|
||||
displayName: 'Message',
|
||||
description: 'The input message to be processed by the assistant',
|
||||
required: true,
|
||||
}),
|
||||
conversationId: Property.ShortText({
|
||||
displayName: 'Conversation ID',
|
||||
description:
|
||||
'The Conversation ID of the previous conversation. If empty, a new conversation will be created',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { assistantId, message, conversationId } = context.propsValue;
|
||||
|
||||
const body: any = {
|
||||
assistantId,
|
||||
message,
|
||||
};
|
||||
|
||||
if (conversationId) {
|
||||
body.conversationId = conversationId;
|
||||
}
|
||||
const response = await makeRequest(
|
||||
context.auth,
|
||||
HttpMethod.POST,
|
||||
`/interface-assistant/chat`,
|
||||
body
|
||||
);
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { makeRequest } from './client';
|
||||
import { AppConnectionType } from '@activepieces/shared';
|
||||
|
||||
export const guideliteAuth = PieceAuth.SecretText({
|
||||
displayName: 'Guidelite API Key',
|
||||
description: `
|
||||
To get your API key:
|
||||
1. Sign in to your GuideLite dashboard
|
||||
2. Click on your account in the left panel
|
||||
3. Select "Profile" from the dropdown menu
|
||||
4. Navigate to the API Keys tab and click "Generate API Key"
|
||||
5. Copy your unique API key (you won't be able to view it again unless you delete and create a new one)
|
||||
|
||||
For more information, visit: https://docs.guidelite.ai/reference/quickstart
|
||||
`,
|
||||
required: true,
|
||||
validate: async ({ auth }) => {
|
||||
if (auth) {
|
||||
try {
|
||||
await makeRequest({secret_text: auth, type: AppConnectionType.SECRET_TEXT}, HttpMethod.GET, '/assistant/list');
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Invalid API Key',
|
||||
};
|
||||
}
|
||||
}
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Invalid API Key',
|
||||
};
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
|
||||
import { AppConnectionValueForAuthProperty } from '@activepieces/pieces-framework';
|
||||
import { guideliteAuth } from '../common/auth';
|
||||
|
||||
export const BASE_URL = `https://api.guidelite.ai/external-api/v1`;
|
||||
|
||||
export async function makeRequest(
|
||||
{secret_text}: AppConnectionValueForAuthProperty<typeof guideliteAuth>,
|
||||
method: HttpMethod,
|
||||
path: string,
|
||||
body?: unknown
|
||||
) {
|
||||
try {
|
||||
const response = await httpClient.sendRequest({
|
||||
method,
|
||||
url: `${BASE_URL}${path}`,
|
||||
headers: {
|
||||
authorization: `Bearer ${secret_text}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body,
|
||||
});
|
||||
return response.body;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Unexpected error: ${error.message || String(error)}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { makeRequest } from './client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { guideliteAuth } from './auth';
|
||||
|
||||
export const assistantIdDropdown = Property.Dropdown({
|
||||
displayName: 'Assistant',
|
||||
description: 'Please select assistant',
|
||||
refreshers: [],
|
||||
auth: guideliteAuth,
|
||||
required: true,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Please connect your Guidelite account first.',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
try {
|
||||
const response = await makeRequest(
|
||||
auth,
|
||||
HttpMethod.GET,
|
||||
'/assistant/list'
|
||||
);
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: response.map((model: any) => {
|
||||
return {
|
||||
label: model.assistantName,
|
||||
value: model.assistantId,
|
||||
};
|
||||
}),
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: "Couldn't load assistants, API key is invalid",
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
import {
|
||||
createTrigger,
|
||||
TriggerStrategy,
|
||||
StaticPropsValue,
|
||||
AppConnectionValueForAuthProperty,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import {
|
||||
DedupeStrategy,
|
||||
Polling,
|
||||
pollingHelper,
|
||||
HttpMethod,
|
||||
} from '@activepieces/pieces-common';
|
||||
import dayjs from 'dayjs';
|
||||
import { guideliteAuth } from '../common/auth';
|
||||
import { makeRequest } from '../common/client';
|
||||
import { assistantIdDropdown } from '../common/props';
|
||||
|
||||
const props = {
|
||||
assistantId: assistantIdDropdown,
|
||||
};
|
||||
|
||||
const polling: Polling<AppConnectionValueForAuthProperty<typeof guideliteAuth>, StaticPropsValue<typeof props>> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
items: async ({ propsValue, auth, lastFetchEpochMS }) => {
|
||||
const { assistantId } = propsValue;
|
||||
|
||||
const fromDate = dayjs(lastFetchEpochMS).format('YYYY-MM-DD HH:mm:ss.SSS');
|
||||
const toDate = dayjs(Date.now()).format('YYYY-MM-DD HH:mm:ss.SSS');
|
||||
|
||||
const leads = await makeRequest(
|
||||
auth,
|
||||
HttpMethod.POST,
|
||||
'/manage-assistant/lead',
|
||||
{
|
||||
assistantId,
|
||||
from: fromDate,
|
||||
to: toDate,
|
||||
country: 'all',
|
||||
}
|
||||
);
|
||||
|
||||
return leads.map((lead: { createdDate: string }) => ({
|
||||
epochMilliSeconds: dayjs(lead.createdDate).valueOf(),
|
||||
data: lead,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
export const newLeadSubmission = createTrigger({
|
||||
auth: guideliteAuth,
|
||||
name: 'newLeadSubmission',
|
||||
displayName: 'new lead submission',
|
||||
description:
|
||||
'Trigger when a new lead is captured through the assistant conversation',
|
||||
props,
|
||||
sampleData: {
|
||||
createdDate: '2024-04-25T10:13:12.504Z',
|
||||
conversationId: '<YOUR-CONVERSATION-ID>',
|
||||
assistantId: '<YOUR-ASSISTANT-ID>',
|
||||
country: 'USA',
|
||||
emailId: 'user@gmail.com',
|
||||
phoneNumber: 1234567890,
|
||||
ipAddress: '192.168.1.1',
|
||||
city: 'New York',
|
||||
countryCode: 'US',
|
||||
},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async onEnable(context) {
|
||||
const { store, auth, propsValue } = context;
|
||||
await pollingHelper.onEnable(polling, { store, auth, propsValue });
|
||||
},
|
||||
|
||||
async onDisable(context) {
|
||||
const { store, auth, propsValue } = context;
|
||||
await pollingHelper.onDisable(polling, { store, auth, propsValue });
|
||||
},
|
||||
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user