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,33 @@
|
||||
{
|
||||
"extends": [
|
||||
"../../../../.eslintrc.base.json"
|
||||
],
|
||||
"ignorePatterns": [
|
||||
"!**/*"
|
||||
],
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx",
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.ts",
|
||||
"*.tsx"
|
||||
],
|
||||
"rules": {}
|
||||
},
|
||||
{
|
||||
"files": [
|
||||
"*.js",
|
||||
"*.jsx"
|
||||
],
|
||||
"rules": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
# pieces-customgpt
|
||||
|
||||
This library was generated with [Nx](https://nx.dev).
|
||||
|
||||
## Building
|
||||
|
||||
Run `nx build pieces-customgpt` to build the library.
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@activepieces/piece-customgpt",
|
||||
"version": "0.0.1",
|
||||
"type": "commonjs",
|
||||
"main": "./src/index.js",
|
||||
"types": "./src/index.d.ts",
|
||||
"dependencies": {
|
||||
"tslib": "^2.3.0"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "pieces-customgpt",
|
||||
"$schema": "../../../../node_modules/nx/schemas/project-schema.json",
|
||||
"sourceRoot": "packages/pieces/community/customgpt/src",
|
||||
"projectType": "library",
|
||||
"release": {
|
||||
"version": {
|
||||
"manifestRootsToUpdate": [
|
||||
"dist/{projectRoot}"
|
||||
],
|
||||
"currentVersionResolver": "git-tag",
|
||||
"fallbackCurrentVersionResolver": "disk"
|
||||
}
|
||||
},
|
||||
"tags": [],
|
||||
"targets": {
|
||||
"build": {
|
||||
"executor": "@nx/js:tsc",
|
||||
"outputs": [
|
||||
"{options.outputPath}"
|
||||
],
|
||||
"options": {
|
||||
"outputPath": "dist/packages/pieces/community/customgpt",
|
||||
"tsConfig": "packages/pieces/community/customgpt/tsconfig.lib.json",
|
||||
"packageJson": "packages/pieces/community/customgpt/package.json",
|
||||
"main": "packages/pieces/community/customgpt/src/index.ts",
|
||||
"assets": [
|
||||
"packages/pieces/community/customgpt/*.md",
|
||||
{
|
||||
"input": "packages/pieces/community/customgpt/src/i18n",
|
||||
"output": "./src/i18n",
|
||||
"glob": "**/!(i18n.json)"
|
||||
}
|
||||
],
|
||||
"buildableProjectDepsInPackageJsonType": "dependencies",
|
||||
"updateBuildableProjectDepsInPackageJson": true
|
||||
},
|
||||
"dependsOn": [
|
||||
"prebuild",
|
||||
"^build"
|
||||
]
|
||||
},
|
||||
"nx-release-publish": {
|
||||
"options": {
|
||||
"packageRoot": "dist/{projectRoot}"
|
||||
}
|
||||
},
|
||||
"prebuild": {
|
||||
"dependsOn": [
|
||||
"^build"
|
||||
],
|
||||
"executor": "nx:run-commands",
|
||||
"options": {
|
||||
"cwd": "packages/pieces/community/customgpt",
|
||||
"command": "bun install --no-save --silent"
|
||||
}
|
||||
},
|
||||
"lint": {
|
||||
"executor": "@nx/eslint:lint",
|
||||
"outputs": [
|
||||
"{options.outputFile}"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { createPiece, PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { createAgent } from './lib/actions/create-agent';
|
||||
import { createConversation } from './lib/actions/create-conversation';
|
||||
import { updateSettings } from './lib/actions/update-settings';
|
||||
import { sendMessage } from './lib/actions/send-message';
|
||||
import { findConversation } from './lib/actions/find-conversation';
|
||||
import { deleteAgent } from './lib/actions/delete-agent';
|
||||
import { updateAgent } from './lib/actions/update-agent';
|
||||
import { exportConversation } from './lib/actions/export-conversation';
|
||||
import { customgptAuth } from './lib/common/auth';
|
||||
import { newConversation } from './lib/triggers/new-conversation';
|
||||
import { PieceCategory } from '@activepieces/shared';
|
||||
|
||||
export const customgpt = createPiece({
|
||||
displayName: 'CustomGPT',
|
||||
auth: customgptAuth,
|
||||
minimumSupportedRelease: '0.36.1',
|
||||
logoUrl: 'https://cdn.activepieces.com/pieces/customgpt.png',
|
||||
authors: ['sanket-a11y'],
|
||||
categories: [PieceCategory.ARTIFICIAL_INTELLIGENCE],
|
||||
description:
|
||||
'CustomGPT allows you to create and deploy custom AI chatbots tailored to your specific needs.',
|
||||
actions: [
|
||||
createAgent,
|
||||
createConversation,
|
||||
deleteAgent,
|
||||
exportConversation,
|
||||
findConversation,
|
||||
sendMessage,
|
||||
updateAgent,
|
||||
updateSettings,
|
||||
],
|
||||
triggers: [newConversation],
|
||||
});
|
||||
@@ -0,0 +1,55 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { customgptAuth } from '../common/auth';
|
||||
import { makeRequest } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const createAgent = createAction({
|
||||
auth: customgptAuth,
|
||||
name: 'createAgent',
|
||||
displayName: 'Create Agent',
|
||||
description:
|
||||
'Create a new CustomGPT agent by importing data from a sitemap or file',
|
||||
props: {
|
||||
project_name: Property.ShortText({
|
||||
displayName: 'Project Name',
|
||||
description: 'The name for your agent/project',
|
||||
required: true,
|
||||
}),
|
||||
sitemap_path: Property.ShortText({
|
||||
displayName: 'Sitemap URL',
|
||||
description:
|
||||
'URL to a sitemap for importing agent knowledge (leave empty if uploading a file)',
|
||||
required: false,
|
||||
}),
|
||||
file: Property.File({
|
||||
displayName: 'File',
|
||||
description:
|
||||
'Upload a file (text, audio, or video format) for agent knowledge (leave empty if using sitemap)',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { project_name, sitemap_path, file } = context.propsValue;
|
||||
|
||||
const body: any = {
|
||||
project_name,
|
||||
};
|
||||
|
||||
if (sitemap_path) {
|
||||
body.sitemap_path = sitemap_path;
|
||||
}
|
||||
|
||||
if (file) {
|
||||
body.file = file;
|
||||
}
|
||||
|
||||
const response = await makeRequest(
|
||||
context.auth.secret_text,
|
||||
HttpMethod.POST,
|
||||
'/projects',
|
||||
body
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { customgptAuth } from '../common/auth';
|
||||
import { makeRequest } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { projectId } from '../common/props';
|
||||
|
||||
export const createConversation = createAction({
|
||||
auth: customgptAuth,
|
||||
name: 'createConversation',
|
||||
displayName: 'Create Conversation',
|
||||
description: 'Create a new conversation in a CustomGPT project',
|
||||
props: {
|
||||
projectId: projectId,
|
||||
name: Property.ShortText({
|
||||
displayName: 'Conversation Name',
|
||||
description: 'Optional name for the conversation',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { projectId, name } = context.propsValue;
|
||||
|
||||
const body: any = {};
|
||||
if (name) body.name = name;
|
||||
|
||||
const response = await makeRequest(
|
||||
context.auth.secret_text,
|
||||
HttpMethod.POST,
|
||||
`/projects/${projectId}/conversations`,
|
||||
body
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
import { createAction } from '@activepieces/pieces-framework';
|
||||
import { projectId } from '../common/props';
|
||||
import { customgptAuth } from '../common/auth';
|
||||
import { makeRequest } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const deleteAgent = createAction({
|
||||
auth: customgptAuth,
|
||||
name: 'deleteAgent',
|
||||
displayName: 'Delete Agent',
|
||||
description: 'Delete a CustomGPT agent',
|
||||
props: {
|
||||
projectId: projectId,
|
||||
},
|
||||
async run(context) {
|
||||
const { projectId } = context.propsValue;
|
||||
|
||||
const response = await makeRequest(
|
||||
context.auth.secret_text,
|
||||
HttpMethod.DELETE,
|
||||
`/projects/${projectId}`
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { customgptAuth } from '../common/auth';
|
||||
import { projectId } from '../common/props';
|
||||
import { makeRequest } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const exportConversation = createAction({
|
||||
auth: customgptAuth,
|
||||
name: 'export_conversation',
|
||||
displayName: 'Export Conversation',
|
||||
description:
|
||||
'Export a conversation with all messages, authors, feedbacks and metadata',
|
||||
props: {
|
||||
project_id: projectId,
|
||||
session_id: Property.ShortText({
|
||||
displayName: 'Session ID',
|
||||
description: 'The session ID of the conversation to export',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
return await makeRequest(
|
||||
auth.secret_text,
|
||||
HttpMethod.GET,
|
||||
`/projects/${propsValue.project_id}/conversations/${propsValue.session_id}/export`
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { customgptAuth } from '../common/auth';
|
||||
import { makeRequest } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { tr } from 'zod/v4/locales';
|
||||
|
||||
export const findAgent = createAction({
|
||||
auth: customgptAuth,
|
||||
name: 'findAgent',
|
||||
displayName: 'Find Agent',
|
||||
description: 'Find Agent by name ',
|
||||
props: {
|
||||
name: Property.ShortText({
|
||||
displayName: 'Agent Name Filter',
|
||||
description: 'Filter agents by name (optional)',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { name } = context.propsValue;
|
||||
|
||||
const queryParams: any = {};
|
||||
|
||||
queryParams.order = 'desc';
|
||||
queryParams.orderBy = 'created_at';
|
||||
if (name) queryParams.name = name;
|
||||
|
||||
const queryString =
|
||||
Object.keys(queryParams).length > 0
|
||||
? '?' + new URLSearchParams(queryParams).toString()
|
||||
: '';
|
||||
|
||||
const response = await makeRequest(
|
||||
context.auth.secret_text,
|
||||
HttpMethod.GET,
|
||||
`/projects${queryString}`
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,69 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { customgptAuth } from '../common/auth';
|
||||
import { projectId } from '../common/props';
|
||||
import { makeRequest } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const findConversation = createAction({
|
||||
auth: customgptAuth,
|
||||
name: 'findConversation',
|
||||
displayName: 'Find Conversation',
|
||||
description:
|
||||
'List and search conversations for an agent with optional filtering',
|
||||
props: {
|
||||
project_id: projectId,
|
||||
name: Property.ShortText({
|
||||
displayName: 'Conversation Name',
|
||||
description: 'Filter conversations by name (optional)',
|
||||
required: false,
|
||||
}),
|
||||
|
||||
userFilter: Property.StaticDropdown({
|
||||
displayName: 'User Filter',
|
||||
description: 'Filter by user who created the conversation (default: all)',
|
||||
required: false,
|
||||
defaultValue: 'all',
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'All Users', value: 'all' },
|
||||
{ label: 'Anonymous Users', value: 'anonymous' },
|
||||
{ label: 'Team Members', value: 'team_member' },
|
||||
{ label: 'Me', value: 'me' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
lastUpdatedAfter: Property.DateTime({
|
||||
displayName: 'Last Updated After',
|
||||
description:
|
||||
'Only return conversations with messages after this date (optional) e.g. 2025-01-09T18:30:00Z',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const { project_id, name, userFilter, lastUpdatedAfter } =
|
||||
context.propsValue;
|
||||
|
||||
// Build query parameters
|
||||
const queryParams: any = {};
|
||||
|
||||
queryParams.order = 'desc';
|
||||
queryParams.orderBy = 'created_at';
|
||||
if (userFilter) queryParams.userFilter = userFilter;
|
||||
if (name) queryParams.name = name;
|
||||
if (lastUpdatedAfter) queryParams.lastUpdatedAfter = lastUpdatedAfter;
|
||||
|
||||
// Build query string
|
||||
const queryString =
|
||||
Object.keys(queryParams).length > 0
|
||||
? '?' + new URLSearchParams(queryParams).toString()
|
||||
: '';
|
||||
|
||||
const response = await makeRequest(
|
||||
context.auth.secret_text,
|
||||
HttpMethod.GET,
|
||||
`/projects/${project_id}/conversations${queryString}`
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,144 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { customgptAuth } from '../common/auth';
|
||||
import { projectId } from '../common/props';
|
||||
import { makeRequest } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const sendMessage = createAction({
|
||||
auth: customgptAuth,
|
||||
name: 'sendMessage',
|
||||
displayName: 'Send Message',
|
||||
description: 'Send a message to a conversation within an agent',
|
||||
props: {
|
||||
project_id: projectId,
|
||||
session_id: Property.ShortText({
|
||||
displayName: 'Session ID',
|
||||
description: 'The session ID of the conversation',
|
||||
required: true,
|
||||
}),
|
||||
prompt: Property.LongText({
|
||||
displayName: 'Prompt',
|
||||
description: 'The message/question to send',
|
||||
required: true,
|
||||
}),
|
||||
stream: Property.Checkbox({
|
||||
displayName: 'Enable Streaming',
|
||||
description: 'Stream the response in real-time (default: false)',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
custom_persona: Property.LongText({
|
||||
displayName: 'Custom Persona',
|
||||
description: 'Custom persona/instructions for the agent (optional)',
|
||||
required: false,
|
||||
}),
|
||||
chatbot_model: Property.StaticDropdown({
|
||||
displayName: 'Agent Model',
|
||||
description: 'AI model to use for the conversation (optional)',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'GPT-4o', value: 'gpt-4o' },
|
||||
{ label: 'GPT-4o Mini', value: 'gpt-4o-mini' },
|
||||
{ label: 'GPT-4 Turbo', value: 'gpt-4-turbo' },
|
||||
{ label: 'GPT-4', value: 'gpt-4' },
|
||||
{ label: 'GPT-3.5 Turbo', value: 'gpt-3.5-turbo' },
|
||||
{ label: 'Claude 3.5 Sonnet', value: 'claude-3-5-sonnet-20240620' },
|
||||
{ label: 'Claude 3 Opus', value: 'claude-3-opus-20240229' },
|
||||
{ label: 'Claude 3 Sonnet', value: 'claude-3-sonnet-20240229' },
|
||||
{ label: 'Claude 3 Haiku', value: 'claude-3-haiku-20240307' },
|
||||
{ label: 'Gemini 1.5 Pro', value: 'gemini-1.5-pro' },
|
||||
{ label: 'Gemini 1.5 Flash', value: 'gemini-1.5-flash' },
|
||||
{ label: 'o1-preview', value: 'o1-preview' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
response_source: Property.StaticDropdown({
|
||||
displayName: 'Response Source',
|
||||
description:
|
||||
'Source for generating responses (default: use only your content)',
|
||||
required: false,
|
||||
defaultValue: 'default',
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Default (Your Content Only)', value: 'default' },
|
||||
{ label: 'Own Content', value: 'own_content' },
|
||||
{ label: 'OpenAI Content (Can improvise)', value: 'openai_content' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
agent_capability: Property.StaticDropdown({
|
||||
displayName: 'Agent Capability',
|
||||
description: 'Capability mode for the agent (default: fastest-responses)',
|
||||
required: false,
|
||||
defaultValue: 'fastest-responses',
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Fastest Responses', value: 'fastest-responses' },
|
||||
{ label: 'Optimal Choice', value: 'optimal-choice' },
|
||||
{ label: 'Advanced Reasoning', value: 'advanced-reasoning' },
|
||||
{ label: 'Complex Tasks', value: 'complex-tasks' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
lang: Property.ShortText({
|
||||
displayName: 'Language',
|
||||
description: 'Language code for the prompt (default: en)',
|
||||
required: false,
|
||||
defaultValue: 'en',
|
||||
}),
|
||||
custom_context: Property.LongText({
|
||||
displayName: 'Custom Context',
|
||||
description: 'Additional context for the conversation (optional)',
|
||||
required: false,
|
||||
}),
|
||||
file: Property.File({
|
||||
displayName: 'File',
|
||||
description:
|
||||
'File to upload with the message (Max 5MB: pdf, docx, doc, odt, txt, jpg, jpeg, png, webp)',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const {
|
||||
project_id,
|
||||
session_id,
|
||||
prompt,
|
||||
stream,
|
||||
custom_persona,
|
||||
chatbot_model,
|
||||
response_source,
|
||||
agent_capability,
|
||||
lang,
|
||||
custom_context,
|
||||
file,
|
||||
} = context.propsValue;
|
||||
|
||||
const queryParams: any = {
|
||||
stream: stream ? 'true' : 'false',
|
||||
};
|
||||
if (lang) queryParams.lang = lang;
|
||||
|
||||
const body: any = {
|
||||
prompt,
|
||||
};
|
||||
|
||||
if (custom_persona) body.custom_persona = custom_persona;
|
||||
if (chatbot_model) body.chatbot_model = chatbot_model;
|
||||
if (response_source) body.response_source = response_source;
|
||||
if (agent_capability) body.agent_capability = agent_capability;
|
||||
if (custom_context) body.custom_context = custom_context;
|
||||
if (file) body.file = file;
|
||||
|
||||
const queryString = '?' + new URLSearchParams(queryParams).toString();
|
||||
|
||||
const response = await makeRequest(
|
||||
context.auth.secret_text,
|
||||
HttpMethod.POST,
|
||||
`/projects/${project_id}/conversations/${session_id}/messages${queryString}`,
|
||||
body
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,96 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { projectId } from '../common/props';
|
||||
import { BASE_URL } from '../common/client';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
import { customgptAuth } from '../common/auth';
|
||||
|
||||
export const updateAgent = createAction({
|
||||
auth: customgptAuth,
|
||||
name: 'update_agent',
|
||||
displayName: 'Update Agent',
|
||||
description: 'Update an existing agent with specific details',
|
||||
props: {
|
||||
project_id: projectId,
|
||||
project_name: Property.ShortText({
|
||||
displayName: 'Agent Name',
|
||||
description: 'The name of the agent',
|
||||
required: false,
|
||||
}),
|
||||
is_shared: Property.Checkbox({
|
||||
displayName: 'Is Shared',
|
||||
description: 'Whether the agent is public or not',
|
||||
required: false,
|
||||
}),
|
||||
sitemap_path: Property.ShortText({
|
||||
displayName: 'Sitemap Path',
|
||||
description: 'URL of the sitemap to crawl',
|
||||
required: false,
|
||||
}),
|
||||
file_data_retension: Property.Checkbox({
|
||||
displayName: 'File Data Retention',
|
||||
description: 'Enable file data retention',
|
||||
required: false,
|
||||
}),
|
||||
is_ocr_enabled: Property.Checkbox({
|
||||
displayName: 'OCR Enabled',
|
||||
description: 'Enable Optical Character Recognition for images',
|
||||
required: false,
|
||||
}),
|
||||
is_anonymized: Property.Checkbox({
|
||||
displayName: 'Anonymized',
|
||||
description: 'Enable anonymization of data',
|
||||
required: false,
|
||||
}),
|
||||
file: Property.File({
|
||||
displayName: 'File',
|
||||
description: 'Upload a file to the agent',
|
||||
required: false,
|
||||
}),
|
||||
are_licenses_allowed: Property.Checkbox({
|
||||
displayName: 'Are Licenses Allowed',
|
||||
description: 'Whether project licenses are allowed',
|
||||
required: false,
|
||||
defaultValue: false,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const body: any = {};
|
||||
|
||||
if (propsValue.project_name !== undefined) {
|
||||
body.project_name = propsValue.project_name;
|
||||
}
|
||||
if (propsValue.is_shared !== undefined) {
|
||||
body.is_shared = propsValue.is_shared;
|
||||
}
|
||||
if (propsValue.sitemap_path !== undefined) {
|
||||
body.sitemap_path = propsValue.sitemap_path;
|
||||
}
|
||||
if (propsValue.file_data_retension !== undefined) {
|
||||
body.file_data_retension = propsValue.file_data_retension;
|
||||
}
|
||||
if (propsValue.is_ocr_enabled !== undefined) {
|
||||
body.is_ocr_enabled = propsValue.is_ocr_enabled;
|
||||
}
|
||||
if (propsValue.is_anonymized !== undefined) {
|
||||
body.is_anonymized = propsValue.is_anonymized;
|
||||
}
|
||||
if (propsValue.file !== undefined) {
|
||||
body.file = propsValue.file;
|
||||
}
|
||||
if (propsValue.are_licenses_allowed !== undefined) {
|
||||
body.are_licenses_allowed = propsValue.are_licenses_allowed;
|
||||
}
|
||||
|
||||
const response = await httpClient.sendRequest({
|
||||
method: HttpMethod.POST,
|
||||
url: `${BASE_URL}/projects/${propsValue.project_id}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${auth.secret_text}`,
|
||||
'content-type': 'multipart/form-data',
|
||||
},
|
||||
body,
|
||||
});
|
||||
|
||||
return response.body;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,258 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { customgptAuth } from '../common/auth';
|
||||
import { projectId } from '../common/props';
|
||||
import { makeRequest } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const updateSettings = createAction({
|
||||
auth: customgptAuth,
|
||||
name: 'update_settings',
|
||||
displayName: 'Update Agent Settings',
|
||||
description: 'Update agent configuration and behavior settings',
|
||||
props: {
|
||||
project_id: projectId,
|
||||
default_prompt: Property.ShortText({
|
||||
displayName: 'Default Prompt',
|
||||
description:
|
||||
'Default prompt text shown to users (e.g., "Ask Me Anything ...")',
|
||||
required: false,
|
||||
}),
|
||||
|
||||
response_source: Property.StaticDropdown({
|
||||
displayName: 'Response Source',
|
||||
description: 'Source for generating responses',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'Default', value: 'default' },
|
||||
{ label: 'Own Content', value: 'own_content' },
|
||||
{ label: 'OpenAI Content', value: 'openai_content' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
chat_bot_avatar: Property.File({
|
||||
displayName: 'Chatbot Avatar',
|
||||
description: 'Upload avatar image for the chatbot',
|
||||
required: false,
|
||||
}),
|
||||
chat_bot_bg: Property.File({
|
||||
displayName: 'Chatbot Background',
|
||||
description: 'Upload background image for the chatbot',
|
||||
required: false,
|
||||
}),
|
||||
chatbot_msg_lang: Property.ShortText({
|
||||
displayName: 'Chatbot Message Language',
|
||||
description:
|
||||
'Language code for chatbot messages (e.g., "en", "es", "ur")',
|
||||
required: false,
|
||||
}),
|
||||
chatbot_color: Property.ShortText({
|
||||
displayName: 'Chatbot Color',
|
||||
description:
|
||||
'Primary color for chatbot UI (hex color code, e.g., "#0e57cc")',
|
||||
required: false,
|
||||
}),
|
||||
chatbot_toolbar_color: Property.ShortText({
|
||||
displayName: 'Chatbot Toolbar Color',
|
||||
description: 'Toolbar color for chatbot UI (hex color code)',
|
||||
required: false,
|
||||
}),
|
||||
persona_instructions: Property.LongText({
|
||||
displayName: 'Persona Instructions',
|
||||
description: 'Custom persona/behavior instructions for the chatbot',
|
||||
required: false,
|
||||
}),
|
||||
citations_answer_source_label_msg: Property.ShortText({
|
||||
displayName: 'Citations Answer Source Label',
|
||||
description: 'Label message for citation answer sources',
|
||||
required: false,
|
||||
}),
|
||||
citations_sources_label_msg: Property.ShortText({
|
||||
displayName: 'Citations Sources Label',
|
||||
description: 'Label message for citation sources',
|
||||
required: false,
|
||||
}),
|
||||
hang_in_there_msg: Property.ShortText({
|
||||
displayName: 'Hang In There Message',
|
||||
description: 'Message shown during long processing times',
|
||||
required: false,
|
||||
}),
|
||||
chatbot_siesta_msg: Property.ShortText({
|
||||
displayName: 'Chatbot Siesta Message',
|
||||
description: 'Message shown when chatbot is temporarily unavailable',
|
||||
required: false,
|
||||
}),
|
||||
is_loading_indicator_enabled: Property.Checkbox({
|
||||
displayName: 'Enable Loading Indicator',
|
||||
description: 'Show loading indicator during responses',
|
||||
required: false,
|
||||
}),
|
||||
enable_citations: Property.Checkbox({
|
||||
displayName: 'Enable Citations',
|
||||
description: 'Enable citation display in responses',
|
||||
required: false,
|
||||
}),
|
||||
enable_feedbacks: Property.Checkbox({
|
||||
displayName: 'Enable Feedbacks',
|
||||
description: 'Enable user feedback collection',
|
||||
required: false,
|
||||
}),
|
||||
citations_view_type: Property.StaticDropdown({
|
||||
displayName: 'Citations View Type',
|
||||
description: 'How citations should be displayed',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'User Controlled', value: 'user' },
|
||||
{ label: 'Always Show', value: 'show' },
|
||||
{ label: 'Always Hide', value: 'hide' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
no_answer_message: Property.ShortText({
|
||||
displayName: 'No Answer Message',
|
||||
description: 'Message shown when no answer is found',
|
||||
required: false,
|
||||
}),
|
||||
ending_message: Property.ShortText({
|
||||
displayName: 'Ending Message',
|
||||
description: 'Message shown at the end of conversations',
|
||||
required: false,
|
||||
}),
|
||||
remove_branding: Property.Checkbox({
|
||||
displayName: 'Remove Branding',
|
||||
description: 'Remove CustomGPT branding from the chatbot',
|
||||
required: false,
|
||||
}),
|
||||
enable_recaptcha_for_public_chatbots: Property.Checkbox({
|
||||
displayName: 'Enable reCAPTCHA',
|
||||
description: 'Enable reCAPTCHA for public chatbots',
|
||||
required: false,
|
||||
}),
|
||||
chatbot_model: Property.StaticDropdown({
|
||||
displayName: 'Chatbot Model',
|
||||
description: 'Default AI model for the chatbot',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'GPT-4o', value: 'gpt-4o' },
|
||||
{ label: 'GPT-4o Mini', value: 'gpt-4o-mini' },
|
||||
{ label: 'GPT-4 Turbo', value: 'gpt-4-turbo' },
|
||||
{ label: 'GPT-4', value: 'gpt-4' },
|
||||
{ label: 'Claude 3.5 Sonnet', value: 'claude-3-5-sonnet-20240620' },
|
||||
{ label: 'Claude 3 Sonnet', value: 'claude-3-sonnet-20240229' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
is_selling_enabled: Property.Checkbox({
|
||||
displayName: 'Enable Selling',
|
||||
description: 'Enable selling features',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run({ auth, propsValue }) {
|
||||
const { chat_bot_avatar, chat_bot_bg } = propsValue;
|
||||
const formData = new FormData();
|
||||
|
||||
if (chat_bot_avatar) {
|
||||
const avatarBuffer = Buffer.from(chat_bot_avatar.base64, 'base64');
|
||||
const avatarBlob = new Blob([avatarBuffer], {
|
||||
type: 'application/octet-stream',
|
||||
});
|
||||
formData.append('file', avatarBlob, chat_bot_avatar.filename || 'avatar');
|
||||
}
|
||||
if (chat_bot_bg) {
|
||||
const bgBuffer = Buffer.from(chat_bot_bg.base64, 'base64');
|
||||
const bgBlob = new Blob([bgBuffer], {
|
||||
type: 'application/octet-stream',
|
||||
});
|
||||
formData.append('chat_bot_bg', bgBlob, chat_bot_bg.filename);
|
||||
}
|
||||
if (propsValue.default_prompt !== undefined) {
|
||||
formData.append('default_prompt', propsValue.default_prompt);
|
||||
}
|
||||
|
||||
if (propsValue.response_source !== undefined) {
|
||||
formData.append('response_source', propsValue.response_source);
|
||||
}
|
||||
if (propsValue.chatbot_msg_lang !== undefined) {
|
||||
formData.append('chatbot_msg_lang', propsValue.chatbot_msg_lang);
|
||||
}
|
||||
if (propsValue.chatbot_color !== undefined) {
|
||||
formData.append('chatbot_color', propsValue.chatbot_color);
|
||||
}
|
||||
if (propsValue.chatbot_toolbar_color !== undefined) {
|
||||
formData.append(
|
||||
'chatbot_toolbar_color',
|
||||
propsValue.chatbot_toolbar_color
|
||||
);
|
||||
}
|
||||
if (propsValue.persona_instructions !== undefined) {
|
||||
formData.append('persona_instructions', propsValue.persona_instructions);
|
||||
}
|
||||
if (propsValue.citations_answer_source_label_msg !== undefined) {
|
||||
formData.append(
|
||||
'citations_answer_source_label_msg',
|
||||
propsValue.citations_answer_source_label_msg
|
||||
);
|
||||
}
|
||||
if (propsValue.citations_sources_label_msg !== undefined) {
|
||||
formData.append(
|
||||
'citations_sources_label_msg',
|
||||
propsValue.citations_sources_label_msg
|
||||
);
|
||||
}
|
||||
if (propsValue.hang_in_there_msg !== undefined) {
|
||||
formData.append('hang_in_there_msg', propsValue.hang_in_there_msg);
|
||||
}
|
||||
if (propsValue.chatbot_siesta_msg !== undefined) {
|
||||
formData.append('chatbot_siesta_msg', propsValue.chatbot_siesta_msg);
|
||||
}
|
||||
if (propsValue.is_loading_indicator_enabled !== undefined) {
|
||||
formData.append(
|
||||
'is_loading_indicator_enabled',
|
||||
String(propsValue.is_loading_indicator_enabled)
|
||||
);
|
||||
}
|
||||
if (propsValue.enable_citations !== undefined) {
|
||||
formData.append('enable_citations', String(propsValue.enable_citations));
|
||||
}
|
||||
if (propsValue.enable_feedbacks !== undefined) {
|
||||
formData.append('enable_feedbacks', String(propsValue.enable_feedbacks));
|
||||
}
|
||||
if (propsValue.citations_view_type !== undefined) {
|
||||
formData.append('citations_view_type', propsValue.citations_view_type);
|
||||
}
|
||||
if (propsValue.no_answer_message !== undefined) {
|
||||
formData.append('no_answer_message', propsValue.no_answer_message);
|
||||
}
|
||||
if (propsValue.ending_message !== undefined) {
|
||||
formData.append('ending_message', propsValue.ending_message);
|
||||
}
|
||||
if (propsValue.remove_branding !== undefined) {
|
||||
formData.append('remove_branding', String(propsValue.remove_branding));
|
||||
}
|
||||
if (propsValue.enable_recaptcha_for_public_chatbots !== undefined) {
|
||||
formData.append(
|
||||
'enable_recaptcha_for_public_chatbots',
|
||||
String(propsValue.enable_recaptcha_for_public_chatbots)
|
||||
);
|
||||
}
|
||||
if (propsValue.chatbot_model !== undefined) {
|
||||
formData.append('chatbot_model', propsValue.chatbot_model);
|
||||
}
|
||||
if (propsValue.is_selling_enabled !== undefined) {
|
||||
formData.append(
|
||||
'is_selling_enabled',
|
||||
String(propsValue.is_selling_enabled)
|
||||
);
|
||||
}
|
||||
|
||||
return await makeRequest(
|
||||
auth.secret_text,
|
||||
HttpMethod.POST,
|
||||
`/projects/${propsValue.project_id}/settings`,
|
||||
formData
|
||||
);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
import { PieceAuth } from '@activepieces/pieces-framework';
|
||||
|
||||
const markdownDescription = `
|
||||
To get your CustomGPT API Key:
|
||||
|
||||
1. Log in to [CustomGPT](https://app.customgpt.ai/login)
|
||||
2. Click the circle in the top right corner of the page and select **My Profile**
|
||||
3. Select the **API** tab
|
||||
4. Click the **Create API Key** button at the bottom of the page
|
||||
5. Copy your API key and paste it below
|
||||
|
||||
For more details, visit the [API Keys and Authentication guide](https://docs.customgpt.ai/reference/api-keys-and-authentication).
|
||||
`;
|
||||
|
||||
export const customgptAuth = PieceAuth.SecretText({
|
||||
displayName: 'API Key',
|
||||
required: true,
|
||||
description: markdownDescription,
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import { HttpMethod, httpClient } from '@activepieces/pieces-common';
|
||||
|
||||
export const BASE_URL = `https://app.customgpt.ai/api/v1`;
|
||||
|
||||
export async function makeRequest(
|
||||
api_key: string,
|
||||
method: HttpMethod,
|
||||
path: string,
|
||||
body?: unknown
|
||||
) {
|
||||
try {
|
||||
const response = await httpClient.sendRequest({
|
||||
method,
|
||||
url: `${BASE_URL}${path}`,
|
||||
headers: {
|
||||
Authorization: `Bearer ${api_key}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body,
|
||||
});
|
||||
return response.body;
|
||||
} catch (error: any) {
|
||||
throw new Error(`Unexpected error: ${error.message || String(error)}`);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import { Property } from '@activepieces/pieces-framework';
|
||||
import { customgptAuth } from './auth';
|
||||
import { makeRequest } from './client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const projectId = Property.Dropdown({
|
||||
auth: customgptAuth,
|
||||
displayName: 'Agent',
|
||||
description: 'Select the agent to use',
|
||||
refreshers: [],
|
||||
required: true,
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Cursor account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await makeRequest(
|
||||
auth.secret_text,
|
||||
HttpMethod.GET,
|
||||
'/projects'
|
||||
);
|
||||
|
||||
if (!response.data || response.data.data.length === 0) {
|
||||
return {
|
||||
options: [],
|
||||
placeholder: 'No agents found',
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
options: response.data.data.map((agent: any) => ({
|
||||
label: `${agent.project_name} (${agent.status})`,
|
||||
value: agent.id,
|
||||
})),
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
options: [],
|
||||
placeholder: 'Failed to load agents. Check your API key.',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,87 @@
|
||||
import {
|
||||
createTrigger,
|
||||
TriggerStrategy,
|
||||
AppConnectionValueForAuthProperty,
|
||||
} from '@activepieces/pieces-framework';
|
||||
import {
|
||||
DedupeStrategy,
|
||||
Polling,
|
||||
pollingHelper,
|
||||
HttpMethod,
|
||||
} from '@activepieces/pieces-common';
|
||||
import dayjs from 'dayjs';
|
||||
import { customgptAuth } from '../common/auth';
|
||||
import { projectId } from '../common/props';
|
||||
import { makeRequest } from '../common/client';
|
||||
|
||||
const polling: Polling<
|
||||
AppConnectionValueForAuthProperty<typeof customgptAuth>,
|
||||
{ project_id: unknown }
|
||||
> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
items: async ({ auth, propsValue, lastFetchEpochMS }) => {
|
||||
const items: any[] = [];
|
||||
const page = 1;
|
||||
|
||||
const queryParams: any = {
|
||||
page: page.toString(),
|
||||
order: 'desc',
|
||||
orderBy: 'created_at',
|
||||
};
|
||||
|
||||
if (lastFetchEpochMS) {
|
||||
const lastFetchDate = new Date(lastFetchEpochMS).toISOString();
|
||||
queryParams.lastUpdatedAfter = lastFetchDate;
|
||||
}
|
||||
|
||||
const queryString = new URLSearchParams(queryParams).toString();
|
||||
|
||||
const response = await makeRequest(
|
||||
auth.secret_text,
|
||||
HttpMethod.GET,
|
||||
`/projects/${propsValue['project_id']}/conversations?${queryString}`
|
||||
);
|
||||
|
||||
if (response.body.status === 'success' && response.body.data.data) {
|
||||
items.push(...response.body.data.data);
|
||||
}
|
||||
|
||||
return items.map((item) => ({
|
||||
epochMilliSeconds: dayjs(item.created_at).valueOf(),
|
||||
data: item,
|
||||
}));
|
||||
},
|
||||
};
|
||||
|
||||
export const newConversation = createTrigger({
|
||||
auth: customgptAuth,
|
||||
name: 'new_conversation',
|
||||
displayName: 'New Conversation',
|
||||
description: 'Triggers when a new conversation is created in an agent',
|
||||
props: {
|
||||
project_id: projectId,
|
||||
},
|
||||
sampleData: {
|
||||
id: 1,
|
||||
session_id: 'f1b9aaf0-5e4e-11eb-ae93-0242ac130002',
|
||||
name: 'Conversation 1',
|
||||
project_id: 1,
|
||||
created_by: 1,
|
||||
created_at: '2023-04-30 16:43:53',
|
||||
updated_at: '2023-04-30 16:43:53',
|
||||
deleted_at: null,
|
||||
},
|
||||
type: TriggerStrategy.POLLING,
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, context);
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"extends": "../../../../tsconfig.base.json",
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"strict": true,
|
||||
"importHelpers": true,
|
||||
"noImplicitOverride": true,
|
||||
"noImplicitReturns": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noPropertyAccessFromIndexSignature": true
|
||||
},
|
||||
"files": [],
|
||||
"include": [],
|
||||
"references": [
|
||||
{
|
||||
"path": "./tsconfig.lib.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "../../../../dist/out-tsc",
|
||||
"declaration": true,
|
||||
"types": ["node"]
|
||||
},
|
||||
"include": ["src/**/*.ts"]
|
||||
}
|
||||
Reference in New Issue
Block a user