1

I am getting an error everytime I run SendGrid.setApiKey with serverless architecture, let me explain...

So when I run sendgrid.service.ts locally (code below) It works perfectly fine and runs how I expect it to; It sends an email and sets my API key. But when I try running it on AWS lambda using this tutorial I get this error: SendGrid.setApiKey is not a function. I thought It was a one-off error, and just did not work with lambda, so I also tried using Vercel with this tutorial , and I got the exact same error. I am not sure why I'm getting this error, my code seems to work fine not in serverless architecture, but every time I try running it in serverless architecture (how I deploy it) I keep getting this error, so I know it is something with my code is incorrect.

I've been stuck on this problem for a couple of days and still have not found a solution, so any help or suggestions would be greatly appreciated.

I know i had similar issue with the package bcrypt because that does not work in serverless environments either, so I might just try using another emailing service, and see if that works.

sendgrid.service.ts (path: src/auth/services):

import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as SendGrid from '@sendgrid/mail';

@Injectable()
export class SendgridService {
    constructor() {  
      SendGrid.setApiKey(process.env.SEND_GRID_KEY);
    }

    async send(mail: SendGrid.MailDataRequired) {
        const transport = await SendGrid.send(mail);
        return transport;
    }
}

package.json:

    {
    "name": "api",
    "version": "0.0.1",
    "description": "",
    "author": "",
    "private": true,
    "license": "UNLICENSED",
    "scripts": {
        "prebuild": "rimraf dist",
        "build": "nest build",
        "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
        "start": "nest start",
        "start:dev": "nest start --watch",
        "start:debug": "nest start --debug --watch",
        "start:prod": "node dist/main",
        "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
        "test": "jest",
        "test:watch": "jest --watch",
        "test:cov": "jest --coverage",
        "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
        "test:e2e": "jest --config ./test/jest-e2e.json"
    },
    "dependencies": {
        "@nestjs/common": "^9.4.0",
        "@nestjs/config": "^2.3.1",
        "@nestjs/core": "^9.4.0",
        "@nestjs/jwt": "^10.0.3",
        "@nestjs/passport": "^9.0.3",
        "@nestjs/platform-express": "^9.4.0",
        "@nestjs/platform-socket.io": "^9.4.0",
        "@nestjs/schedule": "^2.2.1",
        "@nestjs/typeorm": "^9.0.1",
        "@nestjs/websockets": "^9.4.0",
        "@sendgrid/mail": "^7.7.0",
        "@vendia/serverless-express": "^4.10.1",
        "aws-lambda": "^1.0.7",
        "aws-sdk": "^2.1362.0",
        "bcryptjs": "^2.4.3",
        "class-transformer": "^0.5.1",
        "class-validator": "^0.14.0",
        "cookie-parser": "^1.4.6",
        "dotenv": "^16.0.3",
        "file-type": "^18.2.1",
        "jimp": "^0.22.7",
        "morgan": "^1.10.0",
        "nodemailer": "^6.9.1",
        "passport": "^0.6.0",
        "passport-jwt": "^4.0.1",
        "passport-local": "^1.0.0",
        "pg": "^8.10.0",
        "postmark": "^3.0.15",
        "reflect-metadata": "^0.1.13",
        "rxjs": "^7.8.0",
        "sharp": "^0.32.0",
        "socket.io": "^4.6.1",
        "stripe": "^12.2.0",
        "typeorm": "^0.3.15",
        "uuid": "^9.0.0"
    },
    "devDependencies": {
        "@nestjs/cli": "^9.4.0",
        "@nestjs/schematics": "^9.1.0",
        "@nestjs/testing": "^9.4.0",
        "@types/aws-lambda": "^8.10.114",
        "@types/express": "^4.17.17",
        "@types/jest": "^29.5.1",
        "@types/multer": "^1.4.7",
        "@types/node": "^18.15.12",
        "@types/passport-jwt": "^3.0.8",
        "@types/supertest": "^2.0.12",
        "@typescript-eslint/eslint-plugin": "^5.59.0",
        "@typescript-eslint/parser": "^5.59.0",
        "eslint": "^8.38.0",
        "eslint-config-prettier": "^8.8.0",
        "eslint-plugin-prettier": "^4.2.1",
        "jest": "^29.5.0",
        "node-mocks-http": "^1.12.2",
        "prettier": "^2.8.7",
        "rimraf": "^5.0.0",
        "serverless-offline": "^12.0.4",
        "supertest": "^6.3.3",
        "ts-jest": "^29.1.0",
        "ts-loader": "^9.4.2",
        "ts-node": "^10.9.1",
        "tsconfig-paths": "^4.2.0",
        "typescript": "^5.0.4"
    },
    "jest": {
        "moduleFileExtensions": [
            "js",
            "json",
            "ts"
        ],
        "rootDir": "src",
        "testRegex": ".*\\.spec\\.ts$",
        "transform": {
            "^.+\\.(t|j)s$": "ts-jest"
        },
        "collectCoverageFrom": [
            "**/*.(t|j)s"
        ],
        "coverageDirectory": "../coverage",
        "testEnvironment": "node"
    }
}

tsconfig.json:

    {
    "compilerOptions": {
        "module": "commonjs",
        "declaration": true,
        "removeComments": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "allowSyntheticDefaultImports": true,
        "target": "es2017",
        "sourceMap": true,
        "outDir": "./dist",
        "baseUrl": "./",
        "incremental": true,
        "skipLibCheck": true,
        "strictNullChecks": false,
        "noImplicitAny": false,
        "strictBindCallApply": false,
        "forceConsistentCasingInFileNames": false,
        "noFallthroughCasesInSwitch": false,
        "esModuleInterop": true
    }
}

serverless.yaml:

service: SERVICE-NAME

useDotenv: true

plugins:
    - serverless-offline

provider:
    name: aws
    runtime: nodejs12.x
    environment:
        POSTGRES_HOST: ${env:POSTGRES_HOST}
        PORT_OF_POSTGRES: ${env:PORT_OF_POSTGRES}
        POSTGRES_USER: ${env:POSTGRES_USER}
        POSTGRES_PASSWORD: ${env:POSTGRES_PASSWORD}
        POSTGRES_DATABASE: ${env:POSTGRES_DATABASE}
        JWT_SECRET: ${env:JWT_SECRET}
        TIMEZONE: ${env:TIMEZONE}
        ACCESS_KEY_ID: ${env:ACCESS_KEY_ID}
        SECRET_ACCESS_KEY: ${env:SECRET_ACCESS_KEY}
        BUCKET_NAME_FOR_SUMMARY: ${env:BUCKET_NAME_FOR_SUMMARY}
        SEND_GRID_KEY: ${env:SEND_GRID_KEY}
        STRIPE_SECRET_KEY: ${env:STRIPE_SECRET_KEY}
        STRIPE_PUBLIC_KEY: ${env:STRIPE_PUBLIC_KEY}

functions:
    main:
        handler: dist/serverless.handler
        events:
            - http:
                method: ANY
                path: /
            - http:
                method: ANY
                path: '{proxy+}'
Zeke John
  • 79
  • 1
  • 7
  • 1
    How are you deploying your code? Make sure the npm packages are not deployed to, but rather installed on the Lambda – thomaux Apr 21 '23 at 08:50
  • 1
    @thomaux Thanks for the response. I'm trying to deploy my code in a serverless environment, like Lambda or Vercel (the same ways in the tutorial linked above). My NestJS backend code is based on the github here (not using the same code, but similar). When I'm deploying it, I have removed the "node_modules" and "package-lock.json" so it just installs the packages I've included in my "package.json". I have edited my question to include my "package.json", "tsconfig.json" and "serverless.yaml" for more info. #sendgrid #nestjs #serverless – Zeke John Apr 21 '23 at 21:34

0 Answers0