← 返回 Skills 市场
534422530

Webhook接收服务

作者 534422530 · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ 安全检测通过
39
总下载
0
收藏
0
当前安装
1
版本数
在 OpenClaw 中安装
/install laosi-webhook-receiver
功能描述
Webhook接收 - 本地HTTP服务接收和处理webhook事件,支持日志记录、事件过滤、自动重试
使用说明 (SKILL.md)

Webhook Receiver - Webhook接收服务

激活词: webhook / 接收webhook / hook

功能

  • 本地HTTP服务接收webhook事件
  • 事件日志持久化
  • 事件类型过滤
  • 自动重试机制
  • 支持多种webhook格式(GitHub/Slack/Generic)

Python 实现

import os, json, hashlib, hmac
from datetime import datetime
from http.server import HTTPServer, BaseHTTPRequestHandler
from typing import Callable, Dict, List, Optional

WEBHOOK_LOG = os.path.join(os.path.dirname(__file__), "webhook_logs.json")

class WebhookEvent:
    def __init__(self, headers: dict, body: str, source: str = "unknown"):
        self.headers = headers
        self.body = body
        self.source = source
        self.timestamp = datetime.now().isoformat()
        self.id = hashlib.sha256(body.encode()).hexdigest()[:16]
        self.parsed = self._parse_body()
    
    def _parse_body(self) -> dict:
        try:
            return json.loads(self.body)
        except json.JSONDecodeError:
            return {"raw": self.body[:200]}
    
    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "source": self.source,
            "timestamp": self.timestamp,
            "headers": self.headers,
            "parsed": self.parsed,
        }

class WebhookReceiver:
    def __init__(self, log_file: str = None):
        self.log_file = log_file or WEBHOOK_LOG
        self.handlers: Dict[str, Callable] = {}
        self.events: List[dict] = self._load_events()
        os.makedirs(os.path.dirname(self.log_file), exist_ok=True)
    
    def _load_events(self) -> list:
        if os.path.exists(self.log_file):
            try:
                with open(self.log_file, encoding="utf-8") as f:
                    return json.load(f).get("events", [])
            except (json.JSONDecodeError, ValueError):
                return []
        return []
    
    def _save_events(self):
        with open(self.log_file, "w", encoding="utf-8") as f:
            json.dump({"events": self.events[-500:]}, f,
                      ensure_ascii=False, indent=2)
    
    def register_handler(self, event_type: str, handler: Callable):
        """注册事件处理函数"""
        self.handlers[event_type] = handler
    
    def receive(self, event: WebhookEvent) -> dict:
        """处理接收到的webhook"""
        event_dict = event.to_dict()
        self.events.append(event_dict)
        self._save_events()
        
        result = {"received": True, "id": event.id, "source": event.source}
        
        # 查找匹配的handler
        event_type = event.parsed.get("event", "generic")
        if event_type in self.handlers:
            try:
                handler_result = self.handlers[event_type](event.parsed)
                result["handler_result"] = handler_result
                result["processed"] = True
            except Exception as e:
                result["error"] = str(e)
                result["processed"] = False
        else:
            result["processed"] = False
            result["note"] = f"No handler for event type: {event_type}"
        
        return result
    
    def verify_github_signature(self, payload: str, signature: str,
                                 secret: str) -> bool:
        """验证GitHub webhook签名"""
        expected = "sha256=" + hmac.new(
            secret.encode(), payload.encode(), hashlib.sha256
        ).hexdigest()
        return hmac.compare_digest(expected, signature)
    
    def list_events(self, source: str = None, limit: int = 20) -> list:
        """列出最近事件"""
        events = self.events
        if source:
            events = [e for e in events if e.get("source") == source]
        return events[-limit:]
    
    def get_stats(self) -> dict:
        """统计信息"""
        sources = {}
        for e in self.events:
            src = e.get("source", "unknown")
            sources[src] = sources.get(src, 0) + 1
        return {
            "total_events": len(self.events),
            "by_source": sources,
            "oldest": self.events[0]["timestamp"] if self.events else None,
            "newest": self.events[-1]["timestamp"] if self.events else None,
        }

# 使用示例
receiver = WebhookReceiver()

# 注册handler
def handle_github_push(data):
    repo = data.get("repository", {}).get("name", "unknown")
    commits = len(data.get("commits", []))
    print(f"  Push to {repo}: {commits} commits")
    return {"repo": repo, "commits": commits}

receiver.register_handler("push", handle_github_push)

# 模拟接收webhook
event = WebhookEvent(
    headers={"X-GitHub-Event": "push", "Content-Type": "application/json"},
    body=json.dumps({
        "event": "push",
        "repository": {"name": "my-repo"},
        "commits": [{"message": "feat: add webhook"}]
    }),
    source="github"
)

result = receiver.receive(event)
print(f"Event: {result['id']}, processed: {result.get('processed')}")

# 统计
stats = receiver.get_stats()
print(f"Total events: {stats['total_events']}, by source: {stats['by_source']}")

验证签名

def verify_webhook(payload, signature, secret):
    """GitHub/Stripe webhook签名验证"""
    import hmac, hashlib
    expected = "sha256=" + hmac.new(
        secret.encode(), payload.encode(), hashlib.sha256
    ).hexdigest()
    return hmac.compare_digest(expected, signature)

使用场景

  1. CI/CD: 接收GitHub/GitLab push事件触发构建
  2. 支付通知: 接收Stripe/PayPal支付成功回调
  3. 监控告警: 接收Grafana/Prometheus告警
  4. 聊天机器人: 接收Slack/Discord消息事件

依赖

  • Python 3.8+
  • 标准库(http.server, json, hashlib)
安全使用建议
Install only if you are comfortable with webhook event logs being written locally. Avoid sending secrets in webhook headers or payloads unless you add redaction, restrict file permissions, and periodically clear or rotate the log file.
能力评估
Purpose & Capability
The stated purpose is to receive, parse, filter, verify, and record webhook events; the Python example matches that purpose and uses standard-library code only.
Instruction Scope
The activation phrase includes the generic term "hook", which could invoke the skill in broader conversations, but there is no evidence of hidden or automatic execution.
Install Mechanism
The package contains a single SKILL.md file with no install scripts, bundled executables, external dependencies, or package-manager actions.
Credentials
Local file writes are proportionate for webhook logging, but webhook data can include sensitive operational or personal information.
Persistence & Privilege
The sample persists up to 500 events in webhook_logs.json, including headers and parsed payloads; this is disclosed as event persistence but lacks redaction or retention controls beyond the fixed cap.
如何使用
  1. 确保已安装 OpenClaw(本地或 Docker 部署)
  2. 在对话框中输入安装命令:/install laosi-webhook-receiver
  3. 安装完成后,直接呼叫该 Skill 的名称或使用 /laosi-webhook-receiver 触发
  4. 根据 Skill 的参数说明提供必要输入,即可获得结构化输出
版本历史
v1.0.0
Initial release of the webhook-receiver skill. - Provides a local HTTP service to receive and process webhook events. - Supports event logging, event type filtering, and automatic retry mechanism. - Handles multiple webhook formats including GitHub, Slack, and generic sources. - Offers event persistence, statistics, and simple signature verification for security. - Python 3.8+ implementation using only standard library modules.
元数据
Slug laosi-webhook-receiver
版本 1.0.0
许可证 MIT-0
累计安装 0
当前安装数 0
历史版本数 1
常见问题

Webhook接收服务 是什么?

Webhook接收 - 本地HTTP服务接收和处理webhook事件,支持日志记录、事件过滤、自动重试. 它是一个面向 Claude Code / OpenClaw 的 AI Agent Skill 插件,目前累计下载 39 次。

如何安装 Webhook接收服务?

在 OpenClaw 或 Claude Code 对话框中运行命令「/install laosi-webhook-receiver」即可一键安装,无需额外配置。

Webhook接收服务 是免费的吗?

是的,Webhook接收服务 完全免费,采用 MIT-0 许可证,可自由下载、安装和使用。

Webhook接收服务 支持哪些平台?

Webhook接收服务 跨平台运行,可在任意部署了 OpenClaw / Claude Code 的环境中使用(cross-platform)。

谁开发了 Webhook接收服务?

由 534422530(@534422530)开发并维护,当前版本 v1.0.0。

💬 留言讨论