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,71 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { fragmentAuth } from '../common/auth';
|
||||
import { fragmentClient } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const createTask = createAction({
|
||||
auth: fragmentAuth,
|
||||
name: 'create_task',
|
||||
displayName: 'Create Task',
|
||||
description: 'Creates a new task in Fragment.',
|
||||
props: {
|
||||
title: Property.ShortText({
|
||||
displayName: 'Title',
|
||||
description: 'The title of the task',
|
||||
required: true,
|
||||
}),
|
||||
url: Property.ShortText({
|
||||
displayName: 'URL',
|
||||
description: 'A URL associated with the task (e.g., link to a ticket or resource)',
|
||||
required: false,
|
||||
}),
|
||||
due_at: Property.DateTime({
|
||||
displayName: 'Due Date',
|
||||
description: 'When the task is due',
|
||||
required: false,
|
||||
}),
|
||||
assignee: Property.ShortText({
|
||||
displayName: 'Assignee',
|
||||
description: 'Email of the person to assign this task to.',
|
||||
required: false,
|
||||
}),
|
||||
tags: Property.Array({
|
||||
displayName: 'Tags',
|
||||
description: 'Tags to categorize the task',
|
||||
required: false,
|
||||
}),
|
||||
custom_fields: Property.Object({
|
||||
displayName: 'Custom Fields',
|
||||
description: 'Additional custom fields for the task',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const fields: Record<string, any> = {
|
||||
title: context.propsValue.title,
|
||||
...(context.propsValue.custom_fields ?? {}),
|
||||
};
|
||||
|
||||
const taskPayload: Record<string, any> = {
|
||||
fields,
|
||||
};
|
||||
|
||||
if (context.propsValue.url) {
|
||||
fields['url'] = context.propsValue.url;
|
||||
}
|
||||
if (context.propsValue.due_at) {
|
||||
taskPayload['due_at'] = context.propsValue.due_at;
|
||||
}
|
||||
|
||||
if (context.propsValue.assignee) {
|
||||
taskPayload['assignee_email'] = context.propsValue.assignee;
|
||||
}
|
||||
if (context.propsValue.tags && Array.isArray(context.propsValue.tags)) {
|
||||
taskPayload['tags'] = context.propsValue.tags;
|
||||
}
|
||||
|
||||
const response = await fragmentClient.makeRequest(HttpMethod.POST, '/tasks', context.auth, taskPayload);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
import { createCustomApiCallAction } from '@activepieces/pieces-common';
|
||||
import { fragmentAuth } from '../common/auth';
|
||||
|
||||
export const customApiCall = createCustomApiCallAction({
|
||||
auth: fragmentAuth,
|
||||
name: 'custom_api_call',
|
||||
displayName: 'Custom API Call',
|
||||
description: 'Make a custom API call to any Fragment endpoint',
|
||||
baseUrl: () => 'https://api.onfragment.com/api/v1',
|
||||
authMapping: async (auth) => ({
|
||||
'Authorization': `Bearer ${auth}`,
|
||||
'Content-Type': 'application/json',
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { fragmentAuth } from '../common/auth';
|
||||
import { fragmentClient } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const deleteTask = createAction({
|
||||
auth: fragmentAuth,
|
||||
name: 'delete_task',
|
||||
displayName: 'Delete Task',
|
||||
description: 'Deletes an existing task.',
|
||||
props: {
|
||||
task_uid: Property.ShortText({
|
||||
displayName: 'Task UID',
|
||||
description: 'The unique identifier of the task to delete',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const response = await fragmentClient.makeRequest(
|
||||
HttpMethod.DELETE,
|
||||
`/tasks/${context.propsValue.task_uid}`,
|
||||
context.auth
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { fragmentAuth } from '../common/auth';
|
||||
import { fragmentClient } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const getTask = createAction({
|
||||
auth: fragmentAuth,
|
||||
name: 'get_task',
|
||||
displayName: 'Get Task',
|
||||
description: 'Retrieves details of a specific task.',
|
||||
props: {
|
||||
task_uid: Property.ShortText({
|
||||
displayName: 'Task UID',
|
||||
description: 'The unique identifier of the task to retrieve',
|
||||
required: true,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const response = await fragmentClient.makeRequest(
|
||||
HttpMethod.GET,
|
||||
`/tasks/${context.propsValue.task_uid}`,
|
||||
context.auth
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { fragmentAuth } from '../common/auth';
|
||||
import { fragmentClient } from '../common/client';
|
||||
import { HttpMethod, QueryParams } from '@activepieces/pieces-common';
|
||||
|
||||
export const listTasks = createAction({
|
||||
auth: fragmentAuth,
|
||||
name: 'list_tasks',
|
||||
displayName: 'List Tasks',
|
||||
description: 'Retrieves a list of tasks from.',
|
||||
props: {
|
||||
status: Property.StaticDropdown({
|
||||
displayName: 'Status',
|
||||
description: 'Filter tasks by status',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'TODO', value: 'TODO' },
|
||||
{ label: 'STARTED', value: 'STARTED' },
|
||||
{ label: 'DONE', value: 'DONE' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
assignee: Property.ShortText({
|
||||
displayName: 'Assignee',
|
||||
description: 'Filter tasks by assignee email or ID',
|
||||
required: false,
|
||||
}),
|
||||
limit: Property.Number({
|
||||
displayName: 'Limit',
|
||||
description: 'Maximum number of tasks to return (default: 50)',
|
||||
required: false,
|
||||
defaultValue: 50,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const queryParams: QueryParams = {};
|
||||
|
||||
if (context.propsValue.status) {
|
||||
queryParams['status'] = context.propsValue.status;
|
||||
}
|
||||
if (context.propsValue.assignee) {
|
||||
queryParams['assignee_uid'] = context.propsValue.assignee;
|
||||
}
|
||||
if (context.propsValue.limit !== undefined) {
|
||||
queryParams['limit'] = context.propsValue.limit.toString();
|
||||
}
|
||||
|
||||
const response = await fragmentClient.makeRequest(
|
||||
HttpMethod.GET,
|
||||
'/tasks',
|
||||
context.auth,
|
||||
undefined,
|
||||
queryParams
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
import { createAction, Property } from '@activepieces/pieces-framework';
|
||||
import { fragmentAuth } from '../common/auth';
|
||||
import { fragmentClient } from '../common/client';
|
||||
import { HttpMethod } from '@activepieces/pieces-common';
|
||||
import { isEmpty } from '@activepieces/shared';
|
||||
|
||||
export const updateTask = createAction({
|
||||
auth: fragmentAuth,
|
||||
name: 'update_task',
|
||||
displayName: 'Update Task',
|
||||
description: 'Updates an existing task.',
|
||||
props: {
|
||||
task_uid: Property.ShortText({
|
||||
displayName: 'Task UID',
|
||||
description: 'The unique identifier of the task to update',
|
||||
required: true,
|
||||
}),
|
||||
title: Property.ShortText({
|
||||
displayName: 'Title',
|
||||
description: 'The updated title of the task',
|
||||
required: false,
|
||||
}),
|
||||
url: Property.ShortText({
|
||||
displayName: 'URL',
|
||||
description: 'The updated URL for the task',
|
||||
required: false,
|
||||
}),
|
||||
due_at: Property.DateTime({
|
||||
displayName: 'Due Date',
|
||||
description: 'The updated due date',
|
||||
required: false,
|
||||
}),
|
||||
status: Property.StaticDropdown({
|
||||
displayName: 'Status',
|
||||
description: 'The status of the task',
|
||||
required: false,
|
||||
options: {
|
||||
options: [
|
||||
{ label: 'TODO', value: 'TODO' },
|
||||
{ label: 'STARTED', value: 'STARTED' },
|
||||
{ label: 'DONE', value: 'DONE' },
|
||||
],
|
||||
},
|
||||
}),
|
||||
assignee: Property.ShortText({
|
||||
displayName: 'Assignee',
|
||||
description: 'Email of the person to assign this task to',
|
||||
required: false,
|
||||
}),
|
||||
tags: Property.Array({
|
||||
displayName: 'Tags',
|
||||
description: 'Updated tags for the task',
|
||||
required: false,
|
||||
}),
|
||||
custom_fields: Property.Object({
|
||||
displayName: 'Custom Fields',
|
||||
description: 'Updated custom fields',
|
||||
required: false,
|
||||
}),
|
||||
},
|
||||
async run(context) {
|
||||
const fields: Record<string, any> = {
|
||||
...(context.propsValue.custom_fields ?? {}),
|
||||
};
|
||||
const taskPayload: Record<string, any> = {};
|
||||
|
||||
if (context.propsValue.title) {
|
||||
fields['title'] = context.propsValue.title;
|
||||
}
|
||||
if (context.propsValue.url) {
|
||||
fields['url'] = context.propsValue.url;
|
||||
}
|
||||
if (context.propsValue.due_at) {
|
||||
taskPayload['due_at'] = context.propsValue.due_at;
|
||||
}
|
||||
if (context.propsValue.status) {
|
||||
taskPayload['status'] = context.propsValue.status;
|
||||
}
|
||||
if (context.propsValue.assignee) {
|
||||
taskPayload['assignee_email'] = context.propsValue.assignee;
|
||||
}
|
||||
if (context.propsValue.tags && Array.isArray(context.propsValue.tags)) {
|
||||
taskPayload['tags'] = context.propsValue.tags;
|
||||
}
|
||||
|
||||
if(!isEmpty(fields)) taskPayload['fields'] = fields;
|
||||
|
||||
const response = await fragmentClient.makeRequest(
|
||||
HttpMethod.PATCH,
|
||||
`/tasks/${context.propsValue.task_uid}`,
|
||||
context.auth,
|
||||
taskPayload
|
||||
);
|
||||
|
||||
return response;
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
import { PieceAuth } from '@activepieces/pieces-framework';
|
||||
import { httpClient, HttpMethod } from '@activepieces/pieces-common';
|
||||
|
||||
export const fragmentAuth = PieceAuth.SecretText({
|
||||
displayName: 'API Token',
|
||||
description: `You can obtain your API token by navigating to [Developer Settings](https://app.onfragment.com/settings/account/developers).`,
|
||||
required: true,
|
||||
validate: async ({ auth }) => {
|
||||
try {
|
||||
// Validate by attempting to list tasks
|
||||
await httpClient.sendRequest({
|
||||
method: HttpMethod.GET,
|
||||
url: 'https://api.onfragment.com/api/v1/tasks',
|
||||
headers: {
|
||||
'Authorization': `Bearer ${auth}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
queryParams: {
|
||||
limit: '1',
|
||||
},
|
||||
});
|
||||
return {
|
||||
valid: true,
|
||||
};
|
||||
} catch (error: any) {
|
||||
return {
|
||||
valid: false,
|
||||
error: 'Invalid API token. Please check your API token and try again.',
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
import { httpClient, HttpMethod, HttpMessageBody } from '@activepieces/pieces-common';
|
||||
import { AppConnectionValueForAuthProperty } from '@activepieces/pieces-framework';
|
||||
import { fragmentAuth } from './auth';
|
||||
|
||||
export const BASE_URL = 'https://api.onfragment.com/api/v1';
|
||||
|
||||
export interface FragmentTask {
|
||||
uid?: string;
|
||||
title: string;
|
||||
url?: string;
|
||||
due_at?: string;
|
||||
priority?: 'low' | 'medium' | 'high' | 'urgent';
|
||||
status?: 'open' | 'completed' | 'cancelled';
|
||||
assignee?: string;
|
||||
tags?: string[];
|
||||
custom_fields?: Record<string, any>;
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export const fragmentClient = {
|
||||
async makeRequest<T extends HttpMessageBody = any>(
|
||||
method: HttpMethod,
|
||||
path: string,
|
||||
apiKey: AppConnectionValueForAuthProperty<typeof fragmentAuth>,
|
||||
body?: any,
|
||||
queryParams?: Record<string, string>
|
||||
): Promise<T> {
|
||||
const url = `${BASE_URL}${path}`;
|
||||
|
||||
try {
|
||||
const response = await httpClient.sendRequest<T>({
|
||||
method,
|
||||
url,
|
||||
headers: {
|
||||
'Authorization': `Bearer ${apiKey.secret_text}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body,
|
||||
queryParams,
|
||||
});
|
||||
|
||||
return response.body;
|
||||
} catch (error: any) {
|
||||
const errorMessage = error.response?.body?.message || error.message || 'Unknown error occurred';
|
||||
throw new Error(`Fragment API Error: ${errorMessage}`);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from './auth';
|
||||
export * from './client';
|
||||
|
||||
@@ -0,0 +1,132 @@
|
||||
import { AppConnectionValueForAuthProperty, createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { fragmentAuth } from '../common/auth';
|
||||
import { fragmentClient, FragmentTask } from '../common/client';
|
||||
import { HttpMethod, QueryParams } from '@activepieces/pieces-common';
|
||||
import { DedupeStrategy, Polling, pollingHelper } from '@activepieces/pieces-common';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const polling: Polling<AppConnectionValueForAuthProperty<typeof fragmentAuth>, Record<string, never>> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
items: async ({ auth, lastFetchEpochMS }) => {
|
||||
const isTest = lastFetchEpochMS > 0;
|
||||
|
||||
const qs: QueryParams = {
|
||||
order_by: 'created_at',
|
||||
limit: isTest ? '10' : '100',
|
||||
};
|
||||
|
||||
if (!isTest) {
|
||||
qs['created_at_after'] = dayjs(lastFetchEpochMS).toISOString();
|
||||
}
|
||||
|
||||
const response = await fragmentClient.makeRequest<{ items: FragmentTask[] }>(
|
||||
HttpMethod.GET,
|
||||
'/tasks',
|
||||
auth,
|
||||
undefined,
|
||||
qs,
|
||||
);
|
||||
|
||||
const items = response.items.map((task) => ({
|
||||
epochMilliSeconds: dayjs(task.created_at).valueOf(),
|
||||
data: task,
|
||||
}));
|
||||
|
||||
return items;
|
||||
},
|
||||
};
|
||||
|
||||
export const newTaskTrigger = createTrigger({
|
||||
auth: fragmentAuth,
|
||||
name: 'new_task',
|
||||
displayName: 'New Task',
|
||||
description: 'Triggers when a new task is created.',
|
||||
props: {},
|
||||
type: TriggerStrategy.POLLING,
|
||||
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
sampleData: {
|
||||
uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
archived: true,
|
||||
status: 'TODO',
|
||||
legacy_data: {},
|
||||
skills: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
|
||||
queue_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
assignee_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
participants: {},
|
||||
case_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
parent_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
due_at: '2023-11-07T05:31:56Z',
|
||||
snooze_expires_at: '2023-11-07T05:31:56Z',
|
||||
fields: {},
|
||||
metadata_form_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
form_data: {},
|
||||
form_type: '<string>',
|
||||
assigned_at: '2023-11-07T05:31:56Z',
|
||||
started_at: '2023-11-07T05:31:56Z',
|
||||
done_at: '2023-11-07T05:31:56Z',
|
||||
created_at: '2023-11-07T05:31:56Z',
|
||||
updated_at: '2023-11-07T05:31:56Z',
|
||||
assignee_updated_by: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
queue_updated_by: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
is_assigned_player: true,
|
||||
internal_created_at: '2023-11-07T05:31:56Z',
|
||||
internal_updated_at: '2023-11-07T05:31:56Z',
|
||||
external_created_at: '2023-11-07T05:31:56Z',
|
||||
external_updated_at: '2023-11-07T05:31:56Z',
|
||||
external_status: 'TODO',
|
||||
external_status_updated_at: '2023-11-07T05:31:56Z',
|
||||
external_assignee_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
queue_time: 123,
|
||||
queue_time_business: 123,
|
||||
work_time: 123,
|
||||
work_time_business: 123,
|
||||
incremental_work_time: 123,
|
||||
incremental_work_time_business: 123,
|
||||
resolution_time: 123,
|
||||
resolution_time_business: 123,
|
||||
num_children: 123,
|
||||
num_children_done: 123,
|
||||
sla_breach_at: '2023-11-07T05:31:56Z',
|
||||
sla_breach_business_at: '2023-11-07T05:31:56Z',
|
||||
wait_time: 123,
|
||||
wait_time_business: 123,
|
||||
review_status: '<string>',
|
||||
task_type: '<string>',
|
||||
played_at: '2023-11-07T05:31:56Z',
|
||||
assignee: {
|
||||
uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
archived: true,
|
||||
role: 'super_admin',
|
||||
email: 'jsmith@example.com',
|
||||
first_name: '<string>',
|
||||
last_name: '<string>',
|
||||
skills: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
|
||||
legacy_data: {},
|
||||
created_at: '2023-11-07T05:31:56Z',
|
||||
updated_at: '2023-11-07T05:31:56Z',
|
||||
is_registered: true,
|
||||
},
|
||||
parent: {},
|
||||
children: [{}],
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,132 @@
|
||||
import { AppConnectionValueForAuthProperty, createTrigger, TriggerStrategy } from '@activepieces/pieces-framework';
|
||||
import { fragmentAuth } from '../common/auth';
|
||||
import { fragmentClient, FragmentTask } from '../common/client';
|
||||
import { HttpMethod, QueryParams } from '@activepieces/pieces-common';
|
||||
import { DedupeStrategy, Polling, pollingHelper } from '@activepieces/pieces-common';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const polling: Polling<AppConnectionValueForAuthProperty<typeof fragmentAuth>, Record<string, never>> = {
|
||||
strategy: DedupeStrategy.TIMEBASED,
|
||||
items: async ({ auth, lastFetchEpochMS }) => {
|
||||
const isTest = lastFetchEpochMS > 0;
|
||||
|
||||
const qs: QueryParams = {
|
||||
order_by: 'updated_at',
|
||||
limit: isTest ? '10' : '100',
|
||||
};
|
||||
|
||||
if (!isTest) {
|
||||
qs['updated_at_after'] = dayjs(lastFetchEpochMS).toISOString();
|
||||
}
|
||||
|
||||
const response = await fragmentClient.makeRequest<{ items: FragmentTask[] }>(
|
||||
HttpMethod.GET,
|
||||
'/tasks',
|
||||
auth,
|
||||
undefined,
|
||||
qs,
|
||||
);
|
||||
|
||||
const items = response.items.map((task) => ({
|
||||
epochMilliSeconds: dayjs(task.updated_at).valueOf(),
|
||||
data: task,
|
||||
}));
|
||||
|
||||
return items;
|
||||
},
|
||||
};
|
||||
|
||||
export const taskUpdatedTrigger = createTrigger({
|
||||
auth: fragmentAuth,
|
||||
name: 'task_updated',
|
||||
displayName: 'Task Updated',
|
||||
description: 'Triggers when a task is updated.',
|
||||
props: {},
|
||||
type: TriggerStrategy.POLLING,
|
||||
|
||||
async onEnable(context) {
|
||||
await pollingHelper.onEnable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async onDisable(context) {
|
||||
await pollingHelper.onDisable(polling, {
|
||||
auth: context.auth,
|
||||
store: context.store,
|
||||
propsValue: context.propsValue,
|
||||
});
|
||||
},
|
||||
async test(context) {
|
||||
return await pollingHelper.test(polling, context);
|
||||
},
|
||||
async run(context) {
|
||||
return await pollingHelper.poll(polling, context);
|
||||
},
|
||||
sampleData: {
|
||||
uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
archived: true,
|
||||
status: 'TODO',
|
||||
legacy_data: {},
|
||||
skills: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
|
||||
queue_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
assignee_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
participants: {},
|
||||
case_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
parent_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
due_at: '2023-11-07T05:31:56Z',
|
||||
snooze_expires_at: '2023-11-07T05:31:56Z',
|
||||
fields: {},
|
||||
metadata_form_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
form_data: {},
|
||||
form_type: '<string>',
|
||||
assigned_at: '2023-11-07T05:31:56Z',
|
||||
started_at: '2023-11-07T05:31:56Z',
|
||||
done_at: '2023-11-07T05:31:56Z',
|
||||
created_at: '2023-11-07T05:31:56Z',
|
||||
updated_at: '2023-11-07T05:31:56Z',
|
||||
assignee_updated_by: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
queue_updated_by: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
is_assigned_player: true,
|
||||
internal_created_at: '2023-11-07T05:31:56Z',
|
||||
internal_updated_at: '2023-11-07T05:31:56Z',
|
||||
external_created_at: '2023-11-07T05:31:56Z',
|
||||
external_updated_at: '2023-11-07T05:31:56Z',
|
||||
external_status: 'TODO',
|
||||
external_status_updated_at: '2023-11-07T05:31:56Z',
|
||||
external_assignee_uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
queue_time: 123,
|
||||
queue_time_business: 123,
|
||||
work_time: 123,
|
||||
work_time_business: 123,
|
||||
incremental_work_time: 123,
|
||||
incremental_work_time_business: 123,
|
||||
resolution_time: 123,
|
||||
resolution_time_business: 123,
|
||||
num_children: 123,
|
||||
num_children_done: 123,
|
||||
sla_breach_at: '2023-11-07T05:31:56Z',
|
||||
sla_breach_business_at: '2023-11-07T05:31:56Z',
|
||||
wait_time: 123,
|
||||
wait_time_business: 123,
|
||||
review_status: '<string>',
|
||||
task_type: '<string>',
|
||||
played_at: '2023-11-07T05:31:56Z',
|
||||
assignee: {
|
||||
uid: '3c90c3cc-0d44-4b50-8888-8dd25736052a',
|
||||
archived: true,
|
||||
role: 'super_admin',
|
||||
email: 'jsmith@example.com',
|
||||
first_name: '<string>',
|
||||
last_name: '<string>',
|
||||
skills: ['3c90c3cc-0d44-4b50-8888-8dd25736052a'],
|
||||
legacy_data: {},
|
||||
created_at: '2023-11-07T05:31:56Z',
|
||||
updated_at: '2023-11-07T05:31:56Z',
|
||||
is_registered: true,
|
||||
},
|
||||
parent: {},
|
||||
children: [{}],
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user