worker / entrypoint.sh
EmilyReed96989's picture
Update entrypoint.sh
3936d07 verified
#!/bin/bash
set -e
# 强制使用北京时间(解决 HF Spaces 默认 UTC 导致汇报时间错误)
# 使用 OpenClaw 3.13 新增的 OPENCLAW_TZ 环境变量
export TZ="Asia/Shanghai"
export OPENCLAW_TZ="Asia/Shanghai"
CONFIG="/root/.openclaw/openclaw.json"
IP_RECORD="/root/.openclaw/.last_outbound_ip"
export OPENCLAW_STATE_DIR="/root/.openclaw"
export OPENCLAW_CONFIG_PATH="$CONFIG"
# ============================================================
# 从 GitHub 仓库根目录复制部署文件
# 默认仓库:Viciy2023/huggingface-new-worker
# 默认路径:仓库根目录
# 需要通过 GitHub Token 认证
# ============================================================
GITHUB_OWNER="${GITHUB_OWNER:-Viciy2023}"
GITHUB_REPO="${GITHUB_REPO:-huggingface-new-worker}"
GITHUB_BRANCH="${GITHUB_BRANCH:-main}"
GITHUB_TOKEN="${GITHUB_TOKEN:-}"
GITHUB_CLONE_ROOT="/tmp/github-deploy-source"
GITHUB_CLONE_DIR="${GITHUB_CLONE_ROOT}/repo"
prepare_github_source() {
if [ -z "$GITHUB_TOKEN" ]; then
echo "❌ GITHUB_TOKEN is not set"
return 1
fi
rm -rf "$GITHUB_CLONE_ROOT"
mkdir -p "$GITHUB_CLONE_ROOT"
local repo_url="https://x-access-token:${GITHUB_TOKEN}@github.com/${GITHUB_OWNER}/${GITHUB_REPO}.git"
echo "=== Cloning deploy files from GitHub repository ==="
echo "Repository: ${GITHUB_OWNER}/${GITHUB_REPO}"
echo "Branch: ${GITHUB_BRANCH}"
echo "Source path: repository root"
if ! git clone --depth 1 --branch "$GITHUB_BRANCH" "$repo_url" "$GITHUB_CLONE_DIR"; then
echo "❌ Failed to clone GitHub repository"
return 1
fi
return 0
}
copy_repo_file() {
local src="$1"
local dest="$2"
local source_path="${GITHUB_CLONE_DIR}/${src}"
mkdir -p "$(dirname "$dest")"
echo " Copying: ${src}"
echo " From: ${source_path}"
echo " To: ${dest}"
if [ -f "$source_path" ]; then
cp "$source_path" "$dest"
echo "✅ Copied: $src"
return 0
fi
echo "❌ Failed: $src (file not found in GitHub repository root)"
return 1
}
if [ -n "$GITHUB_OWNER" ] && [ -n "$GITHUB_REPO" ]; then
FAIL_COUNT=0
echo "=== Using HF Secrets for environment variables ==="
echo "⚠️ .env download is disabled; runtime secrets must come from HF Space Secrets"
if prepare_github_source; then
# 配置文件
copy_repo_file "openclaw.json" "/root/.openclaw/openclaw.json" || FAIL_COUNT=$((FAIL_COUNT + 1))
# workspace 文件(角色设定、任务文档等)
# 注意:OpenClaw 3.13 只加载一个内存引导文件,MEMORY.md 优先
copy_repo_file "SOUL.md" "/root/.openclaw/workspace/SOUL.md" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "IDENTITY.md" "/root/.openclaw/workspace/IDENTITY.md" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "USER.md" "/root/.openclaw/workspace/USER.md" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "AGENTS.md" "/root/.openclaw/workspace/AGENTS.md" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "TOOLS.md" "/root/.openclaw/workspace/TOOLS.md" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "BOOTSTRAP.md" "/root/.openclaw/workspace/BOOTSTRAP.md" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "MEMORY.md" "/root/.openclaw/workspace/MEMORY.md" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "HEARTBEAT.md" "/root/.openclaw/workspace/HEARTBEAT.md" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "WORKFLOW_AUTO.md" "/root/.openclaw/workspace/WORKFLOW_AUTO.md" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "task-dispatch.md" "/root/.openclaw/workspace/task-dispatch.md" || FAIL_COUNT=$((FAIL_COUNT + 1))
# cron 任务配置
copy_repo_file "cron/jobs.json" "/root/.openclaw/cron/jobs.json" || FAIL_COUNT=$((FAIL_COUNT + 1))
# ClawEdit 项目文件 - 文章配套媒体生成系统 (原生插件模式)
# 源路径:GitHub 子目录中的 clawedit 目录
# 目标路径:~/.openclaw/extensions/clawedit
CLAWEDIT_DEST="/root/.openclaw/extensions/clawedit"
copy_repo_file "clawedit/index.ts" "$CLAWEDIT_DEST/index.ts" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "clawedit/package.json" "$CLAWEDIT_DEST/package.json" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "clawedit/openclaw.plugin.json" "$CLAWEDIT_DEST/openclaw.plugin.json" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "clawedit/core/types.ts" "$CLAWEDIT_DEST/core/types.ts" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "clawedit/core/config.ts" "$CLAWEDIT_DEST/core/config.ts" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "clawedit/core/errors.ts" "$CLAWEDIT_DEST/core/errors.ts" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "clawedit/core/process.ts" "$CLAWEDIT_DEST/core/process.ts" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "clawedit/generator/image-pipeline.ts" "$CLAWEDIT_DEST/generator/image-pipeline.ts" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "clawedit/generator/video-pipeline.ts" "$CLAWEDIT_DEST/generator/video-pipeline.ts" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "clawedit/generator/batch-generator.ts" "$CLAWEDIT_DEST/generator/batch-generator.ts" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "clawedit/planner/article-planner.ts" "$CLAWEDIT_DEST/planner/article-planner.ts" || FAIL_COUNT=$((FAIL_COUNT + 1))
copy_repo_file "clawedit/editor/markdown-enricher.ts" "$CLAWEDIT_DEST/editor/markdown-enricher.ts" || FAIL_COUNT=$((FAIL_COUNT + 1))
echo "=== Deploy files copy complete (failures: $FAIL_COUNT) ==="
if [ "$FAIL_COUNT" -gt 0 ]; then
echo "⚠️ WARNING: $FAIL_COUNT file(s) failed to copy, service may not work correctly"
fi
else
echo "❌ GitHub deploy source preparation failed"
fi
else
echo "⚠️ GitHub deploy source is not configured, skipping deploy file copy"
fi
# ============================================================
# 调试:检查环境变量是否正确加载
# ============================================================
echo "=== Debug: Checking environment variables ==="
echo "GATEWAY_TOKEN length: ${#GATEWAY_TOKEN}"
echo "GATEWAY_TOKEN first 20 chars: ${GATEWAY_TOKEN:0:20}..."
echo "CLIPROXY_BASE_URL: ${CLIPROXY_BASE_URL}"
echo "WECOM_TOKEN length: ${#WECOM_TOKEN}"
echo ""
echo "=== Debug: Checking config file before replacement ==="
grep -n "GATEWAY_TOKEN" "$CONFIG" | head -5
echo ""
# ============================================================
# 替换 openclaw.json 中的占位符
# 环境变量全部由 HF Secrets 注入
# ============================================================
echo "=== Replacing placeholders in openclaw.json ==="
CONTROL_UI_ORIGIN="${PUBLIC_BASE_URL%/}"
if [ -n "$CONTROL_UI_ORIGIN" ]; then
CONTROL_UI_ORIGIN="${CONTROL_UI_ORIGIN%%/*}"
if [[ "$PUBLIC_BASE_URL" =~ ^https?:// ]]; then
CONTROL_UI_ORIGIN="${PUBLIC_BASE_URL%/}"
fi
fi
sed -i "s|__PUBLIC_BASE_URL__|${CONTROL_UI_ORIGIN}|g" "$CONFIG"
sed -i "s|__WECOM_APP_API_BASE_URL__|${WECOM_APP_API_BASE_URL}|g" "$CONFIG"
sed -i "s|__GATEWAY_TOKEN__|${GATEWAY_TOKEN}|g" "$CONFIG"
# 主模型配置(动态替换)
sed -i "s|__PRIMARY_PROVIDER_NAME__|${PRIMARY_PROVIDER_NAME}|g" "$CONFIG"
sed -i "s|__PRIMARY_PROVIDER_BASE_URL__|${PRIMARY_PROVIDER_BASE_URL}|g" "$CONFIG"
sed -i "s|__PRIMARY_PROVIDER_API_KEY__|${PRIMARY_PROVIDER_API_KEY}|g" "$CONFIG"
sed -i "s|__PRIMARY_PROVIDER_API__|${PRIMARY_PROVIDER_API}|g" "$CONFIG"
sed -i "s|__PRIMARY_MODEL_ID__|${PRIMARY_MODEL_ID}|g" "$CONFIG"
sed -i "s|__PRIMARY_MODEL_NAME__|${PRIMARY_MODEL_NAME}|g" "$CONFIG"
# CLIPROXY 配置已删除,不再使用
# sed -i "s|__CLIPROXY_BASE_URL__|${CLIPROXY_BASE_URL}|g" "$CONFIG"
# sed -i "s|__CLIPROXY_API_KEY__|${CLIPROXY_API_KEY}|g" "$CONFIG"
# 旧的 GROKPROXY 配置(保留兼容性,如果新变量未设置则使用旧变量)
sed -i "s|__GROKPROXY_BASE_URL__|${GROKPROXY_BASE_URL}|g" "$CONFIG"
sed -i "s|__GROKPROXY_API_KEY__|${GROKPROXY_API_KEY}|g" "$CONFIG"
sed -i "s|__HFGROK2API_B_KEY__|${HFGROK2API_B_KEY}|g" "$CONFIG"
sed -i "s|__HFGROK2API_B_BASE_URL__|${HFGROK2API_B_BASE_URL}|g" "$CONFIG"
sed -i "s|__WECOM_WS_BOT_ID__|${WECOM_WS_BOT_ID}|g" "$CONFIG"
sed -i "s|__WECOM_WS_SECRET__|${WECOM_WS_SECRET}|g" "$CONFIG"
sed -i "s|__WECOM_TOKEN__|${WECOM_TOKEN}|g" "$CONFIG"
sed -i "s|__WECOM_AES_KEY__|${WECOM_AES_KEY}|g" "$CONFIG"
sed -i "s|__WECOM_CORP_ID__|${WECOM_CORP_ID}|g" "$CONFIG"
sed -i "s|__WECOM_APP_TOKEN__|${WECOM_APP_TOKEN}|g" "$CONFIG"
sed -i "s|__WECOM_APP_AES_KEY__|${WECOM_APP_AES_KEY}|g" "$CONFIG"
sed -i "s|__WECOM_APP_SECRET__|${WECOM_APP_SECRET}|g" "$CONFIG"
sed -i "s|__WECOM_APP_ASR_APP_ID__|${WECOM_APP_ASR_APP_ID}|g" "$CONFIG"
sed -i "s|__WECOM_APP_ASR_SECRET_ID__|${WECOM_APP_ASR_SECRET_ID}|g" "$CONFIG"
sed -i "s|__WECOM_APP_ASR_SECRET_KEY__|${WECOM_APP_ASR_SECRET_KEY}|g" "$CONFIG"
sed -i "s|__QQBOT_APP_ID__|${QQBOT_APP_ID}|g" "$CONFIG"
sed -i "s|__QQBOT_CLIENT_SECRET__|${QQBOT_CLIENT_SECRET}|g" "$CONFIG"
sed -i "s|__QQBOT_ASR_APP_ID__|${QQBOT_ASR_APP_ID}|g" "$CONFIG"
sed -i "s|__QQBOT_ASR_SECRET_ID__|${QQBOT_ASR_SECRET_ID}|g" "$CONFIG"
sed -i "s|__QQBOT_ASR_SECRET_KEY__|${QQBOT_ASR_SECRET_KEY}|g" "$CONFIG"
sed -i "s|__FEISHU_APP_ID__|${FEISHU_APP_ID}|g" "$CONFIG"
sed -i "s|__FEISHU_APP_SECRET__|${FEISHU_APP_SECRET}|g" "$CONFIG"
sed -i "s|__FEISHU_VERIFICATION_TOKEN__|${FEISHU_VERIFICATION_TOKEN}|g" "$CONFIG"
sed -i "s|__FEISHU_ENCRYPT_KEY__|${FEISHU_ENCRYPT_KEY}|g" "$CONFIG"
# 以下 Grok2 API 节点配置已删除,不再使用
# sed -i "s|__VOLCENGINE_ARK_API_KEY__|${VOLCENGINE_ARK_API_KEY}|g" "$CONFIG"
# sed -i "s|__VOLCENGINE_PROXY_TOKEN__|${VOLCENGINE_PROXY_TOKEN}|g" "$CONFIG"
# sed -i "s|__VOLCENGINE_PROXY_URL__|${VOLCENGINE_PROXY_URL}|g" "$CONFIG"
# sed -i "s|__HFOPCF_GROK2API_KEY__|${HFOPCF_GROK2API_KEY}|g" "$CONFIG"
# sed -i "s|__HFOPCF_GROK2API_BASE_URL__|${HFOPCF_GROK2API_BASE_URL}|g" "$CONFIG"
# sed -i "s|__HFOP_GROK2API_B_KEY__|${HFOP_GROK2API_B_KEY}|g" "$CONFIG"
# sed -i "s|__HFOP_GROK2API_B_BASE_URL__|${HFOP_GROK2API_B_BASE_URL}|g" "$CONFIG"
# sed -i "s|__HFOPKUAKE_GROK2API_KEY__|${HFOPKUAKE_GROK2API_KEY}|g" "$CONFIG"
# sed -i "s|__HFOPKUAKE_GROK2API_BASE_URL__|${HFOPKUAKE_GROK2API_BASE_URL}|g" "$CONFIG"
# sed -i "s|__HFOPSOUGOU_GROK2API_KEY__|${HFOPSOUGOU_GROK2API_KEY}|g" "$CONFIG"
# sed -i "s|__HFOPSOUGOU_GROK2API_BASE_URL__|${HFOPSOUGOU_GROK2API_BASE_URL}|g" "$CONFIG"
# sed -i "s|__HFOPVIDEOSOUGOU_GROK_API_KEY__|${HFOPVIDEOSOUGOU_GROK_API_KEY}|g" "$CONFIG"
# sed -i "s|__HFOPVIDEOSOUGOU_GROK_BASE_URL__|${HFOPVIDEOSOUGOU_GROK_BASE_URL}|g" "$CONFIG"
# sed -i "s|__HFGROK2API_KEY__|${HFGROK2API_KEY}|g" "$CONFIG"
# sed -i "s|__HFGROK2API_BASE_URL__|${HFGROK2API_BASE_URL}|g" "$CONFIG"
echo "✅ Placeholders replaced"
echo ""
echo "=== Debug: Checking config file after replacement ==="
grep -n '"token"' "$CONFIG" | head -10
echo ""
echo "=== Debug: Checking if any placeholders remain ==="
PLACEHOLDER_COUNT=$(grep -o "__[A-Z_]*__" "$CONFIG" | wc -l)
echo "Remaining placeholders: $PLACEHOLDER_COUNT"
if [ "$PLACEHOLDER_COUNT" -ne 0 ]; then
echo "⚠️ WARNING: Found unreplaced placeholders:"
grep -o "__[A-Z_]*__" "$CONFIG" | sort -u
fi
echo ""
# Fix config file permission (suppress security audit warning)
chmod 600 "$CONFIG"
# Check outbound IP and notify if changed
CURRENT_IP=$(curl -s --max-time 10 https://ifconfig.me || curl -s --max-time 10 https://api.ipify.org || echo "unknown")
# ============================================================
# 打印HF空间当前动态IP地址(醒目显示)
# ============================================================
echo ""
echo "════════════════════════════════════════════════════════════════"
echo "🌐 HF Space Outbound IP: ${CURRENT_IP}"
echo "════════════════════════════════════════════════════════════════"
echo ""
# ============================================================
# 测试微信公众号 API 连通性
# ============================================================
if [ -n "$WECHAT_APP_ID" ] && [ -n "$WECHAT_APP_SECRET" ]; then
echo "=== Testing WeChat Official Account API connectivity ==="
WECHAT_TOKEN_URL="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${WECHAT_APP_ID}&secret=${WECHAT_APP_SECRET}"
WECHAT_RESPONSE=$(curl -s --max-time 10 "$WECHAT_TOKEN_URL" || echo '{"errcode":-1,"errmsg":"network error"}')
# 检查是否成功获取 access_token
if echo "$WECHAT_RESPONSE" | grep -q '"access_token"'; then
echo "✅ WeChat API connection successful"
echo " Access Token obtained (expires in 7200s)"
else
echo "❌ WeChat API connection FAILED"
echo " Response: $WECHAT_RESPONSE"
# 解析错误信息
ERRCODE=$(echo "$WECHAT_RESPONSE" | grep -o '"errcode":[0-9-]*' | cut -d':' -f2)
ERRMSG=$(echo "$WECHAT_RESPONSE" | grep -o '"errmsg":"[^"]*"' | cut -d'"' -f4)
if [ -n "$ERRCODE" ]; then
echo " ❌ Error Code: $ERRCODE"
echo " ❌ Error Message: $ERRMSG"
# 常见错误提示
case "$ERRCODE" in
40013)
echo " 💡 Hint: Invalid AppID, please check WECHAT_APP_ID"
;;
40001)
echo " 💡 Hint: Invalid AppSecret, please check WECHAT_APP_SECRET"
;;
40164)
echo " 💡 Hint: IP not in whitelist, please add ${CURRENT_IP} to WeChat Official Account IP whitelist"
;;
-1)
echo " 💡 Hint: Network error or API timeout"
;;
esac
fi
fi
echo ""
else
echo "⚠️ WECHAT_APP_ID or WECHAT_APP_SECRET not set, skipping WeChat API test"
echo ""
fi
LAST_IP=""
if [ -f "$IP_RECORD" ]; then
LAST_IP=$(cat "$IP_RECORD")
fi
if [ "$CURRENT_IP" != "unknown" ] && [ "$CURRENT_IP" != "$LAST_IP" ]; then
echo "$CURRENT_IP" > "$IP_RECORD"
if [ -n "$WECOM_WEBHOOK_KEY" ]; then
WEBHOOK_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${WECOM_WEBHOOK_KEY}"
if [ -z "$LAST_IP" ]; then
MSG="🦞 OpenClaw HF Space 首次启动\n\n出口IP: ${CURRENT_IP}\n\n请确认该IP已添加到企业微信可信IP白名单中。"
else
MSG="⚠️ OpenClaw HF Space 出口IP已变更\n\n旧IP: ${LAST_IP}\n新IP: ${CURRENT_IP}\n\n请立即到企业微信后台更新可信IP白名单,否则 wecom-app 将无法主动发送消息。"
fi
curl -s -X POST "$WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d "{\"msgtype\":\"text\",\"text\":{\"content\":\"${MSG}\"}}" \
|| echo "Failed to send webhook notification"
fi
fi
# ============================================================
# 验证 openclaw-china channels 插件(已在 Dockerfile 中安装)
# ============================================================
echo "=== Verifying openclaw-china channels plugin ==="
if node /app/openclaw.mjs plugins list 2>&1 | grep -qi "channels"; then
echo "✅ @openclaw-china/channels plugin is installed and loaded"
else
echo "⚠️ @openclaw-china/channels plugin not found, attempting runtime install..."
if node /app/openclaw.mjs plugins install @openclaw-china/channels; then
echo "✅ @openclaw-china/channels plugin installed successfully at runtime"
else
echo "❌ Failed to install @openclaw-china/channels plugin"
fi
fi
# ============================================================
# 克隆 wechat-allauto-gzh 项目(运行时克隆,确保始终获取 fork 最新版本)
# ============================================================
echo "=== Cloning wechat-allauto-gzh project from fork ==="
WECHAT_SKILL_DIR="/root/.openclaw/workspace/wechat-allauto-gzh"
WECHAT_ALLAUTO_GZH_REPO_URL="${WECHAT_ALLAUTO_GZH_REPO_URL:-https://github.com/Viciy2023/wechat-allauto-gzh.git}"
WECHAT_ALLAUTO_GZH_BRANCH="${WECHAT_ALLAUTO_GZH_BRANCH:-main}"
if [ -d "$WECHAT_SKILL_DIR/.git" ]; then
echo "⚠️ wechat-allauto-gzh already exists, pulling latest fork changes..."
git -C "$WECHAT_SKILL_DIR" fetch origin "$WECHAT_ALLAUTO_GZH_BRANCH" && \
git -C "$WECHAT_SKILL_DIR" checkout "$WECHAT_ALLAUTO_GZH_BRANCH" && \
git -C "$WECHAT_SKILL_DIR" pull --ff-only origin "$WECHAT_ALLAUTO_GZH_BRANCH" || echo "Failed to pull latest fork changes"
else
echo "Cloning wechat-allauto-gzh from fork repository..."
mkdir -p /root/.openclaw/workspace
rm -rf "$WECHAT_SKILL_DIR"
git clone --depth 1 --branch "$WECHAT_ALLAUTO_GZH_BRANCH" "$WECHAT_ALLAUTO_GZH_REPO_URL" "$WECHAT_SKILL_DIR" || \
echo "❌ Failed to clone wechat-allauto-gzh fork"
fi
if [ -d "$WECHAT_SKILL_DIR" ]; then
echo "✅ wechat-allauto-gzh fork is ready at: $WECHAT_SKILL_DIR"
# 安装 Python 依赖(Agent 只需要 Python 环境)
echo "=== Installing Python dependencies ==="
pip install --no-cache-dir requests pyyaml --break-system-packages || echo "⚠️ pip install failed"
else
echo "❌ wechat-allauto-gzh directory not found after clone attempt"
fi
# ============================================================
# ClawHub 技能、agent-browser CLI 兜底安装、Skill Node 依赖安装与技能校验
# 已迁移到 Dockerfile 构建阶段,运行时仅输出状态,避免容器启动时再进行网络安装。
# ============================================================
echo "=== ClawHub skills are preinstalled during Docker build ==="
SKILLS_DIR="/root/.openclaw/workspace/skills"
if [ -d "$SKILLS_DIR" ]; then
echo "📂 Workspace skills directory contents:"
ls -la "$SKILLS_DIR" || echo "⚠️ Failed to list skills directory"
else
echo "⚠️ Workspace skills directory not found at runtime: $SKILLS_DIR"
fi
echo ""
echo "=== Verifying preinstalled agent-browser CLI ==="
if command -v agent-browser >/dev/null 2>&1; then
echo "✅ agent-browser CLI is available"
agent-browser --version || echo "⚠️ agent-browser version check failed"
else
echo "⚠️ agent-browser CLI not found at runtime; image build verification may have failed"
fi
echo ""
# ============================================================
# 跳过容器内 openclaw doctor --fix
# doctor 会触发 systemd/gateway 相关检查,不适合 HF 容器前台启动模式
# ============================================================
echo "=== Skipping openclaw doctor --fix in container runtime ==="
# ============================================================
# 安装微信 CLI
# ============================================================
echo "=== Installing WeChat CLI ==="
if npx -y @tencent-weixin/openclaw-weixin-cli@latest install; then
echo "✅ WeChat CLI installed successfully"
else
echo "⚠️ WeChat CLI installation failed, continuing anyway..."
fi
# ============================================================
# 配置微信公众号凭证
# ============================================================
echo "=== Configuring WeChat Official Account credentials ==="
WECHAT_CREDS_FILE="/root/.openclaw/workspace/wechat-allauto-gzh/credentials.json"
if [ -n "$WECHAT_APP_ID" ] && [ -n "$WECHAT_APP_SECRET" ]; then
cat > "$WECHAT_CREDS_FILE" <<EOF
{
"AppID": "${WECHAT_APP_ID}",
"AppSecret": "${WECHAT_APP_SECRET}"
}
EOF
chmod 600 "$WECHAT_CREDS_FILE"
echo "✅ WeChat credentials.json created at: $WECHAT_CREDS_FILE"
echo " AppID: ${WECHAT_APP_ID}"
else
echo "⚠️ WECHAT_APP_ID or WECHAT_APP_SECRET not set"
fi
# 验证 wechat-allauto-gzh 技能是否正确安装
echo "=== Verifying wechat-allauto-gzh skill installation ==="
if [ -d "/root/.openclaw/workspace/wechat-allauto-gzh" ]; then
echo "✅ wechat-allauto-gzh directory exists at workspace"
if [ -f "/root/.openclaw/workspace/wechat-allauto-gzh/SKILL.md" ]; then
echo "✅ SKILL.md found"
else
echo "❌ SKILL.md NOT found"
fi
if [ -d "/root/.openclaw/workspace/wechat-allauto-gzh/src/skills" ]; then
echo "✅ Python skills directory exists"
ls -la /root/.openclaw/workspace/wechat-allauto-gzh/src/skills/ || true
else
echo "❌ Python skills directory NOT found"
fi
if [ -f "$WECHAT_CREDS_FILE" ]; then
echo "✅ credentials.json exists"
else
echo "❌ credentials.json NOT found"
fi
else
echo "❌ wechat-allauto-gzh directory NOT found in workspace"
fi
echo "✅ Config fixed"
# Start gateway
exec node /app/openclaw.mjs gateway --port 7860 --bind lan --allow-unconfigured