#!/bin/bash # wechat_send.sh — unified WeChat send CLI via the internal hook # # Usage: # ./wechat_send.sh text # ./wechat_send.sh image # ./wechat_send.sh voice [duration_ms] # # All send operations go through the wechathook LSPosed module's internal API, # which calls WeChat's own w11.r0/w11.s1 factory — no UI simulation. # : talker id as stored in WeChat DB (e.g. 'filehelper', 'wxid_xxx'). # IMPORTANT: test-only with 'filehelper' to avoid account risk. # # Voice notes: # — local SILK V3 file (Tencent prefix \x02#!SILK_V3). # [duration_ms] — playback duration in ms (default: 3000). # The script pushes the SILK to WeChat's cache dir and fires the broadcast. # # Examples: # ./wechat_send.sh text filehelper "hello world" # ./wechat_send.sh image filehelper /tmp/screenshot.png # ./wechat_send.sh voice filehelper /tmp/tts_out.silk 4617 set -e ADB="${ADB:-adb}" WECHAT_CACHE="/data/data/com.tencent.mm/cache/hook_voice_src.amr" usage() { echo "Usage: $0 text " echo " $0 image " echo " $0 voice [duration_ms]" exit 1 } [ $# -lt 3 ] && usage CMD="$1"; WXID="$2"; shift 2 case "$CMD" in text) PAYLOAD="$*" B64_WXID=$(printf '%s' "$WXID" | base64 | tr -d '\n') B64_TEXT=$(printf '%s' "$PAYLOAD" | base64 | tr -d '\n') INNER=$(printf 'TO=$(printf "%%s" "%s" | base64 -d); TEXT=$(printf "%%s" "%s" | base64 -d); am broadcast -a com.hermes.wechat.SEND_MSG_INTERNAL --es to "$TO" --es text "$TEXT"' \ "$B64_WXID" "$B64_TEXT") B64_INNER=$(printf '%s' "$INNER" | base64 | tr -d '\n') echo "Sending text to $WXID..." $ADB shell "su -c 'echo $B64_INNER | base64 -d | sh'" ;; image) # Internal API: WeChat's own b80.u.oj (insert+prebuild) + v70.w.oj (CDN upload). # No UI, no contact picker — fire-and-forget to . Verified full-res delivery. IMAGE_PATH="$1" [ -z "$IMAGE_PATH" ] && usage EXT="${IMAGE_PATH##*.}" # Stage into /sdcard so the WeChat process (runs the hook) can read it, regardless # of whether the source path is root-only. If already under /sdcard this is a no-op copy. SHARE="/sdcard/wechat_send_tmp.$EXT" echo "Staging image to $SHARE..." $ADB shell "su -c 'cp \"$IMAGE_PATH\" \"$SHARE\" && chmod 644 \"$SHARE\"'" echo "Sending image to $WXID via internal API..." $ADB shell "su -c 'am broadcast -a com.hermes.wechat.SEND_IMAGE_INTERNAL --es to \"$WXID\" --es path \"$SHARE\"'" echo "Sent. (Verify via WeChat UI screenshot; full image uploads async via CDN.)" ;; voice) SILK_PATH="$1" DURATION="${2:-3000}" [ -z "$SILK_PATH" ] && usage [ ! -f "$SILK_PATH" ] && { echo "File not found: $SILK_PATH"; exit 1; } echo "Pushing SILK to WeChat cache..." $ADB push "$SILK_PATH" /sdcard/hook_voice_tmp.amr $ADB shell "su -c 'cp /sdcard/hook_voice_tmp.amr $WECHAT_CACHE && chmod 644 $WECHAT_CACHE && chown u0_a330:u0_a330 $WECHAT_CACHE && rm /sdcard/hook_voice_tmp.amr'" echo "Sending voice to $WXID (duration=${DURATION}ms)..." $ADB shell "su -c 'am broadcast -a com.hermes.wechat.SEND_VOICE_INTERNAL --es to $WXID --es src_path $WECHAT_CACHE --ei duration $DURATION'" ;; *) echo "Unknown command: $CMD" usage ;; esac