feat(integrations): add FormyChat create lead action#167
Conversation
- Implemented FormyChat integration in the frontend, including components for editing and configuring the integration. - Added FormyChatController and RecordApiHelper in the backend to handle authorization and widget management. - Created routes for FormyChat actions. - Introduced common functions for handling FormyChat-specific logic. - Added necessary UI components for field mapping and integration layout. - Included FormyChat assets and static data for integration actions.
There was a problem hiding this comment.
Code Review
This pull request introduces a new integration for FormyChat, including backend controllers, API helpers, and a complete frontend UI for authorization and field mapping. The review feedback identifies critical issues regarding PHP 8.0+ compatibility, specifically the need to validate potential WP_Error objects using is_wp_error() before accessing them as arrays or objects to prevent fatal errors. Additionally, the feedback suggests adopting more defensive programming patterns by using null coalescing operators when handling field mapping data to avoid undefined property warnings.
✅ WordPress Plugin Check Report
📊 ReportAll checks passed! No errors or warnings found. 🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check |
There was a problem hiding this comment.
Pull request overview
Adds a new FormyChat "Create Lead" action integration. Backend introduces a controller (with authorization/widget/field refresh endpoints), a RecordApiHelper that builds the request payload and dispatches via a formy_chat_create_lead filter hook, and route registrations. Frontend wires up the new integration into the action picker, NewInteg, EditInteg, and IntegInfo dispatchers, and provides Authorization, Layout, FieldMap, MetaFieldMap, common helpers, and Edit components.
Changes:
- Backend FormyChat controller, RecordApiHelper, routes, and trigger-name registration.
- Frontend FormyChat integration suite (auth, layout, field/meta mapping, common helpers, edit screen).
- Registration of FormyChat in SelectAction, NewInteg, EditInteg, and IntegInfo dispatch maps.
Reviewed changes
Copilot reviewed 15 out of 16 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| backend/Core/Util/AllTriggersName.php | Registers FormyChat in the integrations registry. |
| backend/Actions/FormyChat/Routes.php | Declares the 3 REST routes for the new integration. |
| backend/Actions/FormyChat/FormyChatController.php | Handles authorize/widget/field requests and dispatches execution. |
| backend/Actions/FormyChat/RecordApiHelper.php | Builds field/meta payloads and triggers the formy_chat_create_lead hook. |
| frontend/src/components/Flow/New/SelectAction.jsx | Adds FormyChat to the action selection list. |
| frontend/src/components/AllIntegrations/NewInteg.jsx | Lazy-loads and routes to the new FormyChat creation flow. |
| frontend/src/components/AllIntegrations/EditInteg.jsx | Lazy-loads EditFormyChat for the edit flow. |
| frontend/src/components/AllIntegrations/IntegInfo.jsx | Adds FormyChat to the info/auth display dispatcher. |
| frontend/src/components/AllIntegrations/FormyChat/FormyChat.jsx | 3-step new-integration screen orchestrator. |
| frontend/src/components/AllIntegrations/FormyChat/EditFormyChat.jsx | Edit screen for existing FormyChat integrations. |
| frontend/src/components/AllIntegrations/FormyChat/FormyChatAuthorization.jsx | Step-1 authorization UI. |
| frontend/src/components/AllIntegrations/FormyChat/FormyChatIntegLayout.jsx | Action/widget selection plus field/meta mapping UI. |
| frontend/src/components/AllIntegrations/FormyChat/FormyChatFieldMap.jsx | Row UI for mapping a form field to a FormyChat field. |
| frontend/src/components/AllIntegrations/FormyChat/FormyChatMetaFieldMap.jsx | Row UI for mapping meta keys. |
| frontend/src/components/AllIntegrations/FormyChat/FormyChatCommonFunc.js | Shared helpers (input, refresh, validation, meta map ops). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
… in API responses
- Implemented SureDash integration with multiple steps for configuration. - Created SureDashAuthorization component for handling authorization with SureDash. - Developed SureDashIntegLayout for managing integration actions and field mappings. - Added SureDashFieldMap for mapping form fields to SureDash fields. - Introduced utility functions for handling input and refreshing data from SureDash. - Created static data for integration actions and field requirements. - Added SVG and WEBP images for SureDash integration representation.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 25 out of 28 changed files in this pull request and generated 9 comments.
Comments suppressed due to low confidence (1)
backend/Core/Util/AllTriggersName.php:134
AllTriggersNameis used to populate the trigger list when Pro isn’t active (seebackend/Triggers/TriggerController.php).SureDashis being registered here as a trigger, but this PR adds it as an action integration. If SureDash isn’t a trigger, it should not be listed inAllTriggersName(or it should be added to the appropriate actions registry instead).
'SureMail' => ['name' => 'SureMail', 'isPro' => true, 'is_active' => false],
'SureForms' => ['name' => 'SureForms', 'isPro' => true, 'is_active' => false],
'SureFeedback' => ['name' => 'SureFeedback', 'isPro' => true, 'is_active' => false],
'SureDash' => ['name' => 'SureDash', 'isPro' => true, 'is_active' => false],
'SureMembers' => ['name' => 'SureMembers', 'isPro' => true, 'is_active' => false],
'EventsCalendar' => ['name' => 'The Events Calendar', 'isPro' => true, 'is_active' => false],
| { type: 'ZagoMail' }, | ||
| { type: 'Drip' }, | ||
| { type: 'Newsletter' }, | ||
| { type: 'SureDash' }, | ||
| { type: 'SureMembers' }, | ||
| { type: 'Mailster' }, |
There was a problem hiding this comment.
Noted. The PR title/description will be updated to reflect both FormyChat and SureDash integrations.
| { type: 'MailerPress' }, | ||
| { type: 'CreatorLms' }, | ||
| { type: 'FluentCart' }, | ||
| { type: 'FormyChat' }, |
There was a problem hiding this comment.
The logo exists at frontend/src/resource/img/integ/formyChat.webp. GetLogo is called with extension="webp" so it resolves correctly — no missing asset.
| return <WhatsAppAuthorization whatsAppConf={integrationConf} step={1} isInfo /> | ||
| case 'Newsletter': | ||
| return <NewsletterAuthorization newsletterConf={integrationConf} step={1} isInfo /> | ||
| case 'SureDash': | ||
| return <SureDashAuthorization sureDashConf={integrationConf} step={1} isInfo /> |
There was a problem hiding this comment.
SureDashAuthorization already accepts isInfo and gates all interactive controls (authorize button, Next button) behind {!isInfo && ...}. Calling handlers in info mode is not possible.
| export default function SureDashAuthorization({ | ||
| sureDashConf, | ||
| setSureDashConf, | ||
| step, | ||
| nextPage, | ||
| isLoading, | ||
| setIsLoading, | ||
| setSnackbar | ||
| }) { |
There was a problem hiding this comment.
isInfo is already accepted as a prop (line 15) and all interactive elements are wrapped in {!isInfo && (...)}. The name input also uses disabled={isInfo}. This matches other Authorization components.
| break; | ||
| } | ||
|
|
||
| $responseType = isset($response['success']) && $response['success'] ? 'success' : 'error'; |
There was a problem hiding this comment.
Fixed. Added is_wp_error() guard on line 93 of SureDash/RecordApiHelper.php:
$responseType = !is_wp_error($response) && isset($response['success']) && $response['success'] ? 'success' : 'error';| 'Eventin' => ['name' => 'Eventin', 'isPro' => true, 'is_active' => false], | ||
| 'EVF' => ['name' => 'Everest Forms', 'isPro' => true, 'is_active' => false], | ||
| 'FormGent' => ['name' => 'FormGent', 'isPro' => true, 'is_active' => false], | ||
| 'FormyChat' => ['name' => 'FormyChat', 'isPro' => true, 'is_active' => false], |
There was a problem hiding this comment.
Fixed. Both FormyChat (line 49) and SureDash (line 132) have been removed from AllTriggersName.php — they are actions, not triggers.
| export const checkMappedFields = formyChatConf => { | ||
| const mappedFields = formyChatConf?.field_map | ||
| ? formyChatConf.field_map.filter( | ||
| mappedField => | ||
| !mappedField.formField || | ||
| !mappedField.formyChatField || | ||
| (mappedField.formField === 'custom' && !mappedField.customValue) | ||
| ) | ||
| : [] | ||
| if (mappedFields.length > 0) return false | ||
| if (!formyChatConf?.widgetId || !formyChatConf?.mainAction) return false | ||
|
|
||
| const partialMeta = (formyChatConf?.meta_map || []).filter( | ||
| m => (m.formField && !m.metaKey) || (!m.formField && m.metaKey) | ||
| ) | ||
| if (partialMeta.length > 0) return false | ||
|
|
||
| return true |
There was a problem hiding this comment.
Fixed. Extended the meta validation filter to also block rows where formField === 'custom' but customValue is empty:
const partialMeta = (formyChatConf?.meta_map || []).filter(
m =>
(m.formField && !m.metaKey) ||
(!m.formField && m.metaKey) ||
(m.formField === 'custom' && !m.customValue)
)| import { useEffect } from 'react' | ||
| import { create } from 'mutative' | ||
| import MultiSelect from 'react-multiple-select-dropdown-lite' | ||
| import { useRecoilValue } from 'recoil' | ||
| import { $appConfigState } from '../../../GlobalStates' | ||
| import { __ } from '../../../Utils/i18nwrap' | ||
| import Loader from '../../Loaders/Loader' | ||
| import { checkIsPro, getProLabel } from '../../Utilities/ProUtilHelpers' | ||
| import { addFieldMap } from '../IntegrationHelpers/IntegrationHelpers' | ||
| import { |
There was a problem hiding this comment.
Fixed. Removed unused useEffect import and unused formID/setSnackbar props from FormyChatIntegLayout.
| if (!\defined('SUREDASHBOARD_POST_TYPE')) { | ||
| wp_send_json_error(__('SureDash is not activated or not installed', 'bit-integrations'), 400); | ||
| } | ||
|
|
There was a problem hiding this comment.
Fixed. Removed the redundant !\defined('SUREDASHBOARD_POST_TYPE') check from refreshSpaces() — self::isExists() on the line above already covers it.
…ing and error handling
…ping validation in FormyChat
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 25 out of 28 changed files in this pull request and generated 2 comments.
Comments suppressed due to low confidence (1)
backend/Core/Util/AllTriggersName.php:134
AllTriggersName::allTriggersName()is used to populate the trigger list for non‑Pro installs (seebackend/Triggers/TriggerController.php:35-37). RegisteringSureDashhere will incorrectly surface it as a trigger, even though this PR adds it as an action integration. Please removeSureDashfrom this trigger registry.
'SureMail' => ['name' => 'SureMail', 'isPro' => true, 'is_active' => false],
'SureForms' => ['name' => 'SureForms', 'isPro' => true, 'is_active' => false],
'SureFeedback' => ['name' => 'SureFeedback', 'isPro' => true, 'is_active' => false],
'SureDash' => ['name' => 'SureDash', 'isPro' => true, 'is_active' => false],
'SureMembers' => ['name' => 'SureMembers', 'isPro' => true, 'is_active' => false],
'EventsCalendar' => ['name' => 'The Events Calendar', 'isPro' => true, 'is_active' => false],
| 'Eventin' => ['name' => 'Eventin', 'isPro' => true, 'is_active' => false], | ||
| 'EVF' => ['name' => 'Everest Forms', 'isPro' => true, 'is_active' => false], | ||
| 'FormGent' => ['name' => 'FormGent', 'isPro' => true, 'is_active' => false], | ||
| 'FormyChat' => ['name' => 'FormyChat', 'isPro' => true, 'is_active' => false], | ||
| 'FluentAffiliate' => ['name' => 'FluentAffiliate', 'isPro' => true, 'is_active' => false], | ||
| 'WCAffiliate' => ['name' => 'WC Affiliate', 'isPro' => true, 'is_active' => false], |
| { type: 'ZagoMail' }, | ||
| { type: 'Drip' }, | ||
| { type: 'Newsletter' }, | ||
| { type: 'SureDash' }, | ||
| { type: 'SureMembers' }, | ||
| { type: 'Mailster' }, |
Description
This PR adds a new FormyChat action integration to Bit Integrations, including backend API routes, execution logic, and full frontend setup/edit flows. Users can now connect FormyChat, select a widget, map fields (including custom values), and create leads from automation flows.
Motivation & Context
FormyChat users need a native way to send captured conversation/form data into automation workflows without manual glue code. This change introduces first-class support so lead creation can be configured directly in Bit Integrations with field and meta mapping support.
Related Links: (if applicable)
Type of Change
Key Changes
Backend
formy_chat_create_leadhook with integration logging for success/error outcomes.formy_chat_authorize,refresh_formy_chat_widgets, andrefresh_formy_chat_widget_fields.Frontend
Integration Registry & Navigation
Checklist
Changelog