localsend
Send and receive files to/from nearby devices using the LocalSend protocol. Trigger with /localsend to get an interactive Telegram menu with real inline buttons — device discovery, file sending, text sending, and receiving.
Install via CLI (Recommended)
clawhub install openclaw/skills/skills/chordlini/localsendLocalSend
Interactive file transfer between devices on the local network using real Telegram inline keyboard buttons. Works with any device running the LocalSend app (Android, iOS, Windows, macOS, Linux).
Install
The localsend-cli is a zero-dependency Python CLI. Install from GitHub:
curl -fsSL https://raw.githubusercontent.com/Chordlini/localsend-cli/master/localsend-cli -o ~/.local/bin/localsend-cli
chmod +x ~/.local/bin/localsend-cli
Full docs: https://github.com/Chordlini/localsend-cli
Requires Python 3.8+ and openssl (for TLS).
Telegram Button Format
All menus MUST use OpenClaw's inline button format. Send buttons alongside your message using this structure:
buttons: [
[{ "text": "Label", "callback_data": "ls:action" }],
[{ "text": "Row 2", "callback_data": "ls:other" }]
]
- Outer array = rows of buttons
- Inner array = buttons per row (max 3 per row for readability)
- Prefix all callback_data with
ls:to namespace this skill - When user taps a button, you receive:
callback_data: ls:action
State Awareness (CRITICAL)
This skill uses conversational state. Track where you are in the flow:
| State | Meaning | Next user input should be treated as... |
|---|---|---|
idle | No active flow | Normal message — respond normally |
awaiting_file | Asked user to drop/specify a file to send | The file to send — do NOT comment on it, describe it, or react to it. Immediately use it as the send payload. |
awaiting_text | Asked user to type text to send | The text payload — send it, don't discuss it |
awaiting_confirm | Waiting for send confirmation | Expect ls:confirm-send or ls:menu |
receiving | Receiver is active | Monitor for incoming files |
RULES:
- When in
awaiting_filestate and user sends an image/file/path → treat it as the file to send. Show confirmation buttons immediately. - When in
awaiting_textstate and user types anything → treat it as the text to send. - NEVER comment on, describe, or react to a file/image when you're in
awaiting_filestate. - State resets to
idlewhen user tapsls:menuor the flow completes.
On Trigger: Main Menu
When the user types /localsend or mentions sending/receiving files locally, send this message with real inline buttons:
Message:
📡 LocalSend — File Transfer
Buttons:
buttons: [
[
{ "text": "📤 Send", "callback_data": "ls:send" },
{ "text": "📥 Receive", "callback_data": "ls:receive" }
],
[
{ "text": "🔍 Scan Devices", "callback_data": "ls:devices" }
]
]
Do NOT run any commands yet. Wait for the button tap.
Flow: Scan Devices
Trigger: callback_data: ls:devices or user says "scan", "discover", "find devices"
-
Run:
localsend-cli discover --json -t 2 -
Devices found — create one button per device, plus Refresh and Back:
Metadata
Not sure this is the right skill?
Describe what you want to build — we'll match you to the best skill from 16,000+ options.
Find the right skillPaste this into your clawhub.json to enable this plugin.
{
"plugins": {
"official-chordlini-localsend": {
"enabled": true,
"auto_update": true
}
}
}