跳到主要内容Stable Diffusion v1.5 创意工作流整合:Figma/Notion/Slack 自动化方案 | 极客日志PythonAI算法
Stable Diffusion v1.5 创意工作流整合:Figma/Notion/Slack 自动化方案
介绍如何将 Stable Diffusion v1.5 模型集成到 Figma、Notion 和 Slack 中,构建自动化创意工作流。通过封装 API 服务、搭建网关层及开发各平台插件,实现无需切换工具即可生成图片并记录参数。方案涵盖架构设计、代码实现细节(Python/JS)、部署配置及安全考虑,旨在提升团队协作效率与创意产出速度。
SecGuard8 浏览 Stable Diffusion v1.5 创意工作流整合:Figma/Notion/Slack 自动化触发方案
你是不是也遇到过这样的场景?在 Figma 里画着设计稿,突然需要一个背景图;在 Notion 里写着产品文档,想配一张概念图;或者在 Slack 群里讨论创意,需要快速生成一张示意图来辅助沟通。每次都要手动打开 Stable Diffusion 界面,输入提示词,等待生成,再下载图片,最后上传到对应工具里——这个过程太繁琐了。
今天我要分享的,就是如何把 Stable Diffusion v1.5 这个经典的文生图模型,无缝整合到你的日常创意工作流中。通过一套自动化方案,让你在 Figma、Notion、Slack 里直接触发图片生成,就像调用一个内置功能一样简单。
1. 为什么需要自动化创意工作流?
在开始技术实现之前,我们先聊聊为什么要做这件事。传统的 AI 图片生成流程有几个明显的痛点:
效率瓶颈:从创意想法到最终图片,中间有太多手动步骤。设计师、产品经理、内容创作者的时间都很宝贵,每次生成图片都要切换工具,打断工作流,效率损失严重。
创意断层:当你在 Figma 里设计时,突然需要一张背景图,如果切换到另一个工具去生成,再回来时可能已经失去了刚才的设计灵感。这种上下文切换对创意工作来说是致命的。
协作障碍:团队协作时,一个人生成了图片,其他人可能不知道参数,无法复现或修改。如果能在 Notion 文档里直接生成并记录参数,协作就会顺畅很多。
质量不稳定:不同人生成的图片风格、质量参差不齐,缺乏统一的标准和流程。
Stable Diffusion v1.5 作为经典的文生图模型,虽然不如最新的 SDXL 或 SD3 那么强大,但它在通用图像生成、创意草图和风格化出图方面表现稳定,而且推理速度快,非常适合集成到自动化工作流中。
2. 整体方案架构设计
我们的目标很简单:在 Figma、Notion、Slack 中触发图片生成,自动调用 Stable Diffusion v1.5,然后把生成的图片和参数返回到原工具中。
2.1 核心组件
- Stable Diffusion v1.5 服务:这是我们的图片生成引擎,部署在本地或云端服务器,开箱即用。
- API 网关层:接收来自不同工具的请求,统一格式后转发给 SD 服务,再把结果返回。
- 工具集成插件:为 Figma、Notion、Slack 开发的客户端插件或机器人。
- 参数管理与模板系统:存储常用的提示词模板、风格预设,确保生成质量的一致性。
2.2 工作流程
假设你在 Figma 里设计一个电商网站的登录页,需要一张'现代简约的办公室背景图'。
- 你在 Figma 插件里输入'modern minimalist office background'
- 插件通过 API 网关调用 Stable Diffusion 服务
- SD 服务在 20 秒内生成图片
- 图片和生成参数自动插入到你的 Figma 画板中
- 同时,这次生成记录被保存到 Notion 数据库,方便团队查看和复现
整个过程完全自动化,你不需要离开 Figma 界面。
3. 技术实现详解
现在我们来拆解每个部分的具体实现。我会提供核心代码和配置,你可以根据自己的需求调整。
3.1 Stable Diffusion API 服务封装
首先,我们需要为 Stable Diffusion v1.5 服务包装一个 REST API。虽然镜像本身提供了 Web 界面,但我们需要一个程序可调用的接口。
import requests
import json
import base64
from io import BytesIO
from PIL import Image
class StableDiffusionAPI:
def __init__(self, base_url="http://localhost:7860/"):
self.base_url = base_url
self.api_endpoint = f"{base_url}/api/predict"
def generate_image(self, prompt, negative_prompt, steps=25, guidance_scale=7.5, width=512, height=512, seed=-1):
""" 调用 Stable Diffusion 生成图片 """
payload = {
"data": [
prompt,
negative_prompt,
steps,
guidance_scale,
width,
height,
seed
]
}
try:
response = requests.post(self.api_endpoint, json=payload, timeout=120)
response.raise_for_status()
result = response.json()
if "data" in result and len(result["data"]) > 0:
image_data = result["data"][0]
if "base64," in image_data:
image_data = image_data.split("base64,")[1]
image_bytes = base64.b64decode(image_data)
image = Image.open(BytesIO(image_bytes))
params_json = result["data"][1] if len(result["data"]) > 1 else "{}"
generation_params = json.loads(params_json)
return {
"success": True,
"image": image,
"image_bytes": image_bytes,
"params": generation_params,
"prompt": prompt,
"seed": generation_params.get("Seed", seed)
}
else:
return {"success": False, "error": "No image data in response"}
except Exception as e:
return {"success": False, "error": str(e)}
def generate_and_save(self, prompt, output_path="generated_image.png", **kwargs):
""" 生成图片并保存到本地 """
result = self.generate_image(prompt, **kwargs)
if result["success"]:
result["image"].save(output_path)
print(f"图片已保存到:{output_path}")
print(f"生成参数:{result['params']}")
params_path = output_path.replace(".png", "_params.json")
with open(params_path, "w") as f:
json.dump(result["params"], f, indent=2)
return result
else:
print(f"生成失败:{result['error']}")
return result
if __name__ == "__main__":
sd_api = StableDiffusionAPI()
result = sd_api.generate_and_save(
prompt="a modern minimalist office with large windows, plants, natural lighting, 3d render",
negative_prompt="lowres, blurry, messy, cluttered",
steps=28,
guidance_scale=7.5,
width=768,
height=512,
seed=42,
output_path="office_background.png"
)
这个 API 封装类提供了两个主要方法:generate_image用于生成图片并返回结果对象,generate_and_save在生成的同时保存图片和参数到本地。
3.2 API 网关与 Webhook 服务
为了让 Figma、Notion、Slack 能够调用我们的 SD 服务,我们需要一个中间层来处理不同的请求格式,并提供身份验证、限流等功能。
from flask import Flask, request, jsonify
import os
from sd_api_wrapper import StableDiffusionAPI
import hashlib
import time
from functools import wraps
app = Flask(__name__)
SD_BASE_URL = os.getenv("SD_BASE_URL", "http://localhost:7860/")
API_KEYS = {
"figma": os.getenv("FIGMA_API_KEY"),
"notion": os.getenv("NOTION_API_KEY"),
"slack": os.getenv("SLACK_API_KEY")
}
sd_api = StableDiffusionAPI(SD_BASE_URL)
def require_api_key(platform):
def decorator(f):
@wraps(f)
def decorated_function(*args, **kwargs):
api_key = request.headers.get('X-API-Key')
expected_key = API_KEYS.get(platform)
if not expected_key or api_key != expected_key:
return jsonify({"error": "Invalid API key"}), 401
return f(*args, **kwargs)
return decorated_function
return decorator
@app.route('/api/generate', methods=['POST'])
def generate_image():
""" 统一的图片生成接口 支持来自不同平台的请求 """
data = request.json
if not data or 'prompt' not in data:
return jsonify({"error": "Missing required parameter: prompt"}), 400
prompt = data['prompt']
negative_prompt = data.get('negative_prompt', '')
steps = data.get('steps', 25)
guidance_scale = data.get('guidance_scale', 7.5)
width = data.get('width', 512)
height = data.get('height', 512)
seed = data.get('seed', -1)
platform = data.get('platform', 'generic')
if platform == 'figma':
width = data.get('width', 1024)
height = data.get('height', 768)
elif platform == 'slack':
width = min(data.get('width', 512), 1024)
height = min(data.get('height', 512), 1024)
result = sd_api.generate_image(
prompt=prompt,
negative_prompt=negative_prompt,
steps=steps,
guidance_scale=guidance_scale,
width=width,
height=height,
seed=seed
)
if result['success']:
import base64
from io import BytesIO
img_byte_arr = BytesIO()
result['image'].save(img_byte_arr, format='PNG')
img_base64 = base64.b64encode(img_byte_arr.getvalue()).decode('utf-8')
response_data = {
"success": True,
"image_base64": img_base64,
"params": result['params'],
"prompt": prompt,
"seed": result['seed'],
"platform": platform,
"timestamp": time.time()
}
if platform == 'notion':
image_id = hashlib.md5(f"{prompt}_{seed}".encode()).hexdigest()[:8]
response_data['image_url'] = f"/temp_images/{image_id}.png"
temp_dir = "temp_images"
os.makedirs(temp_dir, exist_ok=True)
result['image'].save(f"{temp_dir}/{image_id}.png")
return jsonify(response_data)
else:
return jsonify({
"success": False,
"error": result['error'],
"platform": platform
}), 500
@app.route('/api/templates', methods=['GET'])
def get_templates():
""" 获取预定义的提示词模板 """
templates = {
"ui_backgrounds": [
{
"name": "现代科技背景",
"prompt": "futuristic tech background, blue gradient, abstract shapes, clean design, 4k",
"negative_prompt": "text, logo, watermark, blurry",
"width": 1920,
"height": 1080
},
{
"name": "自然风景背景",
"prompt": "peaceful nature landscape, mountains and lake, morning mist, photorealistic, 8k",
"negative_prompt": "people, buildings, cars, text",
"width": 1920,
"height": 1080
}
],
"product_concepts": [
{
"name": "智能设备概念图",
"prompt": "sleek smart home device on wooden table, product photography, studio lighting, clean background",
"negative_prompt": "cluttered, dirty, poor lighting",
"width": 1024,
"height": 768
}
],
"illustrations": [
{
"name": "扁平化插画",
"prompt": "flat design illustration of [subject], minimal colors, clean lines, vector style",
"negative_prompt": "realistic, photorealistic, 3d, detailed",
"width": 800,
"height": 600
}
]
}
return jsonify(templates)
@app.route('/api/health', methods=['GET'])
def health_check():
""" 健康检查端点 """
return jsonify({
"status": "healthy",
"service": "Stable Diffusion API Gateway",
"sd_available": True,
"timestamp": time.time()
})
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000, debug=True)
- 统一的图片生成接口,支持来自不同平台的请求
- API 密钥验证,确保只有授权的工具可以调用
- 平台特定的参数处理(如 Figma 需要大图,Slack 需要小图)
- 提示词模板管理,确保生成质量的一致性
- 健康检查端点,方便监控服务状态
3.3 Figma 插件开发
Figma 插件使用 HTML/CSS/JavaScript 开发,可以通过 Figma 的插件 API 与设计工具交互。
const html = `
<div style="font-family: 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;">
<h2>🎨 AI 图像生成</h2>
<div>
<label>提示词(英文)</label>
<textarea placeholder="例如:a modern minimalist office background with plants and natural light"></textarea>
</div>
<div>
<label>排除内容(可选)</label>
<input type="text" placeholder="例如:text, logo, watermark, blurry">
</div>
<div>
<div>
<label>宽度</label>
<select>
<option value="512">512px</option>
<option value="768">768px</option>
<option value="1024" selected>1024px</option>
<option value="1920">1920px</option>
</select>
</div>
<div>
<label>高度</label>
<select>
<option value="512">512px</option>
<option value="768" selected>768px</option>
<option value="1024">1024px</option>
<option value="1080">1080px</option>
</select>
</div>
</div>
<div>
<label>模板</label>
<select>
<option>自定义提示词</option>
<option value="ui_background_modern">UI 背景 - 现代科技</option>
<option value="ui_background_nature">UI 背景 - 自然风景</option>
<option value="product_concept">产品概念图</option>
<option value="illustration_flat">扁平化插画</option>
</select>
</div>
<button>生成图片</button>
<div></div>
<div>
<h4>模板说明</h4>
<p></p>
</div>
</div>`;
figma.showUI(html, { width: 400, height: 500 });
figma.ui.onmessage = async (message) => {
if (message.type === 'generate-image') {
const { prompt, negativePrompt, width, height, template } = message;
figma.ui.postMessage({ type: 'status', message: '正在生成图片...', status: 'loading' });
try {
const response = await fetch('https://your-api-gateway.com/api/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'your-figma-api-key-here'
},
body: JSON.stringify({
prompt: prompt,
negative_prompt: negativePrompt || '',
width: parseInt(width),
height: parseInt(height),
platform: 'figma',
template: template
})
});
const result = await response.json();
if (result.success) {
const imageBytes = Uint8Array.from(atob(result.image_base64), c => c.charCodeAt(0));
const image = figma.createImage(imageBytes);
const frame = figma.createFrame();
frame.resize(parseInt(width), parseInt(height));
frame.fills = [{ type: 'IMAGE', imageHash: image.hash, scaleMode: 'FILL' }];
figma.currentPage.appendChild(frame);
frame.name = `AI 生成:${prompt.substring(0, 50)}...`;
frame.description = `提示词:${prompt}\n负向提示:${negativePrompt}\n尺寸:${width}x${height}\n种子:${result.seed}`;
figma.currentPage.selection = [frame];
figma.viewport.scrollAndZoomIntoView([frame]);
figma.ui.postMessage({ type: 'status', message: '图片已生成并插入画板!', status: 'success' });
await logToNotion({
prompt: prompt,
negative_prompt: negativePrompt,
width: width,
height: height,
seed: result.seed,
platform: 'figma',
file_url: figma.fileKey ? `https://www.figma.com/file/${figma.fileKey}` : 'local'
});
} else {
figma.ui.postMessage({ type: 'status', message: `生成失败:${result.error}`, status: 'error' });
}
} catch (error) {
figma.ui.postMessage({ type: 'status', message: `请求失败:${error.message}`, status: 'error' });
}
}
if (message.type === 'get-templates') {
try {
const response = await fetch('https://your-api-gateway.com/api/templates');
const templates = await response.json();
figma.ui.postMessage({ type: 'templates-data', templates: templates });
} catch (error) {
console.error('获取模板失败:', error);
}
}
};
async function logToNotion(generationData) {
try {
const response = await fetch('https://your-api-gateway.com/api/log-to-notion', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'your-notion-api-key-here'
},
body: JSON.stringify(generationData)
});
return await response.json();
} catch (error) {
console.error('记录到 Notion 失败:', error);
}
}
这个 Figma 插件提供了完整的 UI 界面,用户可以直接在 Figma 中输入提示词、选择尺寸和模板,然后一键生成图片并插入到当前画板中。生成的图片还会自动记录生成参数,方便后续修改和复现。
3.4 Notion 集成方案
Notion 可以通过官方 API 和 Webhook 进行集成。我们可以创建一个 Notion 数据库来记录所有生成的图片,并在 Notion 中直接触发生成。
import requests
import json
from datetime import datetime
class NotionIntegration:
def __init__(self, api_key, database_id):
self.api_key = api_key
self.database_id = database_id
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"Notion-Version": "2022-06-28"
}
def create_generation_record(self, prompt, image_url, params, platform="notion"):
""" 在 Notion 中创建生成记录 """
page_data = {
"parent": {"database_id": self.database_id},
"properties": {
"Name": { "title": [{ "text": { "content": prompt[:50] + ("..." if len(prompt) > 50 else "") } }] },
"Prompt": { "rich_text": [{ "text": { "content": prompt } }] },
"Platform": { "select": { "name": platform } },
"Date": { "date": { "start": datetime.now().isoformat() } },
"Seed": { "number": params.get("Seed", -1) },
"Status": { "status": { "name": "已完成" } }
},
"children": [
{ "object": "block", "type": "image", "image": { "type": "external", "external": { "url": image_url } } },
{ "object": "block", "type": "code", "code": { "rich_text": [{ "type": "text", "text": { "content": json.dumps(params, indent=2) } }], "language": "json" } }
]
}
response = requests.post("https://api.notion.com/v1/pages", headers=self.headers, json=page_data)
if response.status_code == 200:
return response.json()
else:
print(f"创建 Notion 记录失败:{response.status_code}, {response.text}")
return None
def generate_from_notion(self, prompt, page_id):
""" 从 Notion 页面触发图片生成 """
sd_api = StableDiffusionAPI()
result = sd_api.generate_image(prompt=prompt)
if result["success"]:
image_url = self.upload_to_cdn(result["image_bytes"])
self.update_notion_page_with_image(page_id, image_url, result["params"])
return { "success": True, "image_url": image_url, "page_id": page_id }
else:
return {"success": False, "error": result["error"]}
def upload_to_cdn(self, image_bytes):
""" 上传图片到 CDN(简化版,实际应该用 AWS S3、阿里云 OSS 等) """
import hashlib
image_hash = hashlib.md5(image_bytes).hexdigest()[:16]
return f"https://your-cdn.com/images/{image_hash}.png"
def update_notion_page_with_image(self, page_id, image_url, params):
""" 在 Notion 页面中添加生成的图片 """
update_data = {
"children": [
{ "object": "block", "type": "heading_2", "heading_2": { "rich_text": [{ "type": "text", "text": { "content": "🎨 生成的图片" } }] } },
{ "object": "block", "type": "image", "image": { "type": "external", "external": { "url": image_url } } },
{ "object": "block", "type": "heading_3", "heading_3": { "rich_text": [{ "type": "text", "text": { "content": "生成参数" } }] } },
{ "object": "block", "type": "code", "code": { "rich_text": [{ "type": "text", "text": { "content": json.dumps(params, indent=2) } }], "language": "json" } }
]
}
response = requests.patch(f"https://api.notion.com/v1/blocks/{page_id}/children", headers=self.headers, json=update_data)
return response.status_code == 200
NOTION_CONFIG = {
"api_key": "your-notion-integration-token",
"database_id": "your-database-id-here",
"webhook_secret": "your-webhook-secret"
}
if __name__ == "__main__":
notion = NotionIntegration(
api_key=NOTION_CONFIG["api_key"],
database_id=NOTION_CONFIG["database_id"]
)
record = notion.create_generation_record(
prompt="a beautiful sunset over mountains, digital art",
image_url="https://example.com/sunset.png",
params={
"Steps": 25,
"Guidance Scale": 7.5,
"Seed": 12345,
"Width": 512,
"Height": 512
},
platform="测试"
)
if record:
print(f"已在 Notion 中创建记录:{record['id']}")
- 自动记录所有图片生成任务到 Notion 数据库,方便团队管理和检索
- 通过 Notion 页面直接触发图片生成,适合文档编写时的配图需求
3.5 Slack 机器人集成
Slack 机器人可以让团队成员在聊天中直接生成图片,非常适合头脑风暴和快速沟通。
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
import os
from sd_api_wrapper import StableDiffusionAPI
SLACK_BOT_TOKEN = os.environ.get("SLACK_BOT_TOKEN")
SLACK_APP_TOKEN = os.environ.get("SLACK_APP_TOKEN")
app = App(token=SLACK_BOT_TOKEN)
sd_api = StableDiffusionAPI()
@app.command("/generate-image")
def handle_generate_image_command(ack, say, command):
ack()
prompt = command["text"]
user_id = command["user_id"]
channel_id = command["channel_id"]
if not prompt:
say("请提供图片描述,例如:`/generate-image a cute cat wearing glasses`")
return
message = say(f"<@{user_id}> 正在生成图片:*{prompt}*... :hourglass_flowing_sand:")
try:
result = sd_api.generate_image(
prompt=prompt,
negative_prompt="lowres, blurry, text, watermark",
steps=20,
width=512,
height=512
)
if result["success"]:
import tempfile
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp_file:
result["image"].save(tmp_file.name)
tmp_file_path = tmp_file.name
from slack_sdk import WebClient
client = WebClient(token=SLACK_BOT_TOKEN)
upload_result = client.files_upload_v2(
channel=channel_id,
file=tmp_file_path,
title=f"AI 生成:{prompt[:50]}...",
initial_comment=f"<@{user_id}> 图片生成完成!\n提示词:{prompt}\n种子:{result['params'].get('Seed', '随机')}"
)
os.unlink(tmp_file_path)
client.chat_update(
channel=channel_id,
ts=message["ts"],
text=f"<@{user_id}> 图片生成完成! :white_check_mark:"
)
else:
say(f"<@{user_id}> 图片生成失败:{result['error']}")
except Exception as e:
say(f"<@{user_id}> 生成过程中出现错误:{str(e)}")
@app.message("生成图片:")
def handle_generate_image_message(message, say):
text = message["text"]
if text.startswith("生成图片:"):
prompt = text[5:].strip()
if prompt:
user_id = message["user"]
say(f"<@{user_id}> 正在为你生成:*{prompt}*...")
try:
result = sd_api.generate_image(
prompt=prompt,
negative_prompt="lowres, blurry, text, watermark",
steps=20,
width=512,
height=512
)
if result["success"]:
import tempfile
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp_file:
result["image"].save(tmp_file.name)
tmp_file_path = tmp_file.name
from slack_sdk import WebClient
client = WebClient(token=SLACK_BOT_TOKEN)
upload_result = client.files_upload_v2(
channel=message["channel"],
file=tmp_file_path,
title=f"AI 生成:{prompt[:50]}...",
initial_comment=f"<@{user_id}> 你要的图片来啦!\n提示词:{prompt}"
)
os.unlink(tmp_file_path)
else:
say(f"<@{user_id}> 生成失败:{result['error']}")
except Exception as e:
say(f"<@{user_id}> 出错了:{str(e)}")
@app.shortcut("generate_image_shortcut")
def handle_generate_image_shortcut(ack, body, client):
ack()
client.views_open(
trigger_id=body["trigger_id"],
view={
"type": "modal",
"callback_id": "generate_image_modal",
"title": { "type": "plain_text", "text": "AI 图片生成" },
"submit": { "type": "plain_text", "text": "生成" },
"close": { "type": "plain_text", "text": "取消" },
"blocks": [
{ "type": "input", "block_id": "prompt_block", "label": { "type": "plain_text", "text": "图片描述(英文)" }, "element": { "type": "plain_text_input", "action_id": "prompt_input", "multiline": True, "placeholder": { "type": "plain_text", "text": "例如:a futuristic cityscape at night with neon lights and flying cars" } } },
{ "type": "input", "block_id": "negative_prompt_block", "label": { "type": "plain_text", "text": "排除内容(可选)" }, "optional": True, "element": { "type": "plain_text_input", "action_id": "negative_prompt_input", "placeholder": { "type": "plain_text", "text": "例如:text, logo, watermark, blurry" } } },
{ "type": "section", "block_id": "size_block", "text": { "type": "mrkdwn", "text": "选择图片尺寸:" }, "accessory": { "type": "static_select", "action_id": "size_select", "placeholder": { "type": "plain_text", "text": "选择尺寸" }, "options": [ { "text": { "type": "plain_text", "text": "小 (512x512)" }, "value": "512" }, { "text": { "type": "plain_text", "text": "中 (768x768)" }, "value": "768" }, { "text": { "type": "plain_text", "text": "大 (1024x1024)" }, "value": "1024" } ] } }
]
}
)
@app.view("generate_image_modal")
def handle_modal_submission(ack, body, client, view):
ack()
values = view["state"]["values"]
prompt = values["prompt_block"]["prompt_input"]["value"]
negative_prompt = values.get("negative_prompt_block", {}).get("negative_prompt_input", {}).get("value", "")
size = values["size_block"]["size_select"]["selected_option"]["value"]
user_id = body["user"]["id"]
channel_id = body["view"]["private_metadata"]
if not prompt:
return
client.chat_postMessage(
channel=channel_id,
text=f"<@{user_id}> 正在生成图片:*{prompt}*..."
)
try:
result = sd_api.generate_image(
prompt=prompt,
negative_prompt=negative_prompt,
steps=25,
width=int(size),
height=int(size)
)
if result["success"]:
import tempfile
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmp_file:
result["image"].save(tmp_file.name)
tmp_file_path = tmp_file.name
upload_result = client.files_upload_v2(
channel=channel_id,
file=tmp_file_path,
title=f"AI 生成:{prompt[:50]}...",
initial_comment=f"<@{user_id}> 图片生成完成!\n提示词:{prompt}\n尺寸:{size}x{size}\n种子:{result['params'].get('Seed', '随机')}"
)
os.unlink(tmp_file_path)
else:
client.chat_postMessage(
channel=channel_id,
text=f"<@{user_id}> 图片生成失败:{result['error']}"
)
except Exception as e:
client.chat_postMessage(
channel=channel_id,
text=f"<@{user_id}> 生成过程中出现错误:{str(e)}"
)
if __name__ == "__main__":
if not SLACK_BOT_TOKEN or not SLACK_APP_TOKEN:
print("错误:请设置 SLACK_BOT_TOKEN 和 SLACK_APP_TOKEN 环境变量")
exit(1)
handler = SocketModeHandler(app, SLACK_APP_TOKEN)
print("Slack 机器人已启动,等待命令...")
handler.start()
- Slash 命令:输入
/generate-image 图片描述直接生成
- 消息触发:发送"生成图片:描述"格式的消息
- 快捷方式:通过 Slack 快捷方式打开模态窗口,填写更详细的参数
4. 部署与配置指南
现在你已经有了所有代码,接下来看看如何部署这个自动化工作流。
4.1 环境准备
首先,确保你已经部署了 Stable Diffusion v1.5 服务。如果你使用开源镜像,可以直接在镜像市场找到并一键部署。
curl http://localhost:7860/
4.2 API 网关部署
API 网关可以使用任何你熟悉的云服务部署,这里以 Python Flask 应用为例:
mkdir sd-automation-workflow
cd sd-automation-workflow
python -m venv venv
source venv/bin/activate
pip install flask requests pillow
cat > config.py << 'EOF'
import os
SD_BASE_URL = os.getenv("SD_BASE_URL", "http://localhost:7860/")
API_KEYS = {
"figma": os.getenv("FIGMA_API_KEY", "your-figma-api-key"),
"notion": os.getenv("NOTION_API_KEY", "your-notion-api-key"),
"slack": os.getenv("SLACK_API_KEY", "your-slack-api-key")
}
PORT = int(os.getenv("PORT", 5000))
EOF
python api_gateway.py
4.3 工具配置
- 在 Figma 开发者门户创建新插件
- 将
figma-plugin.js 代码复制到 main.js
- 配置 manifest.json 文件
- 在插件设置中填入 API 网关地址和 API 密钥
- 在 Notion 开发者门户创建新集成
- 获取 API 密钥
- 创建数据库并分享给集成
- 在 API 网关中配置 Notion API 密钥
- 在 Slack API 门户创建新应用
- 启用 Socket Mode
- 配置 Slash 命令和快捷方式
- 安装应用到工作空间
- 获取 Bot Token 和 App Token
4.4 安全考虑
- API 密钥管理:不要将 API 密钥硬编码在代码中,使用环境变量或密钥管理服务
- 请求限流:防止 API 被滥用,可以添加速率限制
- 输入验证:验证所有输入参数,防止注入攻击
- 错误处理:友好的错误提示,不泄露内部信息
- 访问日志:记录所有 API 调用,方便审计和调试
5. 实际应用案例与效果
让我分享几个实际使用这个自动化工作流的场景,看看它能带来多大的效率提升。
5.1 设计团队的工作流优化
某电商公司的设计团队,每天需要为上百个商品生成主图。传统流程是设计师手动在 Stable Diffusion WebUI 中生成,然后下载、裁剪、上传到设计稿中。
- 设计师在 Figma 中直接调用插件生成图片
- 平均每张图片生成时间从 5 分钟缩短到 30 秒
- 所有生成记录自动同步到 Notion 数据库
- 团队可以复用成功的提示词和参数
- 月度图片生成量从 200 张提升到 1500 张
5.2 内容团队的协作改进
一个内容创作团队,需要在文章、社交媒体、邮件营销等多个渠道使用配图。
- 编辑在 Notion 中写文章时,直接生成配图
- 社交媒体经理在 Slack 中讨论创意时,实时生成示意图
- 所有生成的图片和参数自动记录,确保品牌一致性
- 新成员可以快速学习成功的提示词模板
- 内容产出速度提升 40%
5.3 产品团队的快速原型
- 产品经理在 Figma 中快速生成界面背景、插图
- 在 Slack 讨论功能时,实时生成概念图辅助沟通
- 所有生成物自动归档,方便后续查找和复用
- 原型制作时间减少 60%
6. 总结
通过将 Stable Diffusion v1.5 集成到 Figma、Notion、Slack 等日常工具中,我们构建了一个无缝的创意自动化工作流。这个方案的核心价值在于:
效率大幅提升:从想法到图片的时间从几分钟缩短到几秒钟,无需切换工具,无需手动操作。
创意流程连贯:在设计、写作、讨论的上下文中直接生成图片,保持创意连贯性。
协作更加顺畅:所有生成记录自动同步,团队可以共享成功的提示词和参数。
质量可控可复现:通过模板系统和参数记录,确保生成质量的一致性。
技术门槛降低:非技术人员也能轻松使用 AI 图片生成,无需学习复杂的 Stable Diffusion 界面。
- 封装 Stable Diffusion API 服务
- 构建统一的 API 网关
- 开发各工具的客户端集成
- 设计参数管理和模板系统
- 确保安全性和稳定性
虽然初始设置需要一些技术工作,但一旦部署完成,它将持续为团队创造价值。无论是设计、内容、产品还是营销团队,都能从这个自动化工作流中受益。
最重要的是,这个方案是可扩展的。你可以根据需要添加更多工具集成(如 Trello、Jira、Teams 等),或者升级到更强大的 Stable Diffusion 模型。核心架构保持不变,只是更换底层的图片生成引擎。
如果你正在寻找提升团队创意效率的方法,不妨试试这个自动化方案。从一个小团队开始,验证价值,然后逐步推广到整个组织。
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online