Install
$ agentstack add skill-wangyendt-wayne-skills-lark-bot ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Pywayne Lark Bot - Full-Featured Feishu API Wrapper
Overview
LarkBot is a comprehensive Feishu (Lark) application bot wrapper that provides complete bidirectional interaction capabilities. It's designed for scenarios requiring full message lifecycle management, chat administration, and complex card-based interactions.
Key Capabilities:
- Send all message types (text, image, audio, video, file, rich_text, card)
- Reply, forward, recall, update messages
- Edit sent text/rich_text/card messages with semantic helper methods
- Build and update in-place streaming cards for long-running or LLM-style responses
- Reactions, pins, read receipts, urgent notifications
- Chat management (create, delete, update, members, admins, announcements)
- File upload/download with message resource handling
- User and group information queries
- Batch messaging to users/departments
- Recommended:
send_markdown_message_to_chatwith auto-chunking and table fallback
Companion Classes:
TextContent: Quick text formatting (@mentions, bold, italic, links)PostContent: Rich text builder with Markdown table handlingCardContentV2: Schema 2.0 card builderLarkBotListener: Event listener for incoming messages (separate skill)
Installation
pip install pywayne lark-oapi
Quick Start
from pywayne.lark_bot import LarkBot
# Initialize bot
bot = LarkBot(
app_id="cli_xxxxxxxxxxxx",
app_secret="your_app_secret"
)
# Send text to user
bot.send_text_to_user("ou_xxxxxxxx", "Hello from LarkBot!")
# Send text to chat group
bot.send_text_to_chat("oc_xxxxxxxx", "Hello, everyone!")
LarkBot Class
Constructor
bot = LarkBot(
app_id: str, # Feishu application ID
app_secret: str # Feishu application secret
)
Instance Attributes:
client: Underlyinglark.Clientfor advanced usage- All methods return
Dictwith API response data
Helper Classes
TextContent - Quick Text Formatting
Static helper for creating formatted text patterns used in text messages.
Available Methods:
from pywayne.lark_bot import TextContent
# @mentions
at_all = TextContent.make_at_all_pattern()
at_user = TextContent.make_at_someone_pattern("ou_xxxx", "John", "open_id")
# Text styles
bold = TextContent.make_bold_pattern("Bold text")
italic = TextContent.make_italian_pattern("Italic text")
underline = TextContent.make_underline_pattern("Underlined text")
strikethrough = TextContent.make_delete_line_pattern("Strike text")
# Links
link = TextContent.make_url_pattern("https://example.com", "Click here")
Example: Formatted Notification:
from pywayne.lark_bot import LarkBot, TextContent
bot = LarkBot(app_id="cli_xxx", app_secret="sec_xxx")
message = (
TextContent.make_at_someone_pattern("ou_xxxx", "Wayne", "open_id")
+ " "
+ TextContent.make_bold_pattern("Deployment completed")
+ " - "
+ TextContent.make_url_pattern("https://jenkins.example.com", "View build")
)
bot.send_text_to_chat("oc_xxxx", message)
PostContent - Rich Text Post Builder
Builder for complex structured rich text messages supporting text, links, @mentions, images, code blocks, and Markdown content.
Constructor:
from pywayne.lark_bot import PostContent
post = PostContent(title="Post Title")
Content Creation Methods:
# Text with optional styles
text = post.make_text_content("Text", styles=["bold", "underline", "lineThrough", "italic"])
# Hyperlink
link = post.make_link_content("Display text", "https://example.com")
# @mention
at = post.make_at_content("ou_xxxx", styles=["bold"])
# Image
img = post.make_image_content("img_key")
# Media (video/audio with thumbnail)
media = post.make_media_content(file_key="file_xxx", image_key="thumb_xxx")
# Emoji (Feishu emoji codes like "OK", "THUMBSUP", "HEART")
emoji = post.make_emoji_content("THUMBSUP")
# Horizontal rule
hr = post.make_hr_content()
# Code block
code = post.make_code_block_content(language="python", text='print("hello")')
# Markdown
md = post.make_markdown_content("**Bold** and *italic*")
Adding Content:
# Add to current line
post.add_content_in_line(content_dict)
post.add_contents_in_line([content1, content2]) # Multiple elements in same line
# Add to new line
post.add_content_in_new_line(content_dict)
post.add_contents_in_new_line([content1, content2])
Recommended: Add Markdown Directly:
md_text = """
## Section Title
- Item 1
- Item 2
| Column A | Column B |
| -------- | -------- |
| Data 1 | Data 2 |
"""
# Auto-chunk and handle tables
post.add_markdown(
md_text,
table_as="code_block", # "code_block" or "md"
max_chunk_bytes=8000, # Max bytes per chunk
mono_max_col_width=40 # Max column width for code_block mode
)
# Send
bot.send_rich_text_to_chat("oc_xxx", post.get_content())
Complete Example:
from pywayne.lark_bot import LarkBot, PostContent
bot = LarkBot(app_id="cli_xxx", app_secret="sec_xxx")
# Build post
post = PostContent(title="Release Report")
# Line 1: Title
post.add_content_in_new_line(
post.make_text_content("Version 1.2.0 Released", styles=["bold"])
)
# Line 2: @mention with emoji
post.add_contents_in_new_line([
post.make_at_content("ou_xxx"),
post.make_text_content(" "),
post.make_emoji_content("OK")
])
# Line 3: Link
post.add_content_in_new_line(
post.make_link_content("View release notes", "https://example.com/release/1.2.0")
)
# Line 4: Code block
post.add_content_in_new_line(
post.make_code_block_content("bash", "deploy.sh --env prod --version 1.2.0")
)
# Send
bot.send_rich_text_to_chat("oc_xxx", post.get_content())
CardContentV2 - Schema 2.0 Interactive Card Builder
Lightweight builder for Feishu schema 2.0 cards, ideal for announcements, reports, and status updates with Markdown content.
Constructor:
from pywayne.lark_bot import CardContentV2
card = CardContentV2(
title="Card Title", # Optional header title
template="blue" # Header color: "blue", "wathet", "turquoise", "green", "yellow", "orange", "red", "carmine", "violet", "purple", "indigo", "grey"
)
Methods:
# Add Markdown content (auto-chunks by bytes)
card.add_markdown(md_text: str, *, max_chunk_bytes: int = 18_000)
# Add horizontal divider
card.add_hr()
# Add image
card.add_image(img_key: str, *, size: str = "large", preview: bool = True)
# List commonly used header templates
templates = CardContentV2.list_header_templates() # ["blue", "wathet", ...]
# Get complete card JSON
card_json = card.get_card()
Common Header Templates:
bluewathetturquoisegreenyelloworangeredcarminevioletpurpleindigogrey
Example: Daily Report Card:
from pywayne.lark_bot import LarkBot, CardContentV2
bot = LarkBot(app_id="cli_xxx", app_secret="sec_xxx")
# Build card
card = CardContentV2(title="Daily Report", template="blue")
card.add_markdown("""
# Today's Progress
- ✅ API integration completed
- ✅ Fixed 3 critical bugs
- 🔄 Code review in progress
- 📝 Documentation updated
""")
card.add_hr()
card.add_markdown("**Next Steps**: Deploy to staging environment")
# Send
bot.send_card_to_chat("oc_xxx", card.get_card())
Core Messaging Methods
Recommended Entry Point: sendmarkdownmessagetochat
The preferred high-level method for sending Markdown content with automatic chunking, table handling, and dual routing (cardv2/richtext).
responses = bot.send_markdown_message_to_chat(
chat_id: str,
md_text: str,
*,
title: str = "",
prefer: str = "card_v2", # "card_v2" or "post"
table_fallback: str = "code_block", # "code_block" or "md" (for post route)
max_message_bytes: Optional[int] = None
) -> List[Dict]
Parameters:
chat_id: Target chat IDmd_text: Markdown contenttitle: Message titleprefer: Route preference:"card_v2"(default): Send as schema 2.0 card (supports most Markdown)"post": Send as rich_text message (supports table fallback)table_fallback: How to render Markdown tables in rich_text route:"code_block": Convert tables to fixed-width text blocks (stable, recommended)"md": Keep tables as Markdown (may have layout issues)max_message_bytes: Per-message byte limit (defaults: 18k for cardv2, 8k for richtext route)
Returns: List of API response dicts for all sent chunks
Example 1: Simple Markdown (Default card_v2):
md = """
# Deployment Complete
- API: v1.2.3
- Frontend: v2.4.5
- Database: migrated
✅ All services healthy
"""
bot.send_markdown_message_to_chat(
"oc_xxx",
md_text=md,
title="Deployment Status"
)
Example 2: Markdown with Tables (Post route with fallback):
md = """
## Test Results
| Module | Status | Coverage |
| -------- | ------ | -------- |
| Auth | ✅ | 95% |
| Payment | ✅ | 87% |
| API | ⚠️ | 72% |
"""
bot.send_markdown_message_to_chat(
"oc_xxx",
md_text=md,
title="Test Report",
prefer="post", # Use rich_text route for table support
table_fallback="code_block" # Convert table to fixed-width text
)
Example 3: Long Markdown Auto-Chunking:
# Very long markdown content
long_md = "\n".join([f"## Section {i}\n\n" + "- " * 50 for i in range(50)])
# Automatically split into multiple messages
responses = bot.send_markdown_message_to_chat(
"oc_xxx",
md_text=long_md,
title="Long Report",
prefer="card_v2",
max_message_bytes=10000 # Custom chunk size
)
print(f"Sent {len(responses)} message chunks")
Why Use sendmarkdownmessagetochat?
- Handles large content automatically
- Tables render reliably with fallback
- Single API for both card and rich_text routes
- No manual JSON construction
- Consistent chunking and encoding
Text Messages
# Send to user
bot.send_text_to_user(user_open_id: str, text: str = '') -> Dict
# Send to chat
bot.send_text_to_chat(chat_id: str, text: str = '') -> Dict
Examples:
# Simple text
bot.send_text_to_user("ou_xxx", "Hello!")
# With formatting (use TextContent helpers)
from pywayne.lark_bot import TextContent
msg = (
TextContent.make_at_all_pattern() + " "
+ TextContent.make_bold_pattern("Important")
+ ": System maintenance tonight at 23:00"
)
bot.send_text_to_chat("oc_xxx", msg)
Image Messages
# Upload image
image_key = bot.upload_image(image_path: str) -> str
# Send to user
bot.send_image_to_user(user_open_id: str, image_key: str) -> Dict
# Send to chat
bot.send_image_to_chat(chat_id: str, image_key: str) -> Dict
# Download image
bot.download_image(image_key: str, image_save_path: str) -> None
Example:
# Upload and send
image_key = bot.upload_image("/tmp/report.png")
if image_key:
bot.send_image_to_chat("oc_xxx", image_key)
Audio Messages
# Upload audio (typically .opus format)
audio_key = bot.upload_file(file_path: str, file_type: str = "opus") -> str
# Send to user
bot.send_audio_to_user(user_open_id: str, file_key: str) -> Dict
# Send to chat
bot.send_audio_to_chat(chat_id: str, file_key: str) -> Dict
Media Messages (Video)
# Upload video (typically .mp4 format)
video_key = bot.upload_file(file_path: str, file_type: str = "mp4") -> str
# Send to user
bot.send_media_to_user(user_open_id: str, file_key: str) -> Dict
# Send to chat
bot.send_media_to_chat(chat_id: str, file_key: str) -> Dict
File Messages
# Upload file
file_key = bot.upload_file(
file_path: str,
file_type: str = 'stream' # 'stream', 'opus', 'mp4', 'pdf', 'doc', 'xls', 'ppt'
) -> str
# Send to user
bot.send_file_to_user(user_open_id: str, file_key: str) -> Dict
# Send to chat
bot.send_file_to_chat(chat_id: str, file_key: str) -> Dict
# Download file
bot.download_file(file_key: str, file_save_path: str) -> None
Example:
# Upload PDF and send
pdf_key = bot.upload_file("/tmp/report.pdf", file_type="pdf")
bot.send_file_to_chat("oc_xxx", pdf_key)
# Download file
bot.download_file(pdf_key, "/save/path/report.pdf")
Post Messages (Rich Text)
# Send to user
bot.send_rich_text_to_user(user_open_id: str, rich_text_content: Dict) -> Dict
# Send to chat
bot.send_rich_text_to_chat(chat_id: str, rich_text_content: Dict) -> Dict
Example (see PostContent section for builder usage):
from pywayne.lark_bot import PostContent
post = PostContent(title="Announcement")
post.add_markdown("**Important update**: System will be upgraded tonight")
bot.send_rich_text_to_chat("oc_xxx", post.get_content())
Interactive Card Messages
# Send to user
bot.send_card_to_user(user_open_id: str, card: Dict) -> Dict
# Send to chat
bot.send_card_to_chat(chat_id: str, card: Dict) -> Dict
Return Value:
- Both methods return a response
Dict. - When the send succeeds, the response includes the created message metadata, including
message_id. - Save that
message_idif you plan to calledit_card_message(),pin_message(), or other message lifecycle methods later.
Example with Raw Card JSON:
card = {
"header": {
"title": {"content": "Approval Request", "tag": "plain_text"},
"template": "red"
},
"elements": [
{"tag": "markdown", "content": "**Ticket #1234** needs approval"},
{
"tag": "action",
"actions": [
{
"tag": "button",
"text": {"content": "Approve", "tag": "plain_text"},
"type": "primary",
"url": "https://example.com/approve/1234"
}
]
}
]
}
bot.send_card_to_chat("oc_xxx", card)
Example with CardContentV2 Builder:
from pywayne.lark_bot import CardContentV2
card = CardContentV2(title="Status Update", template="green")
card.add_markdown("All systems operational ✅")
card.add_hr()
card.add_image("img_xxx", size="large")
bot.send_card_to_chat("oc_xxx", card.get_card())
Example: Capture message_id for Later Update:
from pywayne.lark_bot import CardContentV2
card = CardContentV2(title="Deployment Status", template="blue")
card.add_markdown("⏳ Deployment started")
msg = bot.send_card_to_chat("oc_xxx", card.get_card())
message_id = msg["message_id"]
# ... perform the long-running task ...
done_card = CardContentV2(title="Deployment Status", template="green")
done_card.add_markdown("✅ Deployment completed successfully")
bot.edit_card_message(message_id, done_card.get_card())
Share Messages
# Share chat to user
bot.share_chat_to_user(user_open_id: str, shared_chat_id: str) -> Dict
# Share chat to chat
bot.share_chat_to_chat(chat_id: str, shared_chat_id: str) -> Dict
# Share user to user
bot.share_user_to_user(user_open_id: str, shared_user_id: str) -> Dict
# Share user to chat
bot.share_user_to_chat(chat_id: str, shared_user_id: str) -> Dict
System Messages
# Send system message to user (special divider-style message)
bot.send_system_message_to_user(user_open_id: str, system_msg_text: str) -> Dict
Message Lifecycle Management
Reply to Message
Reply to an existing message with quote/reference.
response = bot.reply_message(
message_id: str,
msg_type: str, # "text", "image", "post", "interactive", etc.
content: Union[str, Dict[str, Any], List[Any]],
*,
reply_in_thread: bool = False, # Reply in thread instead of main chat
uuid: str = ""
) -> Dict
Examples:
# Reply with text
bot.reply_message("om_xxx", "tex
…
## Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- **Author:** [wangyendt](https://github.com/wangyendt)
- **Source:** [wangyendt/wayne-skills](https://github.com/wangyendt/wayne-skills)
- **License:** MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.