clawra-selfie について
Clawra Selfie は、fal.ai 経由で xAI の Grok Imagine を使って固定の参照画像を編集し、OpenClaw からメッセージチャンネルへ送るスキルです。ミラーセルフィーと正面セルフィーに対応し、同じ画像を複数のチャンネルに配信できます。
主な機能
- 01固定の参照画像を編集
- 02ミラーまたは正面セルフィーを生成
- 03画像の状況と送信先を指定
- 04OpenClaw 経由で結果を送信
- 05同じ編集画像を複数チャンネルへ送信
活用シーン
- 01服装を主題にしたセルフィーの作成
- 02参照人物を指定した場所に配置
- 03編集画像のメッセージチャンネルへの送信
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ sumelabs/ clawra --skill clawra-selfieインストール後、Claude Code で/clawra-selfieを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
package.jsonREADME.md.serena/project.yml.gitignorebin/cli.jsscripts/clawra-selfie.shclawra-selfie.tsskill/scripts/clawra-selfie.shclawra-selfie.tstemplates/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
ワークフロー
- ユーザーのプロンプトを取得し、画像の編集方法を確認します
- 固定の参照画像を使い、fal.ai Grok Imagine Edit API 経由で画像を編集します
- レスポンスから画像 URL を抽出します
- 送信先のチャンネルに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, fashion | mirror |
| cafe, restaurant, beach, park, city, location | direct |
| close-up, portrait, face, eyes, smile | direct |
| full-body, mirror, reflection | mirror |
ステップ 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 |
| 電話番号(JID 形式) | [email protected] | |
| Slack | #channel-name | #random |
| Signal | 電話番号 | +1234567890 |
| MS Teams | チャンネル参照 | (形式は異なります) |
Grok Imagine Edit のパラメーター
| パラメーター | 型 | デフォルト | 説明 |
|---|---|---|---|
image_url | string | 必須 | 編集する画像の URL(このスキルでは固定) |
prompt | string | 必須 | 編集の指示 |
num_images | 1-4 | 1 | 生成する画像の数 |
output_format | enum | "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 の送信に失敗した:ゲートウェイが稼働中で、チャンネルが存在することを確認してください
- レート制限:fal.ai にはレート制限があります。必要に応じて再試行ロジックを実装してください
ヒント
-
ミラーモードのコンテキスト例(服装重視):
- "サンタ帽をかぶっている"
- "ビジネススーツを着ている"
- "夏のワンピースを着ている"
- "ストリートファッション"
-
ダイレクトモードのコンテキスト例(場所・ポートレート重視):
- "暖かな照明の居心地のよいカフェ"
- "夕暮れどきの晴れたビーチ"
- "夜のにぎやかな街路"
- "秋の静かな公園"
-
モードの選択:自動検出に任せるか、制御したい場合は明示的に指定します
-
一括送信:一度編集して、複数のチャンネルに送信します
-
スケジュール設定:OpenClaw スケジューラーと組み合わせて、投稿を自動化します