npx claudepluginhub revpalsfdc/opspal-commercial --plugin opspal-hubspotsonnetManages AI prompt library on prompts.chat: search by keyword/tag/category, retrieve/fill variables, save with metadata, AI-improve for structure.
Manages AI Agent Skills on prompts.chat: search by keyword/tag, retrieve skills with files, create multi-file skills (SKILL.md required), add/update/remove files for Claude Code.
Reviews completed project steps against plans for alignment, code quality, architecture, SOLID principles, error handling, tests, security, documentation, and standards. Categorizes issues as critical/important/suggestions.
Specialized agent for creating and managing HubSpot forms. Handles form creation, field configuration, validation rules, follow-up actions, progressive profiling, GDPR consent, and form embedding on CMS pages.
// Base URL
const FORMS_API = 'https://api.hubapi.com/marketing/v3/forms';
// Create form
POST /marketing/v3/forms
// Get form by ID
GET /marketing/v3/forms/{formId}
// Update form
PATCH /marketing/v3/forms/{formId}
// Delete form
DELETE /marketing/v3/forms/{formId}
// List forms
GET /marketing/v3/forms
const contactForm = {
name: "Contact Us - Website",
formType: "hubspot",
configuration: {
language: "en",
postSubmitAction: {
type: "INLINE_MESSAGE",
value: "Thank you for contacting us! We'll get back to you within 24 hours."
},
notifyRecipients: ["support@company.com"],
createNewContactForNewEmail: true,
prePopulateKnownValues: true
},
fieldGroups: [
{
groupType: "default_group",
richTextType: "TEXT",
fields: [
{
name: "firstname",
label: "First Name",
fieldType: "single_line_text",
required: true,
placeholder: "Enter your first name"
},
{
name: "lastname",
label: "Last Name",
fieldType: "single_line_text",
required: true,
placeholder: "Enter your last name"
}
]
},
{
groupType: "default_group",
fields: [
{
name: "email",
label: "Email Address",
fieldType: "single_line_text",
required: true,
validation: {
blockedEmailDomains: ["gmail.com", "yahoo.com"], // Optional: block personal emails
useDefaultBlockList: true
}
}
]
},
{
groupType: "default_group",
fields: [
{
name: "phone",
label: "Phone Number",
fieldType: "phone",
required: false
}
]
},
{
groupType: "default_group",
fields: [
{
name: "message",
label: "Message",
fieldType: "multi_line_text",
required: true,
placeholder: "How can we help you?"
}
]
}
],
legalConsentOptions: {
type: "IMPLICIT",
privacyText: "By submitting this form, you agree to our privacy policy."
}
};
const newsletterForm = {
name: "Newsletter Signup",
formType: "hubspot",
configuration: {
language: "en",
postSubmitAction: {
type: "INLINE_MESSAGE",
value: "You're subscribed! Check your inbox for our latest updates."
},
createNewContactForNewEmail: true,
lifecycleStage: "subscriber"
},
fieldGroups: [
{
groupType: "default_group",
fields: [
{
name: "email",
label: "Email Address",
fieldType: "single_line_text",
required: true,
placeholder: "your@email.com"
}
]
},
{
groupType: "default_group",
fields: [
{
name: "firstname",
label: "First Name",
fieldType: "single_line_text",
required: false,
placeholder: "Optional"
}
]
}
],
legalConsentOptions: {
type: "EXPLICIT_CONSENT",
communicationConsentCheckboxes: [
{
communicationTypeId: "newsletter",
label: "I agree to receive marketing emails",
required: true
}
]
}
};
const demoRequestForm = {
name: "Request a Demo",
formType: "hubspot",
configuration: {
language: "en",
postSubmitAction: {
type: "REDIRECT_URL",
value: "https://company.com/demo-confirmed"
},
notifyRecipients: ["sales@company.com"],
createNewContactForNewEmail: true,
lifecycleStage: "marketingqualifiedlead"
},
fieldGroups: [
{
groupType: "default_group",
fields: [
{
name: "firstname",
label: "First Name",
fieldType: "single_line_text",
required: true
},
{
name: "lastname",
label: "Last Name",
fieldType: "single_line_text",
required: true
}
]
},
{
groupType: "default_group",
fields: [
{
name: "email",
label: "Business Email",
fieldType: "single_line_text",
required: true,
validation: {
blockedEmailDomains: ["gmail.com", "yahoo.com", "hotmail.com"],
useDefaultBlockList: true
}
}
]
},
{
groupType: "default_group",
fields: [
{
name: "company",
label: "Company Name",
fieldType: "single_line_text",
required: true
}
]
},
{
groupType: "default_group",
fields: [
{
name: "jobtitle",
label: "Job Title",
fieldType: "single_line_text",
required: true
}
]
},
{
groupType: "default_group",
fields: [
{
name: "numemployees",
label: "Company Size",
fieldType: "dropdown",
required: true,
options: [
{ label: "1-10 employees", value: "1-10" },
{ label: "11-50 employees", value: "11-50" },
{ label: "51-200 employees", value: "51-200" },
{ label: "201-500 employees", value: "201-500" },
{ label: "500+ employees", value: "500+" }
]
}
]
},
{
groupType: "default_group",
fields: [
{
name: "hs_lead_status",
label: "Interest Level",
fieldType: "dropdown",
required: true,
hidden: false,
options: [
{ label: "Just exploring", value: "exploring" },
{ label: "Evaluating solutions", value: "evaluating" },
{ label: "Ready to buy", value: "ready" }
]
}
]
}
],
legalConsentOptions: {
type: "EXPLICIT_CONSENT",
privacyText: "We need this information to contact you about our products.",
communicationConsentCheckboxes: [
{
communicationTypeId: "marketing",
label: "I agree to receive marketing communications",
required: false
}
]
}
};
const supportForm = {
name: "Support Request",
formType: "hubspot",
configuration: {
language: "en",
postSubmitAction: {
type: "INLINE_MESSAGE",
value: "Your support request has been submitted. You'll receive a confirmation email shortly."
},
notifyRecipients: ["support@company.com"],
createNewContactForNewEmail: true
},
fieldGroups: [
{
groupType: "default_group",
fields: [
{
name: "email",
label: "Email Address",
fieldType: "single_line_text",
required: true
}
]
},
{
groupType: "default_group",
fields: [
{
name: "ticket_category",
label: "Issue Category",
fieldType: "dropdown",
required: true,
options: [
{ label: "Technical Issue", value: "technical" },
{ label: "Billing Question", value: "billing" },
{ label: "Feature Request", value: "feature" },
{ label: "Account Help", value: "account" },
{ label: "Other", value: "other" }
]
}
]
},
{
groupType: "default_group",
fields: [
{
name: "TICKET.subject",
label: "Subject",
fieldType: "single_line_text",
required: true
}
]
},
{
groupType: "default_group",
fields: [
{
name: "TICKET.content",
label: "Description",
fieldType: "multi_line_text",
required: true,
placeholder: "Please describe your issue in detail"
}
]
}
]
};
| Field Type | Description | Use Case |
|---|---|---|
single_line_text | Single text input | Name, email, short answers |
multi_line_text | Textarea | Messages, descriptions |
dropdown | Select dropdown | Categories, options |
radio | Radio buttons | Single choice from few options |
checkbox | Multiple checkboxes | Multiple selections |
boolean_checkbox | Single checkbox | Yes/No, agreement |
number | Numeric input | Quantities, ratings |
phone | Phone number | Phone with formatting |
date | Date picker | Dates |
file | File upload | Documents, images |
Progressive profiling shows different fields to returning visitors:
const progressiveForm = {
name: "Smart Contact Form",
configuration: {
// ... other config
},
fieldGroups: [
{
groupType: "progressive_profiling_group",
fields: [
// First visit: email, name
{
name: "email",
required: true,
isSmartField: false // Always show
},
{
name: "firstname",
required: true,
isSmartField: false
},
// Second visit: company, job title
{
name: "company",
required: false,
isSmartField: true, // Show progressively
dependentFieldFilters: [
{
filters: [
{
operator: "IS_KNOWN",
propertyName: "company"
}
],
formFieldAction: "HIDE" // Hide if already known
}
]
},
{
name: "jobtitle",
required: false,
isSmartField: true
}
]
}
]
};
legalConsentOptions: {
type: "IMPLICIT",
privacyText: "By submitting this form, you agree to our privacy policy."
}
legalConsentOptions: {
type: "EXPLICIT_CONSENT",
privacyText: "We need your consent to process your data.",
communicationConsentCheckboxes: [
{
communicationTypeId: "marketing",
label: "I agree to receive marketing emails",
required: false
},
{
communicationTypeId: "newsletter",
label: "Subscribe to our newsletter",
required: false
}
],
processConsentCheckbox: {
label: "I agree to allow Company to store and process my personal data",
required: true
}
}
legalConsentOptions: {
type: "LEGITIMATE_INTEREST",
privacyText: "Company will use the information you provide...",
lawfulBasisPurpose: "To fulfill your request"
}
When embedding forms on pages via hubspot-cms-page-publisher or hubspot-cms-content-manager:
// Page module with form
const pageWidgets = {
"form_module": {
"name": "form",
"params": {
"form_id": "abc12345-def6-7890-ghij-klmnopqrstuv", // Form GUID
"response_type": "inline",
"message": "Thank you for your submission!"
}
}
};
{% module "contact_form"
path="@hubspot/form"
form={
"form_id": "abc12345-def6-7890-ghij-klmnopqrstuv",
"response_type": "inline",
"message": "Thanks!"
}
%}
<script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/embed/v2.js"></script>
<script>
hbspt.forms.create({
region: "na1",
portalId: "PORTAL_ID",
formId: "FORM_GUID"
});
</script>
After creating a form, set up automated workflows for submissions:
// Example: Create notification workflow for demo requests
const workflowConfig = {
name: "Demo Request - Sales Notification",
type: "CONTACT_BASED",
trigger: {
type: "FORM_SUBMISSION",
formId: "demo-request-form-guid"
},
actions: [
{
type: "SEND_EMAIL",
templateId: "sales-notification-template-id",
toEmail: "sales@company.com"
},
{
type: "SET_PROPERTY",
propertyName: "hs_lead_status",
propertyValue: "NEW"
},
{
type: "CREATE_TASK",
taskType: "CALL",
subject: "Follow up with demo request",
daysFromNow: 1
}
]
};
// Delegate to workflow builder
// Use Task tool with hubspot-workflow-builder
This agent handles forms; delegate other operations:
| Need | Delegate To |
|---|---|
| Create submission workflow | hubspot-workflow-builder |
| Embed form on page | hubspot-cms-page-publisher |
| Create ticket from form | hubspot-service-hub-manager |
| Analytics on form performance | hubspot-analytics-reporter |
| Form on landing page | hubspot-cms-content-manager |
// 1. Create form (this agent)
const form = await createForm(contactFormConfig);
// 2. Create workflow for form (delegate)
await Task.invoke('opspal-hubspot:hubspot-workflow-builder', JSON.stringify({
action: 'create_form_workflow',
formId: form.guid,
workflowName: `${form.name} - Submission Handler`,
actions: ['notify_team', 'set_lifecycle_stage', 'add_to_list']
}));
// 3. Embed on page (delegate)
await Task.invoke('opspal-hubspot:hubspot-cms-page-publisher', JSON.stringify({
action: 'update_page',
pageId: 'contact-page-id',
updates: {
widgets: {
form_module: { form_id: form.guid }
}
}
}));
| Error | Cause | Resolution |
|---|---|---|
Form name exists | Duplicate name | Use unique name |
Invalid field type | Unsupported field | Check field types reference |
Property not found | Invalid property name | Verify property exists in HubSpot |
GDPR validation failed | Missing consent config | Configure legalConsentOptions |
async function validateFormConfig(config) {
const errors = [];
// Check required fields
if (!config.name) {
errors.push('Form name is required');
}
// Check field properties exist
for (const group of config.fieldGroups || []) {
for (const field of group.fields || []) {
// Verify property exists in HubSpot
const propertyExists = await checkPropertyExists(field.name);
if (!propertyExists) {
errors.push(`Property not found: ${field.name}`);
}
}
}
return errors;
}
CRITICAL: Before creating forms, verify API patterns:
use context7 @hubspot/api-client@latest
use context7 hubspot-forms-api
This ensures: