Skip to content

feat: add Sender (sender.net) email marketing integration#177

Merged
RishadAlam merged 6 commits into
mainfrom
feat/sender
Jun 27, 2026
Merged

feat: add Sender (sender.net) email marketing integration#177
RishadAlam merged 6 commits into
mainfrom
feat/sender

Conversation

@RishadAlam

Copy link
Copy Markdown
Member

Description

Adds a new Sender (sender.net) action integration. Users can connect a Sender account with an API token and push trigger data into Sender as subscriber and group operations. The free plugin handles authorization, group/custom-field fetching, and field mapping; the actual API calls are delegated to Bit Integrations Pro via hooks.

Motivation & Context

Extends the available email-marketing destinations so users can automate subscriber and group management in Sender directly from any Bit Integrations trigger.

Type of Change

  • 🐛 Bug fix
  • ✨ New feature
  • 💥 Breaking change
  • 📚 Documentation update
  • ⚡ Improvement
  • 🔄 Code refactor

Key Changes

Integrations (Backend)

  • Added SenderController — API-token authorization (verified against the /groups endpoint), refreshGroups and refreshFields AJAX handlers, and the Flow execute() entry point.
  • Added RecordApiHelper — builds request data from the field map and routes each of the 9 actions to Pro via Hooks::apply(), with success/error logging through LogHandler.
  • Added Routes.php — registers the auth/refresh AJAX endpoints.
  • Added Custom-field token handling — converts Sender {{slug}} tokens to {$slug} personalization form and excludes default fields (email/firstname/lastname/phone) from custom-field mapping.

Supported Actions

  • Create or update subscriber, update subscriber, delete subscriber, remove phone from subscriber
  • Add/remove subscriber to/from group
  • Create group, update group, delete group

Frontend

  • Added Sender wizard — Sender.jsx, SenderAuthorization.jsx, SenderActions.jsx, SenderIntegLayout.jsx, SenderFieldMap.jsx, EditSender.jsx, SenderCommonFunc.js, staticData.js.
  • Added Integration registration in NewInteg.jsx, EditInteg.jsx, IntegInfo.jsx, SelectAction.jsx, plus tutorial link and sender.webp icon.

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Tests added/updated
  • Documentation updated if needed
  • README updated if needed

Changelog

  • New Actions: Sender (sender.net) — manage subscribers and groups (create/update/delete subscriber, remove phone, add/remove subscriber to group, create/update/delete group)

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new integration for Sender (sender.net), adding backend PHP controllers, helpers, and routes, alongside frontend React components for authorization, field mapping, and action configuration. A critical issue was identified in RecordApiHelper.php where a potential WP_Error response is accessed as an array without validation, which can lead to a fatal error in PHP 8.0+.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

break;
}

$responseType = isset($response['success']) && $response['success'] ? 'success' : 'error';

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

In PHP 8.0+, accessing a WP_Error object as an array (e.g., $response['success']) will trigger a fatal error. Since Hooks::apply can return a WP_Error object, you must validate the response using is_wp_error() before attempting array access.

        $responseType = !is_wp_error($response) && isset($response['success']) && $response['success'] ? 'success' : 'error';
References
  1. In PHP, when handling responses that may return a WP_Error object, always use the is_wp_error() function to validate the response before accessing it as an array or object. This prevents fatal errors in PHP 8.0+.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — verified on PHP 8.4 that isset($wpError['success']) throws Error: Cannot use object of type WP_Error as array, so this was a real fatal risk when the Pro hook returns a WP_Error. Added an is_wp_error() guard:

$responseType = !is_wp_error($response) && isset($response['success']) && $response['success'] ? 'success' : 'error';

abdul-kaioum
abdul-kaioum previously approved these changes Jun 27, 2026
@github-actions

github-actions Bot commented Jun 27, 2026

Copy link
Copy Markdown

🔍 WordPress Plugin Check Report

⚠️ Status: Passed with warnings

📊 Report

🎯 Total Issues ❌ Errors ⚠️ Warnings
1 0 1

⚠️ Warnings (1)

📁 readme.txt (1 warning)
📍 Line 🔖 Check 💬 Message
0 mismatched_plugin_name Plugin name "Bit integrations - Form Integration, Webhook, Spreadsheets, CRM, LMS & Email Automation" is different from the name declared in plugin header "Bit Integrations".

🤖 Generated by WordPress Plugin Check Action • Learn more about Plugin Check

@RishadAlam RishadAlam merged commit 050f1db into main Jun 27, 2026
1 check passed
@RishadAlam RishadAlam deleted the feat/sender branch June 27, 2026 06:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants