Google Действия Push-уведомление с Python? - PullRequest
0 голосов
/ 05 декабря 2018

Я пытаюсь выяснить, как инициировать push-уведомление с помощью DialogFlow / Google Actions.Я собрал некоторый тестовый код, но когда я тестирую его, я получаю ответ «403 Forbidden».Может кто-нибудь предоставить мне хороший пример того, как сделать это с помощью Python 3.

`

import urllib.request
import json

notification = {
    'userNotification': {
        'title': 'Test Notification',
    },
    'target': {
        'userId': 'user-id here',
        'intent': 'Notification Intent',
        'locale': 'en-US',
    }
}


my_url = 'https://actions.googleapis.com/v2/conversations:send'
access_token = 'access token here'

request = urllib.request.Request(my_url)
request.add_header('Content-Type', 'application/json; charset=utf-8')
payload = { 'auth': { 'bearer': access_token },
             'json': 'true',
             'body': { 'customPushMessage': notification, 'isInSandbox': 
             'true' } };

jsondata = json.dumps(payload)
jsondataasbytes = jsondata.encode('utf-8')
response = urllib.request.urlopen(request, jsondataasbytes)

`

Может кто-нибудь дать какие-либо предложения о том, как получить эторабота?

==================================================================

Обновление: я изменил заголовок auth, как предложено, и теперь я получаю '401: Unauthorized'.Я не уверен, правильно ли я создаю токен доступа.Вот как я это делаю:

Я создал закрытый ключ RSA256 на веб-сайте консоли Google.Я использую этот ключ для кодирования JWT, содержащего следующие поля:

{
    "iss": [
        "My Service Name",
        "\"my_service-account@service_name.iam.gserviceaccount.com\""
    ],
    "iat": 1544018697,
    "exp": 1544019898,
    "aud": 
"https://www.googleapis.com/auth/actions.fulfillment.conversation\"",
    "sub": [
        "Push Notification",
        "\"my-service-account@service_name.iam.gserviceaccount.com\""
    ]
}

Я не знаю, правильно ли это: документацию для всего этого сложно собрать.

ОБНОВЛЕНИЕ2:

Я изменил код, предложенный Prisoner, и теперь я могу получить то, что кажется действительным access_token.Это модифицированный код:

from oauth2client.client import GoogleCredentials

service_account_file = 'path-to-service_account_file'
credentials = GoogleCredentials.from_stream(SERVICE_ACCOUNT_FILE)

access_token = credentials.get_access_token().access_token

Когда я пытаюсь использовать токен доступа, я по-прежнему получаю ответ «401 Unauthorized».Кто-нибудь на самом деле сделал это?Если да, можете ли вы дать мне некоторые подробности о правильном URL-адресе и о том, как отформатировать сообщение urllib.request?

Ответы [ 2 ]

0 голосов
/ 10 декабря 2018

Хорошо, я выяснил, как получить access_token, так что часть проблемы решена.Я столкнулся с другой проблемой, связанной с получением разрешения на обновления для моей тестовой учетной записи, но я собираюсь опубликовать новый вопрос для этого.Я адаптировал код из другого ответа, и это, кажется, работает:

# Adapted from https://stackoverflow.com/questions/51821919/how-to-send-push-notification-from-google-assistant-through-dialogflow-fulfilmen/51961677#51961677

import io
import json

import requests
from google.oauth2 import service_account
import google.auth.transport.requests

def send_notification(path_to_service_account="default", intent="default"):
    if path_to_service_account == "default":
        PATH_TO_SERVICE_ACCOUNT = 'path to downloaded service account json file from Google Cloud Console'
    else:
        PATH_TO_SERVICE_ACCOUNT = path_to_service_account

    if intent == "default":
        INTENT = 'Notification Intent'
    else:
        INTENT = intent

    REQUIRED_SCOPE = 'https://www.googleapis.com/auth/actions.fulfillment.conversation'
    USER_ID = 'user id here'
    INTENT = 'Your intent name'

    # Get access token
    with io.open(PATH_TO_SERVICE_ACCOUNT, 'r', encoding='utf-8') as json_fi:
        credentials_info = json.load(json_fi)
    credentials = service_account.Credentials.from_service_account_info(
        credentials_info, scopes=[REQUIRED_SCOPE])
    request = google.auth.transport.requests.Request()
    credentials.refresh(request)

    headers = {
        'Authorization': 'Bearer ' + credentials.token
    }

    payload = {
        'customPushMessage': {
            'userNotification': {
                'title': 'App Title',
                'text': 'Simple Text'
            },
            'target': {
                'userId': USER_ID,
                'intent': INTENT,
                # Expects a IETF BCP-47 language code (i.e. en-US)
                'locale': 'en-US'
            }
        }
    }

    r = requests.request("POST", 'https://actions.googleapis.com/v2/conversations:send', data=json.dumps(payload), headers=headers)

    print(str(r.status_code) + ': ' + r.text)
0 голосов
/ 05 декабря 2018

Вы поместили некоторые вещи в тело запроса, которые принадлежат заголовку.В частности, « 403 запрещено » предполагает, что заголовок Authorization либо неправильный, либо отсутствует, и в вашем случае он выглядит так, как будто отсутствует, поскольку вы пытаетесь поместить его в тело.

Тело того, что вы отправляете, должно содержать JSON с атрибутом customPushMessage.

Я не очень знаком с Python, но я думаю, что-то вроде этого большеВы хотите:

request = urllib.request.Request(my_url)
request.add_header('Authorization', 'bearer '+access_token)
request.add_header('Content-Type', 'application/json; charset=utf-8')
payload = { 'customPushMessage': notification }

jsondata = json.dumps(payload)
jsondataasbytes = jsondata.encode('utf-8')
response = urllib.request.urlopen(request, jsondataasbytes)

Если вы продолжаете получать сообщение «403 Forbidden» - убедитесь, что ваш access_token является текущим и фактически является токеном доступа.Токены доступа создаются из ключа учетной записи службы, но не являются самим ключом.Они имеют ограниченный срок службы (обычно 1 час), в то время как ключ является продолжительным.

Обновление о создании токена доступа из ключей.

Вы можете 't просто создайте и подпишите JWT для использования в качестве токена доступа.

Самый простой способ - использовать Клиентскую библиотеку API Google для Python , которая включает в себя библиотеку для обработки OAuthс учетными записями служб .

Я не проверял, но вы должны быть в состоянии сделать что-то подобное, установив SERVICE_ACCOUNT_FILE в место хранения ключей.

from google.oauth2 import service_account

SCOPES = ['https://www.googleapis.com/auth/actions.fulfillment.conversation']
SERVICE_ACCOUNT_FILE = '/path/to/service.json'

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

access_token = credentials.get_access_token()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...