Zoho CRM API:基于 Python 请求的 POST 或 GET 身份验证 + 插入联系人

问题描述 投票:0回答:2

任务##

允许用户注册的 Django 应用程序,一旦用户单击帐户激活链接,Zoho CRM 就会接收数据并在 CRM 部分创建联系人。

问题

我目前正在开发一个绝对的杰作 - ZOHO API。 我正在努力设置使用 POST/GET 请求的本机 Python 代码。 关于zcrmsdk 3.0.0,我已经完全放弃了这个解决方案,除非有人可以提供一个功能齐全的示例。支持人员只是责怪我的代码。

我查阅的文档: https://www.zoho.com/crm/developer/docs/api/v2/access-refresh.htmlhttps://www.zoho.com/crm/developer/docs/api/v2/insert-records.html

既然 postman API 中的 post 请求工作正常,我不明白为什么它在 python 代码中不起作用

我的方法

  1. 在以下位置生成自客户端 API 代码:https://api-console.zoho.com/
  2. 在 Postman 上插入该代码并检索访问或刷新令牌
  3. 在文档中定义的 add_user_contact 函数中使用此访问令牌 有用!响应即成功,位于 Zoho CRM 中

我使用的权限范围是:ZohoCRM.modules.contacts.ALL、ZohoCRM.users.ALL、ZohoCRM.modules.deals.ALL、ZohoCRM.modules.attachments.ALL、ZohoCRM.settings.ALL、AAAserver.profile.ALL

邮递员 POST REQUEST 的图片

我自己的代码

def authenticate_crm():

"""
access to response object id:
response_object.get('data')[0].get('details').get('id')
"""

url = 'https://accounts.zoho.com/oauth/v2/token'

headers = {
    'Content-Type': 'application/x-www-form-urlencoded'
}

# one time self-client token here -
request_body = {
    "code": "1000.aa8abec144835ab79b8f9141fa1fb170.8ab194e4e668b8452847c7080c2dd479",
    "redirect_uri": "http://example.com/yourcallback",
    "client_id": "1000.H95VDM1H9KCXIADGF05E0E1XSVZKFQ",
    "client_secret": "290e505ec52685fa62a640d874e6560f2fc8632e97",
   " grant_type": "authorization_code"
}

response = requests.post(url=url, headers=headers, data=json.dumps(request_body).encode('utf-8'))
if response is not None:
    print("HTTP Status Code : " + str(response.status_code))
    print(response.json())

我本质上正在努力将 Postman API 请求转换为 Python 请求,以获取令牌作为工作流程的一部分。我在这里做错了什么?

文档指出: 注意:出于安全原因,请将以下参数作为表单数据传递到请求正文中。 (访问刷新链接)但将其作为表单数据传递到邮递员中完全破坏了调用。

根据他们自己的文档(令人费解、矛盾且充满过时的屏幕截图),身份验证密钥仅需要一次。 上面的请求运行后,我将获取第三张图片中的响应并使用刷新键添加联系人。 如果有人可以提供帮助,我也愿意接受 SDK 3.0.0 的解决方案。

python django api crm zoho
2个回答
2
投票

我解决了!

我改变了这一行:

response = requests.post(url=url, headers=headers, data=json.dumps(request_body).encode('utf-8'))

为此添加了一些返回语句:

payload =     '1000.6d9411488dcac999f02304d1f7843ab2.e14190ee4bae175debf00d2f87143b19&'     \
          'redirect_uri=http%3A%2F%2Fexample.com%2Fyourcallback&' \
          'client_id=1000.H95VDM1H9KCXIADGF05E0E1XSVZKFQ&' \
         'client_secret=290e505ec52685fa62a640d874e6560f2fc8632e97&'\
          'grant_type=authorization_code'

response = requests.request(method="POST", url=url, headers=headers,     data=payload)
if response is not None:
    print("HTTP Status Code : " + str(response.status_code))
    # print(response.text)
    print(response.json())
    # catch access and refresh token
at = response.json().get('access_token')
rt = response.json().get('refresh_token')

return at, rt

我不明白为什么会有所不同,但修复了它,我可以从 ZOHO 检索密钥。


0
投票

使用这个答案给出了“无效代码”错误。我通过在有效负载的开头添加

code=
来修复它。所以,而不是:

payload = '1000.6d9411488dcac999f02304d1f7843ab2.e14190ee4bae175debf00d2f87143b19&' \
# ...

我用过

payload = 'code=1000.6d9411488dcac999f02304d1f7843ab2.e14190ee4bae175debf00d2f87143b19&' \
# ...

由于与 Zoho 集成非常痛苦,因此我将包含脚本的其余部分,其中还展示了如何获取初始授予令牌并刷新访问令牌。

我尝试清理现有答案中的方法,使其更易于维护,避免手动编码查询字符串,并为每个步骤提供更好的文档。希望从发布本文到您阅读本文时 API 不会发生太大变化...

"""
Zoho API access token generator

References:
- https://desk.zoho.com/support/APIDocument.do#OauthTokens
- https://stackoverflow.com/questions/67643027

"""

import requests
import urllib


# TODO set up your config
client_id = "1000.rn8abwxxxxxxxxxxxxxxxxxxxxxxxx"
client_secret = "c2b74fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
redirect_uri = "https://exact-url-from-config.com"
scope = "desk.articles.read"
state = "unused"
def get_auth_url() -> str:
    """Requests a grant token, the first step in the process.
    The response has a location header with a URL that can
    be used to login to Zoho by a user in a browser.

    This should look like:
    curl --dump-header - "https://accounts.zoho.com/oauth/v2/auth?response_type=code&client_id=1000.rn8wxxxxxxxxxxxxxxx&scope=desk.articles.read&redirect_uri=https://exact-url-from-config.com&state=-5466400890088961855&access_type=offline"
    """
    grant_url = "https://accounts.zoho.com/oauth/v2/auth"
    params = {
        "response_type": "code",
        "client_id": client_id,
        "scope": scope,
        "redirect_uri": redirect_uri,
        "access_type": "offline", # required for refresh token
        "state": state,
    }
    response = requests.get(grant_url, params=params, allow_redirects=False)
    response.raise_for_status()

    if "location" not in response.headers:
        raise ValueError("No location in response headers")

    return response.headers["location"]


def parse_grant_code(redirected_url: str) -> str:
    """Extracts the code= parameter from a URL"""
    query = urllib.parse.urlsplit(redirected_url).query
    grant_code = dict(urllib.parse.parse_qsl(query)).get("code")
    return grant_code


def get_tokens(grant_code: str) -> dict:
    """Given a grant_code (which expires in 1 minute),
    make a request to get the auth tokens.
    Be careful to not make more than 5 refresh tokens in a minute.
    """
    url = "https://accounts.zoho.com/oauth/v2/token"
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    data = {
        "code": grant_code,
        "client_id": client_id,
        "client_secret": client_secret,
        "grant_type": "authorization_code",
        "redirect_uri": redirect_uri,
    }
    response = requests.post(url=url, headers=headers, data=data)
    response.raise_for_status()
    return response.json()


def refresh_access(refresh_token: str) -> dict:
    """Uses the refresh token to acquire a new access token"""
    url = "https://accounts.zoho.com/oauth/v2/token"
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    data = {
        "refresh_token": refresh_token,
        "client_id": client_id,
        "client_secret": client_secret,
        "scope": scope,
        "redirect_uri": redirect_uri,
        "grant_type": "refresh_token",
    }
    response = requests.post(url=url, headers=headers, data=data)
    response.raise_for_status()
    return response.json()


def interactively_get_tokens():
    auth_url = get_auth_url()
    print("Go to the following link in a browser and sign in\n")
    print(auth_url)

    # After logging in, the user will be redirected to a URL
    # that has a code= query parameter known as a grant token.
    # We need this for the next request. It expires in 1 minute.

    # the redirected URL should look like:
    # https://your-redirect-url.com/?state=-5466400890088961855&code=1000.dd3d00f32a7190c8cc309370d96fa065.827a08c22d78a7df54c58e24800dc7de&location=us&accounts-server=https%3A%2F%2Faccounts.zoho.com&
    redirected_url = input(
        "\nthen paste the browser's redirected URL here and press Enter: "
    )
    grant_code = parse_grant_code(redirected_url)

    # Now that we have the grant_code, make another request
    # for the tokens. The access_token expires in 1 hour.
    # The refresh_token never expires.
    data = get_tokens(grant_code)
    print("Tokens response JSON:", data)
    print("Access token: ", data.get("access_token"))
    refresh_token = data.get("refresh_token")
    print("Refresh token:", refresh_token)

    # After an hour, the access token will expire, so
    # create a new one using the refresh token.
    # access_token = refresh_access(refresh_token)
    # print(access_token)


if __name__ == "__main__":
    interactively_get_tokens()
© www.soinside.com 2019 - 2024. All rights reserved.