diff --git a/MEMORY_TEMPLATE.md b/MEMORY_TEMPLATE.md new file mode 100644 index 0000000..7079084 --- /dev/null +++ b/MEMORY_TEMPLATE.md @@ -0,0 +1,28 @@ +# 用户信息 + +## 身份 +- 用户是 WordPress 网站管理员 +- 网站域名:www.nanlou.net +- 使用 OpenClaw 作为 AI 助手 + +## 技术栈 +- WordPress 网站 + 飞书机器人自动化发布 +- 通义千问模型 (qwen-plus, qwen-vl-max, qwen-vl-plus) +- Tushare 金融数据 API +- OpenClaw 部署在宝塔面板 Docker 容器中 + +## 常用操作 +- 发布文章:#标题 + #分类 + 内容 +- 更新文章:#更新 ID/标题 + 新内容(追加模式) +- 飞书机器人 webhook 端口:8080 + +## 分类 +- ai - 人工智能 (ID: 9) +- ai-kepu - AI 科普 (ID: 12) +- ai-zixun - AI 资讯 (ID: 11) +- geo - GEO 优化 (ID: 16) +- jishu - 技术资料 (ID: 5) +- fenxiang - 好物分享 (ID: 10) +- wenzhang - 文章分享 (ID: 4) +- zaji - 杂记 (ID: 8) +- suibi - 随笔 (ID: 7, 默认) diff --git a/feishu_bot.py b/feishu_bot.py index 4695e66..710bbc6 100644 --- a/feishu_bot.py +++ b/feishu_bot.py @@ -165,6 +165,13 @@ class FeishuBot: status=instruction.get('status', 'publish'), images=images if images else None ) + elif instruction.get('action') == 'update': + return self._update_article( + target=instruction.get('target', ''), + text=instruction.get('text', ''), + title=instruction.get('title', ''), + status=instruction.get('status', 'publish') + ) elif instruction.get('action') == 'help': return self._get_help_message() elif instruction.get('action') == 'status': @@ -365,6 +372,9 @@ class FeishuBot: instruction['action'] = 'help' elif line.startswith('#状态') or line.startswith('#status'): instruction['action'] = 'status' + elif line.startswith('#更新') or line.startswith('#update'): + instruction['action'] = 'update' + instruction['target'] = line.replace('#更新', '').replace('#update', '').strip() else: text_lines.append(line) @@ -466,6 +476,49 @@ class FeishuBot: logger.error(f"发布文章失败:{str(e)}", exc_info=True) return f"❌ 发布失败:{str(e)}" + def _update_article(self, target='', text='', title='', status='publish'): + """ + 更新已有文章(追加内容模式) + + Args: + target: 文章 ID 或标题关键词 + text: 新增内容 + title: 新标题(可选) + status: 发布状态 + + Returns: + str: 回复消息 + """ + if not target: + return "⚠️ 请指定文章 ID 或标题,例如:\n`#更新 12345`\n`#更新 文章标题`" + if not text: + return "⚠️ 更新内容不能为空" + + logger.info(f"🔄 准备更新文章 - 目标:{target}") + + try: + from scripts.wp_publish_text import update_post_with_text + + result = update_post_with_text( + target=target, + new_text=text, + new_title=title if title else None, + status=status + ) + + if result.get('success'): + reply = "✅ 文章更新成功!\n" + reply += f"📝 标题:{result.get('title')}\n" + reply += f"🔗 链接:{result.get('post_url')}\n" + reply += f"📊 文章 ID:{result.get('post_id')}" + return reply + else: + return f"❌ 更新失败:{result.get('error')}" + + except Exception as e: + logger.error(f"更新文章失败:{str(e)}", exc_info=True) + return f"❌ 更新失败:{str(e)}" + def _publish_word_document(self, file_path): """ 发布 Word 文档(直接调用 Python 函数) @@ -535,6 +588,7 @@ class FeishuBot: `#标签 标签名` - 指定标签 `#草稿` - 保存为草稿 `#发布` - 立即发布(默认) +`#更新 ID或标题` - 更新已有文章(追加内容) --- @@ -546,6 +600,19 @@ class FeishuBot: 人工智能正在改变世界... ``` +**更新示例**: + +``` +#更新 12345 +新增的内容追加到原文末尾... +``` + +``` +#更新 AI发展趋势 +#标题 AI 发展趋势 2026 更新版 +补充一段关于 Agent 的最新进展... +``` + **可用分类**: - ai - 人工智能 - ai-kepu - Ai 科普 diff --git a/scripts/wp_publish_text.py b/scripts/wp_publish_text.py index 73b2ef4..5544b3e 100644 --- a/scripts/wp_publish_text.py +++ b/scripts/wp_publish_text.py @@ -243,6 +243,101 @@ def publish_text_with_images(text, images=None, instruction=None, status=None, } +def update_post_with_text(target, new_text, new_title=None, status='publish', + category_id=None, tags=None): + """ + 更新已有文章(追加内容模式) + + Args: + target: 文章 ID(数字)或标题关键词(字符串) + new_text: 新增的正文内容 + new_title: 新标题(可选) + status: 发布状态 + category_id: 分类 ID(可选) + tags: 标签列表(可选) + + Returns: + dict: 更新结果 + """ + pl = get_publish_logger() + dl = get_debug_logger() + config = load_config() + + wp_api = create_wp_api(config['wp_url'], config['wp_user'], config['wp_password']) + formatter = create_formatter() + + pl.start_publish('更新文章', target) + + try: + # ========== 步骤 1:查找文章 ========== + post_data = None + post_id = None + + if target.isdigit(): + # 按 ID 精确查找 + post_id = int(target) + result = wp_api.get_post(post_id) + if result.get('success'): + post_data = result.get('data') + else: + pl.error(f"未找到文章 ID: {post_id}") + return {'success': False, 'error': f'未找到文章 ID: {post_id}'} + else: + # 按标题搜索 + search_results = wp_api.search_posts(target, per_page=1) + if not search_results: + pl.error(f"未找到匹配标题的文章: {target}") + return {'success': False, 'error': f'未找到匹配标题的文章: {target}'} + post_data = search_results[0] + post_id = post_data.get('id') + pl.info(f"🔍 搜索匹配到文章 ID: {post_id}") + + # ========== 步骤 2:获取原文内容 ========== + old_content = post_data.get('content', {}).get('rendered', '') + old_title = post_data.get('title', {}).get('rendered', '') + + pl.info(f"📖 原文标题:{old_title},原文长度:{len(old_content)} 字符") + + # ========== 步骤 3:格式化新内容 ========== + new_html = formatter.format_text_content(new_text) + + # ========== 步骤 4:合并内容(追加模式)========== + merged_content = old_content.rstrip() + "\n\n" + new_html.lstrip() + + # ========== 步骤 5:构建更新数据 ========== + final_title = new_title if new_title else old_title + + update_result = wp_api.update_post( + post_id=post_id, + title=final_title, + content=merged_content, + status=status, + categories=[category_id] if category_id else None, + tags=tags + ) + + # ========== 步骤 6:返回结果 ========== + if update_result.get('success'): + post_url = update_result.get('data', {}).get('link', '') + pl.end_publish(True, post_id=post_id, post_url=post_url) + return { + 'success': True, + 'post_id': post_id, + 'post_url': post_url, + 'title': final_title, + 'original_length': len(old_content), + 'merged_length': len(merged_content) + } + else: + pl.end_publish(False, error_msg=update_result.get('error')) + return {'success': False, 'error': update_result.get('error')} + + except Exception as e: + pl.end_publish(False, error_msg=str(e)) + dl.error(f"更新异常:{str(e)}", exc_info=True) + return {'success': False, 'error': str(e)} + + def main(): """命令行入口""" parser = argparse.ArgumentParser(description='WordPress 文字 + 图片发布工具')