Skip to content

Notifly in WordPress

WordPress sends almost all important events through the hook system (do_action, apply_filters). You can hook into them from a tiny mu-plugin — no admin panel, no visual editor.

  1. Create the folder wp-content/mu-plugins/ if it doesn’t exist.
  2. Put the file notifly.php there (see below).

mu-plugins are loaded automatically on every request and are not disabled by updates.

<?php
/**
* Plugin Name: Notifly notifications
* Description: Push notifications about key site events.
*/
if (!defined('ABSPATH')) exit;
if (!function_exists('notifly_send')) {
function notifly_send(string $title, string $message, int $priority = 5): void {
$url = defined('NOTIFLY_URL') ? NOTIFLY_URL : (getenv('NOTIFLY_URL') ?: '');
$token = defined('NOTIFLY_TOKEN') ? NOTIFLY_TOKEN : (getenv('NOTIFLY_TOKEN') ?: '');
if (!$url || !$token) return;
wp_remote_post("$url/message?token=$token", [
'timeout' => 5,
'headers' => ['Content-Type' => 'application/json'],
'body' => wp_json_encode([
'title' => mb_substr($title, 0, 200),
'message' => mb_substr($message, 0, 1500),
'priority' => $priority,
], JSON_UNESCAPED_UNICODE),
]);
}
}

In wp-config.php set:

define('NOTIFLY_URL', 'https://your-notifly.example.com');
define('NOTIFLY_TOKEN', 'AGdjfk_L.dKe8q');
add_action('comment_post', function ($comment_id, $approved) {
$c = get_comment($comment_id);
if (!$c) return;
$status = $approved === 1 ? 'опубликован' : ($approved === 0 ? 'на модерации' : 'спам');
notifly_send(
title: "💬 Комментарий ($status): " . wp_trim_words($c->comment_content, 8),
message: "Автор: {$c->comment_author}\n" .
"Пост: " . get_the_title($c->comment_post_ID) . "\n" .
"Текст:\n{$c->comment_content}\n\n" .
"Управление: " . admin_url("comment.php?action=editcomment&c=$comment_id"),
priority: $approved === 0 ? 6 : 4,
);
}, 10, 2);
add_action('user_register', function ($user_id) {
$u = get_userdata($user_id);
if (!$u) return;
notifly_send(
title: "👤 Новый пользователь: {$u->user_login}",
message: "Email: {$u->user_email}\n" .
"Роль: " . implode(',', $u->roles) . "\n" .
"Профиль: " . admin_url("user-edit.php?user_id=$user_id"),
priority: 4,
);
});
add_action('upgrader_process_complete', function ($upgrader, $hook_extra) {
$type = $hook_extra['type'] ?? 'unknown';
$action = $hook_extra['action'] ?? '?';
notifly_send(
title: "🔄 WordPress: $action $type",
message: "Сайт: " . home_url() . "\nДетали: " . wp_json_encode($hook_extra, JSON_UNESCAPED_UNICODE),
priority: 5,
);
}, 10, 2);
add_action('woocommerce_new_order', function ($order_id) {
$order = wc_get_order($order_id);
if (!$order) return;
$items = [];
foreach ($order->get_items() as $item) {
$items[] = "{$item->get_name()} × {$item->get_quantity()}";
}
notifly_send(
title: "🛒 Новый заказ #{$order->get_order_number()}" .
wc_price($order->get_total()),
message:
"Покупатель: {$order->get_billing_first_name()} {$order->get_billing_last_name()}\n" .
"Email: {$order->get_billing_email()}\n" .
"Телефон: {$order->get_billing_phone()}\n" .
"Способ оплаты: {$order->get_payment_method_title()}\n\n" .
"Состав:\n" . implode("\n", $items) . "\n\n" .
admin_url("post.php?post=$order_id&action=edit"),
priority: 8,
);
});

WP-cron runs on every HTTP request. If there are no requests, scheduled tasks don’t run. Set up a “canary” — a daily event that should arrive in Notifly:

register_activation_hook(__FILE__, function () {
if (!wp_next_scheduled('notifly_daily_canary')) {
wp_schedule_event(time(), 'daily', 'notifly_daily_canary');
}
});
add_action('notifly_daily_canary', function () {
notifly_send(
'🟢 WP-cron alive',
'Сайт ' . home_url() . ' жив. Время сервера: ' . current_time('mysql'),
2
);
});

If there’s no notification within 25 hours — something is wrong with the site’s cron.

To avoid receiving 100 notifications in 5 minutes during a spam wave:

function notifly_throttled(string $key, int $cooldown, callable $fn): void {
$cache_key = "notifly_throttle_$key";
if (get_transient($cache_key)) return;
set_transient($cache_key, 1, $cooldown);
$fn();
}
add_action('comment_post', function ($id) {
notifly_throttled("comment_$id", 60, function () use ($id) {
notifly_send(/* ... */);
});
});
  • See the live pulse of the site. Every order, every registration — push notifications.
  • No email in spam. Notifly bypasses mail filters.
  • No need for paid plugins like Mainwp, Jetpack or specialized “alert” add-ons.
  • Separate Notifly channels for different sites in a multisite network.
  • Tags in extras: you can filter messages in the Notifly admin by tag wc_order or comment.
  • “Confirm” / “Mark as spam” buttons via your own REST endpoint.