### **引言**
视觉内容变得越来越重要,无论是营销材料、产品演示还是客户交流,引人入胜的图像和视觉效果可以提高内容的吸引力和影响力。然而,创建高质量的视觉内容通常需要专业的设计技能和昂贵的工具,这对于许多企业是一个挑战。
**在本文中,我们将介绍如何基于 [Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) 托管的 SDXL 基础模型构建一个 Slack 图像生成助手 App**。该 Slack App 允许 Slack 用户通过发送文本提示来请求生成图像,并将生成的图像直接发送到 Slack 频道。这不仅为团队提供了一种创建视觉内容的简单方式,而且还可以促进协作和讨论。
[Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) 是一项完全托管的基础模型服务,通过单个 API 提供来自 AI21 Labs、Anthropic、Cohere、Meta、Mistral AI、Stability AI 和亚马逊云科技等领先人工智能公司的高性能基础模型,以及通过安全性、隐私性和负责任的人工智能构建生成式人工智能应用程序所需的一系列广泛功能。**由于 [Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) 是[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)的,因此您无需管理任何基础设施**,并且可以使用已经熟悉的亚马逊云科技服务将生成式人工智能功能安全地集成和部署到您的应用程序中。
### **解决方法概述**
在这篇文章中,我们将介绍如何在 Amazon Lambda 中部署 Slack 网关服务,用于接收 Slack 消息并使用 [Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) 及其托管的 Stability AI SDXL 基础模型生成相应的图像。**我们利用了多个亚马逊云科技服务来构建一个健壮的解决方案:Amazon Secrets Manager 用于安全地存储密钥,[Amazon DynamoDB](https://aws.amazon.com/cn/dynamodb/?trk=cndc-detail) 用于防止重复消息处理,[Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) Bucket 和 [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 用于存储和分发生成的图像**。通过将所有这些服务与 Amazon Lambda 结合使用,我们可以构建一个[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)的、可扩展的应用程序,用于处理 Slack 消息并生成图像。
![image.png](https://dev-media.amazoncloud.cn/5a08d746969b47bf95140c0274b04b33_image.png "image.png")
### **先决条件**
* 可用的亚马逊云科技账户;
* [Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) Stable AI SDXL 基础模型服务已启用;
* 已创建私有的 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) Bucket 用于存储生成的图像;
* 通过 [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 分发私有 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) Bucket 中的图像,实现静态内容加速,同时也可以配置 [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 实现 [Amazon API Gateway](https://aws.amazon.com/cn/api-gateway/?trk=cndc-detail) 动态加速。
### **创建Slack App**
在 Slack 工作区中创建一个新的 Slack 应用程序,启用 “im:history”、“chat:write” 和 “commands” 作用域,具体步骤如下:
1.打开 https\://api.slack.com/apps/new?trk=cndc-detail 并选择 ”From a manifest”。
2.选择要将应用程序安装到的工作区。
3.将以下.yaml 格式的 Template 的内容复制到文本框中(在 YAML 选项卡内),然后单击“下一步”。
```
display_information:
name: SDXL
features:
app_home:
home_tab_enabled: true
messages_tab_enabled: false
messages_tab_read_only_enabled: false
bot_user:
display_name: SDXL
always_online: false
oauth_config:
scopes:
bot:
- im:read
- im:write
- chat:write
- app_mentions:read
- im:history
- incoming-webhook
settings:
event_subscriptions:
request_url: https://tobemodified.com
bot_events:
- app_home_opened
- app_mention
- message.im
org_deploy_enabled: false
socket_mode_enabled: false
token_rotation_enabled: false
```
![image.png](https://dev-media.amazoncloud.cn/df5ad6fc20c84d7d8df36a3dc0136710_image.png "image.png")
![image.png](https://dev-media.amazoncloud.cn/24c554fbdc75443cbfb91e63754e5d60_image.png "image.png")
4.查看配置,然后单击 “Create”。
完成 App 创建后,查看 Signing Secret,接下来会通过 Amazon CloudFormation 保存到 Amazon Secret Manager 中。
![image.png](https://dev-media.amazoncloud.cn/e8a30bc36a6849afb7c41db48276e2de_image.png "image.png")
5.选择左边栏 “OAuth & Permissions”,点击 “Install to Workspace”,然后点击 Allow。
![image.png](https://dev-media.amazoncloud.cn/2a27f200356046b1a266ed68ea98c872_image.png "image.png")
查看生成的 OAuth Token,接下来会通过 Amazon CloudFormation 保存到 Amazon Secret Manager 中。
![image.png](https://dev-media.amazoncloud.cn/ee1ac7ff36fd4a11969a05879ba6c13e_image.png "image.png")
### **创建亚马逊云科技云服务**
我们将使用 Amazon CloudFormation 来部署所需的亚马逊云科技云服务,包括 Amazon Lambda 函数、[Amazon API Gateway](https://aws.amazon.com/cn/api-gateway/?trk=cndc-detail)、Amazon Secrets Manager 和 [Amazon DynamoDB](https://aws.amazon.com/cn/dynamodb/?trk=cndc-detail)。**Amazon CloudFormation 模板将自动配置所有必需的资源,简化了部署过程。**
点击 “Launch Stack” 以创建 Amazon CloudFormation 堆栈。
依次填写用于保存 [Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) SDXL 产生的图片的私有 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) Bucket、用于分发图片的 Amazon CloudFronnt 分配、Slack App 签名密钥、Slack App OAuth Token,勾选 “acknowledge”,然后 Create stack。
![image.png](https://dev-media.amazoncloud.cn/739fcff86f5b4c58b8b6a8ebd8784271_image.png "image.png")
Stack 创建完成后,复制 SlackAPIGatewayEndpoint。
![image.png](https://dev-media.amazoncloud.cn/8e63f661e6bc40168516747ca7b760bb_image.png "image.png")
将 SlackAPIGatewayEndpoint 配置为事件订阅的请求 URL,替换模版中的默认值,如果显示 Verified 表示 Slack App 连接 Amazon Lambda 函数成功,点击 “Save Changes”。
![image.png](https://dev-media.amazoncloud.cn/9492b370fa0d426c98f28b7083942896_image.png "image.png")
### **Amazon Lambda 函数介绍**
**Amazon Lambda 函数将处理来自 Slack 的事件,调用 [Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) 生成图像,并将图像上传到 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 存储桶**。该函数首先验证 Slack 签名以确保请求来自 Slack。然后,它处理URL验证挑战或实际的 Slack 消息事件。对于消息事件,它会将客户端消息 ID 和时间戳写入 [Amazon DynamoDB](https://aws.amazon.com/cn/dynamodb/?trk=cndc-detail) 表,以防止重复处理。
```
import json
import boto3
# import ...
def handler(event, context):
event_body = json.loads(event.get("body"))
response = None
# Verify the Slack signature
if not verify_slack_signature(event['headers'], event['body']):
return {
'statusCode': 401,
'body': json.dumps({'error': 'Invalid Slack signature'})
}
if event_body.get("type") == "url_verification":
response = {
'statusCode': 200,
'body': event_body['challenge']
}
else:
client_msg_id = event_body['event']['client_msg_id']
try:
table.put_item(
Item={
'client_msg_id': client_msg_id,
'timestamp': int(time.time()) # Add a timestamp for replay attack prevention
},
ConditionExpression='attribute_not_exists(client_msg_id)'
)
response = handle_message(event_body)
except ClientError as e:
if e.response['Error']['Code'] != 'ConditionalCheckFailedException':
return {
'statusCode': 200,
'body': json.dumps('Event already processed')
}
return response
```
handle_message 函数提取实际的消息文本,调用 call_bedrock 函数生成图像,并将生成的图像 URL 发送回 Slack 频道。
```
def handle_message(slack_body):
slack_text = slack_body.get('event').get('text')
slack_user = slack_body.get('event').get('user')
channel = slack_body.get('event').get('channel')
pattern = r'<@\\w+>\\s*(.+)'
match = re.search(pattern, slack_text)
if match:
slack_text = match.group(1)
image_url = call_bedrock(slack_text)
data = {
'channel': channel,
'blocks': [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"<@{slack_user}> Generated Image:"
}
},
{
"type": "image",
"image_url": image_url,
"alt_text": "Generated Image"
}
]
}
headers = {'Authorization': f'Bearer {slack_token}', 'Content-Type': 'application/json'}
http.request('POST', slack_api_url, headers=headers, body=json.dumps(data))
return {'statusCode': 200, 'body': json.dumps({'msg': "message received"})}
```
call_bedrock 函数调用 [Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) 服务生成图像,并将生成的图像上传到 [Amazon S3](https://aws.amazon.com/cn/s3/?trk=cndc-detail) 存储桶,并返回 [Amazon CloudFront](https://aws.amazon.com/cn/cloudfront/?trk=cndc-detail) 分发的图像 URL。
```
response = client.invoke_model(modelId=model_id, body=request)
except Exception as e:
print(f"Error calling Bedrock AI model: {e}")
return "Sorry, I'm having trouble processing your request right now."
model_response = json.loads(response["body"].read())
base64_image_data = model_response["artifacts"][0]["base64"]
image_key = f"{S3_PREFIX}{str(uuid.uuid4())}.png"
s3_client.put_object(
Bucket=S3_BUCKET_NAME,
Key=image_key,
Body=base64.b64decode(base64_image_data),
ContentType="image/png"
)
image_url = f"https://{CLOUDFRONT_NAME}/{image_key}"
return image_url
```
### **验证 Slack App**
现在,您可以在 Slack 频道中发送消息,**Amazon Lambda 函数将调用 [Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) 生成相应的图像,并将图像发送回 Slack 频道**。通过 @SlackAppName+ 提示词的方式向 App 提问,第1次使用的时候,需要点击 “Invite Them”,手机 App 输出效果如下:
![image.png](https://dev-media.amazoncloud.cn/e322edfe6c21465c92790b720ff675c9_image.png "image.png")
选择 Invite Them 后,Slack App SDXL 根据提示词输出了图片:
![image.png](https://dev-media.amazoncloud.cn/983efe4828434f72990834b991e7ce9c_image.png "image.png")
### **总结**
通过 Amazon CloudFormation 部署了所需的云服务之后,您需要将 [Amazon API Gateway](https://aws.amazon.com/cn/api-gateway/?trk=cndc-detail) 端点配置为 Slack App 的事件订阅 URL。然后,**每当 Slack 用户在频道中发送文本提示时,Amazon Lambda 函数就会被触发,调用 [Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) 服务生成相应的图像,并将图像发送回 Slack 频道。**
通过 [Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) 以及 Amazon Lambda、[Amazon API Gateway](https://aws.amazon.com/cn/api-gateway/?trk=cndc-detail)、Amazon Secrets Manager 和 [Amazon DynamoDB](https://aws.amazon.com/cn/dynamodb/?trk=cndc-detail) 等服务的强大功能,您可以轻松构建一个功能强大的 、基于[无服务器](https://aws.amazon.com/cn/serverless/?trk=cndc-detail)架构的 Slack 图像生成助手 App。这不仅可以提高团队的工作效率,还可以激发创造力,促进更好的协作和沟通。
#### **参考资料**
> **1.Slack Quickstart: Send a mesage**
>
> https\://api.slack.com/quickstart?trk=cndc-detail
>
> **2.Verifying requests from Slack**
>
> https\://api.slack.com/authentication/verifying-requests-from-slack?trk=cndc-detail
>
> **3.Invoke Stable Diffusion XL on [Amazon Bedrock](https://aws.amazon.com/cn/bedrock/?trk=cndc-detail) to generate an image**
>
> https\://docs.aws.amazon.com/bedrock/latest/userguide/bedrock-runtime_example_bedrock-runtime_InvokeModel_StableDiffusion_section.html?trk=cndc-detail
![image.png](https://dev-media.amazoncloud.cn/bf8d28fc82f14dd6a5facbf617751662_image.png "image.png")
![image.png](https://dev-media.amazoncloud.cn/383c05371f494c058fa068876364bd05_image.png "image.png")
![image.png](https://dev-media.amazoncloud.cn/acd6eb17200d4574b4288e84fe643831_image.png "image.png")
![image.png](https://dev-media.amazoncloud.cn/e6311afc0283457d908ec744258b2772_image.png "image.png")