{"id":296916,"date":"2026-04-30T15:29:08","date_gmt":"2026-04-30T15:29:08","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/besked-notifications\/"},"modified":"2026-07-24T14:29:22","modified_gmt":"2026-07-24T14:29:22","slug":"besked-wa-notifications","status":"publish","type":"plugin","link":"https:\/\/ug.wordpress.org\/plugins\/besked-wa-notifications\/","author":6017941,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"1.11.0","stable_tag":"1.11.0","tested":"7.0.2","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"Besked Notifications","header_author":"Hardweb.it","header_description":"Send WhatsApp notifications via the Besked API. Native WooCommerce integration for order notifications.","assets_banners_color":"545454","last_updated":"2026-07-24 14:29:22","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/besked.it","header_author_uri":"https:\/\/hardweb.it","rating":0,"author_block_rating":0,"active_installs":0,"downloads":264,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"1.10.0":{"tag":"1.10.0","author":"giangel84","date":"2026-07-23 12:58:48"},"1.10.2":{"tag":"1.10.2","author":"giangel84","date":"2026-07-24 07:08:50"},"1.10.3":{"tag":"1.10.3","author":"giangel84","date":"2026-07-24 14:29:22"},"1.11.0":{"tag":"1.11.0","author":"giangel84","date":"2026-07-24 14:29:22"},"1.5.4":{"tag":"1.5.4","author":"giangel84","date":"2026-04-30 15:28:30"},"1.8.1":{"tag":"1.8.1","author":"giangel84","date":"2026-07-22 15:58:24"}},"upgrade_notice":{"1.11.0":"<p>Waitlist confirmation &amp; back-in-stock messages now send immediately (fixes messages stuck in &quot;pending&quot; when WP-Cron is unreliable). New: bulk delete on the Messages page.<\/p>","1.10.0":"<p>New: Waitlist \/ &quot;Avvisami&quot; back-in-stock notifications with an Elementor button + popup, a Waitlist admin section, dedicated WhatsApp templates, and a full Italian translation of the back-end.<\/p>","1.9.2":"<p>Fix: campaign delivery counters are now accurate even after the backend cleans up delivered messages \u2014 no more &quot;273 sent \/ 0 pending&quot; while messages are still queued. Recovered campaigns also store their true total.<\/p>","1.9.1":"<p>New: recover the live status of campaigns sent before 1.9.0, and more accurate counters for multi-day campaigns. Requires app.besked.it 3.61.1+.<\/p>","1.9.0":"<p>New: live campaign delivery status (sent \/ pending \/ failed \/ total) with Pause and Resume. Requires the Besked backend 3.61.0+.<\/p>","1.8.2":"<p>New: filter the Contacts list by &quot;Numbers to validate&quot; to quickly find numbers flagged as non-mobile.<\/p>","1.8.1":"<p>Critical fix: resolves a fatal error on the contacts page and during campaign sending introduced in 1.8.0.<\/p>","1.8.0":"<p>New: contact names shown in Title Case (also in {first_name}\/{last_name}); campaign preview now shows image\/video\/document attachments in the WhatsApp bubble.<\/p>","1.7.0":"<p>New: landline numbers are flagged and excluded from sending until reviewed, campaigns support video attachments and a &quot;whole address book&quot; target.<\/p>","1.6.0":"<p>New: edit a contact&#039;s phone number inline from the Contacts page; linked customers are kept in sync on their profile.<\/p>","1.4.0":"<p>New: WordPress user import, custom phone field mapping, media attachments for campaigns.<\/p>"},"ratings":[],"assets_icons":{"icon-128x128.jpg":{"filename":"icon-128x128.jpg","revision":3519684,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.jpg":{"filename":"icon-256x256.jpg","revision":3519684,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3519711,"resolution":"1544x500","location":"assets","locale":"","width":1544,"height":500},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3519711,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["1.10.0","1.10.2","1.10.3","1.11.0","1.5.4","1.8.1"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Settings page \u2014 API configuration and session management","2":"Contact address book with search, filters, and bulk actions","3":"Campaign editor with live WhatsApp preview","4":"WooCommerce order notification templates","5":"Abandoned cart automation rules"}},"plugin_section":[],"plugin_tags":[2512,4906,711,3160,286],"plugin_category":[41,45],"plugin_contributors":[128517],"plugin_business_model":[],"class_list":["post-296916","plugin","type-plugin","status-publish","hentry","plugin_tags-messaging","plugin_tags-notifications","plugin_tags-sms","plugin_tags-whatsapp","plugin_tags-woocommerce","plugin_category-communication","plugin_category-ecommerce","plugin_contributors-giangel84","plugin_committers-giangel84"],"banners":{"banner":"https:\/\/ps.w.org\/besked-wa-notifications\/assets\/banner-772x250.png?rev=3519711","banner_2x":"https:\/\/ps.w.org\/besked-wa-notifications\/assets\/banner-1544x500.png?rev=3519711","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/besked-wa-notifications\/assets\/icon-128x128.jpg?rev=3519684","icon_2x":"https:\/\/ps.w.org\/besked-wa-notifications\/assets\/icon-256x256.jpg?rev=3519684","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Besked WhatsApp Notifications connects your WordPress site to the Besked WhatsApp messaging platform, enabling you to:<\/p>\n\n<ul>\n<li>Send automated WhatsApp notifications for WooCommerce orders (new order, processing, completed, cancelled, refunded, on-hold, and custom statuses)<\/li>\n<li>Manage a contact address book with WhatsApp consent (GDPR-compliant)<\/li>\n<li>Create and schedule broadcast campaigns to contact lists with per-recipient personalisation<\/li>\n<li>Track abandoned carts and send automated recovery messages<\/li>\n<li>Import contacts from WooCommerce orders, WordPress users, or CSV files<\/li>\n<li>Collect WhatsApp consent at checkout, on the account page, and via a dedicated \"My Account\" section<\/li>\n<\/ul>\n\n<h4>Key Features<\/h4>\n\n<p><strong>Order Notifications<\/strong>\nAutomatically notify customers on every order status change with fully customisable message templates and dynamic placeholders (<code>{order_number}<\/code>, <code>{order_total}<\/code>, <code>{customer_first_name}<\/code>, etc.).<\/p>\n\n<p><strong>Contact Management<\/strong>\nFull-featured address book with search, filtering, list segmentation, CSV import\/export, and bulk actions (enable\/revoke consent, add\/remove from lists).<\/p>\n\n<p><strong>Broadcast Campaigns<\/strong>\nCompose WhatsApp campaigns with a live preview editor (bold, italic, strikethrough, monospace), attach images or documents, schedule delivery, and track per-contact delivery logs.<\/p>\n\n<p><strong>Abandoned Cart Recovery<\/strong>\nDetect abandoned carts and automatically send recovery messages after a configurable delay, with optional discount coupon codes.<\/p>\n\n<p><strong>GDPR &amp; Consent<\/strong>\nCollect explicit WhatsApp consent at checkout and in the account area. Contacts can unsubscribe via a secure tokenised link in any message.<\/p>\n\n<h4>Requirements<\/h4>\n\n<ul>\n<li>A Besked account and API key \u2014 sign up at <a href=\"https:\/\/besked.it\">besked.it<\/a><\/li>\n<li>WordPress 6.2 or higher<\/li>\n<li>PHP 7.4 or higher<\/li>\n<li>WooCommerce 5.0+ (optional \u2014 required only for order notifications and cart tracking)<\/li>\n<\/ul>\n\n<h3>External services<\/h3>\n\n<p>This plugin connects to the Besked WhatsApp messaging API (provided by Besked.it, https:\/\/besked.it) to deliver WhatsApp messages and to manage WhatsApp sessions. Using the plugin therefore requires an active Besked account and an API key, which the site owner enters in the plugin settings.<\/p>\n\n<p><strong>What the service is and what it is used for<\/strong><\/p>\n\n<p>Besked is a third-party WhatsApp messaging gateway. The plugin relies on it to:<\/p>\n\n<ul>\n<li>Send single WhatsApp messages (for example, WooCommerce order status notifications).<\/li>\n<li>Send bulk\/broadcast WhatsApp campaigns to contact lists, with optional media attachments.<\/li>\n<li>Retrieve the list of WhatsApp sessions available for the account.<\/li>\n<li>Check the connection status of a WhatsApp session.<\/li>\n<\/ul>\n\n<p><strong>What data is sent, and when<\/strong><\/p>\n\n<p>The following requests are made to <code>https:\/\/app.besked.it<\/code>:<\/p>\n\n<ul>\n<li><code>POST \/api\/v1\/send<\/code> \u2014 every time a single WhatsApp notification is sent (for example, when a WooCommerce order changes status, or an abandoned cart recovery message is triggered). Data sent: the configured Session ID, the recipient phone number in E.164 format, the message body, and optionally a media URL, media type and file name.<\/li>\n<li><code>POST \/api\/v1\/send\/bulk<\/code> \u2014 every time a campaign is dispatched. Data sent: the Session ID, the message template and the recipient list (phone number plus any per-recipient personalisation variables), and optional media.<\/li>\n<li><code>GET \/api\/v1\/sessions<\/code> \u2014 when the site administrator opens the plugin settings page, to display the list of available WhatsApp sessions.<\/li>\n<li><code>GET \/api\/v1\/sessions\/{session_id}\/status<\/code> \u2014 when the site administrator checks the connection status of a session.<\/li>\n<\/ul>\n\n<p>Every request includes the API key configured by the site owner, sent as the <code>X-API-Key<\/code> HTTP header for authentication. No data is sent to Besked for visitors who have not given WhatsApp consent (consent is stored per contact as <code>whatsapp_consent = 1<\/code>).<\/p>\n\n<p><strong>Service provider, terms and privacy<\/strong><\/p>\n\n<p>The service is provided by Besked.it. For details about how Besked handles the data it receives, please refer to the provider's legal documents:<\/p>\n\n<ul>\n<li>Terms of Service: https:\/\/besked.it\/termini.html<\/li>\n<li>Privacy Policy: https:\/\/besked.it\/privacy-policy.html<\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>besked-wa-notifications<\/code> folder to the <code>\/wp-content\/plugins\/<\/code> directory, or install directly from the WordPress plugin directory.<\/li>\n<li>Activate the plugin through the <strong>Plugins<\/strong> menu in WordPress.<\/li>\n<li>Go to <strong>Besked \u2192 Impostazioni<\/strong> and enter your API Key and Session ID from your <a href=\"https:\/\/app.besked.it\">Besked dashboard<\/a>.<\/li>\n<li>Configure notification templates under <strong>Notifiche WooCommerce<\/strong>.<\/li>\n<li>(Optional) Enable WhatsApp consent collection under <strong>GDPR &amp; Consenso<\/strong>.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"do%20i%20need%20a%20besked%20account%3F\"><h3>Do I need a Besked account?<\/h3><\/dt>\n<dd><p>Yes. The plugin sends messages through the Besked API. You need a Besked account and an active WhatsApp session. Sign up at <a href=\"https:\/\/besked.it\">besked.it<\/a>.<\/p><\/dd>\n<dt id=\"does%20it%20work%20without%20woocommerce%3F\"><h3>Does it work without WooCommerce?<\/h3><\/dt>\n<dd><p>Yes. The contact address book, campaign management, and manual messaging features work independently of WooCommerce. Order notification and cart abandonment features require WooCommerce.<\/p><\/dd>\n<dt id=\"is%20it%20gdpr%20compliant%3F\"><h3>Is it GDPR compliant?<\/h3><\/dt>\n<dd><p>The plugin includes a built-in consent system. You can collect explicit opt-in at checkout and in the customer account area. Contacts can unsubscribe at any time via a secure link. No message is sent to contacts without <code>whatsapp_consent = 1<\/code>.<\/p><\/dd>\n<dt id=\"what%20placeholders%20are%20available%20in%20message%20templates%3F\"><h3>What placeholders are available in message templates?<\/h3><\/dt>\n<dd><p>Order templates: <code>{order_number}<\/code>, <code>{order_date}<\/code>, <code>{order_total}<\/code>, <code>{order_status}<\/code>, <code>{customer_first_name}<\/code>, <code>{customer_last_name}<\/code>, <code>{customer_email}<\/code>, <code>{billing_address}<\/code>, <code>{shipping_address}<\/code>, <code>{payment_method}<\/code>, <code>{order_items}<\/code>, <code>{site_name}<\/code>, <code>{site_url}<\/code>, <code>{customer_note}<\/code>, <code>{bacs_details}<\/code>, <code>{unsubscribe}<\/code>.<\/p>\n\n<p>Campaign templates: <code>{first_name}<\/code>, <code>{last_name}<\/code>, <code>{phone}<\/code>, <code>{email}<\/code>, <code>{site_name}<\/code>, <code>{site_url}<\/code>, <code>{unsubscribe}<\/code>.<\/p><\/dd>\n<dt id=\"can%20i%20send%20to%20contacts%20without%20woocommerce%3F\"><h3>Can I send to contacts without WooCommerce?<\/h3><\/dt>\n<dd><p>Yes. Import contacts via CSV or from existing WordPress users (with custom phone field mapping via <strong>Impostazioni \u2192 Mappa campi custom<\/strong>), then create a campaign or send manual messages.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>1.11.0<\/h4>\n\n<ul>\n<li>New: the Messages history page now lets you select messages (with a \"select all\" checkbox) and delete them in bulk, plus a per-row delete button<\/li>\n<li>Fix: the waitlist confirmation \/ back-in-stock messages are now sent immediately (synchronously), like the order notifications, instead of only being queued for the retry cron. On sites where WP-Cron does not run reliably the messages stayed \"pending\" and were never delivered<\/li>\n<li>Fix: the message-retry cron event (<code>besked_retry_messages<\/code>) is now self-scheduled by the cron handler, so automatic retries of failed\/pending messages keep working even if the event ever went missing from the schedule<\/li>\n<\/ul>\n\n<h4>1.10.2<\/h4>\n\n<ul>\n<li>Fix: the \"Avvisami\" (waitlist) popup did not open on click \u2014 the popup script\/style are now loaded by the Elementor widget itself (independent of <code>is_product()<\/code> and hook timing), and the hard dependency on <code>wc-add-to-cart-variation<\/code> (which could silently prevent the script from loading) was removed<\/li>\n<li>Fix: the waitlist Elementor widget now renders nothing on the front end when the waitlist is disabled or not available for the visitor's role (it still renders in the Elementor editor so it can be styled)<\/li>\n<\/ul>\n\n<h4>1.10.1<\/h4>\n\n<ul>\n<li>Fix: saving the Waitlist message templates opened a blank admin-post.php page and did not save \u2014 the save handler referenced the activator class, which is not loaded on that request. It now loads it explicitly (same pattern as the WooCommerce notifications save)<\/li>\n<\/ul>\n\n<h4>1.10.0<\/h4>\n\n<ul>\n<li>New: <strong>Waitlist \/ \"Avvisami\"<\/strong> \u2014 when a product (or a specific variation) is out of stock, an \"Avvisami\" button lets shoppers join a back-in-stock waitlist. Guests leave name + WhatsApp number (with optional opt-in); logged-in customers confirm\/update their number and see their current consent state. When the product returns in stock they are automatically notified on WhatsApp<\/li>\n<li>New: <strong>Elementor widget<\/strong> (\"Besked \u2014 Avvisami\") to place and fully style the button and its consent popup (button, popup border\/background\/title\/description typography, and the two footer buttons with hover states) on the single-product page<\/li>\n<li>New: <strong>Waitlist admin section<\/strong> \u2014 see who is waiting per product\/variation and drill into each subscriber (guest\/customer, email, phone, request date, and whether they have been informed)<\/li>\n<li>New: Waitlist settings \u2014 enable\/disable, choose which roles it is active for (all incl. guests by default), and three toggleable WhatsApp templates (subscription confirmation to the customer, to the admin, and the back-in-stock notification)<\/li>\n<li>New: two message shortcodes for the back-in-stock template \u2014 <code>{link_product}<\/code> (link to the product) and <code>{link_checkout}<\/code> (a one-tap \"direct checkout\" link that adds the product to the cart and goes to checkout). Both tag the visit so WooCommerce records the order Origin as \"Besked \/ WhatsApp\", and the link preview on WhatsApp shows the product (image\/title), never a bare checkout page<\/li>\n<li>New: the WhatsApp live preview (as seen in Campaigns) now also appears next to the message template editors under Waitlist, Abandoned Carts \u2192 Automations, and Settings \u2192 Notifications<\/li>\n<li>Improved: the plugin back-end is now fully translated to Italian (the Abandoned Carts automations\/settings screens and other admin strings were partly untranslated)<\/li>\n<\/ul>\n\n<h4>1.9.2<\/h4>\n\n<ul>\n<li>Fix: campaign delivery counters are now correct even when the backend has already cleaned up delivered messages. \"Sent\" is derived from the total minus the (never-cleaned) pending and failed counts, instead of the backend's eroded sent-row count, so a campaign no longer shows more \"sent\" than its total or 0 pending while messages are still queued<\/li>\n<li>Fix: recovering a campaign now stores its true recipient total instead of the (possibly shrunk) count of messages still present in the queue<\/li>\n<\/ul>\n\n<h4>1.9.1<\/h4>\n\n<ul>\n<li>New: \"Recover status\" action on campaigns that were sent before live tracking existed \u2014 it lists the matching batches still present in the Besked queue and lets you reconnect the campaign so its real sent\/pending\/failed counters are shown again<\/li>\n<li>Reliability: campaigns delivered over several days (spread out by anti-ban daily limits) now keep accurate counters, and a campaign is reconciled to 100% (or marked Failed if all recipients failed) once complete<\/li>\n<li>The status poll now requests a lightweight summary from the backend<\/li>\n<li>Requires app.besked.it 3.61.1+<\/li>\n<\/ul>\n\n<h4>1.9.0<\/h4>\n\n<ul>\n<li>New: live campaign delivery status \u2014 each campaign now shows the number of messages sent, pending (in the queue), failed and the total expected, kept in sync with the Besked sending queue by a cron that runs every 5 minutes<\/li>\n<li>New: Pause \/ Resume controls on a sending campaign \u2014 pausing suspends the messages still queued in Besked until you resume them<\/li>\n<li>Campaigns now stay in a \"Sending\" state and update their counters over time instead of being marked complete the moment they are queued<\/li>\n<li>Requires the Besked backend that exposes the campaign batch status and pause\/resume endpoints (app.besked.it 3.61.0+)<\/li>\n<\/ul>\n\n<h4>1.8.2<\/h4>\n\n<ul>\n<li>New: added a \"Numbers to validate\" option to the Contacts consent filter, showing only contacts whose phone number carries the non-mobile\/landline warning (excluded from sending until reviewed)<\/li>\n<\/ul>\n\n<h4>1.8.1<\/h4>\n\n<ul>\n<li>Fix: fatal error (\"Undefined constant MB_TITLE_CASE\") when displaying contacts or sending campaigns \u2014 the Title Case helper used the wrong mbstring constant; corrected to MB_CASE_TITLE<\/li>\n<\/ul>\n\n<h4>1.8.0<\/h4>\n\n<ul>\n<li>New: contact names are shown in Title Case in the address book (First name \/ Last name columns) and when printed in messages via the {first_name} and {last_name} placeholders \u2014 e.g. \"MARIO DI FALCO\" is displayed as \"Mario Di Falco\" (multibyte\/accent aware; the stored value is left unchanged)<\/li>\n<li>New: the campaign live preview now renders attachments inside the WhatsApp bubble following WhatsApp's UI \u2014 images and video (with a play overlay) above the caption, and a document card with icon and file name<\/li>\n<li>Accessibility\/UX: the landline warning icon now exposes an accessible label; disabled recipient controls are visually dimmed; the background page is made inert while the phone-edit dialog is open; the Media Library picker is correctly titled when choosing a video<\/li>\n<li>Compatibility: tested up to WordPress 7.0<\/li>\n<\/ul>\n\n<h4>1.7.0<\/h4>\n\n<ul>\n<li>New: non-mobile \/ landline numbers are flagged in the Contacts page with a warning icon (hover tooltip) and are automatically excluded from WhatsApp messages, notifications and campaigns until corrected; the inline phone editor shows a \"Consider this number correct and remove the warning\" checkbox to override the flag. Confident detection covers Italian numbers (mobiles start with 3); extend other countries via the <code>besked_phone_is_flagged<\/code> filter<\/li>\n<li>New: campaigns can attach a <strong>video<\/strong> (in addition to image and document\/PDF)<\/li>\n<li>New: \"WHOLE ADDRESS BOOK\" option in a campaign's recipient section \u2014 send to every contact with consent; selecting it disables the custom lists, and choosing custom lists clears it (mutually exclusive)<\/li>\n<li>Changed: the campaign send option \"Send now (within 1 minute)\" now reads \"Send now (at your next cron job)\" to reflect that delivery happens on the next cron run<\/li>\n<li>Accessibility: the inline phone editor now returns focus to the edited row on close, traps Tab focus inside the dialog, announces validation\/success messages, and keeps the edit affordance visible on touch devices<\/li>\n<\/ul>\n\n<h4>1.6.0<\/h4>\n\n<ul>\n<li>New: inline phone-number editing in the Contacts page \u2014 click a number to open a popup with a <code>tel<\/code> field and Save\/Cancel buttons<\/li>\n<li>New: when the edited contact is linked to a registered customer, the number is also written back to the customer's profile (<code>billing_phone<\/code>, or the field configured under Settings \u2192 Custom field mapping); unlinked contacts are updated in the address book only<\/li>\n<li>The edit rejects a number already assigned to another contact (the phone column is unique) and normalises the input to E.164 before saving<\/li>\n<\/ul>\n\n<h4>1.5.4<\/h4>\n\n<ul>\n<li>Code quality: in <code>ajax_media_upload()<\/code> removed the unused <code>require_once wp-admin\/includes\/media.php<\/code> and moved <code>require_once wp-admin\/includes\/image.php<\/code> immediately before <code>wp_generate_attachment_metadata()<\/code>, so each core admin file is loaded right before the function from it is used<\/li>\n<li>Security: added an explicit <code>wp_verify_nonce( 'woocommerce-process_checkout' )<\/code> check at the start of <code>validate_phone()<\/code>, <code>sanitize_phone_on_save()<\/code> and <code>save_checkout_data()<\/code> in the WooCommerce checkout integration, so the nonce verification is visible inline (it was already enforced upstream by WooCommerce)<\/li>\n<li>Security: added a <code>besked_media_filters<\/code> nonce to the Besked Media admin page sort\/filter links and form, with <code>wp_verify_nonce<\/code> on incoming requests; filter and sort query args are now ignored unless accompanied by a valid nonce<\/li>\n<\/ul>\n\n<h4>1.5.3<\/h4>\n\n<ul>\n<li>Code quality: replaced all inline <code>&lt;script&gt;<\/code> and <code>&lt;style&gt;<\/code> tags with <code>wp_enqueue_script()<\/code>, <code>wp_enqueue_style()<\/code>, <code>wp_add_inline_script()<\/code>, and <code>wp_localize_script()<\/code> per WordPress coding standards<\/li>\n<li>Security: added nonce verification to the checkout cart-tracking AJAX endpoint (<code>besked_track_billing<\/code>)<\/li>\n<li>Security: input fields of the abandoned-cart automation save handler are now individually sanitised with the appropriate WordPress functions (<code>sanitize_text_field<\/code>, <code>wp_kses_post<\/code>, <code>absint<\/code>, whitelist checks)<\/li>\n<li>Security: replaced direct SQL interpolation with <code>$wpdb-&gt;prepare()<\/code> and placeholders across campaigns, messages, contacts, abandoned-carts and lists queries<\/li>\n<li>Docs: added the <code>== External services ==<\/code> section describing the Besked API usage, data sent and links to the provider's Terms of Service and Privacy Policy<\/li>\n<\/ul>\n\n<h4>1.4.0<\/h4>\n\n<ul>\n<li>Added \"Import from WordPress users\" feature with phone field mapping<\/li>\n<li>Added \"Custom field mapping\" settings tab for non-WooCommerce phone fields<\/li>\n<li>Added media attachments (image\/document) to broadcast campaigns<\/li>\n<li>Added Besked Media library page with bulk delete<\/li>\n<li>Added CSV import with auto-detected delimiter and column mapping<\/li>\n<li>Improved bulk action confirmation prompts<\/li>\n<\/ul>\n\n<h4>1.3.0<\/h4>\n\n<ul>\n<li>Added broadcast campaigns with per-recipient variable substitution<\/li>\n<li>Added live WhatsApp preview editor with formatting toolbar<\/li>\n<li>Added campaign scheduling and per-contact delivery logs<\/li>\n<\/ul>\n\n<h4>1.2.0<\/h4>\n\n<ul>\n<li>Added contact list segmentation<\/li>\n<li>Added GDPR unsubscribe tokens<\/li>\n<li>Added My Account \"Notification preferences\" endpoint<\/li>\n<\/ul>\n\n<h4>1.1.0<\/h4>\n\n<ul>\n<li>Added abandoned cart tracking and automated recovery messages<\/li>\n<li>Added Formidable Forms integration<\/li>\n<\/ul>\n\n<h4>1.0.0<\/h4>\n\n<ul>\n<li>Initial release<\/li>\n<\/ul>","raw_excerpt":"Send WhatsApp notifications via Besked API. Native WooCommerce integration for order notifications, contact management, and broadcast campaigns.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/ug.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/296916","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ug.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/ug.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/ug.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=296916"}],"author":[{"embeddable":true,"href":"https:\/\/ug.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/giangel84"}],"wp:attachment":[{"href":"https:\/\/ug.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=296916"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/ug.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=296916"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/ug.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=296916"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/ug.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=296916"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/ug.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=296916"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/ug.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=296916"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}