如何为 CustomMessage_AdminCreateUser 触发器发送自定义消息?
How to send a custom message for CustomMessage_AdminCreateUser trigger?
为 CustomMessage_AdminCreateUser
触发器发送自定义电子邮件消息时,我成功更改了从 Amazon Cognito 收到的事件中的 emailSubject
属性,但似乎无法更改 emailMessage
属性。
从 Cognito 发送的电子邮件包含正确的自定义主题,但邮件根本没有自定义,它始终是 Cognito 池设置中设置的主题。
处理从 Cognito 接收到的事件的 lambda 处理程序成功地为这些触发器定制了消息:
CustomMessage_SignUp
CustomMessage_ResendCode
CustomMessage_ForgotPassword
但我似乎无法让它为 CustomMessage_AdminCreateUser
触发器工作(至少不完全)。
我尝试将 email_verified
用户属性设置为 true
以查看该属性是否取决于成功将自定义邮件发送给创建的用户。此外,我尝试 运行 Docker 容器中的 lambda 以查看返回到 Cognito 的最终事件的输出,但该事件包含正确的数据,电子邮件主题和电子邮件消息都是自定义的。
def lambda_handler(event, context):
if event['userPoolId'] == os.getenv('cognitoPoolId'):
if CustomMessageTriggerEnum.has_value(event.get('triggerSource')):
custom_message_trigger = CustomMessageTriggerEnum(event.get('triggerSource'))
if custom_message_trigger == CustomMessageTriggerEnum.CustomMessageAdminCreateUser:
custom_message_trigger = CustomMessageAdminCreateUser(event)
else:
return None
custom_response = custom_message_trigger.get_custom_response(
custom_message_trigger.ACTION,
custom_message_trigger.EMAIL_SUBJECT,
custom_message_trigger.EMAIL_MESSAGE
)
event = custom_message_trigger.set_custom_response(**custom_response)
return event
class CustomMessageAdminCreateUser(BaseCustomMessageTrigger):
""" Custom message admin create user trigger """
ACTION = "changepassword"
EMAIL_SUBJECT = "Welcome to {service}"
EMAIL_MESSAGE = "Your account has been created. <a href='{0}'>Click here</a> to set your password and start using {service}."
def __init__(self, event):
super().__init__(event)
class BaseCustomMessageTrigger():
""" Base custom message trigger """
def __init__(self, event):
self.event = event
def get_custom_response(self, action, email_subject, email_message):
""" Gets custom response params as dictionary """
request = self.event.get('request')
custom_response = {}
url = self.get_url(
action=action,
code=request.get('codeParameter'),
email=urlencode({'email': request['userAttributes'].get('email')})
)
custom_response['emailSubject'] = email_subject
custom_response['emailMessage'] = email_message.format(url)
return custom_response
def set_custom_response(self, **kwargs):
""" Updates the event response with provided kwargs """
response = self.event.get('response')
response.update(**kwargs)
return self.event
def get_url(self, action, code, email):
""" Used for constructing URLs. """
rawUrl = 'https://{0}/{1}?code={2}&{3}'
return rawUrl.format(domain, action, code, email)
CustomMessage_AdminCreateUser
触发器的一件重要事情是您必须在邮件 emailMessage
中包含 username
和 password
。
def get_url(self, action, code, email):
""" Used for constructing URLs. """
rawUrl = 'https://{0}/{1}?code={2}&{3}'
return rawUrl.format(domain, action, code, email)
请在 get_url
方法中传递 domain
。
您必须避免对响应参数进行 urlencode,因为 Lambda 将添加占位符,稍后将由 Cognito 替换。
我遇到了完全相同的问题。
我的初始自定义消息:
<html>
<body>
<p> Welcome. Follow the link below to unlock your account and set a new password.</p>
<a href="http://localhost:3000/setNewPasswordcode_parameter=${event.request.codeParameter}&user_name=${event.userName}">Set Password</a>
</body>
</html>
问题是您需要在模板中同时使用:event.request.codeParameter
和 event.request.usernameParameter
(所以在我的初始代码案例中不是 event.userName
)。
此外,codeParameter 和 usernameParameter 必须仅包含 URI 有效字符。因此,如果您的用户名是包含“@”符号的电子邮件地址,则不能在 link 中使用它。
解决方法: 对于临时密码,您可以通过传递一个 TemporaryPassword 参数来确保在调用 adminCreateUser() 时仅使用 URI 有效字符。
cognitoIdentityServiceProvider.adminCreateUser({
UserPoolId,
Username,
TemporaryPassword
}).promise()
对于 link 您可以使用 event.userName
- 这应该是 cognito 用户的子项。请确保在电子邮件中的其他地方包含 event.request.usernameParameter
。在我的例子中,我用 Welcome, ${event.request.usernameParameter}!
开始邮件
澄清一下,电子邮件应按字面意思包含 event.request.usernameParameter
和 event.request.codeParameter
中的值。
我发现 Cognito 忽略了我的电子邮件正文,因为即使 {####}
存在,令牌 {username}
也丢失了。
为 CustomMessage_AdminCreateUser
触发器发送自定义电子邮件消息时,我成功更改了从 Amazon Cognito 收到的事件中的 emailSubject
属性,但似乎无法更改 emailMessage
属性。
从 Cognito 发送的电子邮件包含正确的自定义主题,但邮件根本没有自定义,它始终是 Cognito 池设置中设置的主题。
处理从 Cognito 接收到的事件的 lambda 处理程序成功地为这些触发器定制了消息:
CustomMessage_SignUp
CustomMessage_ResendCode
CustomMessage_ForgotPassword
但我似乎无法让它为 CustomMessage_AdminCreateUser
触发器工作(至少不完全)。
我尝试将 email_verified
用户属性设置为 true
以查看该属性是否取决于成功将自定义邮件发送给创建的用户。此外,我尝试 运行 Docker 容器中的 lambda 以查看返回到 Cognito 的最终事件的输出,但该事件包含正确的数据,电子邮件主题和电子邮件消息都是自定义的。
def lambda_handler(event, context):
if event['userPoolId'] == os.getenv('cognitoPoolId'):
if CustomMessageTriggerEnum.has_value(event.get('triggerSource')):
custom_message_trigger = CustomMessageTriggerEnum(event.get('triggerSource'))
if custom_message_trigger == CustomMessageTriggerEnum.CustomMessageAdminCreateUser:
custom_message_trigger = CustomMessageAdminCreateUser(event)
else:
return None
custom_response = custom_message_trigger.get_custom_response(
custom_message_trigger.ACTION,
custom_message_trigger.EMAIL_SUBJECT,
custom_message_trigger.EMAIL_MESSAGE
)
event = custom_message_trigger.set_custom_response(**custom_response)
return event
class CustomMessageAdminCreateUser(BaseCustomMessageTrigger):
""" Custom message admin create user trigger """
ACTION = "changepassword"
EMAIL_SUBJECT = "Welcome to {service}"
EMAIL_MESSAGE = "Your account has been created. <a href='{0}'>Click here</a> to set your password and start using {service}."
def __init__(self, event):
super().__init__(event)
class BaseCustomMessageTrigger():
""" Base custom message trigger """
def __init__(self, event):
self.event = event
def get_custom_response(self, action, email_subject, email_message):
""" Gets custom response params as dictionary """
request = self.event.get('request')
custom_response = {}
url = self.get_url(
action=action,
code=request.get('codeParameter'),
email=urlencode({'email': request['userAttributes'].get('email')})
)
custom_response['emailSubject'] = email_subject
custom_response['emailMessage'] = email_message.format(url)
return custom_response
def set_custom_response(self, **kwargs):
""" Updates the event response with provided kwargs """
response = self.event.get('response')
response.update(**kwargs)
return self.event
def get_url(self, action, code, email):
""" Used for constructing URLs. """
rawUrl = 'https://{0}/{1}?code={2}&{3}'
return rawUrl.format(domain, action, code, email)
CustomMessage_AdminCreateUser
触发器的一件重要事情是您必须在邮件 emailMessage
中包含 username
和 password
。
def get_url(self, action, code, email):
""" Used for constructing URLs. """
rawUrl = 'https://{0}/{1}?code={2}&{3}'
return rawUrl.format(domain, action, code, email)
请在 get_url
方法中传递 domain
。
您必须避免对响应参数进行 urlencode,因为 Lambda 将添加占位符,稍后将由 Cognito 替换。
我遇到了完全相同的问题。
我的初始自定义消息:
<html>
<body>
<p> Welcome. Follow the link below to unlock your account and set a new password.</p>
<a href="http://localhost:3000/setNewPasswordcode_parameter=${event.request.codeParameter}&user_name=${event.userName}">Set Password</a>
</body>
</html>
问题是您需要在模板中同时使用:event.request.codeParameter
和 event.request.usernameParameter
(所以在我的初始代码案例中不是 event.userName
)。
此外,codeParameter 和 usernameParameter 必须仅包含 URI 有效字符。因此,如果您的用户名是包含“@”符号的电子邮件地址,则不能在 link 中使用它。
解决方法: 对于临时密码,您可以通过传递一个 TemporaryPassword 参数来确保在调用 adminCreateUser() 时仅使用 URI 有效字符。
cognitoIdentityServiceProvider.adminCreateUser({
UserPoolId,
Username,
TemporaryPassword
}).promise()
对于 link 您可以使用 event.userName
- 这应该是 cognito 用户的子项。请确保在电子邮件中的其他地方包含 event.request.usernameParameter
。在我的例子中,我用 Welcome, ${event.request.usernameParameter}!
澄清一下,电子邮件应按字面意思包含 event.request.usernameParameter
和 event.request.codeParameter
中的值。
我发现 Cognito 忽略了我的电子邮件正文,因为即使 {####}
存在,令牌 {username}
也丢失了。