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,65 @@
|
||||
import {
|
||||
AuthenticationType,
|
||||
httpClient,
|
||||
HttpMethod,
|
||||
HttpRequest,
|
||||
} from '@activepieces/pieces-common';
|
||||
import { bexioCommon } from './index';
|
||||
|
||||
export class BexioClient {
|
||||
constructor(private auth: {access_token: string}) {}
|
||||
|
||||
async makeRequest<T>(
|
||||
method: HttpMethod,
|
||||
endpoint: string,
|
||||
data?: unknown,
|
||||
queryParams?: Record<string, string>
|
||||
): Promise<T> {
|
||||
// If endpoint already includes version (starts with /2.0/ or /3.0/), use it directly
|
||||
// Otherwise, prepend the default API version
|
||||
const url = endpoint.startsWith('/2.0/') || endpoint.startsWith('/3.0/')
|
||||
? `${bexioCommon.baseUrl}${endpoint}`
|
||||
: `${bexioCommon.baseUrl}/${bexioCommon.api_version}${endpoint}`;
|
||||
|
||||
const request: HttpRequest = {
|
||||
method,
|
||||
url,
|
||||
authentication: {
|
||||
type: AuthenticationType.BEARER_TOKEN,
|
||||
token: this.auth.access_token,
|
||||
},
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
};
|
||||
|
||||
if (data) {
|
||||
request.body = data;
|
||||
}
|
||||
|
||||
if (queryParams) {
|
||||
request.queryParams = queryParams;
|
||||
}
|
||||
|
||||
const response = await httpClient.sendRequest<T>(request);
|
||||
return response.body;
|
||||
}
|
||||
|
||||
async get<T>(endpoint: string, queryParams?: Record<string, string>): Promise<T> {
|
||||
return this.makeRequest<T>(HttpMethod.GET, endpoint, undefined, queryParams);
|
||||
}
|
||||
|
||||
async post<T>(endpoint: string, data: unknown, queryParams?: Record<string, string>): Promise<T> {
|
||||
return this.makeRequest<T>(HttpMethod.POST, endpoint, data, queryParams);
|
||||
}
|
||||
|
||||
async patch<T>(endpoint: string, data: unknown): Promise<T> {
|
||||
return this.makeRequest<T>(HttpMethod.PATCH, endpoint, data);
|
||||
}
|
||||
|
||||
async delete<T>(endpoint: string): Promise<T> {
|
||||
return this.makeRequest<T>(HttpMethod.DELETE, endpoint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export const bexioCommon = {
|
||||
baseUrl: 'https://api.bexio.com',
|
||||
api_version: '3.0',
|
||||
};
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
import { Property, OAuth2PropertyValue } from '@activepieces/pieces-framework';
|
||||
import { BexioClient } from './client';
|
||||
import { BexioAccount, BexioTax, BexioCurrency } from './types';
|
||||
import { bexioAuth } from '../..';
|
||||
|
||||
export const bexioCommonProps = {
|
||||
account: (options: {
|
||||
displayName: string;
|
||||
description?: string;
|
||||
required: boolean;
|
||||
}) => {
|
||||
return Property.Dropdown({
|
||||
auth: bexioAuth,
|
||||
displayName: options.displayName,
|
||||
description: options.description,
|
||||
required: options.required,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Bexio account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const client = new BexioClient(auth);
|
||||
const accounts = await client.get<BexioAccount[]>('/accounts');
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: accounts.map((account) => ({
|
||||
label: `${account.account_no} - ${account.name}`,
|
||||
value: account.id,
|
||||
})),
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Failed to load accounts',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
tax: Property.Dropdown({
|
||||
auth: bexioAuth,
|
||||
displayName: 'Tax',
|
||||
description: 'Select a tax rate',
|
||||
required: false,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Bexio account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const client = new BexioClient(auth);
|
||||
const taxes = await client.get<BexioTax[]>('/taxes');
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: taxes.map((tax) => ({
|
||||
label: `${tax.name} (${tax.percentage}%)`,
|
||||
value: tax.id,
|
||||
})),
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Failed to load taxes',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
currency: (options: {
|
||||
displayName: string;
|
||||
description?: string;
|
||||
required: boolean;
|
||||
}) => {
|
||||
return Property.Dropdown({
|
||||
auth: bexioAuth,
|
||||
displayName: options.displayName,
|
||||
description: options.description,
|
||||
required: options.required,
|
||||
refreshers: [],
|
||||
options: async ({ auth }) => {
|
||||
if (!auth) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Connect your Bexio account first',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const client = new BexioClient(auth);
|
||||
const currencies = await client.get<BexioCurrency[]>('/3.0/currencies');
|
||||
|
||||
return {
|
||||
disabled: false,
|
||||
options: currencies.map((currency) => ({
|
||||
label: currency.name,
|
||||
value: currency.id,
|
||||
})),
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
disabled: true,
|
||||
placeholder: 'Failed to load currencies',
|
||||
options: [],
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
// Common types for Bexio API
|
||||
|
||||
export interface BexioContact {
|
||||
id: number;
|
||||
nr: string;
|
||||
contact_type_id: number;
|
||||
name_1: string;
|
||||
name_2?: string;
|
||||
salutation_id?: number;
|
||||
salutation_form?: number;
|
||||
title_id?: number;
|
||||
birthday?: string;
|
||||
address?: string;
|
||||
postcode?: string;
|
||||
city?: string;
|
||||
country_id?: number;
|
||||
mail?: string;
|
||||
mail_second?: string;
|
||||
phone_fixed?: string;
|
||||
phone_fixed_second?: string;
|
||||
phone_mobile?: string;
|
||||
fax?: string;
|
||||
url?: string;
|
||||
skype_name?: string;
|
||||
remarks?: string;
|
||||
language_id?: number;
|
||||
contact_group_ids?: string;
|
||||
contact_branch_ids?: string;
|
||||
user_id?: number;
|
||||
owner_id?: number;
|
||||
}
|
||||
|
||||
export interface BexioCompany {
|
||||
id: number;
|
||||
name: string;
|
||||
address?: string;
|
||||
address_nr?: string;
|
||||
postcode?: string;
|
||||
city?: string;
|
||||
country_id?: number;
|
||||
legal_form?: string;
|
||||
}
|
||||
|
||||
export interface BexioAccount {
|
||||
id: number;
|
||||
account_no: string;
|
||||
name: string;
|
||||
account_type: number;
|
||||
}
|
||||
|
||||
export interface BexioTax {
|
||||
id: number;
|
||||
name: string;
|
||||
percentage: string;
|
||||
}
|
||||
|
||||
export interface BexioCurrency {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface BexioManualEntry {
|
||||
debit_account_id?: number;
|
||||
credit_account_id?: number;
|
||||
tax_id?: number;
|
||||
tax_account_id?: number;
|
||||
description?: string;
|
||||
amount?: number;
|
||||
currency_id?: number;
|
||||
currency_factor?: number;
|
||||
}
|
||||
|
||||
export interface BexioManualEntryResponse {
|
||||
id: number;
|
||||
type: 'manual_single_entry' | 'manual_compound_entry' | 'manual_group_entry';
|
||||
date: string;
|
||||
reference_nr?: string;
|
||||
created_by_user_id?: number;
|
||||
edited_by_user_id?: number;
|
||||
entries: BexioManualEntry[];
|
||||
is_locked?: boolean;
|
||||
locked_info?: string;
|
||||
}
|
||||
|
||||
export interface BexioError {
|
||||
error_code: number;
|
||||
message: string;
|
||||
}
|
||||
|
||||
export interface BexioListResponse<T> {
|
||||
data: T[];
|
||||
paging?: {
|
||||
page: number;
|
||||
page_size: number;
|
||||
page_count: number;
|
||||
item_count: number;
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user