我在闲逛工具分享帖子时,意外撞见了Bark这款冷门推送软件,这个软件非常丰富,兼顾极简入门+专业定制,适配脚本、PHP、建站、运维全场景。

简单介绍

仅苹果iPhone/iPad能用(App Store下载),免费开源,作用:电脑/服务器/网站发消息,直接弹窗推送到你手机锁屏,不用APP挂后台、不耗电。

调用方式

  1. GET简易链接(最快,浏览器/curl一键发)
  2. POST-JSON(正式开发、长文本、加密推送首选,不受URL长度限制)
  3. POST表单(对接老旧系统、后端表单提交)

我采用的是GET方式进行url拼接。

效果

由于自己第一次尝试简单开发,我把代码全部挤在一个文件里。

<?php
/**
 * Plugin Name: Bark Notify
 * Plugin URI: https://www.lybblog.cn
 * Description: Bark通知中心,登录成功/失败推送。
 * Version: 1.3
 * Author: YBExistence
 * Author URI: https://www.lybblog.cn
 */
if (!defined('ABSPATH')) {
    exit;
}

// 后台配置菜单
add_action('admin_menu', 'bark_notify_add_opt');
function bark_notify_add_opt()
{
    add_options_page(
        'Bark Notify配置',
        'Bark Notify',
        'manage_options',
        'bark_notify_cfg',
        'bark_notify_page'
    );
}

// 配置页面
function bark_notify_page()
{
    if (isset($_POST['bk_submit']) && current_user_can('manage_options')) {
        update_option('bark_notify_key', sanitize_text_field($_POST['bk'] ?? ''));
        update_option('bark_notify_switch_login_ok', isset($_POST['switch_ok']) ? 1 : 0);
        update_option('bark_notify_switch_login_err', isset($_POST['switch_err']) ? 1 : 0);
        echo '<div class="notice notice-success"><p>配置已保存</p></div>';
    }
    $k           = get_option('bark_notify_key', '');
    $switch_ok   = get_option('bark_notify_switch_login_ok', 1);
    $switch_err  = get_option('bark_notify_switch_login_err', 1);
    ?>
    <div class="wrap">
        <h1>Bark Notify 推送配置</h1>
        <form method="post">
            <table class="form-table">
                <tr>
                    <th>Bark Key</th>
                    <td>
                        <input type="text" name="bk" style="width:620px;" value="<?php echo esc_attr($k); ?>" placeholder="https://api.day.app/后面的密钥">
                    </td>
                </tr>
                <tr>
                    <th>推送开关</th>
                    <td>
                        <label><input type="checkbox" name="switch_ok" <?php checked($switch_ok,1); ?>> 开启【登录成功】推送</label><br>
                        <label><input type="checkbox" name="switch_err" <?php checked($switch_err,1); ?>> 开启【登录失败】推送</label>
                    </td>
                </tr>
            </table>
            <p><button name="bk_submit" class="button button-primary">保存配置</button></p>
        </form>
    </div>
    <?php
}

// 获取真实客户端IP(优化防伪造)
function bark_notify_ip()
{
    $ip = $_SERVER['REMOTE_ADDR'] ?? '未知IP';
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $tmp = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $tmpip = trim($tmp[0]);
        // 简单过滤内网、非法IP
        if (filter_var($tmpip, FILTER_VALIDATE_IP)) {
            $ip = $tmpip;
        }
    }
    return $ip;
}

// UA解析系统+浏览器
function bark_notify_get_device_info()
{
    $ua = $_SERVER['HTTP_USER_AGENT'] ?? '';
    $os = '未知系统';
    $browser = '未知浏览器';

    // 系统
    if (stripos($ua, 'Windows NT 10') !== false) $os = 'Windows10/11';
    elseif (stripos($ua, 'Windows NT 6.1') !== false) $os = 'Windows7';
    elseif (stripos($ua, 'Mac OS X') !== false) $os = 'macOS';
    elseif (stripos($ua, 'iPhone') !== false || stripos($ua, 'iPad') !== false) $os = 'iOS';
    elseif (stripos($ua, 'Android') !== false) $os = 'Android';
    elseif (stripos($ua, 'Linux') !== false) $os = 'Linux';

    // 浏览器
    if (stripos($ua, 'Chrome') !== false && stripos($ua, 'Edg') === false) $browser = 'Chrome谷歌';
    elseif (stripos($ua, 'Edg') !== false) $browser = 'Edge';
    elseif (stripos($ua, 'Firefox') !== false) $browser = 'Firefox火狐';
    elseif (stripos($ua, 'Safari') !== false && stripos($ua, 'Chrome') === false) $browser = 'Safari';

    return [$os, $browser];
}

// Bark推送核心
function bark_notify_send($title, $content)
{
    $key = get_option('bark_notify_key');
    if (empty($key)) return false;

    $site = get_option('blogname');
    $full_title = "【{$site}】".$title;

    $url = sprintf(
        'https://api.day.app/%s/%s/%s?sound=alert',
        $key,
        urlencode($full_title),
        urlencode($content)
    );

    $res = wp_remote_get($url, [
        'timeout' => 3,
        'user-agent' => 'WP-BarkNotify/1.3'
    ]);

    // 可开启日志:失败写入WP日志
    if (is_wp_error($res)) {
        error_log('Bark推送失败:'.$res->get_error_message());
        return false;
    }
    return true;
}

// 登录成功钩子
add_action('wp_login', function ($username, $user) {
    if (!get_option('bark_notify_switch_login_ok',1)) return;

    $ip = bark_notify_ip();
    list($sys, $browser) = bark_notify_get_device_info();
    $msg = "账号:{$username}\n邮箱:{$user->user_email}\nIP:{$ip}\n设备:{$sys}\n浏览器:{$browser}\n时间:".current_time('mysql');
    bark_notify_send('登录成功',$msg);
},10,2);

// 登录失败钩子
add_action('wp_login_failed', function ($username) {
    if (!get_option('bark_notify_switch_login_err',1)) return;

    $ip = bark_notify_ip();
    list($sys, $browser) = bark_notify_get_device_info();
    $msg = "试探账号:{$username}\nIP:{$ip}\n设备:{$sys}\n浏览器:{$browser}\n时间:".current_time('mysql');
    bark_notify_send('登录失败',$msg);
});

期间也是求了ai帮忙进行语法修正,尝试下来我觉得效果也是挺好的,简单的bark key配置,推送登录成功/失败信息。

效果图