You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Telegram聊天bot仅发送MySQL新数据的实现方案咨询

解决Telegram机器人重复发送问题:仅当数据库有新数据时发送消息

核心问题分析

你当前用meta http-equiv="refresh"刷新页面,每次刷新都会执行发送逻辑,导致无新数据时重复发送相同内容。核心解决思路是给每条需要发送的数据做「已发送标记」,仅处理未发送过的新数据,下面提供三种可落地的方案:


方案一:持久化记录最后发送的时间戳(最简单易实现)

通过文件/数据库记录最后一次发送消息对应的最新数据时间戳,每次执行时只查询比该时间戳新的数据,避免重复发送。

修改后的PHP发送代码

<?php
// 1. 读取最后发送的时间戳(用文件存储,也可以存在数据库表中)
$lastSentFile = 'last_sent_timestamp.txt';
$lastSentTimestamp = file_exists($lastSentFile) ? trim(file_get_contents($lastSentFile)) : '0000-00-00 00:00:00';

// 2. 查询仅比最后发送时间新的数据(用预处理语句防SQL注入)
$stmt = $db->prepare('SELECT time_stamp, group_name, message, nvalue, old_svalue, inactive_timestamp, ack_timestamp
                      FROM alarm 
                      WHERE time_stamp > ? 
                      ORDER BY time_stamp DESC');
$stmt->execute([$lastSentTimestamp]);
$orang = $stmt->fetchAll(PDO::FETCH_ASSOC);

// 3. 仅当有新数据时处理发送逻辑
if (count($orang) > 0) {
    $arrayAll = [];
    $latestTimestamp = '';
    
    foreach($orang as $orn){
        $data = implode(" ", $orn);
        $arrayAll[] = $data;
        // 记录这批数据中最新的时间戳
        if ($orn['time_stamp'] > $latestTimestamp) {
            $latestTimestamp = $orn['time_stamp'];
        }
    }

    // 4. 满足nvalue条件时发送消息
    if($orang[0]["nvalue"] >= 30){ // 取最新一条数据的nvalue判断
        $arrayAll = implode("\n", $arrayAll);
        $response = $telegram->sendMessage([
            'chat_id' => "$idChat",
            'text' => "\n$arrayAll",
            'parse_mode' => 'HTML'
        ]);
        // 5. 更新最后发送的时间戳
        file_put_contents($lastSentFile, $latestTimestamp);
        echo "新消息已发送";
    } else {
        echo "Tidak dikirim";
    }
} else {
    echo "无新数据,不执行发送";
}
?>

配套HTML修改

去掉页面自动刷新的meta标签,改为手动刷新或结合AJAX局部更新表格:

<body> 
    <table>
        <tr>
            <th>Message</th>
            <th>Group Name</th>
            <th>Time Stamp</th>
        </tr>
        <?php foreach($orang as $org): ?>
        <tr>
            <td><?php echo htmlspecialchars($org["message"]);?></td>
            <td><?php echo htmlspecialchars($org["group_name"]);?></td>
            <td><?php echo htmlspecialchars($org["time_stamp"]);?></td>
        </tr>
        <?php endforeach; ?>
    </table>
</body>

方案二:AJAX长轮询(前端实时感知新数据)

后端阻塞等待新数据,有数据时立即返回给前端,前端触发页面更新或发送逻辑,避免无意义的页面刷新。

前端HTML+JS代码

<body> 
    <table id="alarmTable">
        <tr>
            <th>Message</th>
            <th>Group Name</th>
            <th>Time Stamp</th>
        </tr>
        <?php foreach($orang as $org): ?>
        <tr>
            <td><?php echo htmlspecialchars($org["message"]);?></td>
            <td><?php echo htmlspecialchars($org["group_name"]);?></td>
            <td class="timestamp"><?php echo htmlspecialchars($org["time_stamp"]);?></td>
        </tr>
        <?php endforeach; ?>
    </table>

    <script>
        // 长轮询函数
        function startLongPoll() {
            // 获取页面中最新的时间戳
            const timestampCells = document.querySelectorAll('.timestamp');
            const lastTimestamp = timestampCells.length > 0 
                ? timestampCells[timestampCells.length - 1].textContent 
                : '0000-00-00 00:00:00';

            fetch(`check_new_data.php?last_ts=${encodeURIComponent(lastTimestamp)}`)
                .then(res => res.json())
                .then(data => {
                    if (data.hasNew) {
                        // 有新数据,刷新页面或局部更新表格
                        location.reload();
                    }
                    // 继续轮询(间隔1秒避免频繁请求)
                    setTimeout(startLongPoll, 1000);
                })
                .catch(err => {
                    console.error('轮询出错:', err);
                    // 出错后5秒重试
                    setTimeout(startLongPoll, 5000);
                });
        }

        // 页面加载后启动轮询
        window.onload = startLongPoll;
    </script>
</body>

后端check_new_data.php代码

<?php
// 连接数据库和Telegram实例(和原代码一致)
$db = ...;
$telegram = ...;
$idChat = ...;

$lastTimestamp = $_GET['last_ts'] ?? '0000-00-00 00:00:00';

// 查询新数据
$stmt = $db->prepare('SELECT time_stamp, group_name, message, nvalue, old_svalue, inactive_timestamp, ack_timestamp
                      FROM alarm 
                      WHERE time_stamp > ? 
                      ORDER BY time_stamp DESC');
$stmt->execute([$lastTimestamp]);
$newData = $stmt->fetchAll(PDO::FETCH_ASSOC);

$response = ['hasNew' => false];

if (count($newData) > 0) {
    $response['hasNew'] = true;
    $arrayAll = [];
    $latestTs = '';

    foreach($newData as $item){
        $arrayAll[] = implode(" ", $item);
        if ($item['time_stamp'] > $latestTs) $latestTs = $item['time_stamp'];
    }

    // 满足条件则发送消息
    if($newData[0]["nvalue"] >= 30){
        $text = implode("\n", $arrayAll);
        $telegram->sendMessage([
            'chat_id' => "$idChat",
            'text' => "\n$text",
            'parse_mode' => 'HTML'
        ]);
    }
}

echo json_encode($response);
?>

方案三:Cron定时任务(后台静默执行,最高效)

如果不需要前端实时展示,直接用服务器定时任务定期检查数据库,有新数据就发送,完全不需要前端页面刷新。

单独的发送脚本send_alarm.php

<?php
// 连接数据库和Telegram
$db = ...;
$telegram = ...;
$idChat = ...;

// 读取最后发送时间戳
$lastSentFile = 'last_sent_timestamp.txt';
$lastSentTimestamp = file_exists($lastSentFile) ? trim(file_get_contents($lastSentFile)) : '0000-00-00 00:00:00';

// 查询新数据
$stmt = $db->prepare('SELECT time_stamp, group_name, message, nvalue, old_svalue, inactive_timestamp, ack_timestamp
                      FROM alarm 
                      WHERE time_stamp > ? 
                      ORDER BY time_stamp DESC');
$stmt->execute([$lastSentTimestamp]);
$newData = $stmt->fetchAll(PDO::FETCH_ASSOC);

if (count($newData) > 0) {
    $arrayAll = [];
    $latestTs = '';

    foreach($newData as $item){
        $arrayAll[] = implode(" ", $item);
        if ($item['time_stamp'] > $latestTs) $latestTs = $item['time_stamp'];
    }

    if($newData[0]["nvalue"] >= 30){
        $text = implode("\n", $arrayAll);
        $telegram->sendMessage([
            'chat_id' => "$idChat",
            'text' => "\n$text",
            'parse_mode' => 'HTML'
        ]);
        file_put_contents($lastSentFile, $latestTs);
    }
}
?>

设置Cron定时任务

在服务器上执行crontab -e,添加以下内容(每分钟执行一次脚本):

* * * * * php /path/to/your/send_alarm.php

内容的提问来源于stack exchange,提问作者Moira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 04:46:47