我正在使用AWS Textract,并且我想分析多页文档,因此我必须使用异步选项,因此我首先使用了startDocumentAnalysis
函数,并获得了JobId作为返回值,但是它需要触发我设置为在SNS主题收到消息时触发的功能。
这些是我的无服务器文件和处理程序文件。
provider:
name: aws
runtime: nodejs8.10
stage: dev
region: us-east-1
iamRoleStatements:
- Effect: "Allow"
Action:
- "s3:*"
Resource: { "Fn::Join": ["", ["arn:aws:s3:::${self:custom.secrets.IMAGE_BUCKET_NAME}", "/*" ] ] }
- Effect: "Allow"
Action:
- "sts:AssumeRole"
- "SNS:Publish"
- "lambda:InvokeFunction"
- "textract:DetectDocumentText"
- "textract:AnalyzeDocument"
- "textract:StartDocumentAnalysis"
- "textract:GetDocumentAnalysis"
Resource: "*"
custom:
secrets: ${file(secrets.${opt:stage, self:provider.stage}.yml)}
functions:
routes:
handler: src/functions/routes/handler.run
events:
- s3:
bucket: ${self:custom.secrets.IMAGE_BUCKET_NAME}
event: s3:ObjectCreated:*
textract:
handler: src/functions/routes/handler.detectTextAnalysis
events:
- sns: "TextractTopic"
resources:
Resources:
TextractTopic:
Type: AWS::SNS::Topic
Properties:
DisplayName: "Start Textract API Response"
TopicName: TextractResponseTopic
Handler.js
module.exports.run = async (event) => {
const uploadedBucket = event.Records[0].s3.bucket.name;
const uploadedObjetct = event.Records[0].s3.object.key;
var params = {
DocumentLocation: {
S3Object: {
Bucket: uploadedBucket,
Name: uploadedObjetct
}
},
FeatureTypes: [
"TABLES",
"FORMS"
],
NotificationChannel: {
RoleArn: 'arn:aws:iam::<accont-id>:role/qvalia-ocr-solution-dev-us-east-1-lambdaRole',
SNSTopicArn: 'arn:aws:sns:us-east-1:<accont-id>:TextractTopic'
}
};
let textractOutput = await new Promise((resolve, reject) => {
textract.startDocumentAnalysis(params, function(err, data) {
if (err) reject(err);
else resolve(data);
});
});
}
我手动向该主题发布了一条sns消息,然后它触发了当前具有此功能的textract lambda,
module.exports.detectTextAnalysis = async (event) => {
console.log('SNS Topic isssss Generated');
console.log(event.Records[0].Sns.Message);
};
我有什么错误?为什么textract startDocumentAnalysis没有发布消息并使其触发lambda?
注意:在使用startTextAnalysis函数之前,我没有使用过startDocumentTextDetection,尽管没有必要在此之前调用它。
答案 0 :(得分:1)
确保您在所使用角色的“信任关系”中:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com",
"textract.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}
答案 1 :(得分:0)
如果您的存储桶已加密,则应授予kms权限,否则将无法正常工作
答案 2 :(得分:0)
通过将Lambda执行资源添加到我的serverless.yml
文件中,我可以直接通过Serverless Framework进行此工作:
resources:
Resources:
IamRoleLambdaExecution:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- textract.amazonaws.com
Action: sts:AssumeRole
然后在启动Textract文档分析时,我只使用了Serverless生成的角色(用于lambda函数)作为通知通道角色参数:
感谢this post指出正确的方向!
答案 3 :(得分:0)
对于在TypeScript中使用CDK的任何人,您都需要像往常一样将Lambda作为ServicePrincipal添加到Lambda执行角色。接下来,访问执行角色的assumeRolePolicy
并调用addStatements
方法。
基本执行角色,无需任何其他声明(稍后添加)
this.executionRole = new iam.Role(this, 'ExecutionRole', {
assumedBy: new ServicePrincipal('lambda.amazonaws.com'),
});
下一步,将Textract添加为其他ServicePrincipal
this.executionRole.assumeRolePolicy?.addStatements(
new PolicyStatement({
principals: [
new ServicePrincipal('textract.amazonaws.com'),
],
actions: ['sts:AssumeRole']
})
);
此外,请确保执行角色对目标SNS主题具有完全权限(请注意,该主题已创建并可以通过fromTopicArn方法访问)
const stmtSNSOps = new PolicyStatement({
effect: iam.Effect.ALLOW,
actions: [
"SNS:*"
],
resources: [
this.textractJobStatusTopic.topicArn
]
});
将策略声明添加到全局策略(在活动堆栈中)
this.standardPolicy = new iam.Policy(this, 'Policy', {
statements: [
...
stmtSNSOps,
...
]
});
最后,将策略附加到执行角色
this.executionRole.attachInlinePolicy(this.standardPolicy);
答案 4 :(得分:0)
SNS 主题名称必须是 AmazonTextract
最后你的 arn 应该是这样的:
arn:aws:sns:us-east-2:111111111111:AmazonTextract