如何使用Intion API和Python在概念中跟踪Gumroad的销售
#教程 #python #api #notion

介绍

在本教程中,您将学习如何跟踪Gumroad 1 实时销售intion 2 ðpython。

您也会学习,

  • 什么是API?
  • 如何使用Gumroad API?
  • 如何使用概念API?
  • 如何运行python脚本等等等等

什么是API?

API代表应用程序编程接口。

让这个术语分解,

应用程序是任何网站或应用程序,例如Twitter,Facebook,Instagram,Reddit等。

编程接口是与这些应用程序交谈的一种方式

apis是使您的代码从(或)立即读取信息的信息的方式。

为什么要使用API​​?


API是自动化任务的好方法。

例如,如果要将帖子发布到社交媒体上,则可以使用诸如hootsuite 3 (或)buffer 47的调度程序。

如果您有安排在下午6:00的社交媒体帖子,则计划软件将使用其API将您的帖子写入社交媒体应用程序。

因此,API是一种非常快速有效地做事的方法。

与API交谈的一种方法是使用编程语言

A mermaid markdown diagram to represent how APIs are called

让我们以示例理解这一点。

使用现实世界类比了解API

想象一个邮政输送系统。

API(应用程序编程接口)在邮政输送系统类比中的请求接收器的信箱充当

发送者(编程语言)可以将字母(数据)发送到请求接收者的信件框(应用API端点)。

API端点接收到数据后,该应用程序可以处理该应用

ð记住:

就像邮政系统具有规则和约束一样,API系统具有定义的协议,标准和端点集,这些协议,标准和端点可以确定如何在发件人和接收方之间传输数据。

发件人(编程语言)需要符合这些规则,以确保API正确接收和处理数据。

在本教程中,您将学习两个applications,并通过他们各自的API与他们交谈:

  1. 概念
  2. Gumroad

在您的教程末尾,您将学习使用python的概念API和Gumroad API。

ð什么是python?

Python是一种免费的强大编程语言,该语言数百万软件开发人员用于构建应用程序和网站。它也非常容易使用。

开始使用Gumroad API


我们将使用Gumroad API阅读您的商店产品。此数据将用于使用概念API自动更新您的概念仪表板。

要阅读您的商店信息,Gumroad需要知道您要求它的人。为了帮助Gumroad理解这一点,我们将通过只有您和Gumroad知道的API请求来传递一个共享的秘密令牌。

任务:获取Gumroad API秘密令牌


如果您已经意识到,可以通过创建设置的应用程序来生成API秘密令牌应用程序来自Gumroad的仪表板。

A screenshot of Gumroad Dashboard where an application instance can be created

步骤:

  1. 提供一个申请名称(您适应的任何名称)
  2. 重定向UI-我们真的不需要这个,因此您可以设置值http://localhost
  3. 上传您想要的任何图标(可选)
  4. 单击Create application按钮
  5. 完成此操作后,在下一步中单击一个称为Generate access token的按钮。将生成访问令牌(您的API秘密密钥)。复制文本并安全地放在一边。

ð请勿与任何人共享您的秘密密钥。

您现在已经成功获得了Gumroad API秘密键。

现在,您可以请求阅读所有Gumroad商店产品以及此秘密钥匙,以便Gumroad可以验证并验证您确实在打电话。

任务:使用Python和您的Gumroad秘密代币要求您的Gumroad商店数据


Gumroad具有API文档,该文档让开发人员知道他们可以要求读取或写入信息的所有API端点(链接)。

- 如果您想更深入地进入Gumroad API的世界,则可以从本文档开始 - https://app.gumroad.com/api

为了本教程,我们需要阅读您的商店产品详细信息所需的API端点如下:

https://api.gumroad.com/v2/products

向此API端点(URL)和您的秘密令牌提出READ请求将以JSON格式返回您所有的Gumroad商店产品。

ð什么是JSON格式?

JSON不是为您提供商店产品及其信息的不可读段落,而是传递数据的结构化方法。

一个简单的JSON对象具有您需要知道的两件事,键和价值。他们经常称为钥匙值对。

例如,如果您想通过问答并回答某人,则可以将其作为JSON对象。

{
    "Which planet do we live in?": "Earth",
}

在这里,关键是问题,值是答案。

通常可以通过编程语言和大软件沿复杂的JSON对象来阅读的JSON,可以通过引擎盖下的编程语言非常快地读取和处理。


回到Gumroad API,https://api.gumroad.com/v2/products返回产品列表作为JSON符号。

让我们了解这里的全流量,

  1. 您将gumroad的请求发送到此API端点(https://api.gumroad.com/v2/products)以及一个秘密令牌

    这就是我们在python中做到的:

    import requests
    
    url = "https://api.gumroad.com/v2/products"
    
    payload='access_token=ACCESS_TOKEN'
    
    response = requests.request("GET", url, headers=headers, data=payload)
    
    print(response.text)
    
  2. Gumroad将验证请求并以JSON格式返回您的产品列表。

    {
      "success": true,
      "products": [{
        "custom_permalink": null,
        "custom_receipt": null,
        "custom_summary": "You'll get one PSD file.",
        "custom_fields": [],
        "customizable_price": null,
        "description": "I made this for fun.",
        "deleted": false,
        "max_purchase_count": null,
        "name": "Pencil Icon PSD",
        "preview_url": null,
        "require_shipping": false,
        "subscription_duration": null,
        "published": true,
        "url": "http://sahillavingia.com/pencil.psd",
        "id": "A-m3CDDC5dlrSdKZp0RFhA==",
        "price": 100,
        "purchasing_power_parity_prices": {
          "US": 100,
          "IN": 50,
          "EC": 25
        },
        "currency": "usd",
        "short_url": "https://sahil.gumroad.com/l/pencil",
        "thumbnail_url": "https://public-files.gumroad.com/variants/72iaezqqthnj1350mdc618namqki/f2f9c6fc18a80b8bafa38f3562360c0e42507f1c0052dcb708593f7efa3bdab8",
        "tags": ["pencil", "icon"],
        "formatted_price": "$1",
        "file_info": {},
        "shown_on_profile": true,
        "sales_count": "0", # available with the 'view_sales' scope
        "sales_usd_cents": "0", # available with the 'view_sales' scope
        "is_tiered_membership": true,
        "recurrences": ["monthly"], # if is_tiered_membership is true, renders list of available subscription durations; otherwise null
        "variants": [
          {
            "title": "Tier",
            "options": [
              {
                "name": "First Tier",
                "price_difference": 0, # set for non-membership product options
                "is_pay_what_you_want": false,
                "recurrence_prices": { # present for membership products; otherwise null
                  "monthly": {
                    "price_cents": 300,
                    "suggested_price_cents": null # may return number if is_pay_what_you_want is true
                  }
                }
              }
            ]
          }
        ]
      }, {...}, {...}]
    }
    

    ðâjson对象通常很复杂,对于人类来说更难理解,但是编程语言和计算机更喜欢它,而不是文本的段落而不是快速处理。

    现在,您了解Gumroad API的工作原理,我们现在将学习如何将商店数据上传到概念。

    我们可以使用上述概念API来做到这一点。

    概念API入门


    Intion API提供了使用代码读取和写入数据的功能。

    就像Gumroad API一样,Notionapi需要您通过秘密令牌以及API请求来验证它确实是您要求API端点的您。

    任务:产生概念集成以及notionapi的秘密钥匙


    要生成概念API秘密密钥,请执行以下步骤:

    1. Go to https://www.notion.so/my-integrations/
    2. 单击+ New Integration按钮
    3. 给它一个名字
    4. 上传徽标(可选)
    5. 如果您有多个帐户,请选择您的概念帐户
    6. 单击Submit
    7. 您将为您提供一个秘密钥匙。复制此秘密键并将其放在一边以供以后使用。

    ð请勿与任何人共享您的秘密密钥。

    任务:构建您的概念数据库


    获取概念模板

    I’ve already built the Notion Template. You can grab it here带折扣优惠券:gumnotion可获得50%的折扣。

    如果您要为自己构建一个,则可以参考架构设计的给定Python代码。

    任务:将您的概念数据库与概念集成联系起来


    要将重复的概念数据库与概念集成联系起来,请执行以下步骤:

    1. 单击数据库页面右上角的三个点
    2. 单击Add Connection选项,搜索并选择您创建的概念集成

    ð确保概念集成与任何其他数据库(或)页面没有连接以防止不必要的问题。

    任务:提出书面请求将数据存储到您的概念工作空间中


    一旦复制了包含数据库的概念模板。您现在可以考虑向概念提出API请求,以将您的产品详细信息写入其中。

    如果您有兴趣深入研究概念API,则可以从这里开始 - https://developers.notion.com/reference/intro

    我们将使用将数据写入概念的核心API端点是

    https://api.notion.com/v1/pages/
    

    让我们了解这里的全流量,

    1. 您向koude15 API端点提出写作请求

      import requests
      import json
      
      url = "https://api.notion.com/v1/pages/"
      
      payload = json.dumps({
        "cover": {
          "type": "external",
          "external": {
            "url": ""
          }
        },
        "parent": {
          "database_id": "<DATABASE-ID>"
        },
        "properties": {
          "Sales Count": {
            "type": "number",
            "number": 0
          },
          "Revenue": {
            "type": "number",
            "number": 0
          },
          "id": {
            "type": "rich_text",
            "rich_text": [
              {
                "type": "text",
                "text": {
                  "content": "<product-id>",
                  "link": None
                },
                "annotations": {
                  "bold": False,
                  "italic": False,
                  "strikethrough": False,
                  "underline": False,
                  "code": False,
                  "color": "default"
                },
                "plain_text": "<product-id>",
                "href": None
              }
            ]
          },
          "Link": {
            "type": "url",
            "url": "<product-url>"
          },
          "Price": {
            "type": "number",
            "number": 1000
          },
          "Name": {
            "id": "title",
            "type": "title",
            "title": [
              {
                "type": "text",
                "text": {
                  "content": "<Your-Gumroad-Product-Name>",
                  "link": None
                },
                "annotations": {
                  "bold": False,
                  "italic": False,
                  "strikethrough": False,
                  "underline": False,
                  "code": False,
                  "color": "default"
                },
                "plain_text": "<Your-Gumroad-Product-Name>",
                "href": None
              }
            ]
          }
        }
      })
      headers = {
        'Content-Type': 'application/json',
        'Notion-Version': '2022-02-22',
        'Authorization': 'Bearer <secret-token>',
      }
      
      response = requests.request("POST", url, headers=headers, data=payload)
      
      print(response.text)
      
    2. 概念验证并写入您的概念数据库中的产品,并将其作为JSON对象返回了成功的响应。例如:

      {
        "object": "page",
        "id": "59833787-2cf9-4fdf-8782-e53db20768a5",
        "created_time": "2022-03-01T19:05:00.000Z",
        "last_edited_time": "2022-07-06T19:16:00.000Z",
        "created_by": {
          "object": "user",
          "id": "ee5f0f84-409a-440f-983a-a5315961c6e4"
        },
        "last_edited_by": {
          "object": "user",
          "id": "ee5f0f84-409a-440f-983a-a5315961c6e4"
        },
        "cover": {
          "type": "external",
          "external": {
            "url": "https://upload.wikimedia.org/wikipedia/commons/6/62/Tuscankale.jpg"
          }
        },
        "icon": {
          "type": "emoji",
          "emoji": "🥬"
        },
        "parent": {
          "type": "database_id",
          "database_id": "d9824bdc-8445-4327-be8b-5b47500af6ce"
        },
        "archived": false,
        "properties": {
          "Store availability": {
            "id": "%3AUPp"
          },
          "Food group": {
            "id": "A%40Hk"
          },
          "Price": {
            "id": "BJXS"
          },
          "Responsible Person": {
            "id": "Iowm"
          },
          "Last ordered": {
            "id": "Jsfb"
          },
          "Cost of next trip": {
            "id": "WOd%3B"
          },
          "Recipes": {
            "id": "YfIu"
          },
          "Description": {
            "id": "_Tc_"
          },
          "In stock": {
            "id": "%60%5Bq%3F"
          },
          "Number of meals": {
            "id": "zag~"
          },
          "Photo": {
            "id": "%7DF_L"
          },
          "Name": {
            "id": "title"
          }
        },
        "url": "https://www.notion.so/Tuscan-Kale-test"
      }
      

ð请求和响应看起来有点令人生畏,因为概念是一个复杂的数据存储。如果一切都正确,则您不必亲自处理这些回复。

连接概念和gumroad Apis


现在,您对如何使用API​​有所了解,让我们尝试将请求和响应结合起来,以确切地完成我们需要的事情。

A sequence diagram of how we plan to talk to gumroad and notion using APIs

以下是我写的python脚本,您可以运行以将其从gumroad提取的产品信息保存到您的概念数据库。

import json
import time
import requests
import traceback
import sys
import os

class MyIntegration:

    def __init__(self):
        """
        Gets required variable data from config yaml file.
        """
        self.my_variables_map = {
            "MY_NOTION_SECRET_TOKEN": os.getenv("MY_NOTION_SECRET_TOKEN"),
            "MY_GUMROAD_SECRET_TOKEN": os.getenv("MY_GUMROAD_SECRET_TOKEN"),
            "NOTION_ENTRIES": {},
        }
        self.fallback_cover_image_url = (
            "https://assets-global.website-files.com/6171b265e5c8aa59b42c3472/6195275a9e5f4655891de886_gum-coins.svg"  # noqa: E501
        )
        self.get_page_and_database_data()

    def get_page_and_database_data(self):
        url = "https://api.notion.com/v1/search"
        headers = {
            "Content-Type": "application/json",
            'Notion-Version': '2022-02-22',
            'Authorization':
                'Bearer ' + self.my_variables_map["MY_NOTION_SECRET_TOKEN"]
        }
        payload = json.dumps({
            "query": 'Store',
            "filter": {
                "value": "database",
                "property": "object"
            }
        })
        response = requests.request("POST", url, headers=headers, data=payload)
        self.my_variables_map["DATABASE_ID"] = \
            response.json()["results"][0]["id"]
        # Database Entries
        url = f"https://api.notion.com/v1/databases/"\
              f"{self.my_variables_map['DATABASE_ID']}/query"
        response = requests.request("POST", url, headers=headers)
        resp = response.json()
        for v in resp["results"]:
            self.my_variables_map["NOTION_ENTRIES"].update({
                v["properties"]["id"]["rich_text"][0]["plain_text"]: {
                    "Sales Count": v["properties"]["Sales Count"]["number"],
                    "Price": v["properties"]["Price"]["number"],
                    "Revenue": v["properties"]["Revenue"]["number"],
                    "Link": v["properties"]["Link"]["url"],
                    "Name": v["properties"]["Name"]["title"][0]["plain_text"],
                    "id": v["properties"]["id"]["rich_text"][0]["plain_text"],
                    "cover": v["cover"]["external"]["url"],
                    "page_id": v['id']
                }
            })

    def get_gumroad_products(self):
        url = "https://api.gumroad.com/v2/products/"
        headers = {
            'Authorization': 'Bearer ' +
            self.my_variables_map["MY_GUMROAD_SECRET_TOKEN"],
        }
        response = requests.request("GET", url, headers=headers)
        for i in response.json()["products"]:
            self.update_notion_entries(i)

    def update_notion_entries(self, data):
        or_data_page_id = self.my_variables_map["NOTION_ENTRIES"].get(
            data['id'], {}
        ).get('page_id', None)
        self.my_variables_map["NOTION_ENTRIES"].update({
            data["id"]: {
                "Name": data["name"],
                "Price": float(data["price"]) / 100,
                "Sales Count": data["sales_count"],
                "Revenue": float(data["sales_usd_cents"]) / 100,
                "Link": data["short_url"],
                "id": data["id"],
                "cover": data.get(
                    "preview_url", self.fallback_cover_image_url
                ) or self.fallback_cover_image_url,
                "page_id": or_data_page_id
            }
        })

    def update_notion_database(self, database_id, data):
        if data.get("page_id"):
            url = "https://api.notion.com/v1/pages/" + str(data.get("page_id"))
            method = "PATCH"
        else:
            url = "https://api.notion.com/v1/pages/"
            method = "POST"
        headers = {
            'Authorization':
                'Bearer ' + self.my_variables_map["MY_NOTION_SECRET_TOKEN"],
            'Notion-Version': '2022-02-22',
            'Content-Type': 'application/json'
        }
        payload = json.dumps({
            "cover": {
                "type": "external",
                "external": {
                    "url": data["cover"]
                }
            },
            "parent": {
                "database_id": database_id
            },
            "properties": {
                "Sales Count": {
                        "type": "number",
                        "number": float(data["Sales Count"])
                },
                "Revenue": {
                    "type": "number",
                    "number": float(data["Revenue"])
                },
                "id": {
                    "type": "rich_text",
                    "rich_text": [
                        {
                            "type": "text",
                            "text": {
                                "content": data["id"],
                                "link": None
                            },
                            "annotations": {
                                "bold": False,
                                "italic": False,
                                "strikethrough": False,
                                "underline": False,
                                "code": False,
                                "color": "default"
                            },
                            "plain_text": data["id"],
                            "href": None
                        }
                    ]
                },
                "Link": {
                    "type": "url",
                    "url": data["Link"]
                },
                "Price": {
                    "type": "number",
                    "number": float(data["Price"])
                },
                "Name": {
                    "id": "title",
                    "type": "title",
                    "title": [
                        {
                            "type": "text",
                            "text": {
                                "content": data["Name"],
                                "link": None
                            },
                            "annotations": {
                                "bold": False,
                                "italic": False,
                                "strikethrough": False,
                                "underline": False,
                                "code": False,
                                "color": "default"
                            },
                            "plain_text": data["Name"],
                            "href": None
                        }
                    ]
                }
            }
        })
        response = requests.request(method, url, headers=headers, data=payload)
        return response.json()["id"]

    def update_indefinitely(self):
        while True:
            try:
                self.get_gumroad_products()
                for _, data in self.my_variables_map["NOTION_ENTRIES"].items():
                    data["page_id"] = self.update_notion_database(
                        data=data,
                        database_id=self.my_variables_map["DATABASE_ID"]
                    )
                    time.sleep(5)
                time.sleep(10)
            except Exception:
                traceback.print_exception(*sys.exc_info())
                # Drop memory and rebuild from existing notion server state
                self.my_variables_map["NOTION_ENTRIES"] = {}
                self.get_page_and_database_data()

if __name__ == "__main__":
    # With 😴 sleeps to prevent rate limit from kicking in.
    MyIntegration().update_indefinitely()

现在,我将向您展示如何在Replit上运行此代码,这是一种流行的基于云的代码托管和执行环境。

在Replit上运行Python脚本:


  1. Replit和登录中创建一个免费帐户,
  2. 叉我的替补:https://replit.com/@tnvmadhav/Notion-Gumroad-Sync

ð´分叉意味着制作他人公共存储库的副本

  1. 分叉进入您的工作空间后,与Python脚本共享Gumroad和Intion API Secret Keys
    1. 单击左侧栏中的Secrets
    2. 添加以下变量及其各自的令牌
      1. my_notion_secret_token
      2. my_gumroad_secret_token

A screenshot of how to save API keys inside Replit secret keys form

  1. 从浏览器运行脚本!

A screenshot of the Run button on Replit

就是这样!

如果一切顺利,您应该看到Gumroad产品信息每30秒自动更新一次。

ð如果您想跟上实时销售和收入更新,则可以保持Python脚本运行

感谢您的阅读。

如果您喜欢本指南,您也可能喜欢我使用Python API在Tracking Habits in Notion上写的类似指南。

1 in1311114

参考


  1. biaoqian36â

  2. Notion -- Your wiki, docs, & projects. Together

  3. HootSuite -- Save time and get REAL results on social media 

  4. Buffer -- Grow your audience on social and beyond