@memberjunction/actions-bizapps-crm
Version:
CRM system integration actions for MemberJunction
333 lines (310 loc) • 12.2 kB
text/typescript
import { RegisterClass } from '@memberjunction/global';
import { HubSpotBaseAction } from '../hubspot-base.action';
import { ActionParam, ActionResultSimple, RunActionParams } from '@memberjunction/actions-base';
import { BaseAction } from '@memberjunction/actions';
/**
* Action to create tasks in HubSpot
*/
(BaseAction, 'CreateTaskAction')
export class CreateTaskAction extends HubSpotBaseAction {
/**
* Create a task in HubSpot
*/
protected async InternalRunAction(params: RunActionParams): Promise<ActionResultSimple> {
const { Params, ContextUser } = params;
this.params = Params; // Set params for base class to use
try {
// Extract and validate parameters
const subject = this.getParamValue(Params, 'Subject');
const body = this.getParamValue(Params, 'Body');
const status = this.getParamValue(Params, 'Status') || 'NOT_STARTED';
const priority = this.getParamValue(Params, 'Priority') || 'NONE';
const dueDate = this.getParamValue(Params, 'DueDate');
const reminderDate = this.getParamValue(Params, 'ReminderDate');
const contactIds = this.getParamValue(Params, 'ContactIds');
const companyIds = this.getParamValue(Params, 'CompanyIds');
const dealIds = this.getParamValue(Params, 'DealIds');
const ownerId = this.getParamValue(Params, 'OwnerId');
const taskType = this.getParamValue(Params, 'TaskType') || 'TODO';
const queueId = this.getParamValue(Params, 'QueueId');
if (!subject) {
return {
Success: false,
ResultCode: 'VALIDATION_ERROR',
Message: 'Subject is required',
Params
};
}
// Validate status
const validStatuses = ['NOT_STARTED', 'IN_PROGRESS', 'WAITING', 'COMPLETED', 'DEFERRED'];
if (!validStatuses.includes(status.toUpperCase())) {
return {
Success: false,
ResultCode: 'VALIDATION_ERROR',
Message: `Invalid Status. Must be one of: ${validStatuses.join(', ')}`,
Params
};
}
// Validate priority
const validPriorities = ['NONE', 'LOW', 'MEDIUM', 'HIGH'];
if (!validPriorities.includes(priority.toUpperCase())) {
return {
Success: false,
ResultCode: 'VALIDATION_ERROR',
Message: `Invalid Priority. Must be one of: ${validPriorities.join(', ')}`,
Params
};
}
// Prepare task properties
const taskProperties: any = {
hs_task_subject: subject,
hs_task_body: body || '',
hs_task_status: status.toUpperCase(),
hs_task_priority: priority.toUpperCase(),
hs_task_type: taskType
};
// Add dates if provided
if (dueDate) {
const dueDateObj = new Date(dueDate);
if (isNaN(dueDateObj.getTime())) {
return {
Success: false,
ResultCode: 'VALIDATION_ERROR',
Message: 'Invalid DueDate format',
Params
};
}
// HubSpot expects date in midnight UTC
dueDateObj.setUTCHours(0, 0, 0, 0);
taskProperties.hs_timestamp = dueDateObj.getTime();
}
if (reminderDate) {
const reminderDateObj = new Date(reminderDate);
if (isNaN(reminderDateObj.getTime())) {
return {
Success: false,
ResultCode: 'VALIDATION_ERROR',
Message: 'Invalid ReminderDate format',
Params
};
}
taskProperties.hs_task_reminders = reminderDateObj.getTime();
}
// Add owner if provided
if (ownerId) {
taskProperties.hubspot_owner_id = ownerId;
}
// Add queue if provided
if (queueId) {
taskProperties.hs_queue_membership_ids = queueId;
}
// Create the task using the objects API
const task = await this.makeHubSpotRequest<any>(
'objects/tasks',
'POST',
{ properties: taskProperties },
ContextUser
);
// Associate with contacts, companies, and deals
const associationResults = [];
if (contactIds && Array.isArray(contactIds) && contactIds.length > 0) {
for (const contactId of contactIds) {
try {
await this.associateObjects(
'tasks',
task.id,
'contacts',
contactId,
undefined,
ContextUser
);
associationResults.push({
type: 'contact',
id: contactId,
success: true
});
} catch (error) {
associationResults.push({
type: 'contact',
id: contactId,
success: false,
error: error instanceof Error ? error.message : 'Association failed'
});
}
}
}
if (companyIds && Array.isArray(companyIds) && companyIds.length > 0) {
for (const companyId of companyIds) {
try {
await this.associateObjects(
'tasks',
task.id,
'companies',
companyId,
undefined,
ContextUser
);
associationResults.push({
type: 'company',
id: companyId,
success: true
});
} catch (error) {
associationResults.push({
type: 'company',
id: companyId,
success: false,
error: error instanceof Error ? error.message : 'Association failed'
});
}
}
}
if (dealIds && Array.isArray(dealIds) && dealIds.length > 0) {
for (const dealId of dealIds) {
try {
await this.associateObjects(
'tasks',
task.id,
'deals',
dealId,
undefined,
ContextUser
);
associationResults.push({
type: 'deal',
id: dealId,
success: true
});
} catch (error) {
associationResults.push({
type: 'deal',
id: dealId,
success: false,
error: error instanceof Error ? error.message : 'Association failed'
});
}
}
}
// Format task details
const taskDetails = this.mapHubSpotProperties(task);
// Create summary
const summary = {
taskId: taskDetails.id,
subject: taskDetails.hs_task_subject,
status: taskDetails.hs_task_status,
priority: taskDetails.hs_task_priority,
dueDate: taskDetails.hs_timestamp ? new Date(parseInt(taskDetails.hs_timestamp)).toISOString() : null,
reminderDate: taskDetails.hs_task_reminders ? new Date(parseInt(taskDetails.hs_task_reminders)).toISOString() : null,
owner: taskDetails.hubspot_owner_id,
createdAt: taskDetails.createdAt,
portalUrl: `https://app.hubspot.com/contacts/tasks/${taskDetails.id}`,
associations: associationResults
};
// Update output parameters
const outputParams = [...Params];
const taskDetailsParam = outputParams.find(p => p.Name === 'TaskDetails');
if (taskDetailsParam) taskDetailsParam.Value = taskDetails;
const summaryParam = outputParams.find(p => p.Name === 'Summary');
if (summaryParam) summaryParam.Value = summary;
return {
Success: true,
ResultCode: 'SUCCESS',
Message: `Successfully created task: ${taskDetails.hs_task_subject}`,
Params: outputParams
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : 'Unknown error occurred';
return {
Success: false,
ResultCode: 'ERROR',
Message: `Error creating task: ${errorMessage}`,
Params
};
}
}
/**
* Define the parameters this action expects
*/
public get Params(): ActionParam[] {
const baseParams = this.getCommonCRMParams();
const specificParams: ActionParam[] = [
{
Name: 'Subject',
Type: 'Input',
Value: null
},
{
Name: 'Body',
Type: 'Input',
Value: null
},
{
Name: 'Status',
Type: 'Input',
Value: 'NOT_STARTED'
},
{
Name: 'Priority',
Type: 'Input',
Value: 'NONE'
},
{
Name: 'DueDate',
Type: 'Input',
Value: null
},
{
Name: 'ReminderDate',
Type: 'Input',
Value: null
},
{
Name: 'ContactIds',
Type: 'Input',
Value: null
},
{
Name: 'CompanyIds',
Type: 'Input',
Value: null
},
{
Name: 'DealIds',
Type: 'Input',
Value: null
},
{
Name: 'OwnerId',
Type: 'Input',
Value: null
},
{
Name: 'TaskType',
Type: 'Input',
Value: 'TODO'
},
{
Name: 'QueueId',
Type: 'Input',
Value: null
},
{
Name: 'TaskDetails',
Type: 'Output',
Value: null
},
{
Name: 'Summary',
Type: 'Output',
Value: null
}
];
return [...baseParams, ...specificParams];
}
/**
* Metadata about this action
*/
public get Description(): string {
return 'Creates a task in HubSpot with due dates and optional associations to contacts, companies, and deals';
}
}