name: Discord Release Notification on: release: types: [published] jobs: notify-discord: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v4 with: python-version: '3.10' - name: Install dependencies run: pip install openai discord-webhook requests - name: Enhance release notes and send to Discord env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} OPENAI_BASE_URL: https://api.siliconflow.cn/v1 DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | cat > send_discord_notification.py << 'EOF' import os import sys import json from openai import OpenAI import requests from datetime import datetime from discord_webhook import DiscordWebhook, DiscordEmbed # 设置OpenAI客户端 client = OpenAI( api_key=os.environ.get("OPENAI_API_KEY"), base_url=os.environ.get("OPENAI_BASE_URL") ) # 获取GitHub release信息 github_token = os.environ.get("GITHUB_TOKEN") repo = os.environ.get("GITHUB_REPOSITORY") # 直接从GitHub API获取最新release headers = {"Authorization": f"token {github_token}"} response = requests.get(f"https://api.github.com/repos/{repo}/releases/latest", headers=headers) if response.status_code != 200: print(f"Error fetching release info: {response.status_code}") print(response.text) sys.exit(1) release_info = response.json() # 提取需要的信息 release_notes = release_info.get("body", "无发布说明") version = release_info.get("tag_name", "未知版本") # 安全地解析发布日期 published_at = release_info.get("published_at") if published_at: try: release_date = datetime.strptime(published_at, "%Y-%m-%dT%H:%M:%SZ").strftime("%Y年%m月%d日") except ValueError: release_date = "未知日期" else: release_date = "未知日期" # 使用大模型润色发布说明 try: response = client.chat.completions.create( model="deepseek-ai/DeepSeek-V3", messages=[ {"role": "system", "content": "你是一个专业的软件发布公告优化助手。请优化以下发布说明,使其更加生动、专业,并明确区分新功能、优化内容、修复内容和移除内容等类别。保持原有信息的完整性,同时增强可读性和专业性。使用中文回复。\n\n重要:Discord不支持复杂的Markdown格式,因此请使用简单的格式化:\n1. 使用**粗体**和*斜体*而不是Markdown标题\n2. 使用简单的列表符号(•)而不是Markdown列表\n3. 避免使用#、##等标题格式\n4. 不要使用表格、代码块等复杂格式\n5. 确保段落之间有空行\n6. 使用简单的分隔符(如 ------)来分隔不同部分"}, {"role": "user", "content": f"请优化以下版本{version}的发布说明,使其更适合在Discord社区发布。请记住Discord不支持复杂的Markdown格式,所以使用简单的格式化方式:\n\n{release_notes}"} ], temperature=0.7, ) enhanced_notes = response.choices[0].message.content print(f"大模型润色后的发布说明: \n{enhanced_notes}") except Exception as e: print(f"Error calling OpenAI API: {e}") enhanced_notes = release_notes # 如果API调用失败,使用原始发布说明 # 创建Discord消息 webhook_url = os.environ.get("DISCORD_WEBHOOK_URL") if not webhook_url: print("Error: DISCORD_WEBHOOK_URL not set") sys.exit(1) webhook = DiscordWebhook(url=webhook_url) # 创建嵌入式消息 embed = DiscordEmbed( title=f"🚀 NarratoAI {version} 发布公告", description=f"发布日期: {release_date}", color="5865F2" # Discord蓝色 ) # 处理发布说明,确保不超过Discord的字段限制 # Discord字段值限制为1024个字符 MAX_FIELD_LENGTH = 1024 # 如果内容很短,直接添加 if enhanced_notes and len(enhanced_notes) <= MAX_FIELD_LENGTH: embed.add_embed_field(name="📋 更新内容", value=enhanced_notes) elif enhanced_notes: # 尝试按段落或明显的分隔符分割内容 sections = [] # 检查是否有明显的新功能、优化、修复等部分 if "**新增功能**" in enhanced_notes or "**新功能**" in enhanced_notes: parts = enhanced_notes.split("**新增功能**", 1) if len(parts) > 1: intro = parts[0].strip() if intro: sections.append(("📋 更新概述", intro)) rest = "**新增功能**" + parts[1] # 进一步分割剩余部分 feature_end = -1 for marker in ["**优化内容**", "**性能优化**", "**修复内容**", "**bug修复**", "**问题修复**"]: pos = rest.lower().find(marker.lower()) if pos != -1 and (feature_end == -1 or pos < feature_end): feature_end = pos if feature_end != -1: sections.append(("✨ 新增功能", rest[:feature_end].strip())) rest = rest[feature_end:] else: sections.append(("✨ 新增功能", rest.strip())) rest = "" # 继续分割剩余部分 if rest: optimize_end = -1 for marker in ["**修复内容**", "**bug修复**", "**问题修复**"]: pos = rest.lower().find(marker.lower()) if pos != -1 and (optimize_end == -1 or pos < optimize_end): optimize_end = pos if optimize_end != -1: sections.append(("⚡ 优化内容", rest[:optimize_end].strip())) sections.append(("🔧 修复内容", rest[optimize_end:].strip())) else: sections.append(("⚡ 优化内容", rest.strip())) else: # 如果没有明显的结构,按长度分割 chunks = [enhanced_notes[i:i+MAX_FIELD_LENGTH] for i in range(0, len(enhanced_notes), MAX_FIELD_LENGTH)] for i, chunk in enumerate(chunks): if i == 0: sections.append(("📋 更新内容", chunk)) else: sections.append((f"📋 更新内容(续{i})", chunk)) # 添加所有部分到embed for name, content in sections: if len(content) > MAX_FIELD_LENGTH: # 如果单个部分仍然过长,进一步分割 sub_chunks = [content[i:i+MAX_FIELD_LENGTH] for i in range(0, len(content), MAX_FIELD_LENGTH)] for i, chunk in enumerate(sub_chunks): if i == 0: embed.add_embed_field(name=name, value=chunk) else: embed.add_embed_field(name=f"{name}(续{i})", value=chunk) else: embed.add_embed_field(name=name, value=content) else: embed.add_embed_field(name="📋 更新内容", value="无详细更新内容") # 添加下载链接 html_url = release_info.get("html_url", "") if html_url: embed.add_embed_field(name="📥 下载链接", value=html_url, inline=False) # 设置页脚 embed.set_footer(text=f"NarratoAI 团队 • {release_date}") embed.set_timestamp() # 添加嵌入式消息到webhook webhook.add_embed(embed) # 发送消息 response = webhook.execute() if response: print(f"Discord notification sent with status code: {response.status_code}") else: print("Failed to send Discord notification") EOF # 执行脚本 python send_discord_notification.py