mcpField
C
clawra-selfie

clawra-selfie

github.com/sumelabs创意与媒体2.4k141 次安装37 周前更新
代码仓库

关于 clawra-selfie

Clawra Selfie 是一项 OpenClaw 技能,通过 fal.ai 使用 xAI 的 Grok Imagine 编辑固定参考图,再发送到消息频道。它支持镜面自拍和直视自拍风格,并可将同一张编辑结果发送到多个频道。

主要功能

  1. 01编辑固定参考图
  2. 02生成镜面或直视自拍风格
  3. 03指定图像情境和目标频道
  4. 04通过 OpenClaw 发送结果
  5. 05将同一编辑图发送到多个频道

适用场景

  1. 01制作突出服装的自拍图
  2. 02将参考人物置于指定地点
  3. 03向消息频道发送编辑后的图片

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sumelabs/clawra --skill clawra-selfie

安装后在 Claude Code 中输入/clawra-selfie确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

package.json
README.md
.serena/
project.yml
.gitignore
bin/
cli.js
scripts/
clawra-selfie.sh
clawra-selfie.ts
skill/scripts/
clawra-selfie.sh
clawra-selfie.ts
templates/
soul-injection.md

详细介绍

Clawra 自拍

使用 xAI 的 Grok Imagine 模型编辑固定的参考图像,并通过 OpenClaw 将其发送到各个消息平台(WhatsApp、Telegram、Discord、Slack 等)。

参考图像

此技能使用托管在 jsDelivr CDN 上的固定参考图像:

https://cdn.jsdelivr.net/gh/SumeLabs/clawra@main/assets/clawra.png

适用场景

  • 用户说“发张照片”“给我发张照片”“发张相片”“发张自拍”
  • 用户说“发张你的照片……”“发张你的自拍……”
  • 用户询问“你在做什么?”“你最近怎么样?”“你在哪里?”
  • 用户描述情境:“发张穿着……的照片”“发张在……的照片”
  • 用户希望 Clawra 出现在特定的服装、地点或情境中

快速参考

必需的环境变量
FAL_KEY=your_fal_api_key          # Get from https://fal.ai/dashboard/keys
OPENCLAW_GATEWAY_TOKEN=your_token  # From: openclaw doctor --generate-gateway-token
工作流
  1. 获取用户提示词,了解他们希望如何编辑图像
  2. 通过 fal.ai Grok Imagine Edit API 使用固定参考图像编辑图像
  3. 提取图像 URL,从响应中获取
  4. 发送到 OpenClaw,并指定目标频道

分步说明

第 1 步:收集用户输入

询问用户:

  • 用户情境:图像中的人物应该在做什么、穿什么、身处何处?
  • 模式(可选):mirror 或 direct 自拍风格
  • 目标频道:要发送到哪里?(例如,#general、@username、频道 ID)
  • 平台(可选):使用哪个平台?(discord、telegram、whatsapp、slack)

提示词模式

模式 1:镜面自拍(默认)

适用于:服装展示、全身照、时尚内容

make a pic of this person, but [user's context]. the person is taking a mirror selfie

示例:“戴着圣诞帽” →

make a pic of this person, but wearing a santa hat. the person is taking a mirror selfie
模式 2:直接自拍

适用于:特写肖像、地点照片、情绪表情

a close-up selfie taken by herself at [user's context], direct eye contact with the camera, looking straight into the lens, eyes centered and clearly visible, not a mirror selfie, phone held at arm's length, face fully visible

示例:“灯光温暖的舒适咖啡馆” →

a close-up selfie taken by herself at a cozy cafe with warm lighting, direct eye contact with the camera, looking straight into the lens, eyes centered and clearly visible, not a mirror selfie, phone held at arm's length, face fully visible
模式选择逻辑
请求中的关键词自动选择模式
outfit、wearing、clothes、dress、suit、fashionmirror
cafe、restaurant、beach、park、city、locationdirect
close-up、portrait、face、eyes、smiledirect
full-body、mirror、reflectionmirror
第 2 步:使用 Grok Imagine 编辑图像

使用 fal.ai API 编辑参考图像:

REFERENCE_IMAGE="https://cdn.jsdelivr.net/gh/SumeLabs/clawra@main/assets/clawra.png"

# Mode 1: Mirror Selfie
PROMPT="make a pic of this person, but <USER_CONTEXT>. the person is taking a mirror selfie"

# Mode 2: Direct Selfie
PROMPT="a close-up selfie taken by herself at <USER_CONTEXT>, direct eye contact with the camera, looking straight into the lens, eyes centered and clearly visible, not a mirror selfie, phone held at arm's length, face fully visible"

# Build JSON payload with jq (handles escaping properly)
JSON_PAYLOAD=$(jq -n \
  --arg image_url "$REFERENCE_IMAGE" \
  --arg prompt "$PROMPT" \
  '{image_url: $image_url, prompt: $prompt, num_images: 1, output_format: "jpeg"}')

curl -X POST "https://fal.run/xai/grok-imagine-image/edit" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d "$JSON_PAYLOAD"

响应格式:

{
  "images": [
    {
      "url": "https://v3b.fal.media/files/...",
      "content_type": "image/jpeg",
      "width": 1024,
      "height": 1024
    }
  ],
  "revised_prompt": "Enhanced prompt text..."
}
第 3 步:通过 OpenClaw 发送图像

使用 OpenClaw 消息 API 发送编辑后的图像:

openclaw message send \
  --action send \
  --channel "<TARGET_CHANNEL>" \
  --message "<CAPTION_TEXT>" \
  --media "<IMAGE_URL>"

替代方案:直接调用 API

curl -X POST "http://localhost:18789/message" \
  -H "Authorization: Bearer $OPENCLAW_GATEWAY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "send",
    "channel": "<TARGET_CHANNEL>",
    "message": "<CAPTION_TEXT>",
    "media": "<IMAGE_URL>"
  }'

完整脚本示例

#!/bin/bash
# grok-imagine-edit-send.sh

# Check required environment variables
if [ -z "$FAL_KEY" ]; then
  echo "Error: FAL_KEY environment variable not set"
  exit 1
fi

# Fixed reference image
REFERENCE_IMAGE="https://cdn.jsdelivr.net/gh/SumeLabs/clawra@main/assets/clawra.png"

USER_CONTEXT="$1"
CHANNEL="$2"
MODE="${3:-auto}"  # mirror, direct, or auto
CAPTION="${4:-Edited with Grok Imagine}"

if [ -z "$USER_CONTEXT" ] || [ -z "$CHANNEL" ]; then
  echo "Usage: $0 <user_context> <channel> [mode] [caption]"
  echo "Modes: mirror, direct, auto (default)"
  echo "Example: $0 'wearing a cowboy hat' '#general' mirror"
  echo "Example: $0 'a cozy cafe' '#general' direct"
  exit 1
fi

# Auto-detect mode based on keywords
if [ "$MODE" == "auto" ]; then
  if echo "$USER_CONTEXT" | grep -qiE "outfit|wearing|clothes|dress|suit|fashion|full-body|mirror"; then
    MODE="mirror"
  elif echo "$USER_CONTEXT" | grep -qiE "cafe|restaurant|beach|park|city|close-up|portrait|face|eyes|smile"; then
    MODE="direct"
  else
    MODE="mirror"  # default
  fi
  echo "Auto-detected mode: $MODE"
fi

# Construct the prompt based on mode
if [ "$MODE" == "direct" ]; then
  EDIT_PROMPT="a close-up selfie taken by herself at $USER_CONTEXT, direct eye contact with the camera, looking straight into the lens, eyes centered and clearly visible, not a mirror selfie, phone held at arm's length, face fully visible"
else
  EDIT_PROMPT="make a pic of this person, but $USER_CONTEXT. the person is taking a mirror selfie"
fi

echo "Mode: $MODE"
echo "Editing reference image with prompt: $EDIT_PROMPT"

# Edit image (using jq for proper JSON escaping)
JSON_PAYLOAD=$(jq -n \
  --arg image_url "$REFERENCE_IMAGE" \
  --arg prompt "$EDIT_PROMPT" \
  '{image_url: $image_url, prompt: $prompt, num_images: 1, output_format: "jpeg"}')

RESPONSE=$(curl -s -X POST "https://fal.run/xai/grok-imagine-image/edit" \
  -H "Authorization: Key $FAL_KEY" \
  -H "Content-Type: application/json" \
  -d "$JSON_PAYLOAD")

# Extract image URL
IMAGE_URL=$(echo "$RESPONSE" | jq -r '.images[0].url')

if [ "$IMAGE_URL" == "null" ] || [ -z "$IMAGE_URL" ]; then
  echo "Error: Failed to edit image"
  echo "Response: $RESPONSE"
  exit 1
fi

echo "Image edited: $IMAGE_URL"
echo "Sending to channel: $CHANNEL"

# Send via OpenClaw
openclaw message send \
  --action send \
  --channel "$CHANNEL" \
  --message "$CAPTION" \
  --media "$IMAGE_URL"

echo "Done!"

Node.js/TypeScript 实现

import { fal } from "@fal-ai/client";
import { exec } from "child_process";
import { promisify } from "util";

const execAsync = promisify(exec);

const REFERENCE_IMAGE = "https://cdn.jsdelivr.net/gh/SumeLabs/clawra@main/assets/clawra.png";

interface GrokImagineResult {
  images: Array<{
    url: string;
    content_type: string;
    width: number;
    height: number;
  }>;
  revised_prompt?: string;
}

type SelfieMode = "mirror" | "direct" | "auto";

function detectMode(userContext: string): "mirror" | "direct" {
  const mirrorKeywords = /outfit|wearing|clothes|dress|suit|fashion|full-body|mirror/i;
  const directKeywords = /cafe|restaurant|beach|park|city|close-up|portrait|face|eyes|smile/i;

  if (directKeywords.test(userContext)) return "direct";
  if (mirrorKeywords.test(userContext)) return "mirror";
  return "mirror"; // default
}

function buildPrompt(userContext: string, mode: "mirror" | "direct"): string {
  if (mode === "direct") {
    return `a close-up selfie taken by herself at ${userContext}, direct eye contact with the camera, looking straight into the lens, eyes centered and clearly visible, not a mirror selfie, phone held at arm's length, face fully visible`;
  }
  return `make a pic of this person, but ${userContext}. the person is taking a mirror selfie`;
}

async function editAndSend(
  userContext: string,
  channel: string,
  mode: SelfieMode = "auto",
  caption?: string
): Promise<string> {
  // Configure fal.ai client
  fal.config({
    credentials: process.env.FAL_KEY!
  });

  // Determine mode
  const actualMode = mode === "auto" ? detectMode(userContext) : mode;
  console.log(`Mode: ${actualMode}`);

  // Construct the prompt
  const editPrompt = buildPrompt(userContext, actualMode);

  // Edit reference image with Grok Imagine
  console.log(`Editing image: "${editPrompt}"`);

  const result = await fal.subscribe("xai/grok-imagine-image/edit", {
    input: {
      image_url: REFERENCE_IMAGE,
      prompt: editPrompt,
      num_images: 1,
      output_format: "jpeg"
    }
  }) as { data: GrokImagineResult };

  const imageUrl = result.data.images[0].url;
  console.log(`Edited image URL: ${imageUrl}`);

  // Send via OpenClaw
  const messageCaption = caption || `Edited with Grok Imagine`;

  await execAsync(
    `openclaw message send --action send --channel "${channel}" --message "${messageCaption}" --media "${imageUrl}"`
  );

  console.log(`Sent to ${channel}`);
  return imageUrl;
}

// Usage Examples

// Mirror mode (auto-detected from "wearing")
editAndSend(
  "wearing a cyberpunk outfit with neon lights",
  "#art-gallery",
  "auto",
  "Check out this AI-edited art!"
);
// → Mode: mirror
// → Prompt: "make a pic of this person, but wearing a cyberpunk outfit with neon lights. the person is taking a mirror selfie"

// Direct mode (auto-detected from "cafe")
editAndSend(
  "a cozy cafe with warm lighting",
  "#photography",
  "auto"
);
// → Mode: direct
// → Prompt: "a close-up selfie taken by herself at a cozy cafe with warm lighting, direct eye contact..."

// Explicit mode override
editAndSend("casual street style", "#fashion", "direct");

支持的平台

OpenClaw 支持发送到:

平台频道格式示例
Discord#channel-name 或频道 ID#general、123456789
Telegram@username 或聊天 ID@mychannel、-100123456
WhatsApp电话号码(JID 格式)[email protected]
Slack#channel-name#random
Signal电话号码+1234567890
MS Teams频道引用(因情况而异)

Grok Imagine Edit 参数

参数类型默认值描述
image_urlstring必填要编辑的图像 URL(此技能中固定)
promptstring必填编辑指令
num_images1-41要生成的图像数量
output_formatenum"jpeg"jpeg、png、webp

设置要求

1. 安装 fal.ai 客户端(用于 Node.js)
npm install @fal-ai/client
2. 安装 OpenClaw CLI
npm install -g openclaw
3. 配置 OpenClaw Gateway
openclaw config set gateway.mode=local
openclaw doctor --generate-gateway-token
4. 启动 OpenClaw Gateway
openclaw gateway start

错误处理

  • 缺少 FAL_KEY:确保已在环境中设置 API 密钥
  • 图像编辑失败:检查提示词内容和 API 配额
  • OpenClaw 发送失败:确认 Gateway 正在运行且频道存在
  • 速率限制:fal.ai 有速率限制;必要时实现重试逻辑

提示

  1. 镜像模式的上下文示例(侧重服装):

    • “戴着圣诞帽”
    • “穿着商务套装”
    • “穿着夏装”
    • “身着街头时尚风格”
  2. 直接模式的上下文示例(侧重地点/肖像):

    • “灯光温暖的舒适咖啡馆”
    • “日落时分阳光明媚的海滩”
    • “夜晚繁忙的城市街道”
    • “秋日宁静的公园”
  3. 模式选择:让系统自动检测,或明确指定以便控制

  4. 批量发送:编辑一次,发送到多个频道

  5. 定时安排:与 OpenClaw scheduler 结合,实现自动发布

评论

支持 Markdown