{"id":320755,"date":"2026-06-04T16:39:48","date_gmt":"2026-06-04T16:39:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/telegram-messenger-integration\/"},"modified":"2026-08-28T12:40:16","modified_gmt":"2026-08-28T12:40:16","slug":"makarski-bot-connector-for-telegram","status":"publish","type":"plugin","link":"https:\/\/en-za.wordpress.org\/plugins\/makarski-bot-connector-for-telegram\/","author":14694637,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.3.5","stable_tag":"0.3.5","tested":"7.1","requires":"6.2","requires_php":"8.0","requires_plugins":null,"header_name":"Makarski Bot Connector for Telegram","header_author":"Dzmitry Makarski","header_description":"Allows you to manage your Telegram bot via WordPress","assets_banners_color":"062650","last_updated":"2026-08-28 12:40:16","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":289,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.2.43":{"tag":"0.2.43","author":"makaravich","date":"2026-06-04 16:43:28","revision":3561318},"0.3.0":{"tag":"0.3.0","author":"makaravich","date":"2026-06-09 17:44:32","revision":3566390},"0.3.2":{"tag":"0.3.2","author":"makaravich","date":"2026-06-22 15:38:28","revision":3582000},"0.3.3":{"tag":"0.3.3","author":"makaravich","date":"2026-08-28 11:14:30","revision":3670207},"0.3.4":{"tag":"0.3.4","author":"makaravich","date":"2026-08-28 11:42:44","revision":3670246},"0.3.5":{"tag":"0.3.5","author":"makaravich","date":"2026-08-28 12:40:16","revision":3670359}},"upgrade_notice":{"0.3.0":"<p>New Broadcast feature requires no action \u2014 database tables are created automatically on first load after update.<\/p>","0.2.30":"<p>The <code>tgbot_process_multimedia_message<\/code> hook is deprecated. Please migrate your code to use <code>tgbot_message<\/code> \u2014 the signature is identical.<\/p>"},"ratings":[],"assets_icons":{"icon-256x256.png":{"filename":"icon-256x256.png","revision":3561322,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-772x250.png":{"filename":"banner-772x250.png","revision":3561314,"resolution":"772x250","location":"assets","locale":"","width":1824,"height":576}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.2.43","0.3.0","0.3.2","0.3.3","0.3.4","0.3.5"],"block_files":[],"assets_screenshots":{"screenshot-1.png":{"filename":"screenshot-1.png","revision":3561314,"resolution":"1","location":"assets","locale":"","width":1249,"height":810},"screenshot-2.png":{"filename":"screenshot-2.png","revision":3561314,"resolution":"2","location":"assets","locale":"","width":1249,"height":810},"screenshot-3.png":{"filename":"screenshot-3.png","revision":3566389,"resolution":"3","location":"assets","locale":"","width":1922,"height":931}},"screenshots":{"1":"Settings page \u2014 enable\/disable toggle, token, connection mode (webhook\/polling)","2":"Users list \u2014 Telegram Nickname column added automatically for linked users","3":"Broadcast page \u2014 recipient list with language filter, real-time progress bar, history table"}},"plugin_section":[],"plugin_tags":[2359,2364,6336,4906,9171],"plugin_category":[],"plugin_contributors":[265856],"plugin_business_model":[],"class_list":["post-320755","plugin","type-plugin","status-publish","hentry","plugin_tags-bot","plugin_tags-chatbot","plugin_tags-messenger","plugin_tags-notifications","plugin_tags-telegram","plugin_contributors-makaravich","plugin_committers-makaravich"],"banners":{"banner":"https:\/\/ps.w.org\/makarski-bot-connector-for-telegram\/assets\/banner-772x250.png?rev=3561314","banner_2x":false,"banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/makarski-bot-connector-for-telegram\/assets\/icon-256x256.png?rev=3561322","icon_2x":"https:\/\/ps.w.org\/makarski-bot-connector-for-telegram\/assets\/icon-256x256.png?rev=3561322","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/makarski-bot-connector-for-telegram\/assets\/screenshot-1.png?rev=3561314","caption":"Settings page \u2014 enable\/disable toggle, token, connection mode (webhook\/polling)"},{"src":"https:\/\/ps.w.org\/makarski-bot-connector-for-telegram\/assets\/screenshot-2.png?rev=3561314","caption":"Users list \u2014 Telegram Nickname column added automatically for linked users"},{"src":"https:\/\/ps.w.org\/makarski-bot-connector-for-telegram\/assets\/screenshot-3.png?rev=3566389","caption":"Broadcast page \u2014 recipient list with language filter, real-time progress bar, history table"}],"raw_content":"<!--section=description-->\n<p><strong>Makarski Bot Connector for Telegram<\/strong> provides a clean foundation for building Telegram bots powered by WordPress. It handles all the low-level communication with the Telegram Bot API so you can focus on your bot's logic.<\/p>\n\n<h4>What it does<\/h4>\n\n<ul>\n<li>Registers a Telegram bot webhook or runs in polling mode (via WP-Cron)<\/li>\n<li>Automatically creates WordPress users for incoming chat IDs<\/li>\n<li>Dispatches incoming messages and commands through WordPress action hooks<\/li>\n<li>Provides a full-featured BotApi class with 30+ methods<\/li>\n<li>Ships a tabbed Analytics page, mass Broadcast, and in-admin Documentation<\/li>\n<\/ul>\n\n<h4>Key features<\/h4>\n\n<ul>\n<li><strong>Webhook &amp; Polling<\/strong> \u2014 works on any hosting; polling mode requires no public HTTPS URL<\/li>\n<li><strong>Command routing<\/strong> \u2014 register bot commands with <code>register_bot_command()<\/code><\/li>\n<li><strong>Normalized message hook<\/strong> \u2014 <code>tgbot_message<\/code> fires for all message types (text, photo, voice, video, document, callback_query) with a consistent object structure<\/li>\n<li><strong>Broadcast<\/strong> \u2014 send mass messages to all bot users from the WP admin (Telegram Bot \u2192 Broadcast); filter by language, compose per-locale messages, cron-batched delivery with real-time progress and history<\/li>\n<li><strong>Analytics<\/strong> \u2014 a tabbed page (Telegram Bot \u2192 Analytics): overview counters, command usage, blocked chats and failed sends, first-touch acquisition sources from <code>?start=<\/code> deep links, arrival languages, referrals; consumer plugins can add their own tabs via the <code>tgbot_analytics_tabs<\/code> filter<\/li>\n<li><strong>Auto-split long messages<\/strong> \u2014 text over Telegram's 4096-character limit is split at paragraph\/line\/word boundaries with HTML tags kept valid per chunk<\/li>\n<li><strong>Privacy by default<\/strong> \u2014 auto-created bot users are hidden from author archives, the users sitemap, and the public REST users collection (opt out with the <code>tgbot_protect_bot_users<\/code> filter)<\/li>\n<li><strong>Send gating<\/strong> \u2014 the Enable-bot toggle silences outgoing traffic too; check <code>tgbot_can_send()<\/code> in your own sending paths<\/li>\n<li><strong>Referral links<\/strong> \u2014 built-in <code>?start=ref_&lt;code&gt;<\/code> tracking with a reward hook for your plugin<\/li>\n<li><strong>Stars payments<\/strong> \u2014 built-in support for Telegram Stars invoices, pre-checkout, and refunds<\/li>\n<li><strong>Multipart uploads<\/strong> \u2014 send photos, audio, voice messages, videos, and documents<\/li>\n<li><strong>Documentation in wp-admin<\/strong> \u2014 the full developer manual on its own admin page<\/li>\n<li><strong>Internationalization<\/strong> \u2014 translatable, ships with a .pot file<\/li>\n<\/ul>\n\n<h4>Available BotApi methods<\/h4>\n\n<pre><code>send_message, `send_plain_message`, `send_markdown_message`, `send_photo`, `send_document`, `send_audio`, `send_voice`, `send_video`, `send_animation`, `send_chat_action`, `send_location`, `send_stars_invoice`, `forward_message`, `copy_message`, `delete_message`, `delete_messages`, `edit_message`, `edit_message_markup`, `answer_callback_query`, `answer_pre_checkout_query`, `set_my_commands`, `set_webhook`, `delete_webhook`, `get_webhook_info`, `get_updates`, `get_document_url`, `get_photo_url`, `refund_star_payment`\n<\/code><\/pre>\n\n<h4>Available action hooks<\/h4>\n\n<p><strong><code>tgbot_message<\/code><\/strong> <em>(primary hook)<\/em>\nFires for every non-command incoming message (text, media, callback_query).<\/p>\n\n<pre><code>add_action( 'tgbot_message', function( $bot, $user_id, $message ) {\n    \/\/ $message-&gt;type   \u2014 'text' | 'image' | 'voice' | 'video' | 'audio'\n    \/\/                     | 'document' | 'sticker' | 'video_note' | 'callback_query'\n    \/\/ $message-&gt;text   \u2014 message text, caption, or callback data\n    \/\/ $message-&gt;files  \u2014 array of WP attachment IDs (downloaded files)\n    \/\/ $message-&gt;has_media_group \u2014 true if part of a multi-file album\n    \/\/ $message-&gt;media_group_id  \u2014 Telegram media_group_id string\n    if ( $message-&gt;type === 'voice' ) {\n        $bot-&gt;send_message( 'Got a voice message!' );\n    }\n}, 10, 3 );\n<\/code><\/pre>\n\n<p><strong><code>tgbot_handle_custom_bot_commands<\/code><\/strong>\nFires when a slash command is received, before the built-in dispatcher.<\/p>\n\n<pre><code>add_action( 'tgbot_handle_custom_bot_commands', function( $bot, $user_id, $command ) {\n    \/\/ $command \u2014 e.g. '\/mycommand'\n}, 10, 3 );\n<\/code><\/pre>\n\n<p><strong><code>tgbot_bot_call<\/code><\/strong>\nFires for every incoming update, including commands. Useful for cross-cutting concerns.<\/p>\n\n<p><strong><code>tgbot_pre_checkout_query<\/code><\/strong>\nFires when a Telegram Stars pre-checkout query arrives.<\/p>\n\n<pre><code>add_action( 'tgbot_pre_checkout_query', function( $bot, $query, $user_id ) {\n    $bot-&gt;answer_pre_checkout_query( $query-&gt;id, true );\n}, 10, 3 );\n<\/code><\/pre>\n\n<p><strong><code>tgbot_successful_payment<\/code><\/strong>\nFires after a successful Telegram Stars payment.<\/p>\n\n<pre><code>add_action( 'tgbot_successful_payment', function( $bot, $payment, $user_id ) {\n    \/\/ $payment-&gt;telegram_payment_charge_id \u2014 use for refunds\n    \/\/ $payment-&gt;total_amount \u2014 amount in Stars\n}, 10, 3 );\n<\/code><\/pre>\n\n<p><strong><code>tgbot_raw_message<\/code><\/strong>\nFires with the raw Telegram update object for advanced use cases.<\/p>\n\n<p><strong><code>tgbot_my_chat_member<\/code><\/strong>\nFires when the bot is added to or removed from a group.<\/p>\n\n<p><strong><code>tgbot_user_registered<\/code><\/strong>\nFires when a WordPress user is created for a new Telegram chat.<\/p>\n\n<pre><code>add_action( 'tgbot_user_registered', function( $wp_user_id, $chat_id, $from ) {\n    \/\/ $from \u2014 Telegram 'from' object (may be null)\n}, 10, 3 );\n<\/code><\/pre>\n\n<p><strong><code>tgbot_referral_completed<\/code><\/strong>\nFires when a new chat registers via a <code>?start=ref_&lt;code&gt;<\/code> referral link \u2014 grant your reward here.<\/p>\n\n<h4>Registering bot commands<\/h4>\n\n<p>Use <code>TGBot\\register_bot_command()<\/code> inside an <code>init<\/code> hook:<\/p>\n\n<pre><code>add_action( 'init', function() {\n    TGBot\\register_bot_command( 'hello', function( $bot ) {\n        $bot-&gt;send_message( 'Hello, ' . $bot-&gt;chat_id . '!' );\n    } );\n\n    TGBot\\register_bot_command( 'ping', function( $bot ) {\n        $bot-&gt;send_message( 'Pong \ud83c\udfd3' );\n    } );\n} );\n<\/code><\/pre>\n\n<h4>Minimal plugin example<\/h4>\n\n<pre><code>add_action( 'init', function() {\n    TGBot\\register_bot_command( 'start', function( $bot ) {\n        $bot-&gt;send_message( 'Welcome!' );\n    } );\n} );\n\nadd_action( 'tgbot_message', function( $bot, $user_id, $msg ) {\n    if ( $msg-&gt;type === 'text' ) {\n        $bot-&gt;send_message( 'You said: ' . esc_html( $msg-&gt;text ) );\n    }\n}, 10, 3 );\n<\/code><\/pre>\n\n<h3>External Services<\/h3>\n\n<p>This plugin communicates with the <strong>Telegram Bot API<\/strong> (api.telegram.org) to operate a Telegram bot connected to your WordPress site.<\/p>\n\n<p><strong>What the service is:<\/strong> Telegram Bot API is a third-party service by Telegram FZ-LLC that allows applications to send and receive messages through Telegram bots.<\/p>\n\n<p><strong>What data is sent and when:<\/strong>\n* Bot token \u2014 sent with every API request to authenticate the bot.\n* Chat ID \u2014 sent when delivering messages to a specific user.\n* Message text and media files \u2014 sent when the bot responds to users.\n* Incoming updates (messages, commands, files) \u2014 received from Telegram via webhook (HTTP POST from Telegram to your site) or polling (your site requests updates from Telegram periodically via WP-Cron).<\/p>\n\n<p>No data is sent to Telegram unless the bot is enabled and a valid token is configured.<\/p>\n\n<p><strong>Telegram Privacy Policy:<\/strong> https:\/\/telegram.org\/privacy\n<strong>Telegram Terms of Service:<\/strong> https:\/\/telegram.org\/tos<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>makarski-bot-connector-for-telegram<\/code> folder to <code>\/wp-content\/plugins\/<\/code><\/li>\n<li>Activate the plugin via <strong>Plugins<\/strong> in WordPress admin<\/li>\n<li>Go to <strong>Telegram Bot \u2192 Settings<\/strong><\/li>\n<li>Enter your bot token (get one from <a href=\"https:\/\/t.me\/BotFather\">@BotFather<\/a>)<\/li>\n<li>Choose connection mode:\n\n<ul>\n<li><strong>Webhook<\/strong> \u2014 paste your site's HTTPS URL, click <em>Set Webhook<\/em>. Requires a public HTTPS URL.<\/li>\n<li><strong>Polling<\/strong> \u2014 no public URL needed. The bot polls Telegram via WP-Cron. Works on localhost.<\/li>\n<\/ul><\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20work%20on%20localhost%3F\"><h3>Does this work on localhost?<\/h3><\/dt>\n<dd><p>Yes \u2014 use <strong>Polling<\/strong> mode. Telegram cannot reach localhost for webhooks, but polling works anywhere.<\/p><\/dd>\n<dt id=\"what%20php%20version%20is%20required%3F\"><h3>What PHP version is required?<\/h3><\/dt>\n<dd><p>PHP 8.0 or higher. PHP 8.1+ recommended.<\/p><\/dd>\n<dt id=\"can%20i%20use%20this%20with%20shared%20hosting%3F\"><h3>Can I use this with shared hosting?<\/h3><\/dt>\n<dd><p>Yes. Tested on Orangehost and similar shared environments. Use Polling mode if outgoing HTTPS connections are restricted, or configure <code>ALTERNATE_WP_CRON<\/code> if WP-Cron has issues.<\/p><\/dd>\n<dt id=\"how%20do%20i%20handle%20multiple%20files%20sent%20at%20once%20%28media%20groups%29%3F\"><h3>How do I handle multiple files sent at once (media groups)?<\/h3><\/dt>\n<dd><p>Each file in a Telegram album arrives as a separate <code>tgbot_message<\/code> action with <code>has_media_group = true<\/code> and the same <code>media_group_id<\/code>. Handle each file individually or buffer them yourself using <code>media_group_id<\/code> as the grouping key.<\/p><\/dd>\n<dt id=\"is%20%60tgbot_process_multimedia_message%60%20still%20supported%3F\"><h3>Is `tgbot_process_multimedia_message` still supported?<\/h3><\/dt>\n<dd><p>Yes, as a deprecated alias for <code>tgbot_message<\/code>. Migrate to <code>tgbot_message<\/code> \u2014 the signature is identical.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.3.5<\/h4>\n\n<ul>\n<li>New Analytics admin page (Telegram Bot \u2192 Analytics) with tabs: Overview, Commands, Delivery (blocked chats + failed sends), Sources (first-touch acquisition from <code>?start=<\/code> deep links), Languages (arrival language_code), Referrals<\/li>\n<li>New analytics tables (<code>tgbot_users<\/code>, <code>tgbot_commands<\/code>, <code>tgbot_deliveries<\/code>, <code>tgbot_referrals<\/code>) filled automatically by the connector; existing bot users are back-filled on upgrade<\/li>\n<li>Blocked-chat detection: a permanent Telegram refusal (\"blocked by the user\", \"user is deactivated\", \"chat not found\") stamps <code>blocked_at<\/code>; the next incoming update clears it<\/li>\n<li>Built-in referral tracking via <code>?start=ref_&lt;code&gt;<\/code> deep links \u2014 <code>TGBot\\Analytics::referral_code()<\/code> builds codes, the <code>tgbot_referral_completed<\/code> action lets your plugin grant rewards<\/li>\n<li>New <code>tgbot_user_registered<\/code> action \u2014 fires when a WordPress user is created for a new Telegram chat<\/li>\n<li>Tab API for consumer plugins: the <code>tgbot_analytics_tabs<\/code> filter plus public rendering helpers <code>AdminAnalytics::card()<\/code> \/ <code>cards()<\/code> \/ <code>table()<\/code><\/li>\n<li>New Documentation admin page (Telegram Bot \u2192 Documentation) \u2014 the full developer manual rendered in wp-admin, with a GitHub link<\/li>\n<\/ul>\n\n<h4>0.3.4<\/h4>\n\n<ul>\n<li>Compatibility: tested up to WordPress 7.1<\/li>\n<li><strong>Privacy fix:<\/strong> WordPress users auto-created by the connector for Telegram chats are no longer exposed on public site surfaces. Before this fix the author archive <code>\/author\/&lt;chat_id&gt;\/<\/code> (and <code>?author=&lt;ID&gt;<\/code>) returned 200 with the chat_id in the page title, letting anyone confirm from outside whether a given Telegram account had contacted the bot. Bot-user author archives now return a genuine 404, and bot users are excluded from the core users sitemap and the public REST users collection. Real (human) author pages are not affected. Existing bot users are marked automatically on upgrade. Opt out with <code>add_filter( 'tgbot_protect_bot_users', '__return_false' )<\/code>.<\/li>\n<li>BotApi: <code>send_message()<\/code>, <code>send_plain_message()<\/code>, <code>send_markdown_message()<\/code> auto-split text longer than the Telegram limit (4096 UTF-16 code units) into several messages \u2014 split prefers paragraph, then line, then word boundaries; HTML tags left open at a boundary are closed and re-opened so every chunk stays valid; <code>reply_markup<\/code> is attached to the last chunk. Previously such messages were rejected by Telegram (\"message is too long\") and silently lost.<\/li>\n<li>Broadcast admin UI: the \"HTML\" format works now \u2014 message text was run through <code>sanitize_textarea_field()<\/code>, which strips all tags, so HTML broadcasts arrived unformatted; HTML messages are now sanitized with <code>wp_kses()<\/code> against the Telegram-supported tag whitelist<\/li>\n<li>Fix: empty \"Date\" column in the user-profile Broadcast History for pending\/failed rows (<code>job_created<\/code> SQL alias was missing)<\/li>\n<li>The \"Enable bot\" toggle now also gates OUTGOING messages: while the bot is disabled, all user-facing API calls (send<em>\/edit<\/em>\/delete<em>\/forward<\/em>\/copy<em>\/answer<\/em>\/pin*) are suppressed and return <code>ok = false<\/code> with a distinguishable <code>tgbot_disabled = true<\/code> property; administrative calls (getMe, webhook management, getUpdates, setMyCommands, refunds) keep working. New helper <code>tgbot_can_send()<\/code> (filterable via <code>tgbot_can_send<\/code>) is the single source of truth for consumer plugins with their own sending paths.<\/li>\n<\/ul>\n\n<h4>0.3.3<\/h4>\n\n<ul>\n<li>BotApi: new <code>get_chat_member()<\/code> method \u2014 returns ChatMember object (status: creator, administrator, member, restricted, left, kicked); returns null on failure<\/li>\n<li>BotApi: <code>update_chat_id()<\/code> now also reads <code>my_chat_member-&gt;chat-&gt;id<\/code> \u2014 enables processing of bot-added-to-group updates<\/li>\n<li>ProcessMessages: new <code>tgbot_my_chat_member<\/code> action hook \u2014 fires when the bot is added to or removed from a group, passes (Bot $bot, int $group_wp_user_id, object $mch)<\/li>\n<li>BotApi: <code>send_photo()<\/code> accepts new optional <code>$reply_markup<\/code> parameter \u2014 send an image with inline buttons in one message<\/li>\n<li>Settings: webhook endpoint is normalized on save (slashes trimmed, invalid characters stripped) \u2014 a trailing slash used to silently break the rewrite rule so the webhook returned 404<\/li>\n<li>Fix: an empty endpoint no longer registers a rewrite rule that hijacks the homepage<\/li>\n<\/ul>\n\n<h4>0.3.2<\/h4>\n\n<ul>\n<li>BotApi: fixed <code>update_chat_id()<\/code> \u2014 replaced <code>absint()<\/code> with <code>intval()<\/code> so negative group chat IDs are preserved correctly (group support)<\/li>\n<li>BotApi: <code>send_message()<\/code> accepts new optional <code>$reply_to_message_id<\/code> parameter \u2014 sends the reply using Bot API 7.0+ <code>reply_parameters<\/code><\/li>\n<li>BotApi: new <code>get_me()<\/code> method \u2014 fetches bot info via <code>getMe<\/code> and caches per-token with a 24-hour transient<\/li>\n<li>BotApi \/ Bot: <code>run_command()<\/code> parses the command parameter \u2014 <code>\/start payload<\/code> sets <code>$bot-&gt;command_param = 'payload'<\/code> for use in command callbacks; max command+param length increased from 100 to 200<\/li>\n<\/ul>\n\n<h4>0.3.1<\/h4>\n\n<ul>\n<li>Broadcast API: new <code>campaign_key<\/code> column for deduplication; new <code>tgbot_broadcast()<\/code> helper for programmatic broadcasts from child plugins<\/li>\n<li>Audience registry: <code>tgbot_audiences<\/code> filter lets child plugins register named recipient segments; Broadcast UI shows a segment selector<\/li>\n<li>Locale mapping: added <code>uk<\/code> \u2192 <code>uk_UA<\/code> locale code<\/li>\n<\/ul>\n\n<h4>0.3.0<\/h4>\n\n<ul>\n<li>New Broadcast feature: send messages to WordPress users with Telegram usernames from a dedicated admin page (Telegram Bot \u2192 Broadcast)<\/li>\n<li>Per-locale message composition \u2014 write separate texts for each language used by your users<\/li>\n<li>Message format selector: Plain text, HTML, or MarkdownV2<\/li>\n<li>Cron-batched delivery (200 messages\/batch, ~20 msg\/sec) \u2014 safe for large user bases without blocking the site<\/li>\n<li>Real-time progress bar with sent\/failed counts and estimated time remaining<\/li>\n<li>Broadcast history table on the Broadcast page; per-user broadcast history on the user profile page<\/li>\n<li>New top-level \"Telegram Bot\" admin menu with Settings and Broadcast subpages<\/li>\n<li>New BotApi method: <code>send_plain_message()<\/code> \u2014 send a message without parse_mode<\/li>\n<li>Refactored broadcast admin code into TGBot\\AdminBroadcast class for consistency<\/li>\n<\/ul>\n\n<h4>0.2.43<\/h4>\n\n<ul>\n<li>Auto-generate webhook secret on plugin activation so the mandatory secret check always has a value<\/li>\n<li>Fixed incoming message type detection: reuse already-parsed request object instead of re-calling get_request()<\/li>\n<\/ul>\n\n<h4>0.2.42<\/h4>\n\n<ul>\n<li>Webhook secret is now required: all requests without a valid X-Telegram-Bot-Api-Secret-Token header are rejected<\/li>\n<li>Sanitize incoming text fields (message text, caption, callback data) before dispatching to action hooks<\/li>\n<li>Validate update_id presence after JSON decode<\/li>\n<li>Replaced direct curl in send_multipart_request() with wp_remote_post() + http_api_curl hook<\/li>\n<\/ul>\n\n<h4>0.2.41<\/h4>\n\n<ul>\n<li>Renamed plugin folder and main file to match the approved WordPress.org slug <code>makarski-bot-connector-for-telegram<\/code><\/li>\n<\/ul>\n\n<h4>0.2.40<\/h4>\n\n<ul>\n<li>Webhook secret token support (<code>X-Telegram-Bot-Api-Secret-Token<\/code> header validation)<\/li>\n<li>Input sanitization improvements: <code>absint()<\/code> for chat_id, <code>sanitize_textarea_field()<\/code> for text in BotApi<\/li>\n<li><code>Core::set_current_user()<\/code> hardened with <code>get_userdata()<\/code> check and <code>absint()<\/code><\/li>\n<li>Added <code>== External Services ==<\/code> section to readme.txt<\/li>\n<\/ul>\n\n<h4>0.2.30<\/h4>\n\n<ul>\n<li>Renamed <code>tgbot_process_multimedia_message<\/code> to <code>tgbot_message<\/code>; added deprecated alias for backward compatibility<\/li>\n<li>Added <code>tgbot_raw_message<\/code> hook for advanced use cases<\/li>\n<li>Added <code>media_group_id<\/code> field to normalized message object<\/li>\n<\/ul>\n\n<h4>0.2.28<\/h4>\n\n<ul>\n<li>Fixed PHP 8.5 deprecation: removed <code>curl_close()<\/code> (no-op since PHP 8.0)<\/li>\n<li>Fixed implicit nullable parameter in <code>send_document()<\/code><\/li>\n<\/ul>\n\n<h4>0.2.27<\/h4>\n\n<ul>\n<li>Added 11 new BotApi methods: <code>send_chat_action<\/code>, <code>send_audio<\/code>, <code>send_voice<\/code>, <code>send_video<\/code>, <code>send_animation<\/code>, <code>forward_message<\/code>, <code>copy_message<\/code>, <code>send_location<\/code>, <code>delete_messages<\/code>, <code>set_my_commands<\/code>, <code>refund_star_payment<\/code><\/li>\n<\/ul>\n\n<h4>0.2.26<\/h4>\n\n<ul>\n<li>Fixed callback_query commands (inline buttons) not dispatching in polling mode<\/li>\n<\/ul>\n\n<h4>0.2.25<\/h4>\n\n<ul>\n<li>Auto-created user email now uses <code>tg-{chat_id}@{site_domain}<\/code> instead of <code>{id}@example.com<\/code><\/li>\n<\/ul>\n\n<h4>0.2.22 \u2013 0.2.24<\/h4>\n\n<ul>\n<li>Fixed polling reschedule logic: moved to <code>sanitize_callback<\/code> so Save always applies mode even without settings change<\/li>\n<li>Removed debug logging from production code<\/li>\n<\/ul>\n\n<h4>0.2.18 \u2013 0.2.21<\/h4>\n\n<ul>\n<li>Fixed textdomain loading order (PHP notice in WP 6.7+)<\/li>\n<li>Fixed <code>finish_request()<\/code> header order for correct webhook response<\/li>\n<li>Fixed polling cron scheduling bugs (namespace, <code>add_option<\/code> hook, missing cron detection)<\/li>\n<\/ul>\n\n<h4>0.2.17<\/h4>\n\n<ul>\n<li>Fixed polling namespace bug (<code>\\BotApi<\/code> \u2192 <code>BotApi<\/code>)<\/li>\n<li>Added error logging to <code>wp_schedule_event<\/code> and polling tick<\/li>\n<\/ul>\n\n<h4>0.1.0 \u2013 0.2.16<\/h4>\n\n<ul>\n<li>Initial implementation: webhook management, polling mode, user auto-creation, Stars payments, command routing, internationalization<\/li>\n<\/ul>","raw_excerpt":"Connect WordPress to a Telegram bot. Handle messages, commands, payments and build custom bot logic using WordPress action hooks.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/en-za.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/320755","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/en-za.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/en-za.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/en-za.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=320755"}],"author":[{"embeddable":true,"href":"https:\/\/en-za.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/makaravich"}],"wp:attachment":[{"href":"https:\/\/en-za.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=320755"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/en-za.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=320755"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/en-za.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=320755"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/en-za.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=320755"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/en-za.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=320755"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/en-za.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=320755"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}