auto backup 2026-04-22 08:10:01
This commit is contained in:
parent
1863f9820a
commit
8fcfc2b45f
@ -1 +1 @@
|
|||||||
2026-04-21T08:00:01.234627+08:00
|
2026-04-22T08:00:01.348383+08:00
|
||||||
@ -1,16 +1,17 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# 内容测试问题反馈群消息同步到Wiki脚本
|
# 内容测试问题反馈群消息同步到飞书电子表格脚本
|
||||||
# 群ID: oc_fabff7672e62a9ced7b326ee4a286c26
|
# 群ID: oc_fabff7672e62a9ced7b326ee4a286c26
|
||||||
# 目标Wiki: https://makee-interactive.feishu.cn/wiki/YtJ4wxxkaivHBGk1cYNcPLt5nsd
|
# 目标表格: https://makee-interactive.feishu.cn/wiki/EiPtw2fqWialDIkDvmAcXKp7nUF
|
||||||
# Bot: xiaokui
|
# Bot: xiaokui
|
||||||
# 输出格式:表格(时间 | 反馈人 | 类型 | 内容)
|
# 输出格式:电子表格行(时间 | 反馈人 | 信息类型 | 信息内容(或地址))
|
||||||
|
|
||||||
# 不使用 set -e,手动处理错误
|
# 不使用 set -e,手动处理错误
|
||||||
set -uo pipefail
|
set -uo pipefail
|
||||||
|
|
||||||
# 配置项
|
# 配置项
|
||||||
CHAT_ID="oc_fabff7672e62a9ced7b326ee4a286c26"
|
CHAT_ID="oc_fabff7672e62a9ced7b326ee4a286c26"
|
||||||
OBJ_TOKEN="DfUqddItXoDsnNxPypncbinknxh"
|
SPREADSHEET_TOKEN="EiPtw2fqWialDIkDvmAcXKp7nUF"
|
||||||
|
SHEET_ID="7bce8f"
|
||||||
LAST_SYNC_FILE="/tmp/last_feedback_sync_time"
|
LAST_SYNC_FILE="/tmp/last_feedback_sync_time"
|
||||||
LARK_CLI_CONFIG="/root/.openclaw/credentials/xiaokui"
|
LARK_CLI_CONFIG="/root/.openclaw/credentials/xiaokui"
|
||||||
WORK_DIR="/tmp/feedback_sync_workdir"
|
WORK_DIR="/tmp/feedback_sync_workdir"
|
||||||
@ -58,15 +59,9 @@ fi
|
|||||||
MSG_COUNT=$(echo "$MESSAGES" | wc -l)
|
MSG_COUNT=$(echo "$MESSAGES" | wc -l)
|
||||||
echo "$LOG_PREFIX 发现 $MSG_COUNT 条新消息"
|
echo "$LOG_PREFIX 发现 $MSG_COUNT 条新消息"
|
||||||
|
|
||||||
# 2. 处理每条消息,构建表格内容
|
# 2. 处理每条消息,构建电子表格行数据
|
||||||
# 表格头
|
ROWS="[]"
|
||||||
TABLE_CONTENT="## 📅 同步时间: $(date '+%Y-%m-%d %H:%M')"$'\n\n'
|
|
||||||
TABLE_CONTENT+="| 时间 | 反馈人 | 类型 | 内容 |"$'\n'
|
|
||||||
TABLE_CONTENT+="| --- | --- | --- | --- |"$'\n'
|
|
||||||
|
|
||||||
PROCESSED=0
|
PROCESSED=0
|
||||||
# 收集需要插入图片的消息ID
|
|
||||||
IMAGE_MSGS=""
|
|
||||||
|
|
||||||
while IFS= read -r msg; do
|
while IFS= read -r msg; do
|
||||||
MSG_ID=$(echo "$msg" | jq -r '.message_id')
|
MSG_ID=$(echo "$msg" | jq -r '.message_id')
|
||||||
@ -81,131 +76,101 @@ while IFS= read -r msg; do
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 提取日期和时间
|
# 类型和内容处理
|
||||||
TIME_PART="$CREATE_TIME"
|
TYPE=""
|
||||||
|
|
||||||
# 类型标记和内容
|
|
||||||
TYPE_TAG=""
|
|
||||||
CELL_CONTENT=""
|
CELL_CONTENT=""
|
||||||
|
|
||||||
case "$MSG_TYPE" in
|
case "$MSG_TYPE" in
|
||||||
"text"|"post")
|
"text"|"post")
|
||||||
TYPE_TAG="💬 文本"
|
TYPE="文本"
|
||||||
# 清理HTML标签、管道符(表格分隔符)和换行
|
# 清理HTML标签和换行
|
||||||
CELL_CONTENT=$(echo "$CONTENT" | sed 's/<[^>]*>//g; s/|/|/g' | tr '\n' ' ' | head -c 200)
|
CELL_CONTENT=$(echo "$CONTENT" | sed 's/<[^>]*>//g' | tr '\n' ' ' | head -c 500)
|
||||||
;;
|
;;
|
||||||
"image")
|
"image")
|
||||||
TYPE_TAG="📷 图片"
|
TYPE="图片"
|
||||||
CELL_CONTENT="见下方图片"
|
|
||||||
IMAGE_MSGS+="$msg"$'\n'
|
|
||||||
;;
|
|
||||||
"media")
|
|
||||||
TYPE_TAG="🎬 视频"
|
|
||||||
VIDEO_NAME=$(echo "$CONTENT" | grep -oP 'name="[^"]*"' | head -1 | sed 's/name="//;s/"//' || echo "视频")
|
|
||||||
DURATION=$(echo "$CONTENT" | grep -oP 'duration="[^"]*"' | head -1 | sed 's/duration="//;s/"//' || echo "")
|
|
||||||
CELL_CONTENT="${VIDEO_NAME} (${DURATION})"
|
|
||||||
;;
|
|
||||||
"audio")
|
|
||||||
TYPE_TAG="🎵 语音"
|
|
||||||
CELL_CONTENT="语音消息"
|
|
||||||
;;
|
|
||||||
"file")
|
|
||||||
TYPE_TAG="📎 文件"
|
|
||||||
FILE_NAME=$(echo "$CONTENT" | jq -r '.file_name // "未知文件"' 2>/dev/null || echo "文件")
|
|
||||||
CELL_CONTENT="$FILE_NAME"
|
|
||||||
;;
|
|
||||||
"sticker")
|
|
||||||
TYPE_TAG="😀 表情"
|
|
||||||
CELL_CONTENT="表情包"
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
TYPE_TAG="📌 其他"
|
|
||||||
CELL_CONTENT="${MSG_TYPE}类型"
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
|
|
||||||
# 回复标记
|
|
||||||
REPLY_TO=$(echo "$msg" | jq -r '.reply_to // empty')
|
|
||||||
if [ -n "$REPLY_TO" ]; then
|
|
||||||
CELL_CONTENT="↩️ ${CELL_CONTENT}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
TABLE_CONTENT+="| ${TIME_PART} | ${SENDER_NAME} | ${TYPE_TAG} | ${CELL_CONTENT} |"$'\n'
|
|
||||||
PROCESSED=$((PROCESSED + 1))
|
|
||||||
|
|
||||||
done <<< "$MESSAGES"
|
|
||||||
|
|
||||||
TABLE_CONTENT+=$'\n'
|
|
||||||
|
|
||||||
# 3. 将表格内容追加到Wiki文档
|
|
||||||
if [ "$PROCESSED" -gt 0 ]; then
|
|
||||||
UPDATE_RESULT=$(cd "$WORK_DIR" && LARKSUITE_CLI_CONFIG_DIR="$LARK_CLI_CONFIG" lark-cli docs +update \
|
|
||||||
--doc "$OBJ_TOKEN" \
|
|
||||||
--mode append \
|
|
||||||
--markdown "$TABLE_CONTENT" \
|
|
||||||
--as bot 2>&1)
|
|
||||||
|
|
||||||
UPDATE_OK=$(echo "$UPDATE_RESULT" | jq -r '.ok // false' 2>/dev/null)
|
|
||||||
if [ "$UPDATE_OK" = "true" ]; then
|
|
||||||
echo "$LOG_PREFIX 表格写入成功,共 $PROCESSED 条消息"
|
|
||||||
else
|
|
||||||
echo "$LOG_PREFIX Wiki文档写入失败: $UPDATE_RESULT"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 4. 处理图片消息:下载并插入到文档
|
|
||||||
IMAGE_INSERTED=0
|
|
||||||
if [ -n "$IMAGE_MSGS" ]; then
|
|
||||||
while IFS= read -r msg; do
|
|
||||||
[ -z "$msg" ] && continue
|
|
||||||
|
|
||||||
MSG_ID=$(echo "$msg" | jq -r '.message_id')
|
|
||||||
CONTENT=$(echo "$msg" | jq -r '.content // ""')
|
|
||||||
SENDER_NAME=$(echo "$msg" | jq -r '.sender.name // "未知"')
|
|
||||||
CREATE_TIME=$(echo "$msg" | jq -r '.create_time // ""')
|
|
||||||
IMAGE_KEY=$(echo "$CONTENT" | grep -oP 'img_[a-zA-Z0-9_-]+' | head -1 || true)
|
IMAGE_KEY=$(echo "$CONTENT" | grep -oP 'img_[a-zA-Z0-9_-]+' | head -1 || true)
|
||||||
|
if [ -n "$IMAGE_KEY" ]; then
|
||||||
if [ -z "$IMAGE_KEY" ]; then
|
# 上传图片到COS获取链接
|
||||||
continue
|
IMG_FILE="${WORK_DIR}/${MSG_ID}.png"
|
||||||
fi
|
|
||||||
|
|
||||||
# 下载图片(必须用相对路径)
|
|
||||||
IMG_FILE="${MSG_ID}.png"
|
|
||||||
cd "$WORK_DIR"
|
|
||||||
DL_RESULT=$(LARKSUITE_CLI_CONFIG_DIR="$LARK_CLI_CONFIG" lark-cli im +messages-resources-download \
|
DL_RESULT=$(LARKSUITE_CLI_CONFIG_DIR="$LARK_CLI_CONFIG" lark-cli im +messages-resources-download \
|
||||||
--message-id "$MSG_ID" \
|
--message-id "$MSG_ID" \
|
||||||
--file-key "$IMAGE_KEY" \
|
--file-key "$IMAGE_KEY" \
|
||||||
--type image \
|
--type image \
|
||||||
--output "$IMG_FILE" \
|
--output "$IMG_FILE" \
|
||||||
--as bot 2>/dev/null || echo '{"ok":false}')
|
--as bot 2>/dev/null || echo '{"ok":false}')
|
||||||
|
|
||||||
DL_OK=$(echo "$DL_RESULT" | jq -r '.ok // false' 2>/dev/null)
|
DL_OK=$(echo "$DL_RESULT" | jq -r '.ok // false' 2>/dev/null)
|
||||||
if [ "$DL_OK" != "true" ] || [ ! -s "$WORK_DIR/$IMG_FILE" ]; then
|
if [ "$DL_OK" = "true" ] && [ -s "$IMG_FILE" ]; then
|
||||||
echo "$LOG_PREFIX 图片下载失败: $MSG_ID"
|
# 调用COS上传脚本获取链接
|
||||||
continue
|
COS_URL=$(bash /root/.openclaw/workspace-xiaokui/scripts/upload_to_cos.sh "$IMG_FILE" 2>/dev/null || echo "")
|
||||||
fi
|
if [ -n "$COS_URL" ]; then
|
||||||
|
CELL_CONTENT="$COS_URL"
|
||||||
# 插入图片到文档末尾
|
|
||||||
INSERT_RESULT=$(LARKSUITE_CLI_CONFIG_DIR="$LARK_CLI_CONFIG" lark-cli docs +media-insert \
|
|
||||||
--doc "$OBJ_TOKEN" \
|
|
||||||
--file "$IMG_FILE" \
|
|
||||||
--type image \
|
|
||||||
--caption "📷 ${SENDER_NAME} ${CREATE_TIME}" \
|
|
||||||
--as bot 2>/dev/null || echo '{"ok":false}')
|
|
||||||
|
|
||||||
INSERT_OK=$(echo "$INSERT_RESULT" | jq -r '.ok // false' 2>/dev/null)
|
|
||||||
if [ "$INSERT_OK" = "true" ]; then
|
|
||||||
IMAGE_INSERTED=$((IMAGE_INSERTED + 1))
|
|
||||||
echo "$LOG_PREFIX 图片插入成功: $MSG_ID"
|
|
||||||
else
|
else
|
||||||
echo "$LOG_PREFIX 图片插入失败: $MSG_ID"
|
CELL_CONTENT="图片上传失败"
|
||||||
|
fi
|
||||||
|
rm -f "$IMG_FILE" 2>/dev/null
|
||||||
|
else
|
||||||
|
CELL_CONTENT="图片下载失败"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
CELL_CONTENT="无图片链接"
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"media")
|
||||||
|
TYPE="视频"
|
||||||
|
VIDEO_NAME=$(echo "$CONTENT" | grep -oP 'name="[^"]*"' | head -1 | sed 's/name="//;s/"//' || echo "视频")
|
||||||
|
DURATION=$(echo "$CONTENT" | grep -oP 'duration="[^"]*"' | head -1 | sed 's/duration="//;s/"//' || echo "")
|
||||||
|
CELL_CONTENT="${VIDEO_NAME} (时长${DURATION}秒)"
|
||||||
|
;;
|
||||||
|
"audio")
|
||||||
|
TYPE="语音"
|
||||||
|
CELL_CONTENT="语音消息"
|
||||||
|
;;
|
||||||
|
"file")
|
||||||
|
TYPE="文件"
|
||||||
|
FILE_NAME=$(echo "$CONTENT" | jq -r '.file_name // "未知文件"' 2>/dev/null || echo "文件")
|
||||||
|
CELL_CONTENT="$FILE_NAME"
|
||||||
|
;;
|
||||||
|
"sticker")
|
||||||
|
TYPE="表情"
|
||||||
|
CELL_CONTENT="表情包"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
TYPE="其他"
|
||||||
|
CELL_CONTENT="${MSG_TYPE}类型消息"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# 回复标记
|
||||||
|
REPLY_TO=$(echo "$msg" | jq -r '.reply_to // empty')
|
||||||
|
if [ -n "$REPLY_TO" ]; then
|
||||||
|
CELL_CONTENT="[回复] ${CELL_CONTENT}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f "$WORK_DIR/$IMG_FILE" 2>/dev/null
|
# 添加行数据
|
||||||
done <<< "$IMAGE_MSGS"
|
ROW=$(echo "[]" | jq --arg t "$CREATE_TIME" --arg s "$SENDER_NAME" --arg ty "$TYPE" --arg c "$CELL_CONTENT" '. + [$t, $s, $ty, $c]')
|
||||||
|
ROWS=$(echo "$ROWS" | jq --argjson row "$ROW" '. + [$row]')
|
||||||
|
PROCESSED=$((PROCESSED + 1))
|
||||||
|
|
||||||
|
done <<< "$MESSAGES"
|
||||||
|
|
||||||
|
# 3. 将行数据追加到电子表格
|
||||||
|
if [ "$PROCESSED" -gt 0 ]; then
|
||||||
|
echo "$ROWS" > "${WORK_DIR}/rows.json"
|
||||||
|
APPEND_RESULT=$(LARKSUITE_CLI_CONFIG_DIR="$LARK_CLI_CONFIG" lark-cli sheets +append \
|
||||||
|
--spreadsheet-token "$SPREADSHEET_TOKEN" \
|
||||||
|
--range "${SHEET_ID}!A:D" \
|
||||||
|
--values "$(cat "${WORK_DIR}/rows.json")" \
|
||||||
|
--as bot 2>&1)
|
||||||
|
|
||||||
|
APPEND_OK=$(echo "$APPEND_RESULT" | jq -r '.ok // false' 2>/dev/null)
|
||||||
|
if [ "$APPEND_OK" = "true" ]; then
|
||||||
|
echo "$LOG_PREFIX 电子表格写入成功,共 $PROCESSED 条消息"
|
||||||
|
else
|
||||||
|
echo "$LOG_PREFIX 电子表格写入失败: $APPEND_RESULT"
|
||||||
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "$LOG_PREFIX 同步完成: $PROCESSED 条消息, $IMAGE_INSERTED 张图片"
|
echo "$LOG_PREFIX 同步完成: $PROCESSED 条消息"
|
||||||
echo "$CURRENT_ISO" > "$LAST_SYNC_FILE"
|
echo "$CURRENT_ISO" > "$LAST_SYNC_FILE"
|
||||||
else
|
else
|
||||||
echo "$LOG_PREFIX 处理后无有效消息"
|
echo "$LOG_PREFIX 处理后无有效消息"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user