| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- #!/usr/bin/env bash
- # OpenClaw WeChat Skill Deploy v1.2.0 (Bash, Linux/Mac)
- #
- # Usage:
- # ./deploy-to-openclaw.sh # normal deploy
- # ./deploy-to-openclaw.sh --dry-run # preview
- # SKILLS_ROOT=/custom/path ./deploy-to-openclaw.sh
- set -euo pipefail
- DRY_RUN=0
- for arg in "$@"; do
- case "$arg" in
- --dry-run|-DryRun) DRY_RUN=1 ;;
- esac
- done
- SOURCE_ROOT="${SOURCE_ROOT:-$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)}"
- SKILLS_ROOT="${SKILLS_ROOT:-$HOME/.openclaw/skills}"
- CATEGORIES=("wechat")
- # Colors (disabled if not TTY)
- if [ -t 1 ]; then
- CYAN=$'\e[36m'; GREEN=$'\e[32m'; YELLOW=$'\e[33m'; RED=$'\e[31m'; NC=$'\e[0m'
- else
- CYAN=""; GREEN=""; YELLOW=""; RED=""; NC=""
- fi
- echo "=== OpenClaw WeChat Skill Deploy v1.2.0 ==="
- echo "Source: $SOURCE_ROOT"
- echo "Target: $SKILLS_ROOT"
- [ "$DRY_RUN" -eq 1 ] && echo "${YELLOW}[DRY RUN]${NC}"
- [ "$DRY_RUN" -eq 0 ] && mkdir -p "$SKILLS_ROOT"
- deployed=0; skipped=0; errors=0
- # JSON validator: prefer python3, fallback to node, else skip validation
- validate_json() {
- local file="$1"
- if command -v python3 >/dev/null 2>&1; then
- python3 -c "import json,sys; json.load(open(sys.argv[1],encoding='utf-8'))" "$file" >/dev/null 2>&1
- elif command -v node >/dev/null 2>&1; then
- node -e "JSON.parse(require('fs').readFileSync(process.argv[1],'utf8'))" "$file" >/dev/null 2>&1
- else
- return 0
- fi
- }
- for cat in "${CATEGORIES[@]}"; do
- cat_path="$SOURCE_ROOT/$cat"
- [ -d "$cat_path" ] || continue
- echo "${CYAN}--- $cat ---${NC}"
- for skill_dir in "$cat_path"/*/; do
- [ -d "$skill_dir" ] || continue
- name=$(basename "$skill_dir")
- sm="$skill_dir/SKILL.md"
- ac="$skill_dir/api-config.json"
- if [ ! -f "$sm" ]; then
- skipped=$((skipped+1)); continue
- fi
- # api-config.json is optional reference material in v1.1.0+
- if [ -f "$ac" ] && ! validate_json "$ac"; then
- echo " ${RED}[ERR] $name: invalid api-config.json${NC}"
- errors=$((errors+1)); continue
- fi
- dest="$SKILLS_ROOT/$name"
- if [ "$DRY_RUN" -eq 1 ]; then
- if [ -d "$dest" ]; then echo " [UPDATE] $name"; else echo " [NEW] $name"; fi
- else
- rm -rf "$dest"
- mkdir -p "$dest"
- # copy files (non-recursive, skill files only)
- find "$skill_dir" -maxdepth 1 -type f -exec cp {} "$dest/" \;
- echo " ${GREEN}[OK] $name${NC}"
- fi
- deployed=$((deployed+1))
- done
- done
- echo "Result: $deployed deployed, $skipped skipped, $errors errors"
- # ---- Workflows ----
- wf_source="$SOURCE_ROOT/workflows"
- wf_target="$(dirname "$SKILLS_ROOT")/workflows"
- if [ -d "$wf_source" ]; then
- echo "${CYAN}--- workflows ---${NC}"
- if [ "$DRY_RUN" -eq 0 ]; then
- mkdir -p "$wf_target"
- find "$wf_source" -maxdepth 1 -type f | while read -r f; do
- cp "$f" "$wf_target/"
- echo " ${GREEN}[OK] $(basename "$f")${NC}"
- done
- else
- find "$wf_source" -maxdepth 1 -type f | while read -r f; do
- echo " [WORKFLOW] $(basename "$f")"
- done
- fi
- fi
- # ---- Credentials ----
- parent="$(dirname "$SKILLS_ROOT")"
- if [ "$DRY_RUN" -eq 0 ]; then
- tpl="$SOURCE_ROOT/__config/wechat-credentials.template.json"
- if [ -f "$tpl" ]; then
- cp "$tpl" "$parent/wechat-credentials.template.json"
- echo "Template: $parent/wechat-credentials.template.json"
- cred_file="$parent/wechat-credentials.json"
- if [ ! -f "$cred_file" ]; then
- cp "$tpl" "$cred_file"
- echo "${YELLOW}[!] Created $cred_file - please edit wechatApiBase to your server address${NC}"
- fi
- fi
- fi
- # ---- Auto-reply daemon + config ----
- daemon_src="$SOURCE_ROOT/daemon/auto-reply-daemon.js"
- daemon_dst="$parent/auto-reply-daemon.js"
- cfg_tpl_src="$SOURCE_ROOT/daemon/wechat-auto-reply-config.template.json"
- cfg_tpl_dst="$parent/wechat-auto-reply-config.template.json"
- cfg_dst="$parent/wechat-auto-reply-config.json"
- if [ -f "$daemon_src" ]; then
- echo "${CYAN}--- auto-reply daemon ---${NC}"
- if [ "$DRY_RUN" -eq 1 ]; then
- echo " [DAEMON] $daemon_dst"
- echo " [CONFIG-TEMPLATE] $cfg_tpl_dst"
- [ ! -f "$cfg_dst" ] && echo " [CONFIG-DEFAULT] $cfg_dst"
- else
- cp "$daemon_src" "$daemon_dst"
- chmod +x "$daemon_dst" 2>/dev/null || true
- echo " ${GREEN}[OK] $daemon_dst${NC}"
- if [ -f "$cfg_tpl_src" ]; then
- cp "$cfg_tpl_src" "$cfg_tpl_dst"
- echo " ${GREEN}[OK] $cfg_tpl_dst${NC}"
- if [ ! -f "$cfg_dst" ]; then
- cp "$cfg_tpl_src" "$cfg_dst"
- echo " ${YELLOW}[!] Created default config: $cfg_dst (edit to customize reply rules)${NC}"
- fi
- fi
- fi
- fi
- [ "$DRY_RUN" -eq 0 ] && echo "${GREEN}Done!${NC}"
- exit $([ "$errors" -gt 0 ] && echo 1 || echo 0)
|