Sorry for the long post. I am trying to call a Lex bot with the PostText runtime API with my lambda function. However when I test this call then it returns that the userID is not authorized to use this. This is the error message I receive:
Response:
{
"errorMessage": "An error occurred (AccessDeniedException) when calling the PostText operation: User: arn:aws:sts::981709171824:assumed-role/lambda_basic_execution/OrchestratorAPIApp is not authorized to perform: lex:PostText on resource: arn:aws:lex:us-east-1:981709171824:bot:SupportBot_BookCab:SupportBot_BookCab",
"errorType": "ClientError",
"stackTrace": [
[
"/var/task/lambda_function.py",
18,
"lambda_handler",
"inputText= userInput"
],
[
"/var/runtime/botocore/client.py",
314,
"_api_call",
"return self._make_api_call(operation_name, kwargs)"
],
[
"/var/runtime/botocore/client.py",
612,
"_make_api_call",
"raise error_class(parsed_response, operation_name)"
]
]
}
Request ID:
"677f1820-6ed2-11e8-b891-33ab1951c65f"
Function Logs:
START RequestId: 677f1820-6ed2-11e8-b891-33ab1951c65f Version: $LATEST
An error occurred (AccessDeniedException) when calling the PostText operation: User: arn:aws:sts::981709171824:assumed-role/lambda_basic_execution/OrchestratorAPIApp is not authorized to perform: lex:PostText on resource: arn:aws:lex:us-east-1:981709171824:bot:SupportBot_BookCab:SupportBot_BookCab: ClientError
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 18, in lambda_handler
inputText= userInput
File "/var/runtime/botocore/client.py", line 314, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/var/runtime/botocore/client.py", line 612, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (AccessDeniedException) when calling the PostText operation: User: arn:aws:sts::981709171824:assumed-role/lambda_basic_execution/OrchestratorAPIApp is not authorized to perform: lex:PostText on resource: arn:aws:lex:us-east-1:981709171824:bot:SupportBot_BookCab:SupportBot_BookCab
END RequestId: 677f1820-6ed2-11e8-b891-33ab1951c65f
REPORT RequestId: 677f1820-6ed2-11e8-b891-33ab1951c65f Duration: 325.25 ms Billed Duration: 400 ms Memory Size: 128 MB Max Memory Used: 31 MB
This is my code to calling the API:
import boto3
def lambda_handler(event, context):
responderName = event["DestinationBot"]
userId = event["RecipientID"]
userInput = event["message"]["text"]
client = boto3.client('lex-runtime')
response = client.post_text(
botName=responderName,
botAlias=responderName,
userId=userId,
sessionAttributes={
},
requestAttributes={
},
inputText= userInput
)
This is my sample test input:
{
"DestinationBot": "SupportBot_BookCab",
"RecipientID": "12345",
"message": {
"text": "book me a cab"
}
}
The userID
of PostText
is the way you persist the conversation back and forth between the user and Lex. It can be anything that you can identify the user by in their incoming request that is consistent and unique to them, at least for that session.
From AWS PostText Docs:
userID
The ID of the client application user. Amazon Lex uses this to identify a user's conversation with your bot. At runtime, each request must contain the userID field.
...
Length Constraints: Minimum length of 2. Maximum length of 100.
Pattern: [0-9a-zA-Z._:-]+
So if a user is using Facebook messenger, they will have a Facebook ID that is passed with their messages and you can use that as their userID
.
If a user is using Twilio-SMS, they will have a phone number passed with their messages and you can use that as their userID
.
Your code is currently taking event["RecipientID"]
and using that as a userID
. But the RecipientID
from an incoming message is yourself, the receiver of the incoming message.
Your error is telling you that
... User: arn:aws:sts::XXXXXXXXXX:assumed-role/lambda_basic_execution/OrchestratorAPIApp
So the userID
= event["RecipientID"]
= 'arn:aws:sts::XXXXXXXX:assumed-role/lambda_basic_execution/OrchestratorAPIApp'
You definitely don't want the Recipient ID to be used.
Instead you want the sender's ID to be the userID
. Something like:
userId = event["SenderID"]
That might not be the exact code you use, its just an example. You should be able to view the incoming request, and locate something in there to use as a proper userID as I explained above with Facebook and Twilio.