AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Pywayne Lark Custom Bot

skill-wangyendt-wayne-skills-lark-custom-bot · by wangyendt

Feishu/Lark Custom Bot API wrapper for sending messages via webhook. Use when users need to send text messages, images, rich text posts, interactive cards, or share chat content to Feishu/Lark channels. Supports image upload from files or OpenCV/numpy images, signature verification for security, and @mention functionality. Ideal for one-way notifications, alerts, scheduled tasks, and simple push…

No reviews yet
0 installs
21 views
0.0% view→install

Install

$ agentstack add skill-wangyendt-wayne-skills-lark-custom-bot

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-wangyendt-wayne-skills-lark-custom-bot)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

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 →
Are you the author of Pywayne Lark Custom Bot? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Pywayne Lark Custom Bot - Webhook Message Sender

Overview

LarkCustomBot is a webhook-based Feishu (Lark) bot wrapper designed for one-way message pushing. It's ideal for scenarios where you only need to send messages to Feishu groups without listening for incoming messages or managing complex interactions.

Key Characteristics:

  • Lightweight, simple webhook-based architecture
  • No event subscription or listening capabilities
  • Perfect for alerts, notifications, scheduled tasks
  • Supports signature verification for security

When to Use LarkCustomBot:

  • Push-only scenarios (notifications, alerts, reports)
  • Simple scheduled tasks sending updates
  • Quick setup without event subscription configuration
  • Don't need message replies, reactions, or chat management

When to Use LarkBot Instead:

  • Need to listen and reply to messages
  • Require message lifecycle management (recall, edit, reactions)
  • Need chat management (members, admins, announcements)
  • Interactive features like button callbacks

Installation

pip install pywayne

Quick Start

from pywayne.lark_custom_bot import LarkCustomBot

# Initialize bot with webhook
bot = LarkCustomBot(
    webhook="https://open.feishu.cn/open-apis/bot/v2/hook/xxxxxxxxx"
)

# Send simple text message
bot.send_text("Hello, Feishu!")

# Send text with @all mention
bot.send_text("Important announcement!", mention_all=True)

LarkCustomBot Class

Constructor

bot = LarkCustomBot(
    webhook: str,              # Required: Webhook URL from Feishu group bot settings
    secret: str = '',          # Optional: Signing secret for request verification
    bot_app_id: str = '',      # Optional: App ID for image upload authentication
    bot_secret: str = ''       # Optional: App secret for image upload authentication
)

Parameters:

  • webhook: Webhook URL obtained from Feishu group custom bot settings
  • secret: Signing secret for signature verification (enhances security)
  • bot_app_id: Required for upload_image() and upload_image_from_cv2()
  • bot_secret: Required for upload_image() and upload_image_from_cv2()

Note: Image upload requires app credentials (bot_app_id and bot_secret) because it uses Feishu's OpenAPI authentication, not webhook.

Core Methods

send_text - Send Text Message

Send plain text message with optional @all mention.

bot.send_text(text: str, mention_all: bool = False) -> None

Parameters:

  • text: Message text content
  • mention_all: Whether to @all users in the group (default False)

Examples:

# Simple text
bot.send_text("Daily backup completed successfully")

# With @all mention
bot.send_text("System maintenance at 23:00 tonight", mention_all=True)

# Multi-line text
bot.send_text("""
Deployment completed:
- API: v1.2.3
- Frontend: v2.4.5
- Database migration: done
""")

# With HTML-like formatting (supported in text messages)
bot.send_text("Bold text and italic text")

send_post - Send Rich Text Post

Send rich text message with structured content including text, links, @mentions, and images.

bot.send_post(
    content: List[List[Dict]],      # 2D list of content elements
    title: Optional[str] = None     # Optional post title
) -> None

Parameters:

  • content: 2D list structure where:
  • Outer list = multiple lines
  • Inner list = multiple elements in the same line
  • title: Post title displayed at the top

Content Structure:

content = [
    [element1, element2],  # Line 1 with 2 elements
    [element3],            # Line 2 with 1 element
    [element4, element5],  # Line 3 with 2 elements
]

Basic Example:

from pywayne.lark_custom_bot import (
    LarkCustomBot,
    create_text_content,
    create_link_content,
    create_at_content,
    create_image_content
)

bot = LarkCustomBot(
    webhook="https://open.feishu.cn/open-apis/bot/v2/hook/xxx",
    bot_app_id="cli_xxx",
    bot_secret="sec_xxx"
)

# Upload image first
image_key = bot.upload_image("/tmp/report.png")

# Construct post content
content = [
    # Line 1: Title text
    [create_text_content("Daily Report", unescape=False)],
    
    # Line 2: Link
    [create_link_content(href="https://dashboard.example.com", text="View Dashboard")],
    
    # Line 3: @mention
    [create_at_content(user_id="all", user_name="Everyone")],
    
    # Line 4: Image
    [create_image_content(image_key=image_key, width=400, height=300)],
    
    # Line 5: Multiple elements in one line
    [
        create_text_content("Status: "),
        create_text_content("✅ Completed", unescape=True)
    ]
]

bot.send_post(content, title="Daily Operations Report")

send_image - Send Image Message

Send image message using image key.

bot.send_image(image_key: str) -> None

Note: Must upload image first using upload_image() or upload_image_from_cv2().

Example:

# Upload and send local image
image_key = bot.upload_image("/path/to/chart.png")
bot.send_image(image_key)

# Upload from OpenCV image
import cv2
import numpy as np

img = cv2.imread("/path/to/image.jpg")
# Process image...
image_key = bot.upload_image_from_cv2(img)
bot.send_image(image_key)

send_interactive - Send Interactive Card

Send interactive card message with buttons, forms, or other interactive elements.

bot.send_interactive(card: Dict) -> None

Parameters:

  • card: Interactive card JSON structure following Feishu card schema

Example: Simple Notification Card:

card = {
    "config": {"wide_screen_mode": True},
    "header": {
        "title": {"tag": "plain_text", "content": "Approval Required"},
        "template": "red"
    },
    "elements": [
        {
            "tag": "markdown",
            "content": "**Ticket #1234** is waiting for approval"
        },
        {
            "tag": "action",
            "actions": [
                {
                    "tag": "button",
                    "text": {"tag": "plain_text", "content": "View Details"},
                    "type": "primary",
                    "url": "https://example.com/ticket/1234"
                }
            ]
        }
    ]
}
bot.send_interactive(card)

Example: Status Card with Multiple Elements:

card = {
    "header": {
        "title": {"tag": "plain_text", "content": "Build Status"},
        "template": "blue"
    },
    "elements": [
        {
            "tag": "div",
            "text": {"tag": "lark_md", "content": "**Build #456** completed"}
        },
        {
            "tag": "hr"
        },
        {
            "tag": "div",
            "fields": [
                {"is_short": True, "text": {"tag": "lark_md", "content": "**Duration**\n3m 42s"}},
                {"is_short": True, "text": {"tag": "lark_md", "content": "**Status**\n✅ Success"}}
            ]
        }
    ]
}
bot.send_interactive(card)

sendsharechat - Share Chat

Share a chat group as a card.

bot.send_share_chat(share_chat_id: str) -> None

Example:

# Share a group chat
bot.send_share_chat("oc_a1b2c3d4e5f6g7h8")

Image Upload Methods

upload_image - Upload from File Path

Upload local image file to Feishu and get image key.

image_key = bot.upload_image(file_path: str) -> str

Parameters:

  • file_path: Local path to image file

Returns:

  • str: Image key if successful, empty string if failed

Example:

# Upload and send
image_key = bot.upload_image("/tmp/screenshot.png")
if image_key:
    bot.send_image(image_key)
else:
    print("Image upload failed")

Requirements:

  • Must set bot_app_id and bot_secret in constructor
  • File must exist and not be empty
  • Supported formats: JPEG, PNG, GIF, etc.

uploadimagefrom_cv2 - Upload from OpenCV Image

Upload image directly from OpenCV/numpy array.

image_key = bot.upload_image_from_cv2(cv2_image: np.ndarray) -> str

Parameters:

  • cv2_image: OpenCV image array (np.ndarray)

Returns:

  • str: Image key if successful, empty string if failed

Example: Generate and Send Visualization:

import cv2
import numpy as np

# Create visualization
img = np.zeros((400, 600, 3), dtype=np.uint8)
cv2.putText(img, "TEST PASSED", (80, 220), cv2.FONT_HERSHEY_SIMPLEX, 2, (0, 255, 0), 5)
cv2.rectangle(img, (50, 50), (550, 350), (0, 255, 0), 3)

# Upload and send directly
image_key = bot.upload_image_from_cv2(img)
bot.send_image(image_key)

Example: Process and Send:

import cv2

# Read and process image
original = cv2.imread("/input/image.jpg")
gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150)
edges_colored = cv2.cvtColor(edges, cv2.COLOR_GRAY2BGR)

# Upload processed result
image_key = bot.upload_image_from_cv2(edges_colored)
bot.send_image(image_key)

Use Cases:

  • Algorithm result visualization
  • Real-time monitoring screenshots
  • Computer vision processing results
  • Generated charts and plots

Content Builder Functions

These module-level functions help construct send_post() content elements.

createtextcontent

Create text content element.

create_text_content(text: str, unescape: bool = False) -> Dict

Parameters:

  • text: Text content
  • unescape: Whether to unescape HTML entities (default False)

Example:

text_elem = create_text_content("Normal text")
unescaped_elem = create_text_content("Bold", unescape=True)

createlinkcontent

Create hyperlink content element.

create_link_content(href: str, text: str) -> Dict

Parameters:

  • href: URL link
  • text: Display text for the link

Example:

link_elem = create_link_content("https://www.feishu.cn", "Visit Feishu")

createatcontent

Create @mention content element.

create_at_content(user_id: str, user_name: str) -> Dict

Parameters:

  • user_id: User ID or "all" for @everyone
  • user_name: Display name for the mention

Examples:

# @specific user
at_user = create_at_content("ou_xxxxxxxxxxxx", "John Doe")

# @everyone
at_all = create_at_content("all", "Everyone")

createimagecontent

Create image content element.

create_image_content(
    image_key: str,
    width: Optional[int] = None,
    height: Optional[int] = None
) -> Dict

Parameters:

  • image_key: Image key obtained from upload
  • width: Optional image display width in pixels
  • height: Optional image display height in pixels

Example:

img_elem = create_image_content(
    image_key="img_v3_xxxxxxxxxxxx",
    width=500,
    height=300
)

Common Usage Scenarios

Scenario 1: Simple Scheduled Notification

from pywayne.lark_custom_bot import LarkCustomBot

bot = LarkCustomBot(webhook="https://open.feishu.cn/open-apis/bot/v2/hook/xxx")

# Daily morning notification
bot.send_text("Good morning! Daily inspection started at 09:00")

Scenario 2: Rich Announcement with Multiple Elements

from pywayne.lark_custom_bot import (
    LarkCustomBot,
    create_text_content,
    create_link_content,
    create_at_content
)

bot = LarkCustomBot(webhook="https://open.feishu.cn/open-apis/bot/v2/hook/xxx")

content = [
    [create_text_content("Release v1.2.0 Completed", unescape=False)],
    [create_text_content("New Features:", unescape=False)],
    [create_text_content("  • API optimization")],
    [create_text_content("  • Bug fixes")],
    [create_link_content("https://example.com/release-notes", "View Release Notes")],
    [
        create_at_content("all", "Everyone"),
        create_text_content(" please review and confirm.")
    ]
]

bot.send_post(content, title="Release Announcement")

Scenario 3: Upload and Send Local Image

bot = LarkCustomBot(
    webhook="https://open.feishu.cn/open-apis/bot/v2/hook/xxx",
    bot_app_id="cli_xxx",
    bot_secret="sec_xxx"
)

# Upload image file
image_key = bot.upload_image("/tmp/performance_chart.png")

if image_key:
    bot.send_image(image_key)
else:
    bot.send_text("Failed to upload image")

Scenario 4: OpenCV Processing Pipeline

import cv2
import numpy as np

bot = LarkCustomBot(
    webhook="https://open.feishu.cn/open-apis/bot/v2/hook/xxx",
    bot_app_id="cli_xxx",
    bot_secret="sec_xxx"
)

# Generate test result visualization
img = np.zeros((400, 600, 3), dtype=np.uint8)

# Add test status
status = "PASS"
color = (0, 255, 0)  # Green
cv2.putText(img, status, (120, 220), cv2.FONT_HERSHEY_SIMPLEX, 3, color, 6)
cv2.rectangle(img, (30, 30), (570, 370), color, 3)

# Upload OpenCV image directly
image_key = bot.upload_image_from_cv2(img)
bot.send_image(image_key)

Scenario 5: Combined Post with Text, Image, and Links

from pywayne.lark_custom_bot import (
    LarkCustomBot,
    create_text_content,
    create_link_content,
    create_image_content
)

bot = LarkCustomBot(
    webhook="https://open.feishu.cn/open-apis/bot/v2/hook/xxx",
    bot_app_id="cli_xxx",
    bot_secret="sec_xxx"
)

# Upload dashboard screenshot
image_key = bot.upload_image("/tmp/dashboard.png")

# Construct rich post
content = [
    [create_text_content("Monitoring Snapshot:")],
    [create_image_content(image_key, width=600, height=400)],
    [create_link_content("https://grafana.example.com", "Open Full Dashboard")],
    [create_text_content("Generated at: 2026-03-12 14:30:00")]
]

bot.send_post(content, title="Daily Monitoring Report")

Scenario 6: Interactive Approval Card

card = {
    "config": {"wide_screen_mode": True},
    "header": {
        "title": {"tag": "plain_text", "content": "Approval Request"},
        "template": "orange"
    },
    "elements": [
        {
            "tag": "markdown",
            "content": "**Deployment Request #5678**\n\nEnvironment: Production\nRequested by: John Doe"
        },
        {
            "tag": "hr"
        },
        {
            "tag": "action",
            "actions": [
                {
                    "tag": "button",
                    "text": {"tag": "plain_text", "content": "Approve"},
                    "type": "primary",
                    "url": "https://example.com/approve/5678"
                },
                {
                    "tag": "button",
                    "text": {"tag": "plain_text", "content": "Reject"},
                    "type": "danger",
                    "url": "https://example.com/reject/5678"
                }
            ]
        }
    ]
}

bot.send_interactive(card)

Scenario 7: Secure Sending with Signature Verification

# Initialize with signature secret
bot = LarkCustomBot(
    webhook="https://open.feishu.cn/open-apis/bot/v2/hook/xxx",
    secret="your_signing_secret"
)

# All messages will automatically include timestamp and signature
bot.send_text("This message is signed for security")

Scenario 8: Multi-Step Operations Report

from pywayne.lark_custom_bot import LarkCustomBot, create_text_content, create_link_content

bot = LarkCustomBot(
    webhook="https://open.feishu.cn/open-apis/bot/v2/hook/xxx"
)

# Step 1: Start notification
bot.send_text("🔄 Nightly inspection started...")

# Perform tasks...
# ... inspection logic ...

# Step 2: Send detailed report
content = [
    [create_text_content("✅ Nightly Inspection Completed", unescape=True)],
    [create_text_content("")],
    [create_text_content("Results:")],
    [create_text_content("  • Database backup: OK")],
    [create_text_content("  • Log cleanup: OK")],
    [create_text_content("  • Health check: OK")],
    [create_text_content("  • Disk usage: 42%")],
    [create_text_content("")],
    [create_link_content("https://monitoring.example.com", "View Detailed Report")]
]

bot.send_post(content, title="Inspection Report - 2026-03-12")

Scenario 9

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.