150行Python干掉客户入驻60分钟手工活:从签约到开票全自动流水线

你是不是也这样?
新客户一签约,就得手动建文件夹、发欢迎邮件、拉 Slack 群、开 Trello 看板、填发票草稿、记 Notion……
光这一套操作,就要花掉你 45 分钟——还没开始干活,时间先被流程吃掉了。

别忍了。
这篇就带你用 150 行干净 Python,把整套客户入驻流程变成「一键启动」:
✅ 收到签约通知(Stripe/表单/Webhook)→
✅ 自动建好带结构的 Google Drive 文件夹 →
✅ 发一封带客户名字、套餐时长、下一步提醒的欢迎邮件 →
✅ 开一个预设好「需求收集」「进行中」「审核」「完成」四列的 Trello 项目板 →
✅ 在 Stripe 里生成带金额和描述的待审核发票草稿 →
✅ 把客户信息自动存进 Notion 客户库 →
✅ 最后弹个 Slack 消息告诉你:“新客户来了,快去看看!”

全程 不到 10 秒,失败不中断:Trello 挂了?邮件照发;Notion 延迟?发票照样建。每个环节独立运行,互不拖累。

下面就是全部代码——没有黑魔法,全是标准库 + httpx + FastAPI,每一步都加了中文注释,新手照着抄也能跑通👇

Step 1:配置和客户数据模型

from dataclasses import dataclass, field
from datetime import datetime
from typing import Optional
import os
import httpx
import json

@dataclass
class Client:
    """从表单或 Stripe 回调拿到的新客户信息"""
    name: str          # 客户姓名,比如 "Sarah Chen"
    email: str         # 邮箱,用于发邮件和创建 Stripe 客户
    company: str       # 公司名,用于文件夹命名和 Trello 板标题
    package: str       # 套餐名:"starter" / "growth" / "enterprise"
    phone: Optional[str] = None   # 可选电话
    notes: Optional[str] = None   # 可选备注
    created_at: str = field(default_factory=lambda: datetime.now().isoformat())  # 自动生成时间戳

# 各套餐价格(单位:美分)和对应服务小时数
PACKAGES = {
    "starter":     {"price": 500_00,  "hours": 10},   # 500美元,10小时
    "growth":      {"price": 1500_00, "hours": 30},   # 1500美元,30小时
    "enterprise":  {"price": 5000_00, "hours": 80},   # 5000美元,80小时
}

# 每个客户项目的标准文件夹结构(自动创建)
FOLDER_TEMPLATE = [
    "01_Brief",                 # 需求文档放这里
    "02_Assets",                # 图片、设计稿等素材
    "03_Drafts",                # 中间稿、修改版
    "04_Final_Deliverables",    # 终稿交付物
    "05_Invoices",              # 所有发票存档
]

Step 2:可容错的流水线执行器

class Pipeline:
    """按顺序执行各步骤,某步失败不影响其他步骤,全部结果统一返回"""

    def __init__(self):
        self.results = {}  # 记录每步成功返回的内容,如 "Created folder xxx"
        self.errors = []   # 记录失败步骤名和错误信息

    def run(self, client: Client):
        # 定义所有自动化步骤:名称 + 对应函数
        steps = [
            ("drive", create_project_folder),   # ① 创建 Google Drive 文件夹
            ("email", send_welcome_email),      # ② 发欢迎邮件
            ("trello", create_trello_board),    # ③ 开 Trello 项目板
            ("invoice", create_stripe_invoice), # ④ 生成 Stripe 发票草稿
            ("notion", log_to_notion),          # ⑤ 存入 Notion 客户库
            ("slack", notify_slack),           # ⑥ 发 Slack 提醒
        ]

        for name, step_fn in steps:
            try:
                result = step_fn(client)  # 调用具体函数
                self.results[name] = result
                print(f"✅ {name}: {result}")  # 成功打印绿色对勾
            except Exception as e:
                self.errors.append((name, str(e)))
                print(f"❌ {name}: {e}")  # 失败打印红色叉叉,但继续下一项

        # 返回:是否全成功、各步结果、错误列表
        return len(self.errors) == 0, self.results, self.errors

Step 3:自动建 Google Drive 项目文件夹

def create_project_folder(client: Client) -> str:
    """用 Google Drive API 创建带子文件夹的客户专属空间"""
    DRIVE_API = "https://www.googleapis.com/drive/v3/files"

    headers = {
        "Authorization": f"Bearer {os.environ['GOOGLE_TOKEN']}",  # 你的 Google 访问令牌(需提前获取)
        "Content-Type": "application/json",
    }

    # 第一步:创建最外层客户文件夹,命名如 "Acme Corp - Sarah Chen"
    root = httpx.post(DRIVE_API, headers=headers, json={
        "name": f"{client.company} - {client.name}",
        "mimeType": "application/vnd.google-apps.folder",  # 指定是文件夹类型
    }).json()

    # 第二步:在根文件夹下,批量创建预设的 5 个子文件夹
    for folder_name in FOLDER_TEMPLATE:
        httpx.post(DRIVE_API, headers=headers, json={
            "name": folder_name,
            "mimeType": "application/vnd.google-apps.folder",
            "parents": [root["id"]],  # 指定父文件夹 ID
        })

    return f"Created folder {root['id']}"

Step 4:发个性化欢迎邮件

def send_welcome_email(client: Client) -> str:
    """调用你自己的邮件服务商 API(如 SendGrid/Mailgun),发定制化邮件"""
    package_info = PACKAGES[client.package]
    hours = package_info["hours"]

    body = (
        f"Hi {client.name},\n\n"
        f"Welcome aboard! Excited to work with {client.company}.\n\n"
        f"Here is what happens next:\n\n"
        f"1. Project workspace created — access within 24 hours\n"
        f"2. Project board set up with {hours} hours allocated\n"
        f"3. Brief questionnaire arriving soon for requirements\n\n"
        f"First deliverable: 48 hours from brief completion.\n\n"
        f"Questions? Just reply — we respond within 2 hours.\n\n"
        f"Best,\nVasquez Ventures"
    )

    # 这里换成你实际的邮件 API 地址(如 SendGrid 的 /v3/mail/send)
    httpx.post("https://api.your-email-provider.com/send", json={
        "to": [client.email],                                 # 收件人
        "subject": f"Welcome to Vasquez Ventures, {client.name}!",  # 主题含客户名
        "text": body,                                         # 邮件正文
        "from": "hello@vasquezventures.com",                  # 发件人
    })

    return f"Welcome email sent to {client.email}"

Step 5:秒开 Trello 项目看板

def create_trello_board(client: Client) -> str:
    """自动创建带标准流程列和启动卡片的 Trello 板"""
    TRELLO_API = "https://api.trello.com/1"
    key = os.environ["TRELLO_API_KEY"]   # 你的 Trello 开发者 Key
    token = os.environ["TRELLO_TOKEN"]   # 你的 Trello 用户 Token

    # 创建空板,命名如 "Acme Corp Project"
    board = httpx.post(f"{TRELLO_API}/boards", params={
        "key": key, "token": token,
        "name": f"{client.company} Project",
        "defaultLists": "false",  # 不要默认的 To Do/Doing/Done 列,我们自己建
    }).json()

    board_id = board["id"]

    # 创建四列标准工作流
    lists = ["Brief & Requirements", "In Progress", "Review", "Done"]
    list_ids = {}
    for list_name in lists:
        result = httpx.post(f"{TRELLO_API}/lists", params={
            "key": key, "token": token,
            "name": list_name,
            "idBoard": board_id,
        }).json()
        list_ids[list_name] = result["id"]  # 记下每列的 ID,后面加卡片要用

    # 在「需求收集」列里加一张启动卡,含客户关键信息
    httpx.post(f"{TRELLO_API}/cards", params={
        "key": key, "token": token,
        "name": f"Kickoff: {client.company}",
        "desc": f"Client: {client.name}\nPackage: {client.package}\nEmail: {client.email}",
        "idList": list_ids["Brief & Requirements"],
    })

    return f"Board created: {board['shortUrl']}"

Step 6:生成 Stripe 发票草稿(不扣款!)

def create_stripe_invoice(client: Client) -> str:
    """在 Stripe 创建客户 + 发票项 + 待审核发票(安全,不自动收费)"""
    STRIPE_API = "https://api.stripe.com/v1"
    stripe_key = os.environ["STRIPE_SECRET_KEY"]  # 你的 Stripe 私钥
    headers = {"Authorization": f"Bearer {stripe_key}"}

    # 先创建或查找客户(根据邮箱去重)
    customer = httpx.post(
        f"{STRIPE_API}/customers",
        headers=headers,
        data={
            "name": client.name,
            "email": client.email,
            "metadata": {"company": client.company},  # 额外存公司名,方便后台筛选
        },
    ).json()

    package_info = PACKAGES[client.package]

    # 添加一笔发票项(服务费)
    httpx.post(
        f"{STRIPE_API}/invoiceitems",
        headers=headers,
        data={
            "customer": customer["id"],
            "amount": package_info["price"],     # 金额(单位:美分)
            "currency": "usd",
            "description": f"{client.package.title()} Package",  # 如 "Growth Package"
        },
    )

    # 创建草稿发票(状态为 draft,不会发给客户,也不会扣钱)
    invoice = httpx.post(
        f"{STRIPE_API}/invoices",
        headers=headers,
        data={
            "customer": customer["id"],
            "collection_method": "send_invoice",  # 后续人工确认再发
            "days_until_due": 14,                   # 账期14天
        },
    ).json()

    return f"Draft invoice {invoice['id']} created"

Step 7:自动记入 Notion 客户数据库

def log_to_notion(client: Client) -> str:
    """把客户基本信息写进 Notion 表格,支持后续搜索和统计"""
    NOTION_API = "https://api.notion.com/v1"
    notion_key = os.environ["NOTION_API_KEY"]      # Notion Integration Token
    database_id = os.environ["NOTION_CLIENTS_DB"]  # 你的客户数据库 ID(在 Notion 页面 URL 末尾)

    httpx.post(
        f"{NOTION_API}/pages",
        headers={
            "Authorization": f"Bearer {notion_key}",
            "Notion-Version": "2022-06-28",         # Notion API 版本号(固定)
            "Content-Type": "application/json",
        },
        json={
            "parent": {"database_id": database_id},  # 指定存入哪个数据库
            "properties": {
                "Name": {"title": [{"text": {"content": client.name}}]},           # 标题属性
                "Company": {"rich_text": [{"text": {"content": client.company}}]}, # 富文本
                "Package": {"select": {"name": client.package}},                    # 单选框
                "Email": {"email": client.email},                                  # 邮箱字段
                "Status": {"select": {"name": "New"}},                             # 默认状态为 New
            },
        },
    )

    return f"Logged {client.name} in Notion"

Step 8:发 Slack 提醒(你不会错过任何一个新客户)

def notify_slack(client: Client) -> str:
    """用 Slack Webhook 推送简洁美观的通知卡片"""
    webhook_url = os.environ["SLACK_WEBHOOK_URL"]  # 你在 Slack 创建的 Webhook 地址
    package_info = PACKAGES[client.package]
    price = package_info["price"] / 100  # 换算成美元(原单位是美分)

    httpx.post(webhook_url, json={
        "text": f"New client: {client.name} from {client.company}",  # 纯文本 fallback
        "blocks": [
            {
                "type": "section",
                "text": {
                    "type": "mrkdwn",
                    "text": (
                        f"*New Client Signed Up!*\n\n"
                        f"Name: {client.name}\n"
                        f"Company: {client.company}\n"
                        f"Package: {client.package.title()}\n"
                        f"Email: {client.email}\n"
                        f"Value: ${price:,.0f}"  # 格式化为 $1,500
                    ),
                },
            }
        ],
    })

    return "Slack notification sent"

Step 9:接收外部触发(Webhook 服务端)

from fastapi import FastAPI, Request

app = FastAPI()

@app.post("/webhook/new-client")
async def handle_new_client(request: Request):
    """这是你的「自动化入口」:任何系统(Stripe/Typeform/钉钉)都能 POST 数据进来"""
    payload = await request.json()  # 接收 JSON 数据

    # 把原始数据转成 Client 对象(自动填充默认值)
    client = Client(
        name=payload.get("name", ""),
        email=payload.get("email", ""),
        company=payload.get("company", ""),
        package=payload.get("package", "starter"),  # 默认 starter 套餐
        phone=payload.get("phone"),
        notes=payload.get("notes"),
    )

    # 启动全流程
    pipeline = Pipeline()
    success, results, errors = pipeline.run(client)

    return {
        "status": "success" if success else "partial",  # 全成 or 部分失败
        "client": client.name,
        "results": results,  # 每步返回内容
        "errors": errors,    # 哪些步骤挂了
    }

Step 10:本地测试(不用上线就能验证)

if __name__ == "__main__":
    # 模拟一个真实客户数据(复制粘贴就能跑)
    test_client = Client(
        name="Sarah Chen",
        email="sarah@example.com",
        company="Acme Corp",
        package="growth",
    )

    pipeline = Pipeline()
    success, results, errors = pipeline.run(test_client)

    print(f"\nPipeline {'succeeded' if success else 'had errors'}")
    print(f"Results: {json.dumps(results, indent=2)}")
    if errors:
        print(f"Errors: {errors}")

💡 提米哥划重点(新手必读)
先跑通两步:邮件 + Slack。这两步加起来省下 30 分钟,立刻见效。其余模块可以慢慢接。
所有 API 密钥都存在环境变量里os.environ[xxx]),千万别硬编码到代码里!部署前用 .env 文件管理。
发票只生成草稿(draft),Stripe 不会扣钱,你可以在后台检查无误后再手动发送。安全第一。
文件夹结构不是玄学:统一用 01_Brief 这种数字前缀,所有客户目录打开就是一样顺序,再也不用翻半天找需求文档。

⏱️ 效果实测:原来每客户耗时 45 分钟 → 现在 10 秒执行 + 2 分钟人工复核 = 单客户节省 42 分半
每月 5 个客户?你刚写完这 150 行代码,就已经回本了。

直达网址:https://vasquezventures.surge.sh

作加

类似文章