Token导航 LogoToken导航

Agent Skill · 开发

teamgram-rpc-development(Teamgram RPC 开发)

teamgram-rpc-development 用于辅助前端页面、组件、样式和交互逻辑开发,适合在 OpenClaw 中需要维护前端项目、生成组件或检查界面实现时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

teamgram-rpc-development 是开发类 Agent Skill,可用宿主为 OpenClaw,通过ClawHub获取,权限为只读;许可证为 MIT-0,第三方扫描已通过,按安装量在开发类的 21,746 个 Skill 里排第 5,550。

总安装 6,139周安装 261GitHub Stars 公开资料未说明下载 2,151核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT-0
版本
2.0.0

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:teamgram-rpc-development(Teamgram RPC 开发)
来源仓库:https://github.com/zhihang9978/teamgram-rpc-development
安装命令:
openclaw skills install teamgram-rpc-development
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install teamgram-rpc-development

这个 Skill 是做什么的

开发类 Skill 面向写代码、改代码和排查问题,一般会读写仓库文件,部分还会执行构建或测试命令。

指导在 Teamgram v2.0.0 中新增 RPC 方法的标准流程。包含参数校验、异常处理与版本兼容性说明。适合贡献代码至官方仓库的开发者阅读。teamgram-rpc-development 属于开发类 Skill,可作为该场景下的辅助能力补充。需遵循项目约定的代码风格与注释规范。

未提供单元测试模板与 CI/CD 集成建议。

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 OpenClaw;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 openclaw skills install teamgram-rpc-development;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它标注为只读,先用只读任务试一次,确认行为符合预期再扩大使用范围。

常见问题

6 条

teamgram-rpc-development 怎么安装?

在终端执行 openclaw skills install teamgram-rpc-development。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

teamgram-rpc-development 支持哪些 AI 工具?

公开资料标注支持 OpenClaw。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

teamgram-rpc-development 需要什么权限?

权限级别是只读。该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

teamgram-rpc-development 是免费的吗?

来源标注的许可证是 MIT-0。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

teamgram-rpc-development 用的人多吗?

公开数据是累计安装 6,139 次,近一周安装 261 次,下载 2,151 次。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

teamgram-rpc-development 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 专注 OpenClaw 一种宿主,触发方式和使用习惯不用来回切换。
  • 许可证明确为 MIT-0,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。
  • 标注为只读权限,试用阶段不容易误改本地文件。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 OpenClaw,想直接扩展它能力的人。
  • 需要处理开发类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

开发类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
skill-vetter

技能审查员 · OpenClaw

8,779,018986操作浏览器MIT-0通过
ontology

本体论 · OpenClaw

6,636,960576只读MIT-0通过
entra-app-registration

内部应用程序注册 · Codex、Claude

6,631,872764接触敏感数据未明确通过
entra-app-registration

内部应用程序注册 · Codex、Claude

3,757,680201接触敏感数据未明确通过
nano-banana-pro

纳米香蕉专业版 · OpenClaw

3,526,898364接触敏感数据MIT-0有提醒
teamgram-rpc-development

Teamgram RPC 开发 · 本页

6,139—只读MIT-0通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

name
teamgram-rpc-development
description
Complete guide for developing RPC services in Teamgram Server (v2.0.0). Use when creating new RPC methods, implementing business logic, or extending Teamgram functionality. Covers TL schema, DAO/Core/Server layers, error handling, performance optimization, security, testing, observability, and production best practices.
version
2.0.0

Teamgram RPC Development Guide v2.0.0

Complete guide for developing RPC services in Teamgram Server.

📚 十次版本迭代优化 (v1.0.0 → v2.0.0) 本技能经过十次迭代完善,涵盖从基础开发到生产部署的完整知识体系。

版本迭代历程

版本主题文档
v1.0.0基础开发本指南
v1.1.0错误处理与日志查看
v1.2.0性能优化与缓存查看
v1.3.0安全最佳实践查看
v1.4.0测试策略查看
v1.5.0可观测性查看
v1.6.0数据库优化查看
v1.7.0消息队列查看
v1.8.0熔断限流查看
v1.9.0多租户查看
v2.0.0完整总结查看

快速导航

新手指南: 从 Development Workflow 开始

生产优化: 查看 v1.2.0性能优化 和 v1.3.0安全

问题排查: 参考 v1.1.0错误处理 和 v1.5.0可观测性

Overview

Teamgram uses gRPC for inter-service communication and MTProto for client-server communication. This guide covers both.

RPC Types

1. Internal RPC (Service-to-Service)

// Internal gRPC between services
service BizService {
  rpc MessagesSendMessage(MessagesSendMessageReq) returns (Updates);
  rpc UsersGetUsers(UsersGetUsersReq) returns (Vector<User>);
}

2. External RPC (Client-to-Server)

// MTProto RPC for Telegram clients
messages.sendMessage#520c3870 peer:InputPeer message:string = Updates;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;

Development Workflow

Step 1: Define TL Schema

// File: specs/mtproto.tl

// Request/Response types
premium.getStatus#d0b5e0f2 user_id:long = PremiumStatus;
premium.purchase#8f8c0e1c user_id:long plan_id:int payment_method:string = Bool;

// Object types
premiumStatus#9a4f3e2d user_id:long status:int expires_at:long = PremiumStatus;

Naming Conventions:

  • Method: category.actionName (camelCase)
  • Constructor ID: #8hexdigits (random or sequential)
  • Types: PascalCase

Step 2: Generate Go Code

# Generate from TL schema
make generate
# or
go run cmd/mtprotoc/main.go -I specs/ -o app/

# Output files:
# app/mtproto/premium_get_status.go
# app/mtproto/premium_purchase.go
# app/mtproto/premium_status.go

Step 3: Create Database Schema

-- File: data/schema/premium.sql

CREATE TABLE user_premium (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT NOT NULL,
    status TINYINT DEFAULT 0 COMMENT '0=none, 1=basic, 2=premium',
    plan_id INT DEFAULT 0,
    expires_at BIGINT DEFAULT 0,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    UNIQUE KEY uk_user_id (user_id),
    INDEX idx_expires (expires_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

CREATE TABLE premium_transactions (
    id BIGINT PRIMARY KEY AUTO_INCREMENT,
    user_id BIGINT NOT NULL,
    plan_id INT NOT NULL,
    amount DECIMAL(10,2) NOT NULL,
    currency VARCHAR(3) DEFAULT 'USD',
    payment_method VARCHAR(50),
    status TINYINT DEFAULT 0 COMMENT '0=pending, 1=success, 2=failed',
    transaction_id VARCHAR(255),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    INDEX idx_user_id (user_id),
    INDEX idx_created_at (created_at)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Step 4: Implement DAO Layer

// File: app/service/biz/internal/dao/premium_dao.go

package dao

import (
    "context"
    "database/sql"
    "time"
    
    "github.com/teamgram/teamgram-server/app/service/biz/internal/model"
    "github.com/zeromicro/go-zero/core/stores/sqlx"
)

type PremiumDAO struct {
    db sqlx.SqlConn
}

func NewPremiumDAO(db sqlx.SqlConn) *PremiumDAO {
    return &PremiumDAO{db: db}
}

// GetPremiumStatus 获取用户会员状态
func (d *PremiumDAO) GetPremiumStatus(ctx context.Context, userID int64) (*model.UserPremium, error) {
    var m model.UserPremium
    query := `SELECT * FROM user_premium WHERE user_id = ?`
    err := d.db.QueryRowCtx(ctx, &m, query, userID)
    if err == sqlx.ErrNotFound {
        // 返回默认状态(非会员)
        return &model.UserPremium{UserID: userID, Status: 0}, nil
    }
    return &m, err
}

// CreateOrUpdatePremium 创建或更新会员状态
func (d *PremiumDAO) CreateOrUpdatePremium(ctx context.Context, userID int64, status int32, planID int, expiresAt int64) error {
    query := `
        INSERT INTO user_premium (user_id, status, plan_id, expires_at) 
        VALUES (?, ?, ?, ?)
        ON DUPLICATE KEY UPDATE 
        status = VALUES(status), 
        plan_id = VALUES(plan_id), 
        expires_at = VALUES(expires_at)
    `
    _, err := d.db.ExecCtx(ctx, query, userID, status, planID, expiresAt)
    return err
}

// CreateTransaction 创建交易记录
func (d *PremiumDAO) CreateTransaction(ctx context.Context, txn *model.PremiumTransaction) (int64, error) {
    query := `
        INSERT INTO premium_transactions 
        (user_id, plan_id, amount, currency, payment_method, status, transaction_id) 
        VALUES (?, ?, ?, ?, ?, ?, ?)
    `
    result, err := d.db.ExecCtx(ctx, query,
        txn.UserID, txn.PlanID, txn.Amount, txn.Currency,
        txn.PaymentMethod, txn.Status, txn.TransactionID,
    )
    if err != nil {
        return 0, err
    }
    return result.LastInsertId()
}

// UpdateTransactionStatus 更新交易状态
func (d *PremiumDAO) UpdateTransactionStatus(ctx context.Context, txnID int64, status int32) error {
    query := `UPDATE premium_transactions SET status = ? WHERE id = ?`
    _, err := d.db.ExecCtx(ctx, query, status, txnID)
    return err
}

Step 5: Implement Core Logic

// File: app/service/biz/internal/core/premium_core.go

package core

import (
    "context"
    "errors"
    "time"
    
    "github.com/teamgram/teamgram-server/app/service/biz/internal/dao"
    "github.com/teamgram/teamgram-server/app/service/biz/internal/model"
    "github.com/teamgram/teamgram-server/app/service/biz/internal/svc"
)

var (
    ErrInvalidPlan = errors.New("invalid premium plan")
    ErrPaymentFailed = errors.New("payment processing failed")
)

type PremiumCore struct {
    svcCtx *svc.ServiceContext
    dao    *dao.PremiumDAO
}

func NewPremiumCore(svcCtx *svc.ServiceContext) *PremiumCore {
    return &PremiumCore{
        svcCtx: svcCtx,
        dao:    dao.NewPremiumDAO(svcCtx.DB),
    }
}

// GetPremiumStatus 获取用户会员状态
func (c *PremiumCore) GetPremiumStatus(ctx context.Context, userID int64) (*model.PremiumStatus, error) {
    // 1. 查询数据库
    premium, err := c.dao.GetPremiumStatus(ctx, userID)
    if err != nil {
        return nil, err
    }
    
    // 2. 检查是否过期
    now := time.Now().Unix()
    if premium.Status > 0 && premium.ExpiresAt < now {
        // 已过期,更新状态
        premium.Status = 0
        _ = c.dao.CreateOrUpdatePremium(ctx, userID, 0, 0, 0)
    }
    
    return &model.PremiumStatus{
        UserID:    userID,
        Status:    premium.Status,
        ExpiresAt: premium.ExpiresAt,
    }, nil
}

// PurchasePremium 购买会员
func (c *PremiumCore) PurchasePremium(ctx context.Context, userID int64, planID int, paymentMethod string) error {
    // 1. 验证套餐
    plan := c.getPlanByID(planID)
    if plan == nil {
        return ErrInvalidPlan
    }
    
    // 2. 创建交易记录
    txn := &model.PremiumTransaction{
        UserID:        userID,
        PlanID:        planID,
        Amount:        plan.Price,
        Currency:      plan.Currency,
        PaymentMethod: paymentMethod,
        Status:        0, // pending
    }
    
    txnID, err := c.dao.CreateTransaction(ctx, txn)
    if err != nil {
        return err
    }
    
    // 3. 调用支付网关(异步处理)
    go c.processPayment(txnID, userID, plan)
    
    return nil
}

// processPayment 处理支付(异步)
func (c *PremiumCore) processPayment(txnID int64, userID int64, plan *Plan) {
    ctx := context.Background()
    
    // 调用支付接口...
    // 成功后在回调中:
    
    // 1. 更新交易状态
    _ = c.dao.UpdateTransactionStatus(ctx, txnID, 1) // success
    
    // 2. 更新用户会员状态
    expiresAt := time.Now().AddDate(0, plan.DurationMonths, 0).Unix()
    _ = c.dao.CreateOrUpdatePremium(ctx, userID, 1, plan.ID, expiresAt)
    
    // 3. 发送通知
    c.svcCtx.PushClient.SendToUser(ctx, userID, "Premium activated!")
}

func (c *PremiumCore) getPlanByID(planID int) *Plan {
    plans := map[int]*Plan{
        1: {ID: 1, Name: "Basic", Price: 4.99, DurationMonths: 1},
        2: {ID: 2, Name: "Premium", Price: 49.99, DurationMonths: 12},
    }
    return plans[planID]
}

type Plan struct {
    ID             int
    Name           string
    Price          float64
    Currency       string
    DurationMonths int
}

Step 6: Implement RPC Server

// File: app/service/biz/internal/server/premium_server.go

package server

import (
    "context"
    
    "github.com/teamgram/teamgram-server/app/mtproto"
    "github.com/teamgram/teamgram-server/app/service/biz/internal/core"
    "github.com/teamgram/teamgram-server/app/service/biz/internal/svc"
)

func (s *Server) PremiumGetStatus(ctx context.Context, req *mtproto.TLPremiumGetStatus) (*mtproto.PremiumStatus, error) {
    // 1. 调用Core层
    status, err := s.premiumCore.GetPremiumStatus(ctx, req.UserId)
    if err != nil {
        return nil, err
    }
    
    // 2. 转换为MTProto对象
    return &mtproto.TLPremiumStatus{
        UserId:    status.UserID,
        Status:    status.Status,
        ExpiresAt: status.ExpiresAt,
    }, nil
}

func (s *Server) PremiumPurchase(ctx context.Context, req *mtproto.TLPremiumPurchase) (*mtproto.Bool, error) {
    // 1. 调用Core层
    err := s.premiumCore.PurchasePremium(ctx, req.UserId, int(req.PlanId), req.PaymentMethod)
    if err != nil {
        return mtproto.BoolFalse, err
    }
    
    return mtproto.BoolTrue, nil
}

Step 7: Register RPC

// File: app/service/biz/internal/server/server.go

func Register(grpcServer *grpc.Server, svcCtx *svc.ServiceContext) {
    s := &Server{
        svcCtx:      svcCtx,
        premiumCore: core.NewPremiumCore(svcCtx),
        // ... other cores
    }
    
    // Register all services
    mtproto.RegisterBizServiceServer(grpcServer, s)
}

Step 8: Testing

// File: app/service/biz/internal/core/premium_core_test.go

package core_test

import (
    "context"
    "testing"
    
    "github.com/stretchr/testify/assert"
    "github.com/stretchr/testify/mock"
    "github.com/teamgram/teamgram-server/app/service/biz/internal/core"
)

func TestGetPremiumStatus(t *testing.T) {
    // Setup
    svcCtx := setupTestContext()
    c := core.NewPremiumCore(svcCtx)
    
    // Test: Non-premium user
    status, err := c.GetPremiumStatus(context.Background(), 123456)
    
    // Assert
    assert.NoError(t, err)
    assert.Equal(t, int32(0), status.Status)
    assert.Equal(t, int64(123456), status.UserID)
}

func TestPurchasePremium(t *testing.T) {
    // Setup with mocked payment gateway
    svcCtx := setupTestContext()
    c := core.NewPremiumCore(svcCtx)
    
    // Execute
    err := c.PurchasePremium(context.Background(), 123456, 1, "stripe")
    
    // Assert
    assert.NoError(t, err)
    // Verify transaction created...
}

Advanced Patterns

1. Rate Limiting

func (s *Server) PremiumPurchase(ctx context.Context, req *mtproto.TLPremiumPurchase) (*mtproto.Bool, error) {
    // Check rate limit
    key := fmt.Sprintf("rate_limit:purchase:%d", req.UserId)
    count, err := s.svcCtx.Redis.Incr(key)
    if err == nil && count > 10 {
        return nil, errors.New("rate limit exceeded")
    }
    s.svcCtx.Redis.Expire(key, 3600) // 1 hour
    
    // Process...
}

2. Caching

func (c *PremiumCore) GetPremiumStatus(ctx context.Context, userID int64) (*model.PremiumStatus, error) {
    // Try cache
    cacheKey := fmt.Sprintf("premium:%d", userID)
    cached, err := c.svcCtx.Redis.Get(cacheKey)
    if err == nil {
        var status model.PremiumStatus
        json.Unmarshal([]byte(cached), &status)
        return &status, nil
    }
    
    // Cache miss - query DB
    status, err := c.dao.GetPremiumStatus(ctx, userID)
    if err != nil {
        return nil, err
    }
    
    // Update cache
    data, _ := json.Marshal(status)
    c.svcCtx.Redis.Set(cacheKey, string(data), 300) // 5 min TTL
    
    return status, nil
}

3. Distributed Transactions

func (c *PremiumCore) PurchaseWithTransaction(ctx context.Context, userID int64, planID int) error {
    return c.svcCtx.DB.Transact(func(tx *sql.Tx) error {
        // Deduct balance
        if err := c.dao.DeductBalanceTx(tx, userID, amount); err != nil {
            return err
        }
        
        // Create premium record
        if err := c.dao.CreatePremiumTx(tx, userID, planID); err != nil {
            return err
        }
        
        // Record transaction
        return c.dao.RecordTransactionTx(tx, userID, amount)
    })
}

Common Mistakes

1. Not Handling Context Cancellation

// Wrong
func (c *Core) LongOperation(ctx context.Context) {
    time.Sleep(10 * time.Second) // Blocks even if client disconnected
}

// Correct
func (c *Core) LongOperation(ctx context.Context) error {
    select {
    case <-ctx.Done():
        return ctx.Err()
    case <-time.After(10 * time.Second):
        return nil
    }
}

2. Ignoring Database Errors

// Wrong
data, _ := c.dao.Get(ctx, id) // Silent failure!

// Correct
data, err := c.dao.Get(ctx, id)
if err != nil {
    if err == sqlx.ErrNotFound {
        return nil, status.Error(codes.NotFound, "not found")
    }
    return nil, status.Error(codes.Internal, err.Error())
}

3. Not Using Transactions

// Wrong - partial failure possible
c.dao.DeductBalance(ctx, userID, amount)
c.dao.AddPremium(ctx, userID, planID) // May fail after deduction!

// Correct - atomic operation
c.svcCtx.DB.Transact(func(tx *sql.Tx) error {
    c.dao.DeductBalanceTx(tx, userID, amount)
    c.dao.AddPremiumTx(tx, userID, planID)
    return nil
})

References

See references/rpc-patterns.md for common patterns.

平台分布

OpenClaw

80.04%
按下载量换算1,722

安全审计

VirusTotal

通过

ClawScan

通过

Static analysis

通过

权限和风险

只读

该 Skill 主要提供规则、说明或参考内容,本身偏只读;真正读写文件、联网或执行命令仍取决于宿主 Agent 的任务。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。目前只有一个公开来源,建议同时核对源仓库。

继续浏览同类 Skills