问题
I am trying to make a request to the Proactive Events API by using the requests module of Python.
However I always receive a response that the scope is invalid. Can anyone help? What am I doing wrong? My code looks like this:
@ask.launch
def launch():
content_type = "application/x-www-form-urlencoded;charset=utf-8"
client_id = "amzn1.application-oa2-client.6a48XXXXXXX408"
client_secret = "592XXXXxxxxxxx6"
scope = "alexa::proactive_events"
grant_type = "client_credentials"
data = {"grant_type": grant_type, "client_id": client_id, "client_secret": client_secret, "scope": scope}
r = requests.post("https://api.amazon.com/auth/O2/token", data=data, headers={"content-type": content_type})
speech = render_template("welcome")
reprompt = render_template("welcome_reprompt")
return question(speech).reprompt(reprompt)
That is the response I get:
{'error_description': 'The request has an invalid parameter : scope', 'error': 'invalid_scope'}
回答1:
Since one of the reason you get the invalid scope is that you dont have the events included in your skill manifest I include some steps here. I found quite cumbersome to use the SMAPI to update the skill manifest so instead I used ask cli.
- install ask-cli: get authorization code for your amazon acount. In my case the backend is not an AWS lambda function but an external web server
- get the skill manifest in json format:
ask api get-skill -s "amzn1.ask.skill.ZZZYYYZZ" --stage development > skill.json
Add the notifications permission and the events elements to the manifest:
{ "name": "alexa::devices:all:notifications:write" }
and
"events": { "publications": [ { "eventName": "AMAZON.AAABBBCC" } ], "endpoint": { "uri": "https://XXXYYYZZ:443/whatevercontext" } }
update the manifest:
ask api update-skill -s "amzn1.ask.skill.ZZZYYYZZ" --stage development -f skill.json
- enable the notifications in the alexa app for your specific skill
Now you should be able to get the token and next step is to send the notification to the device
回答2:
Have you tried making the API call via any other method? I just tried that with Postman and it worked for me.
My Python's a bit rusty, but here's the self generated code from Postman for Python. May be this should help?
import http.client
conn = http.client.HTTPConnection("api,amazon,com")
payload = "grant_type=client_credentials&client_id=amzn1.application-oa2-client.whatever-value&client_secret=client-secret&scope=alexa%3A%3Aproactive_events&undefined="
headers = {
'Content-Type': "application/x-www-form-urlencoded"
}
conn.request("POST", "auth,O2,token", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
回答3:
As Karthik asked previously have you tried the call via postman? I first suggest trying to via postman before you trying to code it.
If the issue still persists its most likely because you haven't included the necessary permissions required for Proactive Events in your Skill Manifest. To add the necessary permissions to Skill Manifest you need to use the Skill Management API & ASK Cli. Follow this section of the documentation and visit the links referenced there to correctly add the required permissions to your skill - https://developer.amazon.com/docs/smapi/proactive-events-api.html#onboard-smapi
Once you have successfully added the events and publications with a skill schema you should be able to successfully generate a token. Please feel to ask if you want me to elaborate more on the exact steps. Cheers!
回答4:
This is what I have tried and it worked:
amazon_token_url = "https://api.amazon.com/auth/O2/token"
headers = {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
body = "grant_type=client_credentials&client_id=amzn1.application-oa2-client.XXXYYYZZ&client_secret=ZZZYYYXXX&scope=alexa::proactive_events"
log.debug("Sending token request with body: %s", body)
resp = requests.post(amazon_token_url, data=body, headers=headers)
resp_json = json.loads(resp.content.decode('utf-8'))
if (resp.status_code < 299) and (resp.status_code > 199):
log.debug("token received from Amazon")
log.debug("Content : %s", resp.content)
token = resp_json["access_token"]
return token
来源:https://stackoverflow.com/questions/53795375/amazon-alexa-proactive-events-request-in-python-flask-ask