Plugin Directory

Changeset 3774969


Ignore:
Timestamp:
10/30/2026 10:51:28 AM (35 hours ago)
Author:
techshah
Message:

Version 1.2.0: connect WhatsApp from the plugin

Location:
clientager
Files:
10 edited
1 copied

Legend:

Unmodified
Added
Removed
  • clientager/tags/1.2.0/assets/admin.css

    r3773846 r3774969  
    728728.cg-form-fields { gap: 20px; }
    729729@media (max-width: 600px) { .cg-form-field { gap: 8px; } }
     730
     731/* WhatsApp card (Settings → Chat & websites) */
     732.cg-wa-list { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
     733.cg-wa-list li { display: flex; align-items: flex-start; gap: 10px; margin: 0; color: var(--cg-ink-2, #334155); }
     734.cg-wa-list svg { flex-shrink: 0; margin-top: 1px; color: var(--cg-ok, #16a34a); }
     735#clientager-wa .cg-actions { margin-top: 20px; }
  • clientager/tags/1.2.0/assets/admin.js

    r3773846 r3774969  
    10141014                }
    10151015
     1016                /* WhatsApp: Meta's sign-in runs in a pop-up on clientager.com; the page reloads when it closes. */
     1017                var waOn = $( 'clientager-wa-connect' );
     1018                if ( waOn ) {
     1019                        waOn.addEventListener( 'click', function () {
     1020                                var msg = $( 'clientager-wa-msg' );
     1021                                // Opened inside the click, so pop-up blockers allow it; the address comes a moment later.
     1022                                var win = window.open( '', 'clientager_whatsapp', 'width=560,height=760,left=' + Math.max( 0, ( screen.width - 560 ) / 2 ) + ',top=' + Math.max( 0, ( screen.height - 760 ) / 2 ) );
     1023                                if ( ! win ) {
     1024                                        say( msg, t.waBlocked, 'error' );
     1025                                        return;
     1026                                }
     1027                                busy( waOn, true, t.waOpening );
     1028                                call( 'whatsapp', { op: 'connect' } ).then( function ( r ) {
     1029                                        if ( ! r.success || ! r.data.url ) {
     1030                                                win.close();
     1031                                                busy( waOn, false );
     1032                                                say( msg, ( r.data && r.data.message ) || t.error, 'error' );
     1033                                                return;
     1034                                        }
     1035                                        win.location.href = r.data.url;
     1036                                        busy( waOn, false );
     1037                                        say( msg, t.waWaiting, 'info' );
     1038                                        if ( waOn.dataset.watching ) {
     1039                                                return;
     1040                                        }
     1041                                        waOn.dataset.watching = '1';
     1042                                        // Meta's pages can cut this page's link to the window, so the connection is checked on the server
     1043                                        // (every 5 seconds for 20 minutes, and when you come back to this tab).
     1044                                        var until = Date.now() + 20 * 60 * 1000;
     1045                                        var check = function () {
     1046                                                call( 'whatsapp', { op: 'status' } ).then( function ( s ) {
     1047                                                        if ( s.success && s.data.connected ) {
     1048                                                                window.location.reload();
     1049                                                        }
     1050                                                } );
     1051                                        };
     1052                                        var timer = setInterval( function () {
     1053                                                if ( Date.now() > until ) {
     1054                                                        clearInterval( timer );
     1055                                                        delete waOn.dataset.watching;
     1056                                                        return;
     1057                                                }
     1058                                                if ( ! document.hidden ) {
     1059                                                        check();
     1060                                                }
     1061                                        }, 5000 );
     1062                                        window.addEventListener( 'focus', check );
     1063                                } );
     1064                        } );
     1065                }
     1066                var waOff = $( 'clientager-wa-off' );
     1067                if ( waOff ) {
     1068                        waOff.addEventListener( 'click', function () {
     1069                                if ( ! window.confirm( t.waOff ) ) {
     1070                                        return;
     1071                                }
     1072                                busy( waOff, true, t.sending );
     1073                                call( 'whatsapp', { op: 'disconnect' } ).then( function ( r ) {
     1074                                        if ( r.success ) {
     1075                                                window.location.reload();
     1076                                                return;
     1077                                        }
     1078                                        busy( waOff, false );
     1079                                        say( $( 'clientager-wa-msg' ), ( r.data && r.data.message ) || t.error, 'error' );
     1080                                } );
     1081                        } );
     1082                }
     1083
    10161084                /* Help: a message to the Clientager team */
    10171085                var help = $( 'clientager-help' );
  • clientager/tags/1.2.0/clientager.php

    r3773846 r3774969  
    44 * Plugin URI:        https://www.clientager.com/wordpress
    55 * Description:       An AI assistant that learns your website in minutes, answers visitors 24/7, captures leads and replies to form submissions. Try it free before you pay.
    6  * Version:           1.1.9
     6 * Version:           1.2.0
    77 * Requires at least: 6.0
    88 * Requires PHP:      7.4
    … …  
    2020}
    2121
    22 define( 'CLIENTAGER_VERSION', '1.1.9' );
     22define( 'CLIENTAGER_VERSION', '1.2.0' );
    2323define( 'CLIENTAGER_FILE', __FILE__ );
    2424define( 'CLIENTAGER_DIR', plugin_dir_path( __FILE__ ) );
  • clientager/tags/1.2.0/includes/class-clientager-admin.php

    r3773846 r3774969  
    7575                add_action( 'in_admin_header', array( __CLASS__, 'hide_notices' ), 1000 );
    7676                add_action( 'admin_post_clientager_leads_csv', array( __CLASS__, 'leads_csv' ) );
    77                 foreach ( array( 'connect_start', 'connect_verify', 'learn', 'preview', 'live', 'widget_save', 'notify_save', 'origins_save', 'convo_reply', 'disconnect', 'trial', 'request_update', 'form_save', 'email_look', 'chat_rules', 'review', 'lead_status', 'help' ) as $action ) {
     77                foreach ( array( 'connect_start', 'connect_verify', 'learn', 'preview', 'live', 'widget_save', 'notify_save', 'origins_save', 'convo_reply', 'disconnect', 'trial', 'request_update', 'form_save', 'email_look', 'chat_rules', 'review', 'lead_status', 'help', 'whatsapp' ) as $action ) {
    7878                        add_action( 'wp_ajax_clientager_' . $action, array( __CLASS__, 'ajax_' . $action ) );
    7979                }
    … …  
    172172                                        'saved'        => __( 'Saved. Your chat uses the new settings now.', 'clientager' ),
    173173                                        'savedLimits'  => __( 'Saved. New messages follow these limits.', 'clientager' ),
     174                                        'waOpening'    => __( 'Opening the secure WhatsApp window…', 'clientager' ),
     175                                        'waWaiting'    => __( 'Finish the steps in the WhatsApp window. This page updates by itself when you are done.', 'clientager' ),
     176                                        'waBlocked'    => __( 'Your browser blocked the window. Allow pop-ups for this page and try again.', 'clientager' ),
     177                                        'waOff'        => __( 'Disconnect WhatsApp? Your AI stops answering it. The number stays yours.', 'clientager' ),
    174178                                        'helpSent'     => __( 'Thanks, we got your message. We will reply to your email, usually within one business day.', 'clientager' ),
    175179                                        'badColor'     => __( 'Pick a colour like #2563eb.', 'clientager' ),
    … …  
    19801984                                        </div>
    19811985
     1986                                        <?php self::whatsapp_card(); ?>
    19821987                                        <?php self::origins_card( $s ); ?>
    19831988                                        <?php self::chat_rules_card( $s ); ?>
    … …  
    20622067                                </section>
    20632068                        </div>
     2069                </div>
     2070                <?php
     2071        }
     2072
     2073        /**
     2074         * WhatsApp: the connected number, or Connect (Meta's sign-in opens in a pop-up on clientager.com).
     2075         */
     2076        private static function whatsapp_card() {
     2077                $res  = Clientager_Api::request( 'GET', '/whatsapp' );
     2078                $wa   = $res['ok'] && is_array( $res['data'] ) ? $res['data'] : array();
     2079                $conn = ! empty( $wa['connected']['number'] ) ? $wa['connected'] : null;
     2080                ?>
     2081                <div class="cg-card" id="clientager-wa">
     2082                        <?php self::card_head( __( 'WhatsApp', 'clientager' ), __( 'Your AI answers customers on your own WhatsApp number, 24/7.', 'clientager' ), 'whatsapp' ); ?>
     2083                        <?php if ( $conn ) : ?>
     2084                                <div class="cg-switch-row">
     2085                                        <div>
     2086                                                <strong><?php esc_html_e( 'Connected', 'clientager' ); ?></strong>
     2087                                                <span>
     2088                                                <?php
     2089                                                /* translators: %s: WhatsApp phone number. */
     2090                                                echo esc_html( sprintf( __( 'Your AI answers WhatsApp messages on %s.', 'clientager' ), (string) $conn['number'] ) );
     2091                                                ?>
     2092                                                </span>
     2093                                        </div>
     2094                                        <span class="cg-badge is-won"><?php esc_html_e( 'Live', 'clientager' ); ?></span>
     2095                                </div>
     2096                                <div class="cg-actions">
     2097                                        <a class="cg-btn cg-btn-secondary" href="<?php echo esc_url( 'https://wa.me/' . preg_replace( '/\D/', '', (string) $conn['number'] ) ); ?>" target="_blank" rel="noopener"><?php self::icon( 'whatsapp' ); ?><?php esc_html_e( 'Send a test message', 'clientager' ); ?></a>
     2098                                        <button type="button" class="cg-btn cg-btn-secondary" id="clientager-wa-off"><?php esc_html_e( 'Disconnect', 'clientager' ); ?></button>
     2099                                </div>
     2100                                <p class="cg-help"><?php echo esc_html( ! empty( $conn['app'] ) ? __( 'You can keep using the WhatsApp Business app. When you reply from the app, the AI leaves that chat to you.', 'clientager' ) : __( 'Chats show up in your Inbox, where you can take over any time.', 'clientager' ) ); ?></p>
     2101                        <?php elseif ( empty( $wa['allowed'] ) ) : ?>
     2102                                <p class="cg-help"><?php esc_html_e( 'Included in the 7-day free trial and from the Starter plan. Choose a plan to connect your number.', 'clientager' ); ?></p>
     2103                        <?php elseif ( empty( $wa['available'] ) ) : ?>
     2104                                <p class="cg-help"><?php esc_html_e( 'WhatsApp connect opens soon. We will email you when you can connect your number.', 'clientager' ); ?></p>
     2105                        <?php else : ?>
     2106                                <ul class="cg-wa-list">
     2107                                        <li><?php self::icon( 'check' ); ?><?php esc_html_e( 'Use a new number, or the one on your WhatsApp Business app (you keep the app and your chats).', 'clientager' ); ?></li>
     2108                                        <li><?php self::icon( 'check' ); ?><?php esc_html_e( 'Sign in with Facebook in a secure window. Takes about 5 minutes.', 'clientager' ); ?></li>
     2109                                        <li><?php self::icon( 'check' ); ?><?php esc_html_e( 'The number stays yours. Replies within 24 hours of a customer message are free.', 'clientager' ); ?></li>
     2110                                </ul>
     2111                                <div class="cg-actions"><button type="button" class="cg-btn cg-btn-primary" id="clientager-wa-connect"><?php self::icon( 'whatsapp' ); ?><?php esc_html_e( 'Connect WhatsApp', 'clientager' ); ?></button></div>
     2112                        <?php endif; ?>
     2113                        <div id="clientager-wa-msg" class="clientager-msg" role="status" aria-live="polite"></div>
    20642114                </div>
    20652115                <?php
    … …  
    27792829
    27802830        /**
     2831         * WhatsApp: op=connect returns the sign-in address (on clientager.com, valid 30 minutes), op=status says whether a
     2832         * number is connected, op=disconnect stops it.
     2833         */
     2834        public static function ajax_whatsapp() {
     2835                check_ajax_referer( self::NONCE, 'nonce' );
     2836                self::guard();
     2837                $op = isset( $_POST['op'] ) ? sanitize_key( wp_unslash( $_POST['op'] ) ) : '';
     2838                if ( 'disconnect' === $op ) {
     2839                        self::reply( Clientager_Api::request( 'POST', '/whatsapp', array( 'action' => 'disconnect' ) ) );
     2840                }
     2841                $res = Clientager_Api::request( 'GET', '/whatsapp' );
     2842                if ( 'status' === $op ) {
     2843                        self::reply( $res, array( 'connected' => ! empty( $res['data']['connected'] ) ) );
     2844                }
     2845                $url = $res['ok'] && ! empty( $res['data']['connect_url'] ) ? esc_url_raw( (string) $res['data']['connect_url'] ) : '';
     2846                if ( $res['ok'] && ! $url ) {
     2847                        $res = array( 'ok' => false, 'status' => 409, 'code' => 'wa_unavailable', 'error' => ! empty( $res['data']['connected'] ) ? __( 'WhatsApp is already connected. Reload this page.', 'clientager' ) : __( 'WhatsApp cannot be connected on this plan yet.', 'clientager' ), 'data' => array() );
     2848                }
     2849                self::reply( $res, array( 'url' => $url, 'connected' => ! empty( $res['data']['connected'] ) ) );
     2850        }
     2851
     2852        /**
    27812853         * Saves the contact form's fields, texts and look. The server checks them again and is the only place they are stored.
    27822854         */
  • clientager/tags/1.2.0/readme.txt

    r3773846 r3774969  
    55Tested up to: 7.1
    66Requires PHP: 7.4
    7 Stable tag: 1.1.9
     7Stable tag: 1.2.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    6161* **When a WooCommerce order is paid after the shopper chatted with the AI:** the order id, order number, total and currency, with the chat's id, for the "Sales made by AI" card. No customer or product details are sent. The chat window sets a first-party cookie (clientager_chat, 30 days) holding only a random chat id once the AI has replied, so the order can be matched to that chat.
    6262* **When you send a message from the Help tab:** what you wrote, the type you picked (question, problem or feature request), the reply-to email you entered, your site address and the plugin version, so our team can answer you by email.
     63* **When you connect WhatsApp (Settings):** a request for a short-lived sign-in link. Facebook's sign-in then opens in a window on app.clientager.com; your Facebook password goes only to Facebook, and Clientager receives permission to send and receive WhatsApp messages for the number you choose ([Meta Privacy Policy](https://www.facebook.com/privacy/policy/)).
    6364* **When you disconnect or delete the plugin:** a request to disconnect this site.
    6465
    … …  
    125126
    126127== Changelog ==
     128
     129= 1.2.0 =
     130* Connect WhatsApp from the plugin: Settings → Chat & websites → Connect WhatsApp. Sign in with Facebook in a secure window and your AI answers your own WhatsApp number (new number or your WhatsApp Business app number). Included in the free trial and from Starter.
    127131
    128132= 1.1.9 =
    … …  
    195199== Upgrade Notice ==
    196200
     201= 1.2.0 =
     202Connect your WhatsApp number right from the plugin.
     203
    197204= 1.1.9 =
    198205Faster screens without page reloads, Settings in clear sections, and product cards in the preview.
  • clientager/trunk/assets/admin.css

    r3773846 r3774969  
    728728.cg-form-fields { gap: 20px; }
    729729@media (max-width: 600px) { .cg-form-field { gap: 8px; } }
     730
     731/* WhatsApp card (Settings → Chat & websites) */
     732.cg-wa-list { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-direction: column; gap: 10px; }
     733.cg-wa-list li { display: flex; align-items: flex-start; gap: 10px; margin: 0; color: var(--cg-ink-2, #334155); }
     734.cg-wa-list svg { flex-shrink: 0; margin-top: 1px; color: var(--cg-ok, #16a34a); }
     735#clientager-wa .cg-actions { margin-top: 20px; }
  • clientager/trunk/assets/admin.js

    r3773846 r3774969  
    10141014                }
    10151015
     1016                /* WhatsApp: Meta's sign-in runs in a pop-up on clientager.com; the page reloads when it closes. */
     1017                var waOn = $( 'clientager-wa-connect' );
     1018                if ( waOn ) {
     1019                        waOn.addEventListener( 'click', function () {
     1020                                var msg = $( 'clientager-wa-msg' );
     1021                                // Opened inside the click, so pop-up blockers allow it; the address comes a moment later.
     1022                                var win = window.open( '', 'clientager_whatsapp', 'width=560,height=760,left=' + Math.max( 0, ( screen.width - 560 ) / 2 ) + ',top=' + Math.max( 0, ( screen.height - 760 ) / 2 ) );
     1023                                if ( ! win ) {
     1024                                        say( msg, t.waBlocked, 'error' );
     1025                                        return;
     1026                                }
     1027                                busy( waOn, true, t.waOpening );
     1028                                call( 'whatsapp', { op: 'connect' } ).then( function ( r ) {
     1029                                        if ( ! r.success || ! r.data.url ) {
     1030                                                win.close();
     1031                                                busy( waOn, false );
     1032                                                say( msg, ( r.data && r.data.message ) || t.error, 'error' );
     1033                                                return;
     1034                                        }
     1035                                        win.location.href = r.data.url;
     1036                                        busy( waOn, false );
     1037                                        say( msg, t.waWaiting, 'info' );
     1038                                        if ( waOn.dataset.watching ) {
     1039                                                return;
     1040                                        }
     1041                                        waOn.dataset.watching = '1';
     1042                                        // Meta's pages can cut this page's link to the window, so the connection is checked on the server
     1043                                        // (every 5 seconds for 20 minutes, and when you come back to this tab).
     1044                                        var until = Date.now() + 20 * 60 * 1000;
     1045                                        var check = function () {
     1046                                                call( 'whatsapp', { op: 'status' } ).then( function ( s ) {
     1047                                                        if ( s.success && s.data.connected ) {
     1048                                                                window.location.reload();
     1049                                                        }
     1050                                                } );
     1051                                        };
     1052                                        var timer = setInterval( function () {
     1053                                                if ( Date.now() > until ) {
     1054                                                        clearInterval( timer );
     1055                                                        delete waOn.dataset.watching;
     1056                                                        return;
     1057                                                }
     1058                                                if ( ! document.hidden ) {
     1059                                                        check();
     1060                                                }
     1061                                        }, 5000 );
     1062                                        window.addEventListener( 'focus', check );
     1063                                } );
     1064                        } );
     1065                }
     1066                var waOff = $( 'clientager-wa-off' );
     1067                if ( waOff ) {
     1068                        waOff.addEventListener( 'click', function () {
     1069                                if ( ! window.confirm( t.waOff ) ) {
     1070                                        return;
     1071                                }
     1072                                busy( waOff, true, t.sending );
     1073                                call( 'whatsapp', { op: 'disconnect' } ).then( function ( r ) {
     1074                                        if ( r.success ) {
     1075                                                window.location.reload();
     1076                                                return;
     1077                                        }
     1078                                        busy( waOff, false );
     1079                                        say( $( 'clientager-wa-msg' ), ( r.data && r.data.message ) || t.error, 'error' );
     1080                                } );
     1081                        } );
     1082                }
     1083
    10161084                /* Help: a message to the Clientager team */
    10171085                var help = $( 'clientager-help' );
  • clientager/trunk/clientager.php

    r3773846 r3774969  
    44 * Plugin URI:        https://www.clientager.com/wordpress
    55 * Description:       An AI assistant that learns your website in minutes, answers visitors 24/7, captures leads and replies to form submissions. Try it free before you pay.
    6  * Version:           1.1.9
     6 * Version:           1.2.0
    77 * Requires at least: 6.0
    88 * Requires PHP:      7.4
    … …  
    2020}
    2121
    22 define( 'CLIENTAGER_VERSION', '1.1.9' );
     22define( 'CLIENTAGER_VERSION', '1.2.0' );
    2323define( 'CLIENTAGER_FILE', __FILE__ );
    2424define( 'CLIENTAGER_DIR', plugin_dir_path( __FILE__ ) );
  • clientager/trunk/includes/class-clientager-admin.php

    r3773846 r3774969  
    7575                add_action( 'in_admin_header', array( __CLASS__, 'hide_notices' ), 1000 );
    7676                add_action( 'admin_post_clientager_leads_csv', array( __CLASS__, 'leads_csv' ) );
    77                 foreach ( array( 'connect_start', 'connect_verify', 'learn', 'preview', 'live', 'widget_save', 'notify_save', 'origins_save', 'convo_reply', 'disconnect', 'trial', 'request_update', 'form_save', 'email_look', 'chat_rules', 'review', 'lead_status', 'help' ) as $action ) {
     77                foreach ( array( 'connect_start', 'connect_verify', 'learn', 'preview', 'live', 'widget_save', 'notify_save', 'origins_save', 'convo_reply', 'disconnect', 'trial', 'request_update', 'form_save', 'email_look', 'chat_rules', 'review', 'lead_status', 'help', 'whatsapp' ) as $action ) {
    7878                        add_action( 'wp_ajax_clientager_' . $action, array( __CLASS__, 'ajax_' . $action ) );
    7979                }
    … …  
    172172                                        'saved'        => __( 'Saved. Your chat uses the new settings now.', 'clientager' ),
    173173                                        'savedLimits'  => __( 'Saved. New messages follow these limits.', 'clientager' ),
     174                                        'waOpening'    => __( 'Opening the secure WhatsApp window…', 'clientager' ),
     175                                        'waWaiting'    => __( 'Finish the steps in the WhatsApp window. This page updates by itself when you are done.', 'clientager' ),
     176                                        'waBlocked'    => __( 'Your browser blocked the window. Allow pop-ups for this page and try again.', 'clientager' ),
     177                                        'waOff'        => __( 'Disconnect WhatsApp? Your AI stops answering it. The number stays yours.', 'clientager' ),
    174178                                        'helpSent'     => __( 'Thanks, we got your message. We will reply to your email, usually within one business day.', 'clientager' ),
    175179                                        'badColor'     => __( 'Pick a colour like #2563eb.', 'clientager' ),
    … …  
    19801984                                        </div>
    19811985
     1986                                        <?php self::whatsapp_card(); ?>
    19821987                                        <?php self::origins_card( $s ); ?>
    19831988                                        <?php self::chat_rules_card( $s ); ?>
    … …  
    20622067                                </section>
    20632068                        </div>
     2069                </div>
     2070                <?php
     2071        }
     2072
     2073        /**
     2074         * WhatsApp: the connected number, or Connect (Meta's sign-in opens in a pop-up on clientager.com).
     2075         */
     2076        private static function whatsapp_card() {
     2077                $res  = Clientager_Api::request( 'GET', '/whatsapp' );
     2078                $wa   = $res['ok'] && is_array( $res['data'] ) ? $res['data'] : array();
     2079                $conn = ! empty( $wa['connected']['number'] ) ? $wa['connected'] : null;
     2080                ?>
     2081                <div class="cg-card" id="clientager-wa">
     2082                        <?php self::card_head( __( 'WhatsApp', 'clientager' ), __( 'Your AI answers customers on your own WhatsApp number, 24/7.', 'clientager' ), 'whatsapp' ); ?>
     2083                        <?php if ( $conn ) : ?>
     2084                                <div class="cg-switch-row">
     2085                                        <div>
     2086                                                <strong><?php esc_html_e( 'Connected', 'clientager' ); ?></strong>
     2087                                                <span>
     2088                                                <?php
     2089                                                /* translators: %s: WhatsApp phone number. */
     2090                                                echo esc_html( sprintf( __( 'Your AI answers WhatsApp messages on %s.', 'clientager' ), (string) $conn['number'] ) );
     2091                                                ?>
     2092                                                </span>
     2093                                        </div>
     2094                                        <span class="cg-badge is-won"><?php esc_html_e( 'Live', 'clientager' ); ?></span>
     2095                                </div>
     2096                                <div class="cg-actions">
     2097                                        <a class="cg-btn cg-btn-secondary" href="<?php echo esc_url( 'https://wa.me/' . preg_replace( '/\D/', '', (string) $conn['number'] ) ); ?>" target="_blank" rel="noopener"><?php self::icon( 'whatsapp' ); ?><?php esc_html_e( 'Send a test message', 'clientager' ); ?></a>
     2098                                        <button type="button" class="cg-btn cg-btn-secondary" id="clientager-wa-off"><?php esc_html_e( 'Disconnect', 'clientager' ); ?></button>
     2099                                </div>
     2100                                <p class="cg-help"><?php echo esc_html( ! empty( $conn['app'] ) ? __( 'You can keep using the WhatsApp Business app. When you reply from the app, the AI leaves that chat to you.', 'clientager' ) : __( 'Chats show up in your Inbox, where you can take over any time.', 'clientager' ) ); ?></p>
     2101                        <?php elseif ( empty( $wa['allowed'] ) ) : ?>
     2102                                <p class="cg-help"><?php esc_html_e( 'Included in the 7-day free trial and from the Starter plan. Choose a plan to connect your number.', 'clientager' ); ?></p>
     2103                        <?php elseif ( empty( $wa['available'] ) ) : ?>
     2104                                <p class="cg-help"><?php esc_html_e( 'WhatsApp connect opens soon. We will email you when you can connect your number.', 'clientager' ); ?></p>
     2105                        <?php else : ?>
     2106                                <ul class="cg-wa-list">
     2107                                        <li><?php self::icon( 'check' ); ?><?php esc_html_e( 'Use a new number, or the one on your WhatsApp Business app (you keep the app and your chats).', 'clientager' ); ?></li>
     2108                                        <li><?php self::icon( 'check' ); ?><?php esc_html_e( 'Sign in with Facebook in a secure window. Takes about 5 minutes.', 'clientager' ); ?></li>
     2109                                        <li><?php self::icon( 'check' ); ?><?php esc_html_e( 'The number stays yours. Replies within 24 hours of a customer message are free.', 'clientager' ); ?></li>
     2110                                </ul>
     2111                                <div class="cg-actions"><button type="button" class="cg-btn cg-btn-primary" id="clientager-wa-connect"><?php self::icon( 'whatsapp' ); ?><?php esc_html_e( 'Connect WhatsApp', 'clientager' ); ?></button></div>
     2112                        <?php endif; ?>
     2113                        <div id="clientager-wa-msg" class="clientager-msg" role="status" aria-live="polite"></div>
    20642114                </div>
    20652115                <?php
    … …  
    27792829
    27802830        /**
     2831         * WhatsApp: op=connect returns the sign-in address (on clientager.com, valid 30 minutes), op=status says whether a
     2832         * number is connected, op=disconnect stops it.
     2833         */
     2834        public static function ajax_whatsapp() {
     2835                check_ajax_referer( self::NONCE, 'nonce' );
     2836                self::guard();
     2837                $op = isset( $_POST['op'] ) ? sanitize_key( wp_unslash( $_POST['op'] ) ) : '';
     2838                if ( 'disconnect' === $op ) {
     2839                        self::reply( Clientager_Api::request( 'POST', '/whatsapp', array( 'action' => 'disconnect' ) ) );
     2840                }
     2841                $res = Clientager_Api::request( 'GET', '/whatsapp' );
     2842                if ( 'status' === $op ) {
     2843                        self::reply( $res, array( 'connected' => ! empty( $res['data']['connected'] ) ) );
     2844                }
     2845                $url = $res['ok'] && ! empty( $res['data']['connect_url'] ) ? esc_url_raw( (string) $res['data']['connect_url'] ) : '';
     2846                if ( $res['ok'] && ! $url ) {
     2847                        $res = array( 'ok' => false, 'status' => 409, 'code' => 'wa_unavailable', 'error' => ! empty( $res['data']['connected'] ) ? __( 'WhatsApp is already connected. Reload this page.', 'clientager' ) : __( 'WhatsApp cannot be connected on this plan yet.', 'clientager' ), 'data' => array() );
     2848                }
     2849                self::reply( $res, array( 'url' => $url, 'connected' => ! empty( $res['data']['connected'] ) ) );
     2850        }
     2851
     2852        /**
    27812853         * Saves the contact form's fields, texts and look. The server checks them again and is the only place they are stored.
    27822854         */
  • clientager/trunk/readme.txt

    r3773846 r3774969  
    55Tested up to: 7.1
    66Requires PHP: 7.4
    7 Stable tag: 1.1.9
     7Stable tag: 1.2.0
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    6161* **When a WooCommerce order is paid after the shopper chatted with the AI:** the order id, order number, total and currency, with the chat's id, for the "Sales made by AI" card. No customer or product details are sent. The chat window sets a first-party cookie (clientager_chat, 30 days) holding only a random chat id once the AI has replied, so the order can be matched to that chat.
    6262* **When you send a message from the Help tab:** what you wrote, the type you picked (question, problem or feature request), the reply-to email you entered, your site address and the plugin version, so our team can answer you by email.
     63* **When you connect WhatsApp (Settings):** a request for a short-lived sign-in link. Facebook's sign-in then opens in a window on app.clientager.com; your Facebook password goes only to Facebook, and Clientager receives permission to send and receive WhatsApp messages for the number you choose ([Meta Privacy Policy](https://www.facebook.com/privacy/policy/)).
    6364* **When you disconnect or delete the plugin:** a request to disconnect this site.
    6465
    … …  
    125126
    126127== Changelog ==
     128
     129= 1.2.0 =
     130* Connect WhatsApp from the plugin: Settings → Chat & websites → Connect WhatsApp. Sign in with Facebook in a secure window and your AI answers your own WhatsApp number (new number or your WhatsApp Business app number). Included in the free trial and from Starter.
    127131
    128132= 1.1.9 =
    … …  
    195199== Upgrade Notice ==
    196200
     201= 1.2.0 =
     202Connect your WhatsApp number right from the plugin.
     203
    197204= 1.1.9 =
    198205Faster screens without page reloads, Settings in clear sections, and product cards in the preview.
Note: See TracChangeset for help on using the changeset viewer.