2024-05-29 11:51:04 -04:00

105 lines
3.2 KiB
JavaScript

import _ from 'lodash'
import resolveLambdaTarget from '../../../utils/resolve-lambda-target.js'
class AwsCompileAlexaSkillEvents {
constructor(serverless) {
this.serverless = serverless
this.provider = this.serverless.getProvider('aws')
this.serverless.configSchemaHandler.defineFunctionEvent(
'aws',
'alexaSkill',
{
anyOf: [
{ $ref: '#/definitions/awsAlexaEventToken' },
{
type: 'object',
properties: {
appId: { $ref: '#/definitions/awsAlexaEventToken' },
enabled: { type: 'boolean' },
},
required: ['appId'],
additionalProperties: false,
},
],
},
)
this.hooks = {
initialize: () => {
if (
this.serverless.service.provider.name === 'aws' &&
Object.values(this.serverless.service.functions).some(({ events }) =>
events.some((event) => event === 'alexaSkill'),
)
) {
this.serverless._logDeprecation(
'ALEXA_SKILL_EVENT_WITHOUT_APP_ID',
'Starting with next major version, support for alexaSkill event without appId specified will be removed.',
)
}
},
'package:compileEvents': async () => this.compileAlexaSkillEvents(),
}
}
compileAlexaSkillEvents() {
this.serverless.service.getAllFunctions().forEach((functionName) => {
const functionObj = this.serverless.service.getFunction(functionName)
let alexaSkillNumberInFunction = 0
functionObj.events.forEach((event) => {
if (event.alexaSkill) {
let enabled = true
let appId
if (typeof event.alexaSkill === 'string') {
appId = event.alexaSkill
} else {
appId = event.alexaSkill.appId
// Parameter `enabled` is optional, hence the explicit non-equal check for false.
enabled = event.alexaSkill.enabled !== false
}
alexaSkillNumberInFunction++
const permissionTemplate = {
Type: 'AWS::Lambda::Permission',
DependsOn: _.get(functionObj.targetAlias, 'logicalId'),
Properties: {
FunctionName: resolveLambdaTarget(functionName, functionObj),
Action: enabled
? 'lambda:InvokeFunction'
: 'lambda:DisableInvokeFunction',
Principal: 'alexa-appkit.amazon.com',
},
}
if (appId) {
permissionTemplate.Properties.EventSourceToken = appId.replace(
/\\n|\\r/g,
'',
)
}
const lambdaPermissionLogicalId =
this.provider.naming.getLambdaAlexaSkillPermissionLogicalId(
functionName,
alexaSkillNumberInFunction,
)
const permissionCloudForamtionResource = {
[lambdaPermissionLogicalId]: permissionTemplate,
}
_.merge(
this.serverless.service.provider.compiledCloudFormationTemplate
.Resources,
permissionCloudForamtionResource,
)
}
})
})
}
}
export default AwsCompileAlexaSkillEvents