【问题标题】:AWS Serverless Function: Can't access methods of aws-sdk objects..."is not a function"AWS 无服务器函数:无法访问 aws-sdk 对象的方法...“不是函数”
【发布时间】:2021-03-24 14:59:42
【问题描述】:

我在 CloudFormation 模板中有一个无服务器函数,用于实例化 AWS Connect 实例。但是,我无法访问 aws-sdk 对象上的任何方法,抛出的错误是“connect.createInstance 不是函数”。当我在对象上调用 getOwnPropertyNames 时,它返回以下内容,而不是我尝试访问的方法: [ '配置', 'isGlobalEndpoint', '端点', '_events', 'MONITOR_EVENTS_BUBBLE', 'CALL_EVENTS_BUBBLE', '_originalConfig', '_clientId' ]

作为测试,我实例化了一个 S3 对象并在其上调用 getOwnPropertyNames 返回完全相同的内容。我究竟做错了什么?我在这里遵循规范形式:

https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/Connect.html#createInstance-property

AWSTemplateFormatVersion: "2010-09-09"
Transform: "AWS::Serverless-2016-10-31"
Parameters:
  IdentityManagementType:
    Description: The type of identity management for your Amazon Connect users.
    Type: String
    AllowedValues: ["SAML", "CONNECT_MANAGED", "EXISTING_DIRECTORY"]
    Default: "SAML"
  InboundCallsEnabled:
    Description: Whether your contact center handles incoming contacts.
    Type: String
    AllowedValues: [true, false]
    Default: true
  InstanceAlias:
    Description: The name for your instance.
    Type: String
    MaxLength: 62
  OutboundCallsEnabled:
    Description: Whether your contact center allows outbound calls.
    Type: String
    AllowedValues: [true, false]
    Default: true
  DirectoryId:
    Description: Optional. The identifier for the directory, if using this type of Identity Management.
    Type: String
  ClientToken:
    Description: Optional. The idempotency token. Used for concurrent deployments
    Type: String
    MaxLength: 500
  Region:
    Description: Region to place the AWS Connect Instance
    Type: String
    Default: us-east-1

#Handler for optional values
Conditions:
  HasClientToken: !Not
    - !Equals
      - ""
      - !Ref ClientToken
  HasDirectoryId: !Not
    - !Equals
      - ""
      - !Ref DirectoryId

Resources:
  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - sts:AssumeRole
      Path: "/"
      Policies:
        - PolicyName: AWSConnect
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - connect:*
                Resource: arn:aws:connect:*:*
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

  CreateConnectInstance:
    Type: AWS::Serverless::Function
    Properties:
      Handler: index.handler
      Runtime: nodejs12.x
      Description: Invoke a function to create an AWS Connect instance
      MemorySize: 128
      Timeout: 8
      Role: !GetAtt LambdaExecutionRole.Arn
      Tracing: Active
      Environment:
        Variables:
          IdentityManagementType:
            Ref: IdentityManagementType
          InboundCallsEnabled:
            Ref: InboundCallsEnabled
          InstanceAlias:
            Ref: InstanceAlias
          OutboundCallsEnabled:
            Ref: OutboundCallsEnabled
          Region:
            Ref: Region
          #Optional Values
          ClientToken: !If
            - HasClientToken
            - !Ref ClientToken
            - !Ref "AWS::NoValue"
          DirectoryId: !If
            - HasClientToken
            - !Ref ClientToken
            - !Ref "AWS::NoValue"
      InlineCode: |
        var AWS = require('aws-sdk');
        var params = {
          IdentityManagementType: process.env.IdentityManagementType,
          InboundCallsEnabled: process.env.InboundCallsEnabled,
          OutboundCallsEnabled: process.env.OutboundCallsEnabled,
          ClientToken: process.env.ClientToken,
          DirectoryId: process.env.DirectoryId,
          InstanceAlias: process.env.InstanceAlias,
        };
        var connect = new AWS.Connect({apiVersion: '2017-08-08'});
        console.log(Object.getOwnPropertyNames(connect)); // ***Not what's expected***
        var createConnectRequest = connect.createInstance(params, function(err, data) {
          if (err) console.log(err, err.stack);
          else     console.log(data);
        }); // ***connect.createInstance is not a function***

  InvokeLambda:
    Type: AWS::CloudFormation::CustomResource
    DependsOn: CreateConnectInstance
    Version: "1.0"
    Properties:
      ServiceToken: !Sub ${CreateConnectInstance.Arn}

【问题讨论】:

  • Node.js Lambda 运行时包括 AWS SDK 2.771.0。如果特定版本的 SDK 支持 Connect 的 createInstance 方法,您可能想要在 Lambda 之外进行验证。
  • 因为我明确地固定了 apiVersion,并且在实例化该对象时没有引发错误,我希望该方法存在并且我链接到的文档适用: var connect = new AWS.Connect ({apiVersion: '2017-08-08'});如果这不是一个正确的假设,请有人加入。
  • 不正确的假设 afaik。

标签: node.js amazon-web-services aws-lambda amazon-cloudformation aws-serverless


【解决方案1】:

AWS Connect createInstance 方法在当前与 AWS Lambda Node.js runtime(在撰写本文时为 v2.771.0)一起部署的 AWS 开发工具包中不可用。 createInstance API 似乎处于预览版中。

该功能是在v2.797.0 中引入的。您可以在本地(在 Lambda 之外)验证这一点。我使用二进制切分方法来测试 2.771.0 和当前 (2.809.0) 之间的 AWS 开发工具包版本以及以下简单代码来验证这一点:

const AWS = require('aws-sdk');
const connect = new AWS.Connect({apiVersion: '2017-08-08'});
connect.createInstance('fred');

changelog 显示了 v2.797.0(除其他外):

功能:Connect:此版本添加了一组 Amazon Connect API 以编程方式控制实例创建、修改、描述 和删除。

您可以upload a compatible version of the SDK(在您的 Lambda 程序包中或通过 Lambda 层)访问此函数。

【讨论】:

  • 很棒的答案,非常感谢,并为您解释您的方法以及链接更改日志和解决方案提供奖励。
  • 作为旁注,当您使用实际未使用的 apiVersion 实例化对象时,api 不抛出错误似乎是一种不好的做法。
  • 正在使用那个 API 版本并且它确实支持 Connect API。您遇到的问题是 createInstance 在 Connect 的预览版中。
猜你喜欢
  • 2018-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-03
  • 1970-01-01
  • 1970-01-01
  • 2021-02-09
  • 2019-02-24
相关资源
最近更新 更多