• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » How to securely integrate Twilio SMS Gateway endpoints into WordPress custom plugins using Block Patterns API

How to securely integrate Twilio SMS Gateway endpoints into WordPress custom plugins using Block Patterns API

Setting Up Your Twilio Account and WordPress Environment

Before diving into code, ensure you have a Twilio account. You’ll need your Account SID and Auth Token, which can be found on your Twilio Console dashboard. For this integration, we’ll assume you have a basic WordPress development environment set up, ideally using a local server like LocalWP or a staging server. We’ll be creating a custom plugin to house our Twilio integration logic.

Create a new plugin directory within your WordPress installation’s wp-content/plugins/ folder. Let’s name it twilio-sms-gateway. Inside this directory, create a main plugin file, e.g., twilio-sms-gateway.php, and a sub-directory for our block pattern, say blocks/.

Installing the Twilio PHP SDK

The most straightforward way to interact with the Twilio API in PHP is by using their official SDK. We’ll manage this dependency using Composer. Navigate to your plugin’s root directory in your terminal and run:

cd wp-content/plugins/twilio-sms-gateway
composer require twilio/sdk

This command will download the Twilio PHP library and its dependencies into a vendor/ directory within your plugin. You’ll need to include Composer’s autoloader in your main plugin file to access the SDK classes.

Securing Twilio Credentials

Storing API credentials directly in your plugin files is a significant security risk. WordPress provides a robust way to manage sensitive options using the Settings API and storing them in the database. We’ll create a simple settings page for your plugin to input the Twilio Account SID and Auth Token.

Creating the Settings Page

Add the following code to your twilio-sms-gateway.php file to register the settings page and its fields.

<?php
/**
 * Plugin Name: Twilio SMS Gateway
 * Description: Integrates Twilio SMS Gateway with WordPress using Block Patterns.
 * Version: 1.0
 * Author: Your Name
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly.
}

// Include Composer autoloader
require_once __DIR__ . '/vendor/autoload.php';

// Register settings menu
add_action( 'admin_menu', 'twilio_sms_register_settings_page' );
function twilio_sms_register_settings_page() {
    add_options_page(
        'Twilio SMS Settings',
        'Twilio SMS',
        'manage_options',
        'twilio-sms-settings',
        'twilio_sms_settings_page_html'
    );
}

// Register settings
add_action( 'admin_init', 'twilio_sms_register_settings' );
function twilio_sms_register_settings() {
    register_setting( 'twilio_sms_options_group', 'twilio_account_sid' );
    register_setting( 'twilio_sms_options_group', 'twilio_auth_token' );
    register_setting( 'twilio_sms_options_group', 'twilio_from_number' );

    add_settings_section(
        'twilio_sms_main_section',
        'Twilio API Credentials',
        'twilio_sms_main_section_callback',
        'twilio-sms-settings'
    );

    add_settings_field(
        'twilio_account_sid',
        'Account SID',
        'twilio_account_sid_render',
        'twilio-sms-settings',
        'twilio_sms_main_section'
    );

    add_settings_field(
        'twilio_auth_token',
        'Auth Token',
        'twilio_auth_token_render',
        'twilio-sms-settings',
        'twilio_sms_main_section'
    );

    add_settings_field(
        'twilio_from_number',
        'Twilio Phone Number',
        'twilio_from_number_render',
        'twilio-sms-settings',
        'twilio_sms_main_section'
    );
}

function twilio_sms_main_section_callback() {
    echo '<p>Enter your Twilio Account SID, Auth Token, and Twilio phone number below.</p>';
}

function twilio_account_sid_render() {
    $sid = get_option( 'twilio_account_sid' );
    ?><input type="text" name="twilio_account_sid" value="<?php echo esc_attr( $sid ); ?>"><?php
}

function twilio_auth_token_render() {
    $token = get_option( 'twilio_auth_token' );
    ?><input type="password" name="twilio_auth_token" value="<?php echo esc_attr( $token ); ?>"><?php
}

function twilio_from_number_render() {
    $number = get_option( 'twilio_from_number' );
    ?><input type="text" name="twilio_from_number" value="<?php echo esc_attr( $number ); ?>" placeholder="+15551234567"><?php
}

function twilio_sms_settings_page_html() {
    // Check user capabilities
    if ( ! current_user_can( 'manage_options' ) ) {
        return;
    }
    ?>
    <div class="wrap">
        <h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
        <form action="options.php" method="post">
            <?php
            // Output security fields for the registered setting group
            settings_fields( 'twilio_sms_options_group' );
            // Output setting sections and their fields
            do_settings_sections( 'twilio-sms-settings' );
            // Output save settings button
            submit_button( 'Save Settings' );
            ?>
        </form>
    </div>
    <?php
}
?>

After activating the plugin, you’ll find a new “Twilio SMS” submenu under the “Settings” menu in your WordPress admin area. Here, you can securely enter your Twilio credentials. The get_option() function retrieves these values from the WordPress database, and esc_attr() ensures they are properly escaped for HTML output. Using <input type="password"> for the Auth Token adds an extra layer of visual security.

Creating a Block Pattern for SMS Sending

WordPress Block Patterns allow you to create reusable content structures. We’ll create a simple pattern that includes a form for users to input a recipient’s phone number and a message, which will then trigger an SMS. This pattern will be registered via PHP and its associated JavaScript will handle the AJAX request to send the SMS.

Registering the Block Pattern

In your twilio-sms-gateway.php file, add the following code to register your block pattern. This code defines the structure of the pattern and associates it with a specific block that will handle the form submission.

<?php
// ... (previous code for settings) ...

// Register the block pattern
add_action( 'init', 'twilio_sms_register_block_pattern' );
function twilio_sms_register_block_pattern() {
    if ( ! function_exists( 'register_block_pattern' ) ) {
        return;
    }

    register_block_pattern(
        'twilio-sms-gateway/sms-sender-form',
        array(
            'title'       => __( 'SMS Sender Form', 'twilio-sms-gateway' ),
            'description' => __( 'A form to send SMS messages via Twilio.', 'twilio-sms-gateway' ),
            'content'     => '<!-- wp:group --><div class="wp-block-group"><!-- wp:heading --><h2>Send an SMS</h2><!-- /wp:heading --><!-- wp:paragraph --><p>Enter the recipient number and your message below.</p><!-- /wp:paragraph --><!-- wp:html --><form id="twilio-sms-form"><label for="recipient_number">Recipient Number:</label><br><input type="tel" id="recipient_number" name="recipient_number" required placeholder="+1234567890"><br><br><label for="sms_message">Message:</label><br><textarea id="sms_message" name="sms_message" rows="4" required></textarea><br><br><button type="submit">Send SMS</button><div id="twilio-sms-response"></div></form><!-- /wp:html --></div><!-- /wp:group -->',
            'categories'  => array( 'twilio-sms' ),
        )
    );
}

// Enqueue script for AJAX handling
add_action( 'wp_enqueue_scripts', 'twilio_sms_enqueue_scripts' );
function twilio_sms_enqueue_scripts() {
    // Only enqueue on the front-end if the pattern is likely to be used
    // A more robust check might involve checking if the pattern exists on the page.
    if ( ! is_admin() ) {
        wp_enqueue_script(
            'twilio-sms-script',
            plugins_url( 'js/twilio-sms.js', __FILE__ ),
            array( 'jquery' ),
            '1.0',
            true // Load in footer
        );

        // Localize script with AJAX URL and nonce
        wp_localize_script( 'twilio-sms-script', 'twilio_sms_ajax_object', array(
            'ajax_url' => admin_url( 'admin-ajax.php' ),
            'nonce'    => wp_create_nonce( 'twilio_sms_send_nonce' ),
        ) );
    }
}

// AJAX handler for sending SMS
add_action( 'wp_ajax_send_twilio_sms', 'twilio_sms_handle_send_sms' );
add_action( 'wp_ajax_nopriv_send_twilio_sms', 'twilio_sms_handle_send_sms' ); // For logged-out users if needed

function twilio_sms_handle_send_sms() {
    // Verify nonce for security
    check_ajax_referer( 'twilio_sms_send_nonce', 'nonce' );

    // Retrieve Twilio credentials from options
    $account_sid = get_option( 'twilio_account_sid' );
    $auth_token  = get_option( 'twilio_auth_token' );
    $from_number = get_option( 'twilio_from_number' );

    // Basic validation
    if ( empty( $account_sid ) || empty( $auth_token ) || empty( $from_number ) ) {
        wp_send_json_error( array( 'message' => 'Twilio credentials are not configured. Please check plugin settings.' ) );
        wp_die();
    }

    // Get data from POST request
    $to_number = isset( $_POST['recipient_number'] ) ? sanitize_text_field( $_POST['recipient_number'] ) : '';
    $message   = isset( $_POST['sms_message'] ) ? sanitize_textarea_field( $_POST['sms_message'] ) : '';

    if ( empty( $to_number ) || empty( $message ) ) {
        wp_send_json_error( array( 'message' => 'Recipient number and message are required.' ) );
        wp_die();
    }

    try {
        $client = new Twilio\Rest\Client( $account_sid, $auth_token );

        $message_sent = $client->messages->create(
            $to_number, // Recipient's phone number
            array(
                'from' => $from_number, // Your Twilio phone number
                'body' => $message,     // The message content
            )
        );

        wp_send_json_success( array( 'message' => 'SMS sent successfully! SID: ' . $message_sent->sid ) );

    } catch ( Exception $e ) {
        wp_send_json_error( array( 'message' => 'Error sending SMS: ' . $e->getMessage() ) );
    }

    wp_die(); // This is required to terminate immediately and return a proper response
}
?>

The register_block_pattern function defines the pattern’s title, description, and crucially, its content. The content is an HTML string representing the form. We’ve used standard HTML form elements and assigned IDs for easy JavaScript manipulation. The wp:html block is used here to embed raw HTML within the pattern’s structure.

Creating the JavaScript for AJAX Handling

Now, create a js/ directory inside your plugin folder and add a file named twilio-sms.js. This script will handle the form submission using AJAX.

jQuery(document).ready(function($) {
    $('#twilio-sms-form').on('submit', function(e) {
        e.preventDefault(); // Prevent default form submission

        var recipientNumber = $('#recipient_number').val();
        var smsMessage = $('#sms_message').val();
        var responseDiv = $('#twilio-sms-response');

        // Clear previous responses
        responseDiv.html('');

        // Basic client-side validation
        if (!recipientNumber || !smsMessage) {
            responseDiv.html('<p style="color: red;">Please fill in both recipient number and message.</p>');
            return;
        }

        // Show a loading indicator (optional)
        responseDiv.html('<p>Sending SMS...</p>');

        $.ajax({
            url: twilio_sms_ajax_object.ajax_url, // WordPress AJAX URL
            type: 'POST',
            data: {
                action: 'send_twilio_sms', // The AJAX action hook defined in PHP
                nonce: twilio_sms_ajax_object.nonce, // Security nonce
                recipient_number: recipientNumber,
                sms_message: smsMessage
            },
            success: function(response) {
                if (response.success) {
                    responseDiv.html('<p style="color: green;">' + response.data.message + '</p>');
                    // Clear the form fields on success
                    $('#recipient_number').val('');
                    $('#sms_message').val('');
                } else {
                    responseDiv.html('<p style="color: red;">' + response.data.message + '</p>');
                }
            },
            error: function(jqXHR, textStatus, errorThrown) {
                responseDiv.html('<p style="color: red;">An error occurred: ' + textStatus + ' - ' + errorThrown + '</p>');
            }
        });
    });
});

The wp_enqueue_scripts action hook is used to load our JavaScript file on the front-end. wp_localize_script is crucial here; it passes PHP variables (like the AJAX URL and a security nonce) to the JavaScript, making them accessible via the twilio_sms_ajax_object. The JavaScript then uses jQuery’s $.ajax to send a POST request to WordPress’s admin-ajax.php endpoint. The action parameter (‘send_twilio_sms’) tells WordPress which PHP function to execute.

Handling the AJAX Request in PHP

The PHP code for handling the AJAX request is also included in the twilio-sms-gateway.php file. The wp_ajax_send_twilio_sms and wp_ajax_nopriv_send_twilio_sms hooks are used to register the AJAX handler for both logged-in and logged-out users, respectively. This ensures the SMS sending functionality is available to all visitors.

Inside the twilio_sms_handle_send_sms function:

  • check_ajax_referer(): This is a vital security measure. It verifies that the request originated from your WordPress site and not from an external source, using the nonce passed from JavaScript.
  • Credentials Retrieval: It fetches the Twilio Account SID, Auth Token, and From Number using get_option().
  • Input Sanitization: User-submitted data (recipient number and message) is sanitized using sanitize_text_field() and sanitize_textarea_field() to prevent malicious input.
  • Twilio Client Initialization: An instance of the Twilio REST client is created using the retrieved credentials.
  • SMS Sending: The $client->messages->create() method is used to send the SMS.
  • Response Handling: wp_send_json_success() or wp_send_json_error() is used to send a JSON response back to the JavaScript, indicating success or failure.
  • Error Handling: A try-catch block is used to gracefully handle any exceptions that might occur during the Twilio API call.

Using the Block Pattern in WordPress

Once your plugin is activated and the Twilio credentials are saved in the settings page, you can use the block pattern. Go to the WordPress editor (for a post, page, or even a custom post type). Click the ‘+’ icon to add a block, then search for “SMS Sender Form” or navigate to the “Patterns” tab and find it under the “Twilio SMS” category. Insert the pattern, and you’ll see the form appear on your page.

When a user fills out the form and clicks “Send SMS,” the JavaScript will intercept the submission, send the data via AJAX to your WordPress backend, and the PHP function will use the Twilio SDK to send the message. The response from the server will then be displayed below the form.

Advanced Considerations and Best Practices

Error Logging

For production environments, it’s crucial to implement robust error logging. Instead of just displaying errors to the user, log them to a file or a dedicated logging service. You can use WordPress’s built-in error_log() function or integrate a more sophisticated logging library.

// Inside twilio_sms_handle_send_sms() catch block
error_log( 'Twilio SMS Error: ' . $e->getMessage() );
wp_send_json_error( array( 'message' => 'An internal error occurred. Please try again later.' ) );

Rate Limiting and Security

To prevent abuse, consider implementing rate limiting on your AJAX endpoint. You can use transient API or a custom database table to track request frequency per IP address. Also, ensure your Twilio phone number is configured correctly in your Twilio console to prevent unauthorized use.

Internationalization

The provided code uses WordPress’s internationalization functions (__() and _e()) for strings within the block pattern registration. Ensure your plugin is properly internationalized if you plan to offer it in multiple languages.

User Experience Enhancements

You can enhance the user experience by adding more sophisticated loading indicators, real-time feedback on message status (if Twilio provides webhooks for this), and input validation for phone number formats using JavaScript libraries.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Troubleshooting namespace class loading collisions in production when using modern Sage Roots modern environments wrappers
  • Troubleshooting WooCommerce hook execution loops in production when using modern Classic Core PHP wrappers
  • Implementing automated compliance reporting for custom internal server status logs ledgers using dompdf library
  • Step-by-Step Guide to building a custom CSV bulk exporter block for Gutenberg using SolidJS high-performance reactive components
  • Troubleshooting Zend memory limit exceed in production when using modern Carbon Fields custom wrappers wrappers

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (609)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (824)
  • PHP (5)
  • PHP Development (30)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (587)
  • SEO & Growth (492)
  • Server (23)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (132)
  • WordPress Theme Development (357)

Recent Posts

  • Troubleshooting namespace class loading collisions in production when using modern Sage Roots modern environments wrappers
  • Troubleshooting WooCommerce hook execution loops in production when using modern Classic Core PHP wrappers
  • Implementing automated compliance reporting for custom internal server status logs ledgers using dompdf library

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (824)
  • Debugging & Troubleshooting (609)
  • Security & Compliance (587)
  • SEO & Growth (492)
  • Business & Monetization (390)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala