Si gestionas una web con usuarios registrados en WordPress, una de las mejores formas de mantenerlos comprometidos es notificarles cuando publicas un nuevo artículo o actualizas contenido. Sin embargo, esto puede ser un reto si tienes un gran volumen de usuarios y estás utilizando un hosting compartido, donde los límites de envío de correos pueden restringir tu capacidad de comunicación.
En este artículo, te explico cómo implementar un sistema que envía notificaciones automáticas por correo a tus usuarios registrados, les permite darse de baja fácilmente si no desean recibir más correos y cómo superar las limitaciones de un hosting compartido. Este código es ideal para blogueros que están comenzando y tienen entre 1 y 300 usuarios registrados, pero también veremos soluciones para quienes tienen una base de usuarios más amplia.
¿Qué hace este código?
El código que discutimos anteriormente es una solución completa para notificar a tus usuarios sobre nuevas publicaciones o actualizaciones en tu WordPress. A continuación, explico en detalle cada funcionalidad del código y cómo puede ayudarte a mejorar la comunicación con tus usuarios.
1. Añadir un metabox al editor de entradas
El código añade un metabox en el editor de publicaciones de WordPress, donde puedes decidir si deseas notificar a tus usuarios sobre el artículo al momento de guardarlo.
¿Cómo funciona?
Este metabox incluye una casilla para activar el envío de correos y un editor WYSIWYG donde puedes escribir un mensaje personalizado para incluir en el correo. Puedes personalizar los correos utilizando etiquetas como {nombre_usuario} para incluir automáticamente el nombre del usuario en el mensaje.
Beneficio: Puedes gestionar de manera manual y específica qué artículos deseas notificar, añadiendo un toque personalizado que hace que los correos sean más relevantes y atractivos para tus usuarios.

2. Guardar el contenido personalizado
Cuando guardas o actualizas una publicación, el código almacena el contenido del mensaje personalizado en los metadatos de la publicación. Esto permite que cada publicación tenga un mensaje único que será enviado a los usuarios registrados.
¿Cómo lo hace?
Usa update_post_meta para guardar el mensaje en el metadato _custom_email_message. Este mensaje es recuperado más tarde para incluirlo en los correos enviados a los usuarios.
Beneficio: Este enfoque asegura que puedas adaptar el contenido de cada correo según el artículo que estés publicando, lo que aumenta la relevancia del mensaje.
3. Enviar correos automáticos a los usuarios registrados
Si marcas la casilla para enviar correos al guardar un artículo, el sistema realiza las siguientes acciones:
- Recupera a todos los usuarios registrados en tu WordPress.
- Verifica si un usuario está dado de baja (almacenado en el metadato
has_unsubscribed) y los excluye del envío. - Personaliza cada correo con el nombre del usuario y el contenido del mensaje.
- Envía el correo utilizando
wp_mail.
Beneficio: Este sistema automatiza la tarea de notificar a tus usuarios, asegurándote de que cada correo sea relevante y personalizado.
4. Enlace para darse de baja
Cada correo enviado incluye un enlace único que permite a los usuarios darse de baja de futuras notificaciones. Al hacer clic en el enlace, el sistema actualiza el estado del usuario en la base de datos, evitando que reciba futuros correos.
Beneficio: Cumples con las normativas de privacidad, como el RGPD, y ofreces a los usuarios una manera sencilla de gestionar sus preferencias de comunicación.

5. Reactivación de suscripción
Si un usuario se da de baja por error, puede reactivar su suscripción a través de otro enlace que se proporciona en la página de confirmación de baja. Esto permite a los usuarios volver a recibir notificaciones si cambian de opinión.
Beneficio: Proporcionas flexibilidad a los usuarios, mejorando su experiencia y la percepción de tu servicio.

6. Gestión desde el perfil de usuario
El código también añade un campo en el perfil de usuario donde el administrador puede activar o desactivar la suscripción a los correos. Además desde la página de todos los usuarios el administrador podrá ver de forma rápida quien sigue con la cuenta activa y quien se ha dado de baja
Beneficio: Ofreces un control directo sobre el estado de suscripción, lo que resulta útil para gestionar usuarios específicos.

7. Gestión masiva desde la administración
En la lista de usuarios de WordPress, se añade una columna que muestra si cada usuario está activo o dado de baja. También se incluyen opciones para realizar acciones masivas, como activar o desactivar múltiples usuarios a la vez.
Beneficio: Facilita la administración de grandes volúmenes de usuarios de manera eficiente, ahorrando tiempo y esfuerzo.

¿Por qué este código es ideal para quienes empiezan?
Este código es perfecto para blogueros que están comenzando y tienen una base de entre 1 y 300 usuarios registrados. En este caso, los límites de envío de correos en un hosting compartido suelen ser suficientes para manejar este volumen. Además:
- No necesitas invertir en servicios adicionales, ya que puedes usar el SMTP configurado con tu cuenta de correo del hosting.
- El sistema es fácil de implementar y administrar, lo que lo hace ideal para quienes buscan una solución práctica y funcional.
¿Qué pasa si tienes más de 300 usuarios?
Si tienes más de 300 usuarios, los límites de envío de correos en un hosting compartido pueden ser un problema. Por ejemplo:
- Webempresa: Permite entre 300 y 1,200 correos por hora según el plan.
- Banahosting: Límite de 400 correos por hora.
- Hostinger: Entre 300 y 3,000 correos por día, dependiendo del plan.
Superar estos límites puede ocasionar que algunos correos no se envíen o que tu cuenta sea bloqueada temporalmente.
Soluciones para manejar un gran volumen de usuarios
- Usar un servicio SMTP externo
Servicios como SendGrid, Mailgun o Amazon SES son ideales para manejar grandes volúmenes de correos. Estos servicios ofrecen:- Altos límites de envío (por ejemplo, Amazon SES permite miles de correos diarios).
- Reputación confiable, lo que reduce el riesgo de que tus correos terminen en spam.
- Precios accesibles: Amazon SES, por ejemplo, cuesta $0.10 por cada 1,000 correos enviados.
Puedes conectar estos servicios con WordPress utilizando el plugin WP Mail SMTP, que facilita la configuración.
- Escalonar los envíos
Si decides seguir usando un hosting compartido, puedes escalonar los envíos para cumplir con los límites del servidor. Por ejemplo:- Envía 300 correos por hora.
- Completa el envío a 3,000 usuarios en 10 horas.
- Optimizar las configuraciones del dominio
Configura registros SPF, DKIM y DMARC para autenticar tus correos y mejorar la tasa de entrega. Esto también ayuda a reducir la posibilidad de que los correos sean marcados como spam.
Ventajas del VPS y Servidor Dedicado para el Envío de Correos Masivos
Cuando necesitas enviar grandes volúmenes de correos electrónicos, un VPS o un servidor dedicado ofrece claras ventajas frente al hosting compartido. Estas soluciones son ideales para manejar miles de usuarios sin las limitaciones de recursos y conexiones que afectan a los servidores compartidos.
1. Recursos Dedicados
En un VPS, tienes recursos asignados exclusivamente para ti, mientras que en un servidor dedicado, todo el hardware es tuyo. Esto significa que puedes manejar envíos masivos sin preocuparte por la competencia con otros usuarios.
2. Control Completo
Puedes configurar tu propio servidor SMTP o integrar servicios externos como Amazon SES. Además, puedes optimizar parámetros como conexiones simultáneas y configurar SPF, DKIM y DMARC para evitar que tus correos terminen en spam.
3. Reputación de la IP
Un VPS o dedicado suele incluir una IP exclusiva, lo que evita los problemas de reputación causados por otros usuarios (comunes en hosting compartido). Una buena reputación mejora la tasa de entrega de tus correos.
4. Escalabilidad
Ambas opciones permiten aumentar recursos según crezcan tus necesidades. En un VPS, es tan sencillo como ampliar CPU o RAM; en un servidor dedicado, puedes agregar hardware adicional.
5. Ideal para Soluciones Híbridas
Un VPS o dedicado combinado con un servicio SMTP externo es la solución perfecta. El servidor gestiona las solicitudes, mientras el servicio SMTP (SendGrid, Brevo, etc.) se encarga de la entrega, evitando sobrecargas en tu servidor.
¿Qué elegir?
- VPS: Ideal para 300-5,000 usuarios. Más económico y escalable.
- Servidor Dedicado: Perfecto para más de 5,000 usuarios con necesidades avanzadas.
Ambas opciones ofrecen la robustez necesaria para manejar grandes volúmenes de correos, asegurando un envío eficiente y confiable.
El siguiente código tienes que agregarlo en el functions.php de tu tema hijo o utilizar un plugin como CODE SNIPPETS.
// Añadir un metabox en el editor de entradas
function add_email_checkbox_metabox() {
add_meta_box(
'send_email_checkbox_metabox',
'Enviar artículo por correo',
'render_email_checkbox_metabox',
'post',
'side',
'high'
);
}
add_action('add_meta_boxes', 'add_email_checkbox_metabox');
// Renderizar el checkbox y el campo WYSIWYG dentro del metabox
function render_email_checkbox_metabox($post) {
// Recuperar el contenido previo del WYSIWYG si existe
$custom_message = get_post_meta($post->ID, '_custom_email_message', true);
if (empty($custom_message)) {
$custom_message = ''; // Asegurarnos de que no sea null
}
?>
<input type="checkbox" id="send_email_checkbox" name="send_email_checkbox" value="1">
<label for="send_email_checkbox">Enviar artículo por correo al guardar</label>
<br><br>
<label for="custom_email_message">Mensaje personalizado para el correo (puedes usar {nombre_usuario} para incluir el nombre del usuario):</label>
<?php
wp_editor(
$custom_message,
'custom_email_message',
[
'textarea_name' => 'custom_email_message',
'media_buttons' => false,
'textarea_rows' => 5,
'tinymce' => true, // Habilitar TinyMCE
'quicktags' => true // Habilitar Quicktags para el editor
]
);
}
// Manejar la acción al guardar el post
function handle_email_checkbox_on_save($post_id) {
// Verificar si es un guardado automático
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// Verificar permisos
if (!current_user_can('edit_post', $post_id)) {
return;
}
// Guardar el contenido del WYSIWYG en los metadatos del post
if (isset($_POST['custom_email_message'])) {
update_post_meta($post_id, '_custom_email_message', wp_kses_post($_POST['custom_email_message']));
}
// Comprobar si se marcó el checkbox
if (isset($_POST['send_email_checkbox']) && $_POST['send_email_checkbox'] == '1') {
$post = get_post($post_id);
if ($post) {
// Obtener el contenido del WYSIWYG
$custom_message = get_post_meta($post_id, '_custom_email_message', true);
// Obtener el contenido del post
$subject = 'Artículo Nuevo/Actualizado: ' . $post->post_title;
// Obtener todos los usuarios registrados
$users = get_users(['fields' => ['user_email', 'display_name', 'ID']]);
// Enviar el correo a cada usuario
foreach ($users as $user) {
$is_unsubscribed = get_user_meta($user->ID, 'has_unsubscribed', true);
if ($is_unsubscribed) {
continue; // Saltar usuarios dados de baja
}
$personalized_message = str_replace('{nombre_usuario}', $user->display_name, $custom_message);
// Crear mensaje con información de baja
$unsubscribe_url = home_url('/?unsubscribe_user=' . $user->ID);
$article_url = get_permalink($post_id);
$message = "<div style='border: 1px solid #ccc; padding: 15px; margin-bottom: 20px; background-color: #f9f9f9;'>";
$message .= "<p style='font-size: 16px; margin-bottom: 10px;'>Si no deseas recibir más correos, haz clic en el siguiente botón:</p>";
$message .= "<a href='" . esc_url($unsubscribe_url) . "' style='display:inline-block; padding:10px 20px; background-color:#d9534f; color:white; text-decoration:none; border-radius:5px; font-size: 16px;'>Darse de Baja</a>";
$message .= "<p style='margin-top: 15px; font-size: 14px;'>Si después de darle al botón y confirmar tu baja, aún sigues recibiendo correos, escríbenos a <a href='mailto:info@miweb.com'>info@miweb.com</a>.</p>";
$message .= "<p style='margin-top: 10px; font-size: 14px;'><strong>Leer artículo completo:</strong> <a href='" . esc_url($article_url) . "'>" . esc_html($post->post_title) . "</a></p>";
$message .= "</div>";
$message .= $personalized_message ? $personalized_message . "<br><br>" : '';
$message .= $post->post_content;
wp_mail($user->user_email, $subject, $message, ['Content-Type: text/html; charset=UTF-8']);
}
}
}
}
add_action('save_post', 'handle_email_checkbox_on_save');
// Manejar el proceso de baja directamente desde el enlace del correo
function handle_direct_unsubscribe_request() {
if (isset($_GET['unsubscribe_user'])) {
$user_id = intval($_GET['unsubscribe_user']);
if (get_user_by('ID', $user_id)) {
update_user_meta($user_id, 'has_unsubscribed', true);
$resubscribe_url = home_url('/?resubscribe_user=' . $user_id);
wp_die(
'<h1>Te has dado de baja correctamente.</h1>' .
'<p>Ya no recibirás más correos de nuestra parte.</p>' .
'<p style="margin-top: 20px; font-size: 16px; color: #333;">' .
'¿Te has dado de baja por error? Puedes volver a suscribirte de inmediato haciendo clic en el siguiente botón:' .
'</p>' .
'<a href="' . esc_url($resubscribe_url) . '" style="display:inline-block; padding:10px 20px; background-color:#5cb85c; color:white; text-decoration:none; border-radius:5px; font-size:16px; margin-top:10px;">Volver a Suscribirme</a>' .
'<p style="margin-top: 20px; font-size: 14px; color: #555;">' .
'También puedes guardar el siguiente enlace para suscribirte más adelante: <br>' .
'<code>' . esc_url($resubscribe_url) . '</code>' .
'</p>' .
'<p style="margin-top: 20px; font-size: 14px;">' .
'Si tienes algún problema, puedes escribirnos a <a href="mailto:info@miweb.com">info@miweb.com</a> y solicitar tu suscripción manualmente.' .
'</p>',
'Darse de Baja',
['response' => 200]
);
} else {
wp_die('<h1>Solicitud no válida.</h1><p>No se pudo procesar tu solicitud.</p>', 'Error', ['response' => 400]);
}
}
if (isset($_GET['resubscribe_user'])) {
$user_id = intval($_GET['resubscribe_user']);
if (get_user_by('ID', $user_id)) {
delete_user_meta($user_id, 'has_unsubscribed');
wp_die(
'<h1>Te has vuelto a suscribir correctamente.</h1>' .
'<p>Gracias por volver a unirte a nuestras comunicaciones.</p>',
'Suscripción completada',
['response' => 200]
);
} else {
wp_die('<h1>Solicitud no válida.</h1><p>No se pudo procesar tu solicitud.</p>', 'Error', ['response' => 400]);
}
}
}
add_action('init', 'handle_direct_unsubscribe_request');
// Añadir un campo de radio en el perfil del usuario para dar de alta/baja
function add_subscription_status_radio_to_profile($user) {
$is_unsubscribed = get_user_meta($user->ID, 'has_unsubscribed', true);
?>
<h3>Estado de suscripción</h3>
<table class="form-table">
<tr>
<th><label for="subscription_status">Estado:</label></th>
<td>
<input type="radio" id="subscribe" name="subscription_status" value="active" <?php checked(!$is_unsubscribed); ?>>
<label for="subscribe">Activo</label><br>
<input type="radio" id="unsubscribe" name="subscription_status" value="inactive" <?php checked($is_unsubscribed); ?>>
<label for="unsubscribe">Dado de baja</label>
</td>
</tr>
</table>
<?php
}
add_action('show_user_profile', 'add_subscription_status_radio_to_profile');
add_action('edit_user_profile', 'add_subscription_status_radio_to_profile');
// Guardar el estado de suscripción cuando se actualiza el perfil
function save_subscription_status($user_id) {
if (!current_user_can('edit_user', $user_id)) {
return;
}
if (isset($_POST['subscription_status'])) {
if ($_POST['subscription_status'] === 'inactive') {
update_user_meta($user_id, 'has_unsubscribed', true);
} else {
delete_user_meta($user_id, 'has_unsubscribed');
}
}
}
add_action('personal_options_update', 'save_subscription_status');
add_action('edit_user_profile_update', 'save_subscription_status');
// Añadir una columna personalizada a la lista de usuarios
function add_subscription_status_column($columns) {
$columns['subscription_status'] = 'Estado de Suscripción';
return $columns;
}
add_filter('manage_users_columns', 'add_subscription_status_column');
// Modificar la consulta para ordenar por el estado de suscripción
function sort_by_subscription_status($query) {
if (!is_admin() || $query->get('orderby') !== 'subscription_status') {
return;
}
$query->set('meta_key', 'has_unsubscribed');
$query->set('orderby', 'meta_value');
}
add_action('pre_get_users', 'sort_by_subscription_status');
// Mostrar el estado de suscripción en la columna personalizada
function show_subscription_status_column($value, $column_name, $user_id) {
if ('subscription_status' === $column_name) {
$is_unsubscribed = get_user_meta($user_id, 'has_unsubscribed', true);
return $is_unsubscribed ? 'Dado de baja' : 'Activo';
}
return $value;
}
add_filter('manage_users_custom_column', 'show_subscription_status_column', 10, 3);
// Registrar las acciones en masa
function register_bulk_actions($bulk_actions) {
$bulk_actions['set_active'] = 'Activar usuarios';
$bulk_actions['set_inactive'] = 'Dar de baja usuarios';
return $bulk_actions;
}
add_filter('bulk_actions-users', 'register_bulk_actions');
// Manejar las acciones en masa
function handle_bulk_actions($redirect_to, $doaction, $user_ids) {
if ($doaction === 'set_active') {
foreach ($user_ids as $user_id) {
delete_user_meta($user_id, 'has_unsubscribed');
}
$redirect_to = add_query_arg('bulk_set_active', count($user_ids), $redirect_to);
}
if ($doaction === 'set_inactive') {
foreach ($user_ids as $user_id) {
update_user_meta($user_id, 'has_unsubscribed', true);
}
$redirect_to = add_query_arg('bulk_set_inactive', count($user_ids), $redirect_to);
}
return $redirect_to;
}
add_filter('handle_bulk_actions-users', 'handle_bulk_actions', 10, 3);
// Mostrar un mensaje después de completar las acciones en masa
function show_bulk_action_notices() {
if (isset($_GET['bulk_set_active'])) {
$count = intval($_GET['bulk_set_active']);
echo "<div class='updated'><p>Se activaron {$count} usuarios.</p></div>";
}
if (isset($_GET['bulk_set_inactive'])) {
$count = intval($_GET['bulk_set_inactive']);
echo "<div class='updated'><p>Se dieron de baja {$count} usuarios.</p></div>";
}
}
add_action('admin_notices', 'show_bulk_action_notices');
Lenguaje del código: PHP (php)
Conclusión
Este código es una excelente herramienta para quienes comienzan con un blog o sitio WordPress y tienen una base de usuarios pequeña o moderada. Te permite automatizar las notificaciones de manera personalizada, cumpliendo con las normativas de privacidad y mejorando la comunicación con tus usuarios.
Sin embargo, si tu base de usuarios crece, es fundamental considerar opciones más avanzadas, como un servicio SMTP externo, para garantizar un envío confiable y eficiente. Configurar un servicio como SendGrid o Amazon SES con un plugin como WP Mail SMTP te permitirá escalar tus comunicaciones sin preocupaciones.
Contáctame por WhatsApp para servicios de desarrollo personalizado, ajustes en tu tienda online o cualquier solución a medida que necesites.
➡️Haz clic aquí para contactarme por WhatsApp
Nos vemos en el siguiente tutorial.
Un saludo.




Deja tus opiniones o dudas en los comentarios.