admin管理员组文章数量:1287593
AWS-hosted Alexa skills offer 3 lambda functions, one S3 bucket and one DynamoDB database; but give you very little control over the databases and ultimately they are constrained in size.
I want to extend the S3 storage offered by Amazon for my Alexa Skill to additionally use my personal AWS S3 storage. Using this weblink I have managed to add my personal DynamoDB additionally to the single database offered by AWS hosting and it seems to work. I now have one DynamoDB database for users and the second for content. This involved setting up a Role in my personal AWS account, with a trust relationship to the ARN for my AWS-hosted lambda function, which allows it to assume the role with permissions to DynamoDB and S3. (I set both up at the same time and DynamoDB works.)
The problem I am encountering is with S3 pre-signed URLs, which I can’t make work. Pre-signed URLs use a required util file:
const AWS = require('aws-sdk');
const s3SigV4Client = new AWS.S3({
signatureVersion: 'v4',
region: process.env.S3_PERSISTENCE_REGION
});
module.exports.getS3PreSignedUrl = function getS3PreSignedUrl(s3ObjectKey) {
const bucketName = process.env.S3_PERSISTENCE_BUCKET;
const s3PreSignedUrl = s3SigV4Client.getSignedUrl('getObject', {
Bucket: bucketName,
Key: s3ObjectKey,
Expires: 60*1 // the Expires is capped for 1 minute
});
console.log(`Util.s3PreSignedUrl: ${s3ObjectKey} URL ${s3PreSignedUrl}`);
return s3PreSignedUrl;
}
As a minimum I need to change the bucket name (highlighted) from the S3_PERSISTENCE_BUCKET to the name of my new bucket in my personal account.; but I want to do this conditionally so that the bulk of my code can call the AWS-hosted S3 bucket, but occasionally I want to be access the additional content in the personally-hosted S3 bucket. As you can see from the code below, I’ve had a few attempts.
async handle(handlerInput) {
const intentName = Alexa.getIntentName(handlerInput.requestEnvelope);
// 1. Assume the AWS resource role using STS AssumeRole Action
const STS = new AWS.STS({ apiVersion: '2011-06-15' });
const credentials = await STS.assumeRole({
RoleArn: 'arn:aws:iam::{{MY ROLE}}',
RoleSessionName: 'AlexaHostedLambdaRole'
}, (err, res) => {
if (err) {
console.log('AssumeRole FAILED: ', err);
throw new Error('Error while assuming role');
}
return res;
}).promise();
// 2. Make a new DynamoDB instance with the assumed role credentials
// and scan the DynamoDB table
const dynamoDB = new AWS.DynamoDB({
apiVersion: '2012-08-10',
accessKeyId: credentials.Credentials.AccessKeyId,
secretAccessKey: credentials.Credentials.SecretAccessKey,
sessionToken: credentials.Credentials.SessionToken
});
var params = {
TableName: "AlexaHostedTable",
Key: {
memory_id: { S: "00002" },
}
};
const tableData = await dynamoDB.getItem(params, function (err, data) {
if (err) {
console.log('getItem FAILED', err);
throw new Error('Error while getting Item from DynamoDB');
} else {
return data;}
}).promise();
// 3. Make a new S3 instance with the assumed role credentials
const s3Two = new AWS.S3({
apiVersion: '2012-08-10',
accessKeyId: credentials.Credentials.AccessKeyId,
secretAccessKey: credentials.Credentials.SecretAccessKey,
sessionToken: credentials.Credentials.SessionToken
});
// ... Use table data as required ...
var audioUrl = Util.getS3PreSignedUrl({{..PREFIX..}}tableData.Item.file.S +".mp3").replace(/&/g,'&'); //Marker
// const Util2 = require('./util2.js'); // pre-signs URLs from personal S3 bucket
var audioUrl2 = Util.getS3PreSignedUrl(tableData.Item.file.S +".mp3").replace(/&/g,'&'); //Marker
speakOutput ='Introductory text blah blah blah'+`<audio src="${audioUrl}"/>`+`<audio src="${audioUrl2}"/>`+'Suffix text blah blah blah'; // Marker
console.log ("speakOutput: ", speakOutput);
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt('add a reprompt if you want to keep the session open for the user to respond')
.getResponse();
}
};
I have tried:
- Replicating the util.js function, so that there are two versions for Alexa-hosted and personally-hosted bucket names
- Calling the personally-hosted bucket name outside of the util.js function
- Converting the util.js into a function so that it can accept parameters such as the bucket name
With the current version of the code, the references to the old bucket will work. Alexa appears to created pre-signed URLs to the bucket, but I think this is a red herring as they don't work.
本文标签:
版权声明:本文标题:amazon s3 - How do you use Personal AWS S3 Resources with an Alexa-Hosted Skill, as well as Alexa-hosted S3 resources? - Stack O 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741261716a2367744.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论