{"id":27948,"date":"2014-02-23T23:07:26","date_gmt":"2014-02-23T23:07:26","guid":{"rendered":"https:\/\/wordpress.org\/plugins-wp\/my-newsletter\/"},"modified":"2026-02-26T21:00:34","modified_gmt":"2026-02-26T21:00:34","slug":"my-newsletter","status":"publish","type":"plugin","link":"https:\/\/lmo.wordpress.org\/plugins\/my-newsletter\/","author":10295118,"comment_status":"closed","ping_status":"closed","template":"","meta":{"_crdt_document":"","version":"2.0.2","stable_tag":"2.0.2","tested":"6.9.4","requires":"5.8","requires_php":"7.4","requires_plugins":null,"header_name":"My Newsletter","header_author":"Radovan Georgijevic","header_description":"","assets_banners_color":"dadada","last_updated":"2026-02-26 21:00:34","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/wordpress.org\/plugins\/my-newsletter\/","header_author_uri":"https:\/\/radovangeorgijevic.com","rating":5,"author_block_rating":0,"active_installs":10,"downloads":4163,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.0.7":{"tag":"0.0.7","author":"Georgijevic","date":"2014-02-23 23:20:01"},"0.0.8":{"tag":"0.0.8","author":"Georgijevic","date":"2014-02-23 23:29:17"},"0.0.9":{"tag":"0.0.9","author":"Georgijevic","date":"2014-02-24 00:05:34"},"0.1.0":{"tag":"0.1.0","author":"Georgijevic","date":"2014-02-24 07:53:03"},"0.1.1":{"tag":"0.1.1","author":"Georgijevic","date":"2014-03-20 01:14:17"},"0.1.2":{"tag":"0.1.2","author":"Georgijevic","date":"2014-03-20 01:29:44"},"0.1.3":{"tag":"0.1.3","author":"Georgijevic","date":"2014-09-26 21:38:14"},"1.0.0":{"tag":"1.0.0","author":"Georgijevic","date":"2014-09-27 07:54:06"},"1.0.1":{"tag":"1.0.1","author":"Georgijevic","date":"2014-09-27 07:40:36"},"2.0.2":{"tag":"2.0.2","author":"Georgijevic","date":"2026-02-26 21:00:34"}},"upgrade_notice":{"2.0.2":"<p>Repository review compatibility update: naming\/metadata cleanup and remaining Plugin Check fixes.<\/p>","2.0.1":"<p>Maintenance and compatibility release focused on Plugin Check issues, code hygiene, and repository readiness.<\/p>"},"ratings":{"1":0,"2":0,"3":0,"4":0,"5":"3"},"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3470678,"resolution":"128x128","location":"assets","locale":""},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3470678,"resolution":"256x256","location":"assets","locale":""}},"assets_banners":{"banner-1544x500.png":{"filename":"banner-1544x500.png","revision":3470678,"resolution":"1544x500","location":"assets","locale":""},"banner-772x250.png":{"filename":"banner-772x250.png","revision":3470678,"resolution":"772x250","location":"assets","locale":""}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.0.7","0.0.8","0.0.9","0.1.0","0.1.1","0.1.2","0.1.3","1.0.0","1.0.1","2.0.2"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Campaign composer screen","2":"Settings screen","3":"Campaign progress table"},"jetpack_post_was_ever_published":false},"plugin_section":[],"plugin_tags":[25224,3805,267,455,1917],"plugin_category":[42],"plugin_contributors":[88496],"plugin_business_model":[],"class_list":["post-27948","plugin","type-plugin","status-publish","hentry","plugin_tags-bulk-email","plugin_tags-commenters","plugin_tags-email","plugin_tags-newsletter","plugin_tags-users","plugin_category-contact-forms","plugin_contributors-georgijevic","plugin_committers-georgijevic"],"banners":{"banner":"https:\/\/ps.w.org\/my-newsletter\/assets\/banner-772x250.png?rev=3470678","banner_2x":"https:\/\/ps.w.org\/my-newsletter\/assets\/banner-1544x500.png?rev=3470678","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/my-newsletter\/assets\/icon-128x128.png?rev=3470678","icon_2x":"https:\/\/ps.w.org\/my-newsletter\/assets\/icon-256x256.png?rev=3470678","generated":false},"screenshots":[],"raw_content":"<!--section=description-->\n<p>My Newsletter is a lightweight newsletter plugin focused on a practical use case many site owners need immediately:<\/p>\n\n<ul>\n<li>send a campaign to WordPress users,<\/li>\n<li>send a campaign to commenters,<\/li>\n<li>optionally target commenters from a specific post,<\/li>\n<li>queue the campaign and process it in the background,<\/li>\n<li>include unsubscribe links in every message,<\/li>\n<li>track basic campaign progress in the admin area.<\/li>\n<\/ul>\n\n<p>This plugin is intentionally simple and WordPress-native. It relies on <code>wp_mail()<\/code> for sending and WP-Cron for queue processing, which makes it easy to install and use on most shared hosting environments.<\/p>\n\n<h4>Core functionality<\/h4>\n\n<ul>\n<li><p><strong>Campaign composer (admin screen)<\/strong><\/p>\n\n<ul>\n<li>Create a newsletter subject and HTML content.<\/li>\n<li>Use the WordPress editor for message body content.<\/li>\n<li>Choose recipient source:<\/li>\n<li>Users + Commenters<\/li>\n<li>Users only<\/li>\n<li>Commenters only<\/li>\n<li>Commenters on a specific post<\/li>\n<\/ul><\/li>\n<li><p><strong>Background queue processing<\/strong><\/p>\n\n<ul>\n<li>Recipients are queued in a custom plugin table.<\/li>\n<li>Sending runs in batches through WP-Cron (instead of trying to send everything in one browser request).<\/li>\n<li>Reduces the risk of timeouts and broken sends on slower hosting.<\/li>\n<\/ul><\/li>\n<li><p><strong>Test email before full campaign<\/strong><\/p>\n\n<ul>\n<li>Send a test message to any email address from the composer screen.<\/li>\n<li>Uses the same rendering path and unsubscribe footer logic as real sends.<\/li>\n<\/ul><\/li>\n<li><p><strong>Secure unsubscribe links<\/strong><\/p>\n\n<ul>\n<li>Every email can include an unsubscribe URL.<\/li>\n<li>Unsubscribe tokens use an HMAC-based signature (derived from WordPress salts).<\/li>\n<li>Unsubscribed addresses are stored in a dedicated plugin table and skipped in future campaigns.<\/li>\n<\/ul><\/li>\n<li><p><strong>Template variables (placeholders)<\/strong><\/p>\n\n<ul>\n<li><code>{{site_name}}<\/code><\/li>\n<li><code>{{site_url}}<\/code><\/li>\n<li><code>{{recipient_name}}<\/code><\/li>\n<li><code>{{recipient_email}}<\/code><\/li>\n<li><code>{{unsubscribe_url}}<\/code><\/li>\n<\/ul><\/li>\n<li><p><strong>Settings screen<\/strong><\/p>\n\n<ul>\n<li>From name<\/li>\n<li>From email<\/li>\n<li>Reply-To (optional)<\/li>\n<li>Max emails per cron run (batch size)<\/li>\n<li>Footer HTML (appended to outgoing emails)<\/li>\n<\/ul><\/li>\n<li><p><strong>Basic campaign tracking<\/strong><\/p>\n\n<ul>\n<li>Shows recent campaigns in admin.<\/li>\n<li>Displays queue progress (total \/ sent \/ failed \/ queued).<\/li>\n<\/ul><\/li>\n<\/ul>\n\n<h4>How sending works (important)<\/h4>\n\n<p>This plugin uses <strong>WP-Cron<\/strong>. WP-Cron runs when your site receives traffic. That means:<\/p>\n\n<ul>\n<li>On active sites, sending progresses regularly.<\/li>\n<li>On low-traffic sites, sending may be slower.<\/li>\n<\/ul>\n\n<p>For production use, it is recommended to configure a real server cron that triggers <code>wp-cron.php<\/code> periodically.<\/p>\n\n<h4>Email deliverability note<\/h4>\n\n<p>My Newsletter sends through <code>wp_mail()<\/code>. Actual delivery quality depends on your hosting and email configuration.<\/p>\n\n<p>For best results, use:<\/p>\n\n<ul>\n<li>a real SMTP provider,<\/li>\n<li>a verified sender domain,<\/li>\n<li>properly configured SPF \/ DKIM \/ DMARC,<\/li>\n<li>a valid <code>From<\/code> address on your domain.<\/li>\n<\/ul>\n\n<h4>Data storage<\/h4>\n\n<p>The plugin creates two custom tables:<\/p>\n\n<ul>\n<li><code>wpnl_queue<\/code> \u2013 campaign queue and send status<\/li>\n<li><code>wpnl_unsub<\/code> \u2013 unsubscribed email addresses<\/li>\n<\/ul>\n\n<p>On uninstall, those plugin tables and plugin options are removed.<\/p>\n\n<!--section=installation-->\n<h4>Standard WordPress upload (ZIP)<\/h4>\n\n<ol>\n<li>In WordPress admin, go to <strong>Plugins \u2192 Add New \u2192 Upload Plugin<\/strong>.<\/li>\n<li>Upload the plugin ZIP package.<\/li>\n<li>Activate <strong>My Newsletter<\/strong>.<\/li>\n<li>Go to <strong>My Newsletter \u2192 Settings<\/strong> and configure sender details.<\/li>\n<li>Create your first campaign in <strong>My Newsletter<\/strong>.<\/li>\n<\/ol>\n\n<h4>Manual installation<\/h4>\n\n<ol>\n<li>Upload the <code>my-newsletter<\/code> folder to <code>\/wp-content\/plugins\/<\/code>.<\/li>\n<li>Activate the plugin in <strong>Plugins<\/strong>.<\/li>\n<li>Configure settings and send a test email first.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20plugin%20use%20double%20opt-in%3F\"><h3>Does this plugin use double opt-in?<\/h3><\/dt>\n<dd><p>Not yet. Version 2.x focuses on admin-triggered newsletter sending, background queue processing, and secure unsubscribe handling.<\/p><\/dd>\n<dt id=\"why%20is%20my%20campaign%20sending%20slowly%3F\"><h3>Why is my campaign sending slowly?<\/h3><\/dt>\n<dd><p>Because WP-Cron is traffic based. If your site has little traffic, cron jobs run less frequently. Configure a real cron job for more reliable processing.<\/p><\/dd>\n<dt id=\"can%20i%20send%20to%20only%20commenters%20from%20one%20post%3F\"><h3>Can I send to only commenters from one post?<\/h3><\/dt>\n<dd><p>Yes. Choose <strong>Commenters on a specific post<\/strong> and select the post in the composer screen.<\/p><\/dd>\n<dt id=\"does%20it%20track%20opens%2Fclicks%3F\"><h3>Does it track opens\/clicks?<\/h3><\/dt>\n<dd><p>No. This plugin tracks send queue progress only (queued \/ sent \/ failed). It does not include analytics pixels or click tracking.<\/p><\/dd>\n<dt id=\"will%20unsubscribed%20addresses%20receive%20future%20campaigns%3F\"><h3>Will unsubscribed addresses receive future campaigns?<\/h3><\/dt>\n<dd><p>No. The plugin checks the unsubscribe table before queuing recipients.<\/p><\/dd>\n<dt id=\"what%20if%20%60wp_mail%28%29%60%20fails%3F\"><h3>What if `wp_mail()` fails?<\/h3><\/dt>\n<dd><p>Failed sends are marked as failed in the queue. For reliable sending, configure SMTP and verify the sender domain.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.0.2<\/h4>\n\n<ul>\n<li>Fixed remaining Plugin Check errors (escaping, discouraged functions, and <code>wp_parse_url()<\/code> compatibility)<\/li>\n<li>Added <code>languages<\/code> directory to satisfy plugin header <code>Domain Path<\/code><\/li>\n<li>Updated readme metadata (<code>Tested up to<\/code>, tags) for repository review<\/li>\n<li>Cleaned uninstall routine variable prefixes and PHPCS annotations<\/li>\n<\/ul>\n\n<h4>2.0.1<\/h4>\n\n<ul>\n<li>Plugin Check compatibility pass and cleanup<\/li>\n<li>Unified plugin text domain to <code>my-newsletter<\/code><\/li>\n<li>Cleaned plugin header metadata<\/li>\n<li>Replaced anonymous PHP callbacks with named methods<\/li>\n<li>Moved textdomain loading to proper hook flow<\/li>\n<li>Hardened AJAX handlers (nonce verification, capability checks, input unslashing\/sanitization)<\/li>\n<li>Improved PHPCS annotations for custom DB table queries and uninstall routine<\/li>\n<li>Added repository placeholder assets (icons\/banners)<\/li>\n<li>Bundled improved readme documentation<\/li>\n<\/ul>\n\n<h4>2.0.0<\/h4>\n\n<ul>\n<li>Modernized rewrite \/ rework of the plugin structure<\/li>\n<li>Added background queue processing via WP-Cron<\/li>\n<li>Added secure unsubscribe endpoint and token validation<\/li>\n<li>Added settings screen and sender\/footer configuration<\/li>\n<li>Added test email action<\/li>\n<li>Added campaign progress reporting<\/li>\n<\/ul>","raw_excerpt":"Send newsletters to WordPress users and commenters with background queue processing, test email sending, and secure unsubscribe links.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/27948","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=27948"}],"author":[{"embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/georgijevic"}],"wp:attachment":[{"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=27948"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=27948"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=27948"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=27948"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=27948"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/lmo.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=27948"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}