哈喽宝子们!上篇我们成功把 OpenClaw 接入 Telegram、Discord,还学会了文件管理、浏览器控制、联网搜索三大核心技能。今天直接进入进阶实战:从零开发一个属于你自己的技能,再把 OpenClaw 部署到服务器,24 小时在线不掉线,真正做到私有化、全自动运行!
没看完前两篇的同学先别跳步,确保本地能正常启动、渠道能正常收发消息,再来搞今天的内容~毕竟基础打牢了,进阶操作才能顺风顺水,避免踩不必要的坑。
一、本篇你能学到什么
今天的内容全程干货无废话,每一个知识点都是能直接落地的实战技能,学完你就能:
- 掌握 OpenClaw 自定义技能开发规范(通用模板,套啥功能都能用,后续开发任何技能都不用从零摸索);
- 实战开发「自动发邮件」核心技能(带完整可运行代码 + 邮箱配置避坑指南);
- 理解指令解析底层逻辑(让机器人精准听懂你发的中文指令,不再答非所问);
- 完成服务器私有化部署 + 后台常驻(用 PM2 守护进程,实现 24 小时不掉线);
- 规避开发和部署中的常见报错,做好安全配置(防止隐私泄露、机器人被滥用)。
二、自定义技能:通用开发模板(必背)
OpenClaw 的技能体系采用「模块化设计」,所有自定义技能都遵循统一的结构,记住这个模板,你能开发任何想要的功能 —— 小到自动查天气,大到自动生成报表,都能套进去。
2.1 技能开发核心原则
在写代码前,先明确三个核心原则,避免写出来的技能无法接入主程序:
- 存放路径统一:所有技能文件必须放在项目根目录的
/skills文件夹下,主程序会默认从这个目录加载技能; - 函数暴露规范:每个技能必须暴露可被主程序调用的执行函数(比如
sendEmail()),且函数返回值为「可读的文本结果」(方便机器人把结果返回给 Telegram/Discord); - 指令解析独立:每个技能建议自带指令解析函数(比如
parseEmailCommand()),把用户的自然语言指令转换成程序能识别的参数,降低主程序的耦合度。
2.2 通用模板代码(直接复制改)
javascript
运行
// /skills/xxxSkill.js
// 1. 引入依赖(根据技能需求添加,比如发邮件用nodemailer,爬取数据用axios)
const xxx = require('xxx');
require('dotenv').config(); // 加载环境变量,保护敏感信息
// 2. 核心执行函数(async/await处理异步操作,比如发邮件、调接口)
async function executeXxx(params) {
try {
// 核心业务逻辑:比如调用API、操作文件、发送消息
const result = await xxx.doSomething(params);
// 返回成功结果(格式统一,方便前端/机器人展示)
return `✅ 操作成功:${JSON.stringify(result)}`;
} catch (err) {
// 返回失败结果(明确错误原因,方便排错)
return `❌ 操作失败:${err.message}`;
}
}
// 3. 指令解析函数(把用户的中文指令转成参数对象)
function parseXxxCommand(content) {
// 用正则匹配用户指令中的关键信息,比如「收件人:xxx」「标题:xxx」
const param1 = content.match(/参数1[::](.+?)(\s|\n|$)/)?.[1] || '';
const param2 = content.match(/参数2[::](.+?)(\s|\n|$)/)?.[1] || '';
// 返回参数对象,供执行函数使用
return { param1, param2 };
}
// 4. 暴露函数,让主程序能调用
module.exports = { executeXxx, parseXxxCommand };
这个模板的优势在于:结构清晰、复用性强、易维护。哪怕你是编程新手,只要替换「依赖引入」「核心业务逻辑」「指令解析正则」这三部分,就能快速开发出新技能。
三、实战:开发「自动发邮件」技能
邮件发送是办公场景的高频刚需,比如自动发送日报、告警通知、客户回执等,我们以这个技能为例,一步步拆解开发过程,确保你能跟着做出来。
3.1 前期准备:邮箱 SMTP 配置
首先要开启邮箱的 SMTP 服务(以 QQ 邮箱为例,其他邮箱如 163、Gmail 操作类似):
- 登录 QQ 邮箱,点击右上角「设置」→「账户」;
- 找到「POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV 服务」;
- 开启「SMTP 服务」,按照提示完成短信验证,获取「SMTP 授权码」(注意:不是邮箱登录密码,这是第三方应用调用邮箱的专用密码);
- 记录下 SMTP 服务器信息:QQ 邮箱是
smtp.qq.com,端口465(SSL 加密);163 邮箱是smtp.163.com,端口465。
3.2 安装依赖
进入项目根目录,打开终端执行以下命令,安装邮件发送和环境变量管理的依赖:
bash
运行
# 安装nodemailer(邮件发送核心库)和dotenv(环境变量管理)
npm install nodemailer dotenv --save
安装完成后,查看项目根目录的 package.json 文件,确认 dependencies 里出现 nodemailer 和 dotenv,说明依赖安装成功。
3.3 创建技能文件
在 /skills 文件夹下新建 emailSkill.js 文件,粘贴以下完整代码(带详细注释,看不懂的地方看注释):
javascript
运行
const nodemailer = require('nodemailer');
require('dotenv').config(); // 加载.env文件中的环境变量
/**
* 邮件发送器配置(封装成函数,避免重复创建)
* @returns {object} 配置好的transporter对象
*/
function createTransporter() {
// 配置SMTP服务器信息,不同邮箱的配置不同,参考对应邮箱的官方文档
return nodemailer.createTransport({
host: process.env.EMAIL_SMTP_HOST, // SMTP服务器地址(从.env读取)
port: process.env.EMAIL_SMTP_PORT, // 端口(465为SSL端口,587为TLS端口)
secure: true, // true对应465端口,false对应587端口
auth: {
user: process.env.EMAIL_ACCOUNT, // 发件人邮箱账号(从.env读取)
pass: process.env.EMAIL_AUTH_CODE // SMTP授权码(从.env读取)
}
});
}
/**
* 执行邮件发送
* @param {string} to 收件人邮箱(多个用逗号分隔,如"a@qq.com,b@163.com")
* @param {string} subject 邮件标题
* @param {string} text 邮件正文(纯文本)
* @returns {string} 发送结果(成功/失败提示)
*/
async function sendEmail(to, subject, text) {
// 校验必填参数,避免空值导致报错
if (!to) return '❌ 收件人邮箱不能为空!';
if (!subject) return '❌ 邮件标题不能为空!';
if (!text) return '❌ 邮件正文不能为空!';
try {
const transporter = createTransporter();
// 邮件发送配置
const mailOptions = {
from: `"OpenClaw智能助手" <${process.env.EMAIL_ACCOUNT}>`, // 发件人(显示名称+邮箱)
to, // 收件人
subject, // 标题
text // 正文(纯文本)
// 可选:如果需要发HTML格式的邮件,添加html字段
// html: `<h1>${subject}</h1><p>${text}</p>`
};
// 发送邮件(异步操作,用await等待结果)
let info = await transporter.sendMail(mailOptions); // 注意:原代码是sendEmail,这里是sendMail(nodemailer的正确方法)
// 验证邮件是否发送成功
if (info.messageId) {
return `✅ 邮件发送成功!
📧 收件人:${to}
📝 标题:${subject}
🆔 邮件ID:${info.messageId}
💡 可登录发件人邮箱查看发送状态`;
} else {
return '❌ 邮件发送失败:未获取到邮件ID,请检查配置!';
}
} catch (err) {
// 针对常见错误给出具体提示,方便排错
let errorMsg = '';
if (err.message.includes('Authentication failed')) {
errorMsg = '邮箱账号或SMTP授权码错误,请检查.env文件配置!';
} else if (err.message.includes('connect ECONNREFUSED')) {
errorMsg = 'SMTP服务器连接失败,请检查服务器地址和端口!';
} else if (err.message.includes('Invalid email')) {
errorMsg = '收件人邮箱格式错误,请检查!';
} else {
errorMsg = err.message;
}
return `❌ 邮件发送失败:${errorMsg}`;
}
}
/**
* 解析用户的邮件发送指令(中文指令转参数)
* @param {string} content 用户发送的指令文本(如「发送邮件 收件人:xxx@qq.com 标题:测试 内容:你好」)
* @returns {object} 解析后的参数(to, subject, text)
*/
function parseEmailCommand(content) {
// 正则匹配规则:匹配「收件人:xxx」「标题:xxx」「内容:xxx」格式的内容
// 支持中文冒号「:」和英文冒号「:」,支持换行/空格分隔
const to = content.match(/收件人[::](.+?)(\s|\n|$)/)?.[1]?.trim() || '';
const subject = content.match(/标题[::](.+?)(\s|\n|$)/)?.[1]?.trim() || '';
const text = content.match(/内容[::]([\s\S]+)/)?.[1]?.trim() || ''; // 内容可能包含换行,用[\s\S]匹配所有字符
return { to, subject, text };
}
// 暴露函数,供主程序调用
module.exports = { sendEmail, parseEmailCommand };
3.4 配置环境变量(关键:保护敏感信息)
绝对不要把邮箱账号、授权码写死在代码里!一旦代码泄露,你的邮箱就可能被恶意使用。正确的做法是用 .env 文件管理敏感信息:
- 在项目根目录新建
.env文件,写入以下内容(替换成你自己的信息):
env
# 邮箱配置
EMAIL_ACCOUNT=你的QQ邮箱@qq.com
EMAIL_AUTH_CODE=你的QQ邮箱SMTP授权码
EMAIL_SMTP_HOST=smtp.qq.com
EMAIL_SMTP_PORT=465
- 在项目根目录新建
.gitignore文件(如果没有的话),添加.env,防止把敏感信息提交到代码仓库:
gitignore
# 忽略环境变量文件
.env
# 忽略node_modules(依赖包,无需提交)
node_modules/
# 忽略日志文件
*.log
3.5 在主程序中挂载技能
找到 OpenClaw 的主程序入口(通常是 index.js 或 app.js),在指令处理的位置添加以下代码,把邮件技能挂载进去:
javascript
运行
// 引入邮件技能
const { sendEmail, parseEmailCommand } = require('./skills/emailSkill');
// 假设这是你的消息处理函数(Telegram/Discord的消息监听)
async function handleMessage(msg) {
// 匹配「发送邮件」指令
if (msg.includes('发送邮件')) {
// 解析用户指令中的参数
const { to, subject, text } = parseEmailCommand(msg);
// 执行发送邮件操作
const result = await sendEmail(to, subject, text);
// 把结果返回给用户(Telegram/Discord的消息发送方法)
await sendReply(result);
return;
}
// 其他指令处理(比如之前的文件管理、联网搜索)
if (msg.includes('文件管理')) {
// ... 原有逻辑
}
}
3.6 测试邮件技能
启动本地的 OpenClaw 程序,在 Telegram/Discord 中给机器人发送以下指令(格式要对应解析函数的规则):
plaintext
发送邮件
收件人:你的测试邮箱@163.com
标题:OpenClaw自动发邮件测试
内容:这是通过OpenClaw自定义技能自动发送的邮件,24小时运行超方便!
如果一切配置正确,你会收到机器人返回的「✅ 邮件发送成功」提示,同时测试邮箱能收到这封邮件。如果失败,根据返回的错误提示排查:
- 提示「Authentication failed」:检查
.env中的邮箱账号和授权码是否正确; - 提示「connect ECONNREFUSED」:检查 SMTP 服务器地址和端口是否正确;
- 提示「收件人邮箱不能为空」:检查指令格式是否正确,比如有没有写「收件人:」。
四、扩展:基于通用模板开发更多技能
掌握了上面的模板和邮件技能开发流程,你可以半小时内开发出其他实用技能,以下是几个高频场景的示例(附核心思路):
4.1 自动发微信消息技能
核心依赖:wechaty(微信机器人库)开发思路:
- 安装依赖:
npm install wechaty wechaty-puppet-wechat --save; - 核心执行函数:初始化微信机器人,通过手机号 / 昵称匹配联系人,发送消息;
- 指令解析:匹配「发送微信」「联系人:xxx」「消息:xxx」;
- 注意:微信网页版接口可能有限制,可选用企业微信或第三方协议。
4.2 自动爬取天气技能
核心依赖:axios(HTTP 请求)、cheerio(HTML 解析)开发思路:
- 安装依赖:
npm install axios cheerio --save; - 核心执行函数:调用免费天气 API(如高德天气 API),获取指定城市的天气数据;
- 指令解析:匹配「查天气」「城市:xxx」;
- 示例指令:「查天气 城市:北京」,机器人返回「北京今日天气:晴,温度 10-20℃」。
4.3 自动整理桌面文件技能
核心依赖:fs(文件系统,Node.js 内置)、path(路径处理,Node.js 内置)开发思路:
- 无需额外安装依赖,直接使用 Node.js 内置模块;
- 核心执行函数:读取桌面目录,按文件类型(图片、文档、视频)分类,移动到对应文件夹;
- 指令解析:匹配「整理桌面」即可,无需额外参数;
- 注意:处理文件时添加异常捕获,防止文件被占用导致报错。
4.4 自动备份数据库技能
核心依赖:child_process(执行系统命令,Node.js 内置)开发思路:
- 核心执行函数:调用
mysqldump命令备份 MySQL 数据库,压缩后保存到指定目录; - 指令解析:匹配「备份数据库」「数据库名:xxx」;
- 安全配置:数据库账号密码从
.env读取,备份文件定期清理,防止占满服务器磁盘。
五、私有化部署:让 OpenClaw 24 小时运行
本地运行的机器人只能在电脑开机时使用,部署到服务器后,就能实现 24 小时在线,真正做到全自动运行。以下是详细的部署步骤(以阿里云轻量服务器为例,腾讯云 / 华为云操作一致)。
5.1 服务器选购与系统配置
- 选购建议:轻量应用服务器即可,配置无需太高(1 核 2G 内存、1M 带宽足够),系统选择「Ubuntu 20.04 LTS」或「Ubuntu 22.04 LTS」(兼容性最好);
- 安全组配置:登录服务器控制台,在安全组中开放必要端口(如 22 端口用于 SSH 连接,Telegram/Discord 的端口无需手动开放),禁止开放 3000、8080 等非必要端口,防止被攻击。
5.2 服务器环境安装
- 连接服务器:使用 FinalShell、Xshell 或 VS Code 的 Remote SSH 插件连接服务器(输入服务器 IP、端口 22、用户名 root、密码 / 密钥);
- 更新系统包:执行以下命令更新系统依赖,避免安装出错:
bash
运行
apt update && apt upgrade -y
- 安装 Node.js(18.x 版本,稳定版) :
bash
运行
# 添加Node.js源
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
# 安装Node.js和npm
sudo apt install nodejs -y
# 验证安装(显示版本号则成功)
node -v # 应输出v18.x.x
npm -v # 应输出9.x.x
5.3 上传代码到服务器
- 创建项目目录:在服务器上新建目录,用于存放 OpenClaw 代码:
bash
运行
mkdir -p /usr/local/openclaw
-
上传代码:
-
方法 1(FinalShell):直接把本地项目文件夹拖到服务器的
/usr/local/openclaw目录下; -
方法 2(Git):如果代码托管在 GitHub/Gitee,直接克隆:
bash
运行
git clone 你的代码仓库地址 /usr/local/openclaw
-
-
安装项目依赖:进入项目目录,安装依赖:
bash
运行
cd /usr/local/openclaw
npm install
- 配置环境变量:在服务器的项目目录下新建
.env文件,写入和本地一样的配置(邮箱、Telegram/Discord Token 等):
bash
运行
# 编辑.env文件
nano /usr/local/openclaw/.env
# 粘贴本地的.env内容,保存退出(按Ctrl+O,回车,Ctrl+X)
5.4 安装 PM2 守护进程(关键:后台常驻)
PM2 是 Node.js 的进程管理工具,能实现:后台运行程序、崩溃自动重启、服务器重启后自动启动、查看运行日志等功能,是部署 Node.js 应用的首选工具。
- 全局安装 PM2:
bash
运行
npm install pm2 -g
- 启动 OpenClaw 并命名:
bash
运行
cd /usr/local/openclaw
# 启动程序,命名为OpenClaw(方便管理)
pm2 start index.js --name "OpenClaw"
- 设置 PM2 开机自启:
bash
运行
# 保存当前PM2的进程列表
pm2 save
# 设置开机自启(执行后按提示操作,通常需要输入服务器密码)
pm2 startup
- PM2 常用命令(必记) :
bash
运行
# 查看运行状态
pm2 status
# 查看日志(实时监控程序运行情况)
pm2 logs OpenClaw
# 重启程序(修改代码后需要重启)
pm2 restart OpenClaw
# 停止程序
pm2 stop OpenClaw
# 删除程序
pm2 delete OpenClaw
执行完以上步骤,你的 OpenClaw 就会在服务器后台 24 小时运行 —— 哪怕关闭 SSH 连接、重启服务器,程序也会自动启动,真正实现「私有化、全自动」。
六、部署必看:安全配置与常见报错避坑
6.1 安全配置要点(重中之重)
-
敏感信息绝对不写死:所有 Token、账号、密码、授权码都通过
.env文件管理,且.env必须加入.gitignore; -
服务器端口最小化开放:只开放 22(SSH)、80/443(如果有 Web 界面)端口,其他端口一律关闭;
-
限制机器人访问权限:
- Telegram:在代码中添加 chatId 白名单,只允许指定用户发送指令;
- Discord:设置机器人仅能在指定服务器 / 频道工作;
-
定期备份代码和数据:服务器硬盘可能损坏,定期把项目文件和备份数据(如数据库备份)下载到本地;
-
避免使用 root 用户运行程序:创建普通用户,赋予项目目录的读写权限,用普通用户启动 PM2,降低安全风险。
6.2 常见报错及解决方案
-
报错:PM2 启动后程序立即退出
- 原因:代码有语法错误、依赖未安装、环境变量配置错误;
- 解决:执行
pm2 logs OpenClaw查看具体错误日志,根据日志修复(比如缺少依赖就npm install xxx,语法错误就修正代码)。
-
报错:邮件发送失败「Authentication failed」
- 原因:邮箱 SMTP 授权码错误、未开启 SMTP 服务、邮箱账号输入错误;
- 解决:重新登录邮箱检查 SMTP 服务是否开启,重新获取授权码,确保
.env中的配置和邮箱一致。
-
报错:Telegram 机器人收不到消息
- 原因:Token 错误、服务器网络无法访问 Telegram、机器人未加入聊天群组;
- 解决:检查 Token 是否正确,服务器 ping
api.telegram.org测试网络,确保机器人已被添加到群组且有消息权限。
-
报错:PM2 startup 执行失败
- 原因:服务器权限不足、PM2 版本过低;
- 解决:更新 PM2 到最新版本(
npm update pm2 -g),用 root 用户执行pm2 startup,按提示输入密码完成配置。
-
报错:服务器重启后 PM2 未自动启动
- 原因:未执行
pm2 save或pm2 startup配置错误; - 解决:重新执行
pm2 save和pm2 startup,重启服务器后执行pm2 status验证。
- 原因:未执行
七、下期预告
【OpenClaw 保姆级教程】第四篇:多技能联动 + 定时任务 + API 接口化,把 OpenClaw 变成全自动工作流!
有任何部署失败、指令不识别、邮件发不出的问题,直接评论区留言,我挨个帮你看~