i’m having an issue with alexa smart_home.
when i follow (https://www.home-assistant.io/components/alexa.smart_home/)
I’m able to link alexa, however if i enable Alexa’s proactive mode by adding the client_id and client_secret and then unlink and attempt to re-link. The linking fails with unable to link at this time.
I have noticed the following in the log file, but i think this is because it not linked.
2019-06-25 23:10:55 DEBUG (MainThread) [homeassistant.components.alexa.state_report] Received (401): {"header":{"namespace":"System","name":"Exception","messageId":"HIDDEN"},"payload":{"code":"INVALID_ACCESS_TOKEN_EXCEPTION","description":"Access token is not valid."}}
2019-06-25 23:10:55 ERROR (MainThread) [homeassistant.components.alexa.state_report] Error when sending ChangeReport to Alexa: INVALID_ACCESS_TOKEN_EXCEPTION: Access token is not valid.
The same for me. Adding client_id and client_secret does not seem to be the problem. But activating the “Send Alexa Events” toggle in the Skill’s Permissions is the cause that linking is not possible anymore.
I tried the same yesterday and got the same error. I was thinking it was my mistake. However, disabling proactive doesn’t seems to help. I still not able to link my account.
I disabled my HAASKA skill and re-enabled it and the errors are gone. Not sure if people using Alexa with HA cloud get it or it is just HAASKA integration.
In addition, if you enable the Send Alexa Events permission for the skill, your Lambda function must handle the AcceptGrant directive. If your skill does not handle this directive, account linking fails when the user attempts to enable your skill. See Authenticate a Customer to Alexa with Permissions
The lambda function from @awarecan does not seem to handle this directive. See here
I don’t think this is the error, I made a change to the lambda according to the alexa dev docs and still get the error.
If you want to try (but is not working for everyone, just left as reference)
"""
Copyright 2019 Jason Hu <awaregit at gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import os
import json
import logging
import urllib3
_debug = bool(os.environ.get('DEBUG'))
_logger = logging.getLogger('HomeAssistant-SmartHome')
_logger.setLevel(logging.DEBUG if _debug else logging.INFO)
def lambda_handler(event, context):
"""Handle incoming Alexa directive."""
_logger.debug('Event: %s', event)
base_url = os.environ.get('BASE_URL')
assert base_url is not None, 'Please set BASE_URL environment variable'
directive = event.get('directive')
assert directive is not None, 'Malformatted request - missing directive'
assert directive.get('header', {}).get('payloadVersion') == '3', \
'Only support payloadVersion == 3'
grant = directive.get('header', {}).get('name')
if grant is 'AcceptGrant':
return {
'event': {
'header': {
'messageId': directive.get('header', {}).get('messageId'),
'namespace': 'Alexa.Authorization',
'name': 'AcceptGrant.Response',
'payloadVersion': '3'
},
'payload': {
}
}
}
scope = directive.get('endpoint', {}).get('scope')
if scope is None:
# token is in payload for Discovery directive
scope = directive.get('payload', {}).get('scope')
assert scope is not None, 'Malformatted request - missing endpoint.scope'
assert scope.get('type') == 'BearerToken', 'Only support BearerToken'
token = scope.get('token')
if token is None and _debug:
token = os.environ.get('LONG_LIVED_ACCESS_TOKEN') # only for debug purpose
verify_ssl = not bool(os.environ.get('NOT_VERIFY_SSL'))
http = urllib3.PoolManager(
cert_reqs='CERT_REQUIRED' if verify_ssl else 'CERT_NONE',
timeout=urllib3.Timeout(connect=2.0, read=10.0)
)
response = http.request(
'POST',
'{}/api/alexa/smart_home'.format(base_url),
headers={
'Authorization': 'Bearer {}'.format(token),
'Content-Type': 'application/json',
},
body=json.dumps(event).encode('utf-8'),
)
if response.status >= 400:
return {
'event': {
'payload': {
'type': 'INVALID_AUTHORIZATION_CREDENTIAL'
if response.status in (401, 403) else 'INTERNAL_ERROR',
'message': response.data.decode("utf-8"),
}
}
}
return json.loads(response.data.decode('utf-8'))
I’m using cloud and I get this error but I only seem to get it when I tell alexa to set a colour light to white. When I do that, the light goes white but then alexa says “I don’t know what went wrong” and reports this in the logs. All other colours trigger a success chime from alexa, but still logs invalid access token in the logs. If I do it in the app, most colours work fine, the white ones say “server was unresponsive”. Very odd
Hi!
For all having problems linking: For me, this lambda seems to be working ok (from here). Environment variables HOST and BEARER_TOKEN (long lived acces token) must be set. Handler is called lambda_function.event_handler
Can anyone confirm? Than maybe we can improve it to use the HA authentication instead of the long lived token.