|
@@ -0,0 +1,743 @@
|
|
|
|
|
+#!/bin/bash
|
|
|
|
|
+
|
|
|
|
|
+# 企业微信机器人增强版消息发送工具
|
|
|
|
|
+# 支持多种消息类型:文本、文件、图片、语音、Markdown、模板卡片
|
|
|
|
|
+# 作者: AI Assistant
|
|
|
|
|
+# 版本: 2.0
|
|
|
|
|
+
|
|
|
|
|
+# 配置文件路径
|
|
|
|
|
+CONFIG_FILE="$HOME/.wecom_config"
|
|
|
|
|
+
|
|
|
|
|
+# 颜色定义
|
|
|
|
|
+RED='\033[0;31m'
|
|
|
|
|
+GREEN='\033[0;32m'
|
|
|
|
|
+YELLOW='\033[1;33m'
|
|
|
|
|
+BLUE='\033[0;34m'
|
|
|
|
|
+PURPLE='\033[0;35m'
|
|
|
|
|
+CYAN='\033[0;36m'
|
|
|
|
|
+NC='\033[0m' # No Color
|
|
|
|
|
+
|
|
|
|
|
+# 打印彩色消息
|
|
|
|
|
+print_info() {
|
|
|
|
|
+ echo -e "${BLUE}[INFO]${NC} $1"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+print_success() {
|
|
|
|
|
+ echo -e "${GREEN}[SUCCESS]${NC} $1"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+print_warning() {
|
|
|
|
|
+ echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+print_error() {
|
|
|
|
|
+ echo -e "${RED}[ERROR]${NC} $1"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+print_debug() {
|
|
|
|
|
+ echo -e "${PURPLE}[DEBUG]${NC} $1"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+print_title() {
|
|
|
|
|
+ echo -e "${CYAN}$1${NC}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 加载或创建配置
|
|
|
|
|
+load_config() {
|
|
|
|
|
+ if [ -f "$CONFIG_FILE" ]; then
|
|
|
|
|
+ source "$CONFIG_FILE"
|
|
|
|
|
+ if [ -n "$WEBHOOK_KEY" ]; then
|
|
|
|
|
+ print_info "已加载配置文件中的webhook key"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ fi
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ print_warning "未找到配置文件或webhook key为空"
|
|
|
|
|
+ setup_webhook_key
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 设置webhook key
|
|
|
|
|
+setup_webhook_key() {
|
|
|
|
|
+ print_title "=== 企业微信机器人配置 ==="
|
|
|
|
|
+ echo "请输入你的企业微信机器人webhook key:"
|
|
|
|
|
+ echo "(从 https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_KEY 中提取key部分)"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo -n "Webhook Key: "
|
|
|
|
|
+ read webhook_key
|
|
|
|
|
+
|
|
|
|
|
+ if [ -z "$webhook_key" ]; then
|
|
|
|
|
+ print_error "Webhook key不能为空!"
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 保存配置
|
|
|
|
|
+ echo "WEBHOOK_KEY=\"$webhook_key\"" > "$CONFIG_FILE"
|
|
|
|
|
+ print_success "配置已保存到 $CONFIG_FILE"
|
|
|
|
|
+
|
|
|
|
|
+ WEBHOOK_KEY="$webhook_key"
|
|
|
|
|
+ setup_urls
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 设置API URLs
|
|
|
|
|
+setup_urls() {
|
|
|
|
|
+ BASE_URL="https://qyapi.weixin.qq.com/cgi-bin/webhook"
|
|
|
|
|
+ SEND_URL="${BASE_URL}/send?key=${WEBHOOK_KEY}"
|
|
|
|
|
+ UPLOAD_URL="${BASE_URL}/upload_media?key=${WEBHOOK_KEY}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 发送文本消息
|
|
|
|
|
+send_text() {
|
|
|
|
|
+ local content="$1"
|
|
|
|
|
+ local mention="$2"
|
|
|
|
|
+
|
|
|
|
|
+ local json_data
|
|
|
|
|
+ if [ -n "$mention" ]; then
|
|
|
|
|
+ json_data=$(cat << EOF
|
|
|
|
|
+{
|
|
|
|
|
+ "msgtype": "text",
|
|
|
|
|
+ "text": {
|
|
|
|
|
+ "content": "$content",
|
|
|
|
|
+ "mentioned_list": ["$mention"]
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+EOF
|
|
|
|
|
+)
|
|
|
|
|
+ else
|
|
|
|
|
+ json_data=$(cat << EOF
|
|
|
|
|
+{
|
|
|
|
|
+ "msgtype": "text",
|
|
|
|
|
+ "text": {
|
|
|
|
|
+ "content": "$content"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+EOF
|
|
|
|
|
+)
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ send_request "$json_data" "文本消息"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 上传文件/语音
|
|
|
|
|
+upload_media() {
|
|
|
|
|
+ local file_path="$1"
|
|
|
|
|
+ local file_type="${2:-file}"
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f "$file_path" ]; then
|
|
|
|
|
+ print_error "文件不存在: $file_path" >&2
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 检查文件大小
|
|
|
|
|
+ local file_size=$(get_file_size "$file_path")
|
|
|
|
|
+ if [ "$file_size" -le 5 ]; then
|
|
|
|
|
+ print_error "文件大小必须大于5个字节,当前大小: ${file_size} 字节" >&2
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ print_info "正在上传${file_type}文件: $file_path" >&2
|
|
|
|
|
+ local response=$(curl -s -X POST "${UPLOAD_URL}&type=${file_type}" \
|
|
|
|
|
+ -F "media=@$file_path")
|
|
|
|
|
+
|
|
|
|
|
+ local errcode=$(echo "$response" | grep -o '"errcode":[0-9]*' | cut -d':' -f2)
|
|
|
|
|
+ if [ "$errcode" = "0" ]; then
|
|
|
|
|
+ local media_id=$(echo "$response" | grep -o '"media_id":"[^"]*"' | cut -d'"' -f4)
|
|
|
|
|
+ print_success "文件上传成功!media_id: $media_id" >&2
|
|
|
|
|
+ echo "$media_id"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ else
|
|
|
|
|
+ print_error "文件上传失败: $response" >&2
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 获取文件大小(跨平台兼容)
|
|
|
|
|
+get_file_size() {
|
|
|
|
|
+ local file_path="$1"
|
|
|
|
|
+
|
|
|
|
|
+ if command -v stat >/dev/null 2>&1; then
|
|
|
|
|
+ # Linux系统
|
|
|
|
|
+ if stat -c%s "$file_path" >/dev/null 2>&1; then
|
|
|
|
|
+ stat -c%s "$file_path"
|
|
|
|
|
+ # macOS系统
|
|
|
|
|
+ elif stat -f%z "$file_path" >/dev/null 2>&1; then
|
|
|
|
|
+ stat -f%z "$file_path"
|
|
|
|
|
+ else
|
|
|
|
|
+ wc -c < "$file_path" | tr -d ' '
|
|
|
|
|
+ fi
|
|
|
|
|
+ else
|
|
|
|
|
+ wc -c < "$file_path" | tr -d ' '
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 发送文件消息
|
|
|
|
|
+send_file() {
|
|
|
|
|
+ local file_path="$1"
|
|
|
|
|
+
|
|
|
|
|
+ local media_id=$(upload_media "$file_path" "file")
|
|
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local json_data=$(cat << EOF
|
|
|
|
|
+{
|
|
|
|
|
+ "msgtype": "file",
|
|
|
|
|
+ "file": {
|
|
|
|
|
+ "media_id": "$media_id"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+EOF
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+ send_request "$json_data" "文件消息"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 发送语音消息
|
|
|
|
|
+send_voice() {
|
|
|
|
|
+ local voice_path="$1"
|
|
|
|
|
+
|
|
|
|
|
+ # 检查文件格式(简单检查扩展名)
|
|
|
|
|
+ if [[ ! "$voice_path" =~ \.(amr|mp3|wav|m4a)$ ]]; then
|
|
|
|
|
+ print_warning "语音文件建议使用 .amr、.mp3、.wav 或 .m4a 格式"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local media_id=$(upload_media "$voice_path" "voice")
|
|
|
|
|
+ if [ $? -ne 0 ]; then
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local json_data=$(cat << EOF
|
|
|
|
|
+{
|
|
|
|
|
+ "msgtype": "voice",
|
|
|
|
|
+ "voice": {
|
|
|
|
|
+ "media_id": "$media_id"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+EOF
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+ send_request "$json_data" "语音消息"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 发送图片消息
|
|
|
|
|
+send_image() {
|
|
|
|
|
+ local image_path="$1"
|
|
|
|
|
+
|
|
|
|
|
+ if [ ! -f "$image_path" ]; then
|
|
|
|
|
+ print_error "图片文件不存在: $image_path"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 检查文件格式
|
|
|
|
|
+ if [[ ! "$image_path" =~ \.(jpg|jpeg|png|gif)$ ]]; then
|
|
|
|
|
+ print_warning "图片文件建议使用 .jpg、.png 或 .gif 格式"
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 读取图片并转换为base64
|
|
|
|
|
+ if ! command -v base64 >/dev/null 2>&1; then
|
|
|
|
|
+ print_error "系统缺少base64命令,无法发送图片"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local file_size=$(get_file_size "$image_path")
|
|
|
|
|
+ if [ "$file_size" -gt 2097152 ]; then # 2MB
|
|
|
|
|
+ print_error "图片文件不能超过2M,当前大小: $((file_size/1024))KB"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ print_info "正在处理图片: $image_path"
|
|
|
|
|
+ local image_data=$(base64 "$image_path" | tr -d '\n')
|
|
|
|
|
+ local md5_hash
|
|
|
|
|
+
|
|
|
|
|
+ if command -v md5sum >/dev/null 2>&1; then
|
|
|
|
|
+ md5_hash=$(md5sum "$image_path" | cut -d' ' -f1)
|
|
|
|
|
+ elif command -v md5 >/dev/null 2>&1; then
|
|
|
|
|
+ md5_hash=$(md5 -q "$image_path")
|
|
|
|
|
+ else
|
|
|
|
|
+ print_error "系统缺少md5计算工具,无法发送图片"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ local json_data=$(cat << EOF
|
|
|
|
|
+{
|
|
|
|
|
+ "msgtype": "image",
|
|
|
|
|
+ "image": {
|
|
|
|
|
+ "base64": "$image_data",
|
|
|
|
|
+ "md5": "$md5_hash"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+EOF
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+ send_request "$json_data" "图片消息"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 发送Markdown消息
|
|
|
|
|
+send_markdown() {
|
|
|
|
|
+ local content="$1"
|
|
|
|
|
+
|
|
|
|
|
+ local json_data=$(cat << EOF
|
|
|
|
|
+{
|
|
|
|
|
+ "msgtype": "markdown",
|
|
|
|
|
+ "markdown": {
|
|
|
|
|
+ "content": "$content"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+EOF
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+ send_request "$json_data" "Markdown消息"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 发送图文消息
|
|
|
|
|
+send_news() {
|
|
|
|
|
+ local title="$1"
|
|
|
|
|
+ local description="$2"
|
|
|
|
|
+ local url="$3"
|
|
|
|
|
+ local pic_url="$4"
|
|
|
|
|
+
|
|
|
|
|
+ local json_data=$(cat << EOF
|
|
|
|
|
+{
|
|
|
|
|
+ "msgtype": "news",
|
|
|
|
|
+ "news": {
|
|
|
|
|
+ "articles": [
|
|
|
|
|
+ {
|
|
|
|
|
+ "title": "$title",
|
|
|
|
|
+ "description": "$description",
|
|
|
|
|
+ "url": "$url",
|
|
|
|
|
+ "picurl": "$pic_url"
|
|
|
|
|
+ }
|
|
|
|
|
+ ]
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+EOF
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+ send_request "$json_data" "图文消息"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 发送文本通知模板卡片
|
|
|
|
|
+send_text_card() {
|
|
|
|
|
+ local title="$1"
|
|
|
|
|
+ local content="$2"
|
|
|
|
|
+ local source_desc="${3:-企业微信机器人}"
|
|
|
|
|
+
|
|
|
|
|
+ local json_data=$(cat << EOF
|
|
|
|
|
+{
|
|
|
|
|
+ "msgtype": "template_card",
|
|
|
|
|
+ "template_card": {
|
|
|
|
|
+ "card_type": "text_notice",
|
|
|
|
|
+ "source": {
|
|
|
|
|
+ "desc": "$source_desc",
|
|
|
|
|
+ "desc_color": 0
|
|
|
|
|
+ },
|
|
|
|
|
+ "main_title": {
|
|
|
|
|
+ "title": "$title"
|
|
|
|
|
+ },
|
|
|
|
|
+ "sub_title_text": "$content"
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+EOF
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+ send_request "$json_data" "文本通知卡片"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 发送图文展示模板卡片
|
|
|
|
|
+send_news_card() {
|
|
|
|
|
+ local title="$1"
|
|
|
|
|
+ local desc="$2"
|
|
|
|
|
+ local image_url="$3"
|
|
|
|
|
+ local jump_url="$4"
|
|
|
|
|
+ local source_desc="${5:-企业微信机器人}"
|
|
|
|
|
+
|
|
|
|
|
+ local json_data=$(cat << EOF
|
|
|
|
|
+{
|
|
|
|
|
+ "msgtype": "template_card",
|
|
|
|
|
+ "template_card": {
|
|
|
|
|
+ "card_type": "news_notice",
|
|
|
|
|
+ "source": {
|
|
|
|
|
+ "desc": "$source_desc",
|
|
|
|
|
+ "desc_color": 0
|
|
|
|
|
+ },
|
|
|
|
|
+ "main_title": {
|
|
|
|
|
+ "title": "$title",
|
|
|
|
|
+ "desc": "$desc"
|
|
|
|
|
+ },
|
|
|
|
|
+ "card_image": {
|
|
|
|
|
+ "url": "$image_url",
|
|
|
|
|
+ "aspect_ratio": 2.25
|
|
|
|
|
+ },
|
|
|
|
|
+ "card_action": {
|
|
|
|
|
+ "type": 1,
|
|
|
|
|
+ "url": "$jump_url"
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+EOF
|
|
|
|
|
+)
|
|
|
|
|
+
|
|
|
|
|
+ send_request "$json_data" "图文展示卡片"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 发送HTTP请求
|
|
|
|
|
+send_request() {
|
|
|
|
|
+ local json_data="$1"
|
|
|
|
|
+ local msg_type="$2"
|
|
|
|
|
+
|
|
|
|
|
+ print_info "正在发送${msg_type}..."
|
|
|
|
|
+ local response=$(curl -s -X POST "$SEND_URL" \
|
|
|
|
|
+ -H "Content-Type: application/json" \
|
|
|
|
|
+ -d "$json_data")
|
|
|
|
|
+
|
|
|
|
|
+ local errcode=$(echo "$response" | grep -o '"errcode":[0-9]*' | cut -d':' -f2)
|
|
|
|
|
+ if [ "$errcode" = "0" ]; then
|
|
|
|
|
+ print_success "${msg_type}发送成功!"
|
|
|
|
|
+ return 0
|
|
|
|
|
+ else
|
|
|
|
|
+ print_error "${msg_type}发送失败: $response"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 发送组合消息
|
|
|
|
|
+send_combo() {
|
|
|
|
|
+ local text_content="$1"
|
|
|
|
|
+ local file_path="$2"
|
|
|
|
|
+ local mention="$3"
|
|
|
|
|
+
|
|
|
|
|
+ print_info "开始发送组合消息(文本+文件)"
|
|
|
|
|
+
|
|
|
|
|
+ if ! send_text "$text_content" "$mention"; then
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ sleep 1 # 避免发送太快
|
|
|
|
|
+
|
|
|
|
|
+ if ! send_file "$file_path"; then
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ print_success "组合消息发送完成!"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 显示帮助信息
|
|
|
|
|
+show_help() {
|
|
|
|
|
+ print_title "企业微信机器人增强版消息发送工具 v2.0"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "用法: $0 [选项]"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "基础消息选项:"
|
|
|
|
|
+ echo " -t, --text TEXT 发送文本消息"
|
|
|
|
|
+ echo " -f, --file FILE 发送文件"
|
|
|
|
|
+ echo " -i, --image IMAGE 发送图片"
|
|
|
|
|
+ echo " -v, --voice VOICE 发送语音"
|
|
|
|
|
+ echo " -m, --markdown TEXT 发送Markdown消息"
|
|
|
|
|
+ echo " -c, --combo TEXT FILE 发送文本+文件组合"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "高级消息选项:"
|
|
|
|
|
+ echo " -n, --news 发送图文消息(交互式输入)"
|
|
|
|
|
+ echo " --text-card 发送文本通知卡片(交互式输入)"
|
|
|
|
|
+ echo " --news-card 发送图文展示卡片(交互式输入)"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "其他选项:"
|
|
|
|
|
+ echo " -@ USERID @指定用户(与文本消息配合使用)"
|
|
|
|
|
+ echo " --config 重新配置webhook key"
|
|
|
|
|
+ echo " --test 测试连接"
|
|
|
|
|
+ echo " -h, --help 显示此帮助信息"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "示例:"
|
|
|
|
|
+ echo " $0 -t \"Hello World\" # 发送文本消息"
|
|
|
|
|
+ echo " $0 -f \"report.pdf\" # 发送文件"
|
|
|
|
|
+ echo " $0 -i \"screenshot.png\" # 发送图片"
|
|
|
|
|
+ echo " $0 -v \"voice.amr\" # 发送语音"
|
|
|
|
|
+ echo " $0 -c \"请查看附件\" \"document.pdf\" # 发送文本+文件"
|
|
|
|
|
+ echo " $0 -t \"重要通知\" -@ \"@all\" # @所有人"
|
|
|
|
|
+ echo " $0 -n # 交互式创建图文消息"
|
|
|
|
|
+ echo " $0 --text-card # 交互式创建文本卡片"
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "配置文件位置: $CONFIG_FILE"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 主菜单
|
|
|
|
|
+show_menu() {
|
|
|
|
|
+ print_title "=================================="
|
|
|
|
|
+ print_title " 企业微信机器人增强版发送工具 v2.0"
|
|
|
|
|
+ print_title "=================================="
|
|
|
|
|
+ echo "1. 发送文本消息"
|
|
|
|
|
+ echo "2. 发送文件"
|
|
|
|
|
+ echo "3. 发送图片"
|
|
|
|
|
+ echo "4. 发送语音"
|
|
|
|
|
+ echo "5. 发送文本+文件组合"
|
|
|
|
|
+ echo "6. 发送Markdown消息"
|
|
|
|
|
+ echo "7. 发送图文消息"
|
|
|
|
|
+ echo "8. 发送文本通知卡片"
|
|
|
|
|
+ echo "9. 发送图文展示卡片"
|
|
|
|
|
+ echo "10. 测试连接"
|
|
|
|
|
+ echo "11. 重新配置webhook key"
|
|
|
|
|
+ echo "12. 退出"
|
|
|
|
|
+ print_title "=================================="
|
|
|
|
|
+ echo -n "请选择操作 (1-12): "
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 测试连接
|
|
|
|
|
+test_connection() {
|
|
|
|
|
+ print_info "测试机器人连接..."
|
|
|
|
|
+ local test_msg="🤖 机器人连接测试 - $(date '+%Y-%m-%d %H:%M:%S')"
|
|
|
|
|
+
|
|
|
|
|
+ if send_text "$test_msg"; then
|
|
|
|
|
+ print_success "机器人连接正常!"
|
|
|
|
|
+ else
|
|
|
|
|
+ print_error "机器人连接失败,请检查webhook key是否正确"
|
|
|
|
|
+ fi
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 交互式输入图文消息
|
|
|
|
|
+interactive_news() {
|
|
|
|
|
+ echo "=== 创建图文消息 ==="
|
|
|
|
|
+ echo -n "标题: "
|
|
|
|
|
+ read title
|
|
|
|
|
+ echo -n "描述: "
|
|
|
|
|
+ read description
|
|
|
|
|
+ echo -n "点击跳转URL: "
|
|
|
|
|
+ read url
|
|
|
|
|
+ echo -n "图片URL(可选): "
|
|
|
|
|
+ read pic_url
|
|
|
|
|
+
|
|
|
|
|
+ if [ -z "$title" ] || [ -z "$url" ]; then
|
|
|
|
|
+ print_error "标题和URL不能为空"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ send_news "$title" "$description" "$url" "$pic_url"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 交互式输入文本卡片
|
|
|
|
|
+interactive_text_card() {
|
|
|
|
|
+ echo "=== 创建文本通知卡片 ==="
|
|
|
|
|
+ echo -n "卡片标题: "
|
|
|
|
|
+ read title
|
|
|
|
|
+ echo -n "卡片内容: "
|
|
|
|
|
+ read content
|
|
|
|
|
+ echo -n "来源描述(可选,默认:企业微信机器人): "
|
|
|
|
|
+ read source_desc
|
|
|
|
|
+
|
|
|
|
|
+ if [ -z "$title" ]; then
|
|
|
|
|
+ print_error "卡片标题不能为空"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ send_text_card "$title" "$content" "${source_desc:-企业微信机器人}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 交互式输入图文卡片
|
|
|
|
|
+interactive_news_card() {
|
|
|
|
|
+ echo "=== 创建图文展示卡片 ==="
|
|
|
|
|
+ echo -n "卡片标题: "
|
|
|
|
|
+ read title
|
|
|
|
|
+ echo -n "卡片描述: "
|
|
|
|
|
+ read desc
|
|
|
|
|
+ echo -n "图片URL: "
|
|
|
|
|
+ read image_url
|
|
|
|
|
+ echo -n "点击跳转URL: "
|
|
|
|
|
+ read jump_url
|
|
|
|
|
+ echo -n "来源描述(可选,默认:企业微信机器人): "
|
|
|
|
|
+ read source_desc
|
|
|
|
|
+
|
|
|
|
|
+ if [ -z "$title" ] || [ -z "$image_url" ] || [ -z "$jump_url" ]; then
|
|
|
|
|
+ print_error "标题、图片URL和跳转URL不能为空"
|
|
|
|
|
+ return 1
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ send_news_card "$title" "$desc" "$image_url" "$jump_url" "${source_desc:-企业微信机器人}"
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 主程序
|
|
|
|
|
+main() {
|
|
|
|
|
+ # 加载配置
|
|
|
|
|
+ load_config
|
|
|
|
|
+ setup_urls
|
|
|
|
|
+
|
|
|
|
|
+ local text_content=""
|
|
|
|
|
+ local file_path=""
|
|
|
|
|
+ local mention=""
|
|
|
|
|
+ local markdown_content=""
|
|
|
|
|
+ local action=""
|
|
|
|
|
+
|
|
|
|
|
+ # 解析命令行参数
|
|
|
|
|
+ while [[ $# -gt 0 ]]; do
|
|
|
|
|
+ case $1 in
|
|
|
|
|
+ -t|--text)
|
|
|
|
|
+ text_content="$2"
|
|
|
|
|
+ action="text"
|
|
|
|
|
+ shift 2
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -f|--file)
|
|
|
|
|
+ file_path="$2"
|
|
|
|
|
+ action="file"
|
|
|
|
|
+ shift 2
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -i|--image)
|
|
|
|
|
+ file_path="$2"
|
|
|
|
|
+ action="image"
|
|
|
|
|
+ shift 2
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -v|--voice)
|
|
|
|
|
+ file_path="$2"
|
|
|
|
|
+ action="voice"
|
|
|
|
|
+ shift 2
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -c|--combo)
|
|
|
|
|
+ text_content="$2"
|
|
|
|
|
+ file_path="$3"
|
|
|
|
|
+ action="combo"
|
|
|
|
|
+ shift 3
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -m|--markdown)
|
|
|
|
|
+ markdown_content="$2"
|
|
|
|
|
+ action="markdown"
|
|
|
|
|
+ shift 2
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -n|--news)
|
|
|
|
|
+ action="news"
|
|
|
|
|
+ shift
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --text-card)
|
|
|
|
|
+ action="text-card"
|
|
|
|
|
+ shift
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --news-card)
|
|
|
|
|
+ action="news-card"
|
|
|
|
|
+ shift
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -@)
|
|
|
|
|
+ mention="$2"
|
|
|
|
|
+ shift 2
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --config)
|
|
|
|
|
+ setup_webhook_key
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ ;;
|
|
|
|
|
+ --test)
|
|
|
|
|
+ test_connection
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ ;;
|
|
|
|
|
+ -h|--help)
|
|
|
|
|
+ show_help
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ ;;
|
|
|
|
|
+ *)
|
|
|
|
|
+ print_error "未知选项: $1"
|
|
|
|
|
+ show_help
|
|
|
|
|
+ exit 1
|
|
|
|
|
+ ;;
|
|
|
|
|
+ esac
|
|
|
|
|
+ done
|
|
|
|
|
+
|
|
|
|
|
+ # 如果没有参数,显示交互式菜单
|
|
|
|
|
+ if [ -z "$action" ]; then
|
|
|
|
|
+ while true; do
|
|
|
|
|
+ show_menu
|
|
|
|
|
+ read choice
|
|
|
|
|
+ echo ""
|
|
|
|
|
+
|
|
|
|
|
+ case $choice in
|
|
|
|
|
+ 1)
|
|
|
|
|
+ echo -n "请输入文本内容: "
|
|
|
|
|
+ read text_input
|
|
|
|
|
+ echo -n "是否@某人(可选,直接回车跳过): "
|
|
|
|
|
+ read mention_input
|
|
|
|
|
+ send_text "$text_input" "$mention_input"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ 2)
|
|
|
|
|
+ echo -n "请输入文件路径: "
|
|
|
|
|
+ read file_input
|
|
|
|
|
+ send_file "$file_input"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ 3)
|
|
|
|
|
+ echo -n "请输入图片路径: "
|
|
|
|
|
+ read image_input
|
|
|
|
|
+ send_image "$image_input"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ 4)
|
|
|
|
|
+ echo -n "请输入语音文件路径: "
|
|
|
|
|
+ read voice_input
|
|
|
|
|
+ send_voice "$voice_input"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ 5)
|
|
|
|
|
+ echo -n "请输入文本内容: "
|
|
|
|
|
+ read text_input
|
|
|
|
|
+ echo -n "请输入文件路径: "
|
|
|
|
|
+ read file_input
|
|
|
|
|
+ send_combo "$text_input" "$file_input"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ 6)
|
|
|
|
|
+ echo -n "请输入Markdown内容: "
|
|
|
|
|
+ read markdown_input
|
|
|
|
|
+ send_markdown "$markdown_input"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ 7)
|
|
|
|
|
+ interactive_news
|
|
|
|
|
+ ;;
|
|
|
|
|
+ 8)
|
|
|
|
|
+ interactive_text_card
|
|
|
|
|
+ ;;
|
|
|
|
|
+ 9)
|
|
|
|
|
+ interactive_news_card
|
|
|
|
|
+ ;;
|
|
|
|
|
+ 10)
|
|
|
|
|
+ test_connection
|
|
|
|
|
+ ;;
|
|
|
|
|
+ 11)
|
|
|
|
|
+ setup_webhook_key
|
|
|
|
|
+ setup_urls
|
|
|
|
|
+ ;;
|
|
|
|
|
+ 12)
|
|
|
|
|
+ print_info "再见!"
|
|
|
|
|
+ break
|
|
|
|
|
+ ;;
|
|
|
|
|
+ *)
|
|
|
|
|
+ print_error "无效选择,请重新输入"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ esac
|
|
|
|
|
+ echo ""
|
|
|
|
|
+ echo "按任意键继续..."
|
|
|
|
|
+ read -n 1
|
|
|
|
|
+ clear
|
|
|
|
|
+ done
|
|
|
|
|
+ exit 0
|
|
|
|
|
+ fi
|
|
|
|
|
+
|
|
|
|
|
+ # 执行相应的操作
|
|
|
|
|
+ case $action in
|
|
|
|
|
+ "text")
|
|
|
|
|
+ send_text "$text_content" "$mention"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ "file")
|
|
|
|
|
+ send_file "$file_path"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ "image")
|
|
|
|
|
+ send_image "$file_path"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ "voice")
|
|
|
|
|
+ send_voice "$file_path"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ "combo")
|
|
|
|
|
+ send_combo "$text_content" "$file_path" "$mention"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ "markdown")
|
|
|
|
|
+ send_markdown "$markdown_content"
|
|
|
|
|
+ ;;
|
|
|
|
|
+ "news")
|
|
|
|
|
+ interactive_news
|
|
|
|
|
+ ;;
|
|
|
|
|
+ "text-card")
|
|
|
|
|
+ interactive_text_card
|
|
|
|
|
+ ;;
|
|
|
|
|
+ "news-card")
|
|
|
|
|
+ interactive_news_card
|
|
|
|
|
+ ;;
|
|
|
|
|
+ esac
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+# 运行主程序
|
|
|
|
|
+main "$@"
|