Refactor high-complexity React components in Dify frontend. Use when `pnpm analyze-component...
npx skills add Blooio/use-imessages
Or install specific skill: npx add-skill https://github.com/Blooio/use-imessages
# Description
>
# SKILL.md
name: use-imessages
description: >
Use when the user wants to send an iMessage, text message, or SMS to a phone number or email.
Sends messages via iMessage with automatic fallback to RCS or SMS when iMessage is unavailable.
Use for: sending texts, checking if someone has iMessage, group messaging, message delivery status.
Keywords: iMessage, SMS, RCS, text message, send message, Blooio, messaging API.
dependencies:
- network access (for Blooio API calls)
- Blooio API key (user must provide)
allowed-tools:
- http_request
- fetch
license: MIT
use-imessages
Send messages using iMessage with automatic fallback to RCS or SMS when iMessage isn't available for a contact. Uses the Blooio API.
When to Use This Skill
Use this skill when the user asks to:
- Send a text message, iMessage, or SMS to someone
- Check if a contact supports iMessage
- Send a message to a group chat
- Track if a message was delivered or read
- Set up messaging automation or webhooks
Example Prompts That Trigger This Skill
- "Send a message to +15551234567 saying 'Hey, running 10 mins late'"
- "Text John at 555-123-4567 that the meeting is canceled"
- "Can you check if this number has iMessage?"
- "Send 'Hello team!' to my Sales group"
- "I need to send an SMS to someone who doesn't have iMessage"
- "Set up a webhook to notify me when I receive messages"
Prerequisites
- Blooio API key (Bearer token) - obtain from https://blooio.com
- At least one active device connected to Blooio
API Base URL
https://backend.blooio.com/v2/api
All requests require Bearer authentication:
Authorization: Bearer <your-api-key>
Core Workflow: Send Message with Fallback
Step 1: Check Contact Capabilities
Before sending, determine what protocols the contact supports:
GET /contacts/{contactId}/capabilities
Where contactId is URL-encoded phone (E.164 format like %2B15551234567) or email.
Response:
{
"contact": "+15551234567",
"type": "phone",
"capabilities": {
"imessage": true,
"sms": true
},
"last_checked": 1706123456789
}
Step 2: Send the Message
POST /chats/{chatId}/messages
Content-Type: application/json
{
"text": "Hello! This is your message."
}
The chatId can be:
- Phone number (E.164): %2B15551234567
- Email: user%40example.com
- Group ID: grp_abc123def456
- Multiple recipients (comma-separated): %2B15551234567%2C%2B15559876543
Response (202 Accepted):
{
"message_id": "msg_abc123def456",
"status": "queued"
}
Step 3: Check Delivery Status
GET /chats/{chatId}/messages/{messageId}/status
Response:
{
"message_id": "msg_abc123def456",
"chat_id": "+15551234567",
"direction": "outbound",
"status": "delivered",
"protocol": "imessage",
"time_sent": 1706123456789,
"time_delivered": 1706123457123
}
Protocol values: imessage, sms, rcs, non-imessage
Status values: pending, queued, sent, delivered, failed, read
Decision Logic for Fallback
1. Check capabilities for contact
2. If capabilities.imessage == true:
→ Send message (will use iMessage)
3. Else if capabilities.sms == true:
→ Send message (will use SMS/RCS)
4. Else:
→ Report error: "Cannot send - no supported channel"
5. After sending, check status to confirm protocol used
Note: Blooio handles protocol selection automatically based on capabilities. You send to the same endpoint; the system chooses the best available protocol.
Common Operations
Create a Contact
POST /contacts
Content-Type: application/json
{
"identifier": "+15551234567",
"name": "John Doe"
}
List Contacts
GET /contacts?limit=50&offset=0&q=john
Send Message with Attachments
POST /chats/{chatId}/messages
Content-Type: application/json
{
"text": "Check out this image!",
"attachments": [
"https://example.com/image.jpg"
]
}
Send Multiple Messages at Once
POST /chats/{chatId}/messages
Content-Type: application/json
{
"text": ["First message", "Second message", "Third message"]
}
Returns message_ids array instead of single message_id.
Show Typing Indicator
POST /chats/{chatId}/typing
DELETE /chats/{chatId}/typing
Mark Chat as Read
POST /chats/{chatId}/read
Add Reaction to Message
POST /chats/{chatId}/messages/{messageId}/reactions
Content-Type: application/json
{
"reaction": "+love"
}
Reactions: +love, +like, +dislike, +laugh, +emphasize, +question
Use - prefix to remove: -love
Group Messaging
Create a Group
POST /groups
Content-Type: application/json
{
"name": "Sales Team",
"members": ["+15551234567", "+15559876543", "[email protected]"]
}
Send to Group
POST /chats/grp_abc123def456/messages
Content-Type: application/json
{
"text": "Hello team!"
}
Send to Multiple Recipients (Auto-creates Group)
POST /chats/%2B15551234567%2C%2B15559876543/messages
Content-Type: application/json
{
"text": "Hello both of you!"
}
Webhooks for Real-time Updates
Create Webhook
POST /webhooks
Content-Type: application/json
{
"webhook_url": "https://your-server.com/webhook",
"webhook_type": "all"
}
Types: message (inbound only), status (delivery status), all
Webhook Payload Example
{
"event": "message.received",
"message_id": "msg_abc123",
"external_id": "+15551234567",
"status": "received",
"protocol": "imessage",
"timestamp": 1706123456789,
"text": "Hey there!",
"is_group": false
}
Events: message.received, message.sent, message.delivered, message.failed, message.read
Error Handling
| Status | Meaning | Action |
|---|---|---|
| 400 | Invalid request | Check phone format (E.164), URL encoding |
| 401 | Unauthorized | Verify API key |
| 404 | Not found | Contact/chat doesn't exist |
| 503 | No devices | Ensure device is connected and active |
503 No Devices Available
This means no Blooio device is online. The user needs to:
1. Check their Blooio dashboard
2. Ensure their Mac/device with Blooio is running
3. Verify the device is connected
Complete Example: Send with Fallback
import requests
API_KEY = "your-api-key"
BASE_URL = "https://backend.blooio.com/v2/api"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
def send_message_with_fallback(phone: str, text: str) -> dict:
# URL encode the phone number
encoded_phone = phone.replace("+", "%2B")
# 1. Check capabilities
cap_resp = requests.get(
f"{BASE_URL}/contacts/{encoded_phone}/capabilities",
headers=HEADERS
)
if cap_resp.status_code == 503:
return {"error": "No devices available"}
caps = cap_resp.json().get("capabilities", {})
if not caps.get("imessage") and not caps.get("sms"):
return {"error": "Contact has no supported messaging channel"}
# 2. Send message (Blooio auto-selects best protocol)
send_resp = requests.post(
f"{BASE_URL}/chats/{encoded_phone}/messages",
headers=HEADERS,
json={"text": text}
)
if send_resp.status_code not in [200, 202]:
return {"error": send_resp.json().get("error")}
result = send_resp.json()
# 3. Optionally check what protocol was used
status_resp = requests.get(
f"{BASE_URL}/chats/{encoded_phone}/messages/{result['message_id']}/status",
headers=HEADERS
)
if status_resp.ok:
result["protocol"] = status_resp.json().get("protocol")
return result
# Usage
result = send_message_with_fallback("+15551234567", "Hello from the agent!")
print(f"Sent via {result.get('protocol', 'unknown')}: {result.get('message_id')}")
Tips
- Phone numbers must be E.164 format:
+15551234567(with country code) - URL-encode identifiers in paths:
+becomes%2B,@becomes%40 - Capabilities are cached:
last_checkedtimestamp shows freshness - Use idempotency keys for critical messages to prevent duplicates:
Idempotency-Key: unique-request-id-123 - Group chats are unique by participants: Can't create duplicate groups with same members
- Typing indicators auto-expire: No need to manually stop them before sending
# README.md
use-imessages
A skill for AI agents to send iMessages via Blooio with automatic fallback to RCS or SMS when iMessage is unavailable.
What This Does
When you ask an AI agent to send a text message, this skill:
- Checks capabilities — Determines if the recipient supports iMessage, RCS, or SMS
- Sends via best channel — Uses iMessage if available, falls back to RCS/SMS otherwise
- Tracks delivery — Reports which protocol was used and delivery status
Installation
# Via skills CLI
npx skills add blooio/use-imessages
# Or with bunx
bunx add-skill blooio/use-imessages
Prefer MCP?
If you'd rather use an MCP server instead of a skill, Blooio also offers a hosted MCP at mcp.blooio.com.
Usage Examples
Once installed, trigger the skill with prompts like:
- "Send a message to +15551234567 saying 'Hey, running late'"
- "Text John that the meeting is canceled"
- "Check if this number has iMessage"
- "Send 'Hello team!' to my Sales group"
- "Set up a webhook to notify me when I receive messages"
Prerequisites
- Blooio API key — Get one at blooio.com
- Active device — At least one phone with Blooio connected (blooio managed. See app.blooio.com to purchase numbers)
What's Inside
use-imessages/
├── SKILL.md # Skill definition with API docs and examples
├── AGENTS.md # Guidance for AI coding agents
├── README.md # This file
└── LICENSE # MIT License
API Reference
This skill uses the Blooio API v2. Key endpoints:
| Endpoint | Purpose |
|---|---|
GET /contacts/{id}/capabilities |
Check iMessage/SMS support |
POST /chats/{id}/messages |
Send a message |
GET /chats/{id}/messages/{msgId}/status |
Check delivery status |
POST /webhooks |
Set up real-time notifications |
See SKILL.md for complete API documentation and examples.
Related Resources
- Sign up for Blooio and get a phone number. Free trial no credit card needed
- Blooio Documentation
- Agent Skills Specification
- Claude Custom Skills Guide
Contributing
- Fork the repository
- Create a feature branch
- Make your changes
- Submit a pull request
Please ensure any API changes are reflected in SKILL.md.
License
MIT — see LICENSE for details.
# Supported AI Coding Agents
This skill is compatible with the SKILL.md standard and works with all major AI coding agents:
Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.