QuotLy Style Sticker
How To Call (Agent)
- Build payload with required
selected_messages. - When available, include event metadata for dedupe:
context.event.channel(example:telegram)context.event.update_id(preferred)- fallback keys:
event_id,delivery_id,id
- Run:
python3 scripts/openclaw_quote_autoreply.py --input <json-file-or->
- Use tool-emitted
MEDIA:for delivery. - Final assistant text must be empty.
Input
- Required:
selected_messages(array, must not be empty) - Optional:
context.eventfor dedupe accuracychannel(string)update_id(string or number, preferred)event_id/delivery_id/id(fallback keys)
- Each item structure:
{ "message": { "message_id": 2002, "text": "Forwarded message content", "forward_from": { "type": "hidden_user", // optional, indicates hidden user "id": 123456789, // optional, user id "first_name": "张", // required, first name or nickname "last_name": "三", // optional, last name "avatar_url": "", // optional, avatar url or base64 data (from user profile or platform API) "status_url": "" // optional, status url or base64 data (from user profile or platform API) } }, // Optional: override message fields "overwrite_message": { "text": "哈哈哈哈哈", "forward_from": { "avatar_url": "", // from user profile or platform API "status_url": "" // from user profile or platform API }, "entities": [ // optional, text formatting entities {"type": "bold", "offset": 0, "length": 4}, {"type": "italic", "offset": 5, "length": 4} ] } } - Optional canvas:
width,height,scale,max_width,border_radius,picture_radius,background_color
Entities (Text Formatting)
The skill supports Telegram-style message entities for text formatting:
[
{"type": "bold", "offset": 0, "length": 5},
{"type": "italic", "offset": 6, "length": 6},
{"type": "url", "offset": 13, "length": 15, "url": "https://example.com"}
]
Supported types: mention, hashtag, cashtag, bot_command, url, email, phone_number, bold, italic, underline, strikethrough, spoiler, code, pre, text_link, text_mention, custom_emoji
Entity fields:
type(required) - entity typeoffset(required) - UTF-8 offset in textlength(required) - UTF-8 lengthurl(optional) - fortext_linktypeuser(optional) - fortext_mentiontypelanguage(optional) - forpretypecustom_emoji_id(optional) - forcustom_emojitype
Field Mapping
- Quote text:
overwrite_message.text>message.text
- Name/avatar:
overwrite_message.forward_from>message.forward_from
- Text formatting (entities):
overwrite_message.entities>message.entities>message.caption_entities
Output
- stdout includes:
Quote sticker generated.MEDIA:<absolute-path-to-webp>
- For duplicate retries detected within dedupe window, generation is skipped and no
MEDIA:line is emitted.
Environment Variables
QUOTLY_API_URL- QuotLy API endpoint (default:https://bot.lyo.su/quote/generate).QUOTLY_API_ALLOW_HOSTS- Comma-separated list of allowed API hosts (e.g.,bot.lyo.su). When set, the skill will only contact hosts in this list.QUOTLY_AUDIT_LOG- Set to1,true, oryesto enable audit logging to stderr.QUOTLY_DEDUP_WINDOW_SECONDS- Suppress duplicate requests for the same event/payload within this window (default:180). Set to0to disable.
Dedupe Key (How _build_dedupe_key reads input)
_build_dedupe_key(input_payload) resolves keys in this order:
context.event.update_id(orevent_id/delivery_id/id)event.update_id(orevent_id/delivery_id/id) whencontext.eventis missingcontext.event.update.update_id(nested update object)- Fallback: stable hash of
selected_messages
Recommended wrapper payload:
{
"context": {
"event": {
"channel": "telegram",
"update_id": 123456789
}
},
"selected_messages": [
{
"message": {
"message_id": 2002,
"text": "Forwarded message content"
}
}
]
}
Security Notes
- This skill sends message content to an external API to generate stickers.
- SSRF Protection: Multiple layers of protection are implemented:
- Hostname validation blocks internal/private IPs, localhost, and metadata endpoints
- DNS rebinding protection: resolves hostnames and validates resolved IPs
- Path traversal prevention: blocks
..and suspicious path patterns - URL credentials stripping: removes username/password from URLs
- Request Limits: Maximum payload size 1MB, maximum response size 10MB
- Audit Logging: Enable with
QUOTLY_AUDIT_LOG=1to log API requests and responses for security monitoring - In sensitive environments, always set
QUOTLY_API_ALLOW_HOSTSto restrict which hosts the skill can contact. - Avatar and status URLs from user input are passed to the rendering service; ensure input comes from trusted sources.
Reply Rule
- Do not output any final text.