如何使用Twilio、Notion和Python构建客户付款提醒系统

529 阅读9分钟

经营一个企业需要处理付款。无论你是一个自由职业者还是一个大公司,有时客户会忘记支付他们的欠款。如果你有一个庞大的客户名单,每天翻阅记录并向他们发送催款通知是一种乏味的经历。为了解决这个问题,你可以将整个催款工作流程自动化。

在本教程中,你将学习使用 Twilio的WhatsApp APINotion API和Python,定期向你的客户发送付款提醒信息。你将使用Notion来存储数据,Twilio来发送WhatsApp信息,Python来实现业务逻辑。我们将创建三个提醒,分别在付款到期前7天、前3天、前1天和后1天发送。

前提条件

要学习本教程,你需要以下项目。

这个数据库的全部代码可以在这个 GitHub仓库中找到。

创建一个Notion数据库

你需要做的第一件事是创建一个Notion数据库。

要做到这一点,打开你的Notion账户,点击添加页面,在数据库下选择

Create Notion database

一旦表被创建,选择数据源为新数据库,并给你的数据库起一个名字,如 "客户"。

Name Notion database

Notion的每个数据库表都有一组字段,你可以在其中存储你的数据。在 "名称"字段后添加以下三个字段到你的表中。

  1. Pending Amount (Number)- 用于指定客户要支付的金额。

Add Pending Amount field

  1. Due Date (Date)- 用于指定付款的截止日期。

Add Due date field

  1. Phone No. (电话)- 客户的电话号码。

Add Phone Number field

创建完数据库后,你需要在其中添加一些测试客户。就本教程而言,你可以添加你的家庭成员的详细资料,并添加你可以访问的电话号码。确保按照Twilio推荐的E.164格式添加电话号码,否则你在发送信息时可能会出现一些错误。

Clients Table in Notion

你的Notion数据库现在已经设置好了。接下来,你需要在你的Python应用程序中使用Notion API查询Notion中的数据。

获取Notion API令牌

要使用Notion API,你需要创建一个Notion集成并获得一个API访问令牌。

要做到这一点,请访问 www.notion.so/my-integrat…,并创建一个新的集成。给它取个名字 "*Payment Reminder",*如果你想的话,还可以上传一个标志。

Create Notion integration

接下来,把它的内容能力设置为只读内容评论能力设置为用户能力设置无用户信息,然后点击提交

Setting Notion Integration Permissions

一旦集成被创建,你将看到一个秘密的API令牌。复制并妥善保管它,因为你以后在编写Python应用程序时将会用到它。

Notion Integration token

默认情况下,集成不能访问Notion的页面或数据库。所以,你需要与你的集成分享你想用Notion API查询的特定页面或数据库。

要做到这一点,在Notion中打开你的数据库。点击分享按钮,使用选择器按名称找到你的集成,然后点击邀请

Sharing integration with Notion database

这样,你就可以在你的Python应用程序中使用Notion API访问你的Notion数据库了。

设置Python项目

首先,打开你的终端,导航到你选择的路径,创建一个名为 "payment-reminders "的项目目录,并通过在终端运行以下命令建立一个虚拟环境。

mkdir payment-reminders && cd payment-reminders
python3 -m venv venv
source venv/bin/activate

对于这个项目,你需要安装以下PIP依赖项。

  • twilio- Twilio的Python SDK客户端,用于Twilio API。
  • requests- 用来进行HTTP请求。
  • python-dotenv- 用于从.env 文件中读取环境变量。

接下来,通过在终端运行以下命令来安装上述列出的PIP依赖项。

pip install twilio requests python-dotenv

连接到Notion API并检查服务状态

现在是写一些代码的时候了。首先,你要连接到Notion API并在你的数据库中获取条目。一旦你有了这些条目,你就可以通过发送GET请求来循环检查它们的状态。

要做到这一点,首先在项目的根目录下创建一个src 目录。在src 目录中,创建一个main.py 文件,并在其中添加以下代码。

import os
from datetime import datetime

import requests
from dotenv import load_dotenv

load_dotenv()

TWILIO_ACCOUNT_SID = os.getenv('TWILIO_ACCOUNT_SID')
TWILIO_AUTH_TOKEN = os.getenv('TWILIO_AUTH_TOKEN')
NOTION_API_BASE_URL = 'https://api.notion.com/v1'
NOTION_API_TOKEN = os.getenv('NOTION_API_TOKEN')
NOTION_DATABASE_ID = os.getenv('NOTION_DATABASE_ID')

# 1
def get_client_details() -> list:
    """
    This function calls the Notion API to get a list of clients that we need to monitor.
    """

    headers: dict = {
        'Authorization': f'Bearer {NOTION_API_TOKEN}',
        'Content-Type': 'application/json',
        'Notion-Version': '2021-08-16',
    }

    # uses <https://developers.notion.com/reference/post-database-query>
    response: Response = requests.post(
        f'{NOTION_API_BASE_URL}/databases/{NOTION_DATABASE_ID}/query', headers=headers)

    if response.status_code == 200:
        json_response: dict = response.json()['results']
    else:
        print("Something went wrong")
        return

    # 2
    clients: list = []
    for item in json_response:
        client: dict = {
            'id': item['id'],
            'name': item['properties']['Name']['title'][0]['plain_text'],
            'pending_amount': item['properties']['Pending Amount']['number'],
            'due_date': item['properties']['Due Date']['date']['start'],
            'phone_number': item['properties']['Phone No.']['phone_number'],
        }
        clients.append(client)

    return clients

# 3
def is_due(due_date: str) -> bool:
    """
    This function checks if the date is due or not.
    """

    today = datetime.today()
    delta = datetime.strptime(due_date, "%Y-%m-%d") - today
    return delta.days == 7 or delta.days == 3 or delta.days == 1 or delta.days < 0

# 4
def main():
    clients: list = get_client_details()
    for client in clients:
        if is_due(client['due_date']):
            print(client)
            send_reminder(client)

if __name__ == '__main__':
    main()

在上述代码中。

  1. get_client_details 函数中,你连接到Notion API并查询你的Notion数据库,以获得存储在其中的数据。对api.notion.com/v1/database…

Notion API response

  1. 由于响应相当大,而且你不需要所有的数据,你通过创建一个新的客户端列表来减少响应,该列表的结构如下。
{              
    'id': item['id'],
    'name': item['properties']['Name']['title'][0]['plain_text'],
    'pending_amount': item['properties']['Pending Amount']['number'],
    'due_date': item['properties']['Due Date']['date']['start'],
    'phone_number': item['properties']['Phone No.']['phone_number'],
}
  1. is_due 函数中,你检查due_date 是否到期。因为在本教程中,目标是在七天前、三天前、到期日前一天以及到期日后的每一天发送提醒,所以这个函数检查的内容相同。
  2. 在主函数中,你调用get_client_details 函数,对于有到期日的客户,你调用send_reminder function ,你将在下一节中编写这个函数。

接下来,在项目的根目录下创建一个.env 文件,并向其添加以下两个环境变量。

NOTION_API_TOKEN=<YOUR-INTERNAL-INTEGRATION-TOKEN>
NOTION_DATABASE_ID=<YOUR-DATABASE-ID>

为了得到你的数据库ID,查看Notion页面的URL结构-- www.notion.so/{workspace_…。URL中与{database_id}相对应的部分是你的数据库的ID。它是一个36个字符的长字符串。

如果你的Notion数据库不在一个工作区里,或者它根本不符合上面显示的URL,它可能看起来像这样:www.notion.so/{database_i…

发送WhatsApp通知

发送提醒信息是本教程的主要目的。对于发送提醒,你可以使用 Twilio WhatsApp API来执行这项任务。

要做到这一点,首先,登录到你的Twilio账户,并访问 Twilio控制台。在控制台中,注意账户信息部分,并获得账户SIDAuth Token

Twilio Account Credentials

接下来,激活你的Twilio沙盒来发送和接收WhatsApp信息。

接下来,将账户SIDAuth Token作为环境变量添加到你的*.env*文件中。

TWILIO_ACCOUNT_SID=<YOUR-ACCOUNT-SID>
TWILIO_AUTH_TOKEN=<YOUR-AUTH-TOKEN>

接下来,更新main.py ,在文件的顶部添加twilio 库,并在main 函数之前添加send_reminder 函数。

from twilio.rest import Client

TWILIO_ACCOUNT_SID = os.getenv('TWILIO_ACCOUNT_SID')
TWILIO_AUTH_TOKEN = os.getenv('TWILIO_AUTH_TOKEN')

# 1
def send_reminder(client: dict):
    """
    This function sends a WhatsApp notification using the Twilio WhatsApp Business API.
    """

    twilio_client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN)

    # This is the Twilio Sandbox number. Don't change it.
    from_whatsapp_number = 'whatsapp:+14155238886',
    to_whatsapp_number = f"whatsapp:{client['phone_number']}"
    body: str = f"Hi {client['name']}. Your payment of USD{client['pending_amount']} is due since {client['due_date']}."

    try:
        twilio_client.messages.create(body=body,
                                      from_=from_whatsapp_number,
                                      to=to_whatsapp_number)
    except:
        print('There was an error sending the message')

在上面的代码中,你定义了send_reminder 函数,它以client 为输入。它使用Twilio Python SDK(客户端)从Twilio Sandbox的电话号码发送一条WhatsApp信息到客户端的电话号码to_whatsapp_number 。消息的主体包含客户的姓名、待付金额和到期日期。

最后,通过在终端运行以下命令来执行Python应用程序。

python src/main.py

如果你的Notion数据库中有任何空行或字段,应用程序可能会抛出一个索引错误。否则,如果有任何客户有到期日期,那么应用程序将发送一些WhatsApp通知。

WhatsApp message by Twilio

自动发送提醒

最后一步是将定期运行Python代码的过程自动化,以不断检查新的到期日期。有很多方法可以使脚本执行自动化,例如--在Heroku上托管你的脚本并使用Heroku Scheduler,在自我托管的机器上使用Crontab,或者使用Github Actions。在本教程中,你将使用Github Actions。

要做到这一点,首先,在你的项目的根目录下创建一个目录路径.github/workflows 。在.github/workflows ,添加一个main.yml 文件,并在其中添加以下代码。

name: Monitoring

on:
  schedule:
    - cron: "0 0 * * *"
  workflow_dispatch:

jobs:
  monitor:
    runs-on: ubuntu-latest
    env:
      NOTION_API_TOKEN: ${{ secrets.NOTION_API_TOKEN }}
      NOTION_DATABASE_ID: ${{ secrets.NOTION_DATABASE_ID }}
      TWILIO_ACCOUNT_SID: ${{ secrets.TWILIO_ACCOUNT_SID }}
      TWILIO_AUTH_TOKEN: ${{ secrets.TWILIO_AUTH_TOKEN }}
    steps:
      - name: Setup Repository
        uses: actions/checkout@v2
        with:
          ref: main

      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: 3.x

      - name: Install PIP Dependencies
        run: |-
          python -m pip install --upgrade pip
          pip install -r requirements.txt

      - name: Send Reminders
        run: |-
          python src/main.py

上面的Github动作被安排在每天00:00 UTC运行,由行cron: "0 0 * * *" 指定。根据你的要求,你可以改变代码的运行频率。通过工作流调度,你可以随时手动运行该动作。

编写CRON表达式的一个好工具是crontab.guru/。

接下来,通过在终端运行以下命令,创建一个requirements.txt 文件,列出你的Python应用程序使用的所有依赖项。

pip freeze > requirements.txt

接下来,创建一个 新的Github资源库。转到设置>秘密>行动。

GitHub Repository secrets

接下来,添加以下秘密和它们各自的值作为仓库的秘密。

Github Secrets used by Actions

接下来,通过在终端运行以下命令,在你的本地项目中初始化一个Git仓库。

git init

接下来,在项目的根目录下创建一个.gitignore 文件,并在其中添加以下文件和目录,以防止它们被推送到上游仓库。

venv
.env

最后,通过在终端运行以下命令,提交并推送更改到你的上游仓库。

git add .
git commit -m "initial commit"
git push origin main

测试

为了验证你到目前为止的所有工作,请访问行动选项卡并手动运行工作流。

Github Workflow

等待工作流程完成,并检查WhatsApp上是否有任何通知。

WhatsApp message sent from GitHub Actions workflow

就这样,你已经成功地实现了对客户的付款提醒。

结语

祝贺您!在本教程中,您学会了如何向您的客户发出付款提醒。在本教程中,你学会了使用Twilio、Notion和Python来发送付款提醒信息。你用Notion来存储客户的数据,Python用于逻辑,Twilio用于WhatsApp通知,GitHub Actions用于自动化。

如果这个项目对你有帮助,请告诉我,或者通过电子邮件与我联系,向我问好!这个资源库的全部代码可在这个 GitHub资源库中找到。

Ravgeet是一个在印度的远程全职全栈开发者和技术内容作家。他从事React、Vue、Flutter、Strapi、Python和自动化方面的工作和写作。可以通过电子邮件 ravgeetdhillon[at]gmail.com联系他。 LinkedIn**, 和 Github**.