书接上回,增加Typecho博客备份到Github后发邮箱和Telegram通知

· 记录

目标

本指南将引导您在 Debian 12 服务器上,配置一个自动化的脚本来完成以下任务:

  1. 每日自动备份 Typecho 博客的数据库和 usr 目录。
  2. 将备份文件通过 Git 推送到一个私有的 GitHub 仓库。
  3. 自动清理超过30天的旧备份,节省空间。
  4. 在备份成功或失败时,通过 QQ 邮箱Telegram Bot 发送即时通知。

1. 环境准备与配置

1.1 安装系统依赖

首先,更新系统软件包列表并安装 Python 3 的包管理器(pip)和虚拟环境工具(venv)。

sudo apt update
sudo apt install python3-pip python3-venv

1.2 创建项目目录结构

我们将创建两个目录来分别存放通知脚本和备份脚本,以保持整洁。

# 在您的主目录下创建项目文件夹
mkdir -p ~/backup_notifier
mkdir -p ~/backup_scripts

1.3 配置 Python 虚拟环境

为通知脚本创建一个独立的 Python 环境,以避免与系统库冲突。

# 进入通知脚本目录
cd ~/backup_notifier

# 创建一个名为 'venv' 的虚拟环境
python3 -m venv venv

# 激活虚拟环境
source venv/bin/activate

# 在激活的环境中,安装发送 Telegram 消息所需的库
pip install python-telegram-bot

# 完成后,可以暂时停用虚拟环境(后续脚本会自动调用)
# deactivate

2. 获取必要的凭证

在编写脚本之前,您需要从 QQ 邮箱和 Telegram 获取以下信息。

3. 创建 Python 通知脚本

~/backup_notifier 目录下创建一个名为 send_notification.py 的文件,并填入以下模板代码。

# 文件路径: ~/backup_notifier/send_notification.py
nano ~/backup_notifier/send_notification.py

将以下内容粘贴到文件中,并替换所有 "YOUR_..." 占位符

import smtplib
import telegram
import asyncio
from email.mime.text import MIMEText
from email.utils import formataddr
from datetime import datetime
import sys

# --- ↓↓↓ 请在此处填入您的配置信息 ↓↓↓ ---
# QQ邮箱配置
SENDER_EMAIL = 'YOUR_QQ_EMAIL@qq.com'
AUTH_CODE = 'YOUR_16_DIGIT_AUTH_CODE'
RECEIVER_EMAIL = 'YOUR_RECEIVER_EMAIL@example.com'

# Telegram Bot配置
BOT_TOKEN = 'YOUR_TELEGRAM_BOT_TOKEN'
CHAT_ID = 'YOUR_TELEGRAM_CHAT_ID'
# --- ↑↑↑ 配置结束 ↑↑↑ ---

def send_email_notification(subject, body):
    try:
        msg = MIMEText(body, 'plain', 'utf-8')
        msg['From'] = formataddr(("博客备份系统", SENDER_EMAIL), 'utf-8')
        msg['To'] = formataddr(("管理员", RECEIVER_EMAIL), 'utf-8')
        msg['Subject'] = subject
        server = smtplib.SMTP_SSL('smtp.qq.com', 465)
        server.login(SENDER_EMAIL, AUTH_CODE)
        server.sendmail(SENDER_EMAIL, [RECEIVER_EMAIL], msg.as_string())
        server.quit()
        print("邮件通知发送成功!")
        return True
    except Exception as e:
        print(f"邮件发送失败: {e}", file=sys.stderr)
        return False

async def send_telegram_notification(message):
    try:
        bot = telegram.Bot(token=BOT_TOKEN)
        await bot.send_message(chat_id=CHAT_ID, text=message)
        print("Telegram消息发送成功!")
        return True
    except Exception as e:
        print(f"Telegram消息发送失败: {e}", file=sys.stderr)
        return False

async def main():
    current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
    if len(sys.argv) > 1:
        backup_status_message = " ".join(sys.argv[1:])
        subject = f"博客备份结果通知 - {current_time}"
        body = f"博客备份脚本执行完毕。\n时间: {current_time}\n结果: {backup_status_message}"
    else:
        subject = f"博客备份成功 - {current_time}"
        body = f"您的博客已于 {current_time} 成功完成自动备份。"
    print("开始发送通知...")
    email_success = send_email_notification(subject, body)
    telegram_success = await send_telegram_notification(body)
    print("-" * 20)
    if email_success and telegram_success:
        print("所有通知均已成功发送。")
    else:
        print("部分或全部通知发送失败,请检查上方日志。")

if __name__ == '__main__':
    asyncio.run(main())

4. 创建整合的 Shell 备份脚本

~/backup_scripts 目录下创建一个名为 backup.sh 的文件。

# 文件路径: ~/backup_scripts/backup.sh
nano ~/backup_scripts/backup.sh

将以下内容粘贴进去,并替换所有 "YOUR_..." 占位符

#!/bin/bash

# --- ↓↓↓ 请核对您的配置信息 ↓↓↓ ---
DB_USER="YOUR_DB_USER"
DB_PASS="YOUR_DB_PASSWORD"
DB_NAME="YOUR_DB_NAME"

TYPECHO_ROOT_DIR="/var/www/typecho" # Typecho网站根目录
BACKUP_REPO_DIR="/home/YOUR_USERNAME/typecho_backup_repo" # 本地备份仓库目录
GIT_REPO_URL="git@github.com:YOUR_GITHUB_USERNAME/YOUR_REPO_NAME.git" # 远程Git仓库地址

# 【重要】通知脚本的绝对路径配置
NOTIFIER_SCRIPT="/home/YOUR_USERNAME/backup_notifier/send_notification.py"
VENV_PYTHON="/home/YOUR_USERNAME/backup_notifier/venv/bin/python3"
# --- ↑↑↑ 配置结束 ↑↑↑ ---

send_notification() {
    echo "正在发送通知: $1"
    $VENV_PYTHON $NOTIFIER_SCRIPT "$1"
}

echo "--- [$(date '+%Y-%m-%d %H:%M:%S')] 开始备份 ---"

if [ ! -d "$BACKUP_REPO_DIR" ]; then
    echo "本地仓库不存在,正在从GitHub克隆..."
    git clone $GIT_REPO_URL $BACKUP_REPO_DIR
fi
cd $BACKUP_REPO_DIR || { send_notification "警报:无法进入备份目录 ${BACKUP_REPO_DIR}!"; exit 1; }

echo "正在清理30天前的旧备份..."
find . -type f -name 'db-backup-*.sql' -mtime +30 -delete
find . -type f -name 'usr-backup-*.tar.gz' -mtime +30 -delete

DATE_FORMAT=$(date "+%Y-%m-%d")
DB_BACKUP_FILE="db-backup-${DATE_FORMAT}.sql"
USR_BACKUP_FILE="usr-backup-${DATE_FORMAT}.tar.gz"

echo "正在备份数据库..."
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME > $DB_BACKUP_FILE
if [ $? -ne 0 ]; then
    send_notification "警报:Typecho 数据库备份失败!请立即检查。"
    exit 1
fi

echo "正在备份 usr 目录..."
tar -czf $USR_BACKUP_FILE -C $TYPECHO_ROOT_DIR usr
if [ $? -ne 0 ]; then
    send_notification "警报:Typecho 'usr' 目录打包失败!请立即检查。"
    exit 1
fi

echo "正在将备份推送到 GitHub..."
git pull origin main
git add .
git commit -m "自动备份于 ${DATE_FORMAT}"
git push origin main
if [ $? -ne 0 ]; then
    send_notification "警告:备份文件已在本地生成,但推送到 GitHub 失败!"
    exit 1
fi

SUCCESS_MESSAGE="Typecho 备份成功!文件 ${DB_BACKUP_FILE} 和 ${USR_BACKUP_FILE} 已生成并推送到 GitHub。"
send_notification "$SUCCESS_MESSAGE"

echo "--- [$(date '+%Y-%m-%d %H:%M:%S')] 备份和通知流程全部完成 ---"

保存后,为该脚本添加可执行权限:

chmod +x ~/backup_scripts/backup.sh

5. 设置 Cron 定时任务实现自动化

最后,我们使用 cron 来设置每日定时执行备份脚本。

  1. 打开 crontab 编辑器:

    crontab -e
    
  2. 在文件末尾添加以下一行,设置脚本在每天凌晨3点执行:

    # 在每天的 03:00 执行Typecho备份脚本,并将日志输出到文件
    0 3 * * * /bin/bash /home/YOUR_USERNAME/backup_scripts/backup.sh > /home/YOUR_USERNAME/backup_scripts/backup.log 2>&1
    

    请务必将 YOUR_USERNAME 替换为您服务器的实际用户名。

    • 0 3 * * *:代表每天的 3 点 0 分。
    • > .../backup.log 2>&1:将脚本的所有输出(包括错误信息)都重定向到 backup.log 文件中,方便日后排查问题。

6. 手动测试与验证

在等待定时任务自动执行前,强烈建议您手动运行一次脚本,以确保所有配置都正确无误。

bash ~/backup_scripts/backup.sh

观察终端输出,并检查您的邮箱和 Telegram 是否都收到了成功的通知。

至此,您的全自动博客备份与通知系统已部署完毕。

本文作者: 𝓬𝓸𝓵𝓪 🚀
本文链接: https://bb.bins.fyi/archives/23/
最后修改:
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!