서버 없는 받은 편지함 API를 사용하여 전자 메일 워크플로우 확인

30628 단어 serverlesstestingaws

This article was first published on bahr.dev. Subscribe to get new articles straight to your inbox!


이 문서에서는 전자 메일 발송 워크플로우를 검증하기 위해 서버 없는 API를 구축하는 방법을 배울 것입니다.테스트가 실행될 때마다 새 받은 편지함을 사용할 수 있도록 도메인의 무한 받은 편지함에 액세스할 수 있습니다.
The working code is ready for you to deploy on GitHub .
AWS Services Simple Email Services(SES)와 API 게이트웨이를 통해 완전 자동화된 솔루션을 구축할 수 있습니다.그것의 가격 모델은 대부분의 테스트 작업 부하를 무료층에 포함시켜 매달 10달러만 있으면 10000통의 메일을 처리할 수 있다.유지보수나 개발이 필요 없습니다.그것은 또한 당신이 SES sandbox에 살 수 있도록 허락합니다.

선결 조건


이 솔루션을 구축하려면 AWS 계정과 AWS CDK을 사용한 경험이 있어야 합니다.TypeScript 변형을 사용합니다.이 문서에서는 CDK 버전 1.63.0을 사용합니다.업데이트 버전에 문제가 있으면 알려주세요!
SES를 통해 메시지를 받으려면 도메인이나 하위 도메인이 필요합니다.register a domain with Route53 또는 delegate from another provider을 선택할 수 있습니다.apex 도메인 (예: mail-test.bahr.dev) 을 다른 메일 서버에 연결한 경우, bahr.dev 같은 하위 도메인을 사용하여 메일을 받을 수 있습니다.

고급 개요


이 해결 방안은 두 부분으로 구성되어 있다.전자 우편 수신기와 전자 우편을 받을 수 있는api에 접근할 수 있습니다.전자는 데이터베이스에 쓰고, 후자는 그 중에서 읽는다.

전자 우편 수신기에 대해 우리는 SESReceipt Rules을 사용한다.이 규칙을 사용하여 원본 유효 부하와 첨부 파일을 S3 메모리 통에 저장하고 형식이 좋은 유효 부하를 Lambda 함수에 보냅니다. 이 함수는 DynamoDB 테이블에 항목을 만듭니다.
API 쪽에서는 받는 사람의 전자 메일 주소가 필요한 단일 읽기 작업이 있습니다.이것은 반환될 전자 우편의 수를 줄이기 위해 매개 변수화할 수 있다.
DynamoDB's time to live (TTL) feature은 자동으로 오래된 전자메일을 버리고 데이터베이스를 작게 유지하며 유지 보수 작업이 필요하지 않습니다.

SE 인증 도메인 사용


메시지를 받으려면 SES에 등록할 수 있는 도메인을 제어해야 합니다.이것도 하위 영역일 수 있습니다. 예를 들어 apex 영역(예를 들어 bahr.dev)을 Office 365와 같은 다른 메일 서비스에 사용했다면.
Route53에 도메인이 관리되는 경우 SES와의 통합이 가장 쉽습니다.다른 공급업체(예: GoDaddy)에서 제공하는 도메인을 사용하려면 set up a nameserver delegation을 사용하는 것이 좋습니다.
일단 당신의 도메인 이름이 위탁 관리 구역이 생기면, go to the Domain Identity Management in SES and verify a new domain.그리고 a short video where I verify a domain with SES.

데이터 모델


DynamoDB의 구역과 정렬 키를 사용하여 두 가지 주요 기능을 사용할 것입니다. 여러 개의 별명을 가진 메일을 수신하고 모든 별명을 위한 메일을 여러 개 수신합니다.별명은 front-part[email protected]입니다.
partition_key: [email protected]
sort_key: timestamp#uuid
ttl: timestamp
시간 스탬프와 uuid를 조합하면 시간 스탬프에 따라 정렬하고 필터링할 수 있으며, 두 개의 기록이 서로 충돌하지 않도록 확보할 수 있습니다.TTL은 표를 letting DynamoDB remove old records으로 축소하는 데 도움을 줍니다.
나는 Jeremy Daly's dynamodb-toolbox을 사용하여 나의 데이터베이스 실체를 모델링한다.
import { Table, Entity } from 'dynamodb-toolbox';
import { v4 as uuid } from 'uuid';

// Require AWS SDK and instantiate DocumentClient
import * as DynamoDB from 'aws-sdk/clients/dynamodb';
const DocumentClient = new DynamoDB.DocumentClient();

// Instantiate a table
export const MailTable = new Table({
  // Specify table name (used by DynamoDB)
  name: process.env.TABLE,

  // Define partition and sort keys
  partitionKey: 'pk',
  sortKey: 'sk',

  // Add the DocumentClient
  DocumentClient
});

export const Mail = new Entity({
    name: 'Mail',

    attributes: {
      id: { partitionKey: true }, // recipient address
      sk: { 
        hidden: true, 
        sortKey: true, 
        default: (data: any) => `${data.timestamp}#${uuid()}` 
      },
      timestamp: { type: 'string' },
      from: { type: 'string' },
      to: { type: 'string' },
      subject: { type: 'string' },
      ttl: { type: 'number' },
    },

    table: MailTable
  });

수신기


SES에서는 ReceiptRules을 설정하여 새 메일이 도착할 때 작업을 트리거할 수 있도록 합니다.There are multiple actions to choose from 하지만 우리가 가장 흥미를 느끼는 것은 람다와 S3 동작이다.우리는 Lambda 조작을 사용하여 DynamoDB 테이블에 수신자, 발송자, 주제 등 상세한 정보를 저장합니다.S3 작업을 통해 우리는 원본 전자메일을 파일로 버킷에 보냅니다.메일의 본문과 첨부 파일을 다시 뒤집는 등 앞으로 더 많은 용례를 지원할 수 있을 것이다.ReceiptRules으로 설정된 약어 CDK 코드를 볼 수 있습니다.AWS 콘솔에서 규칙 집합을 활성화해야 합니다.There is currently no high level CDK construct for this, 나는 당신이 의외로 기존 규칙 집합을 덮어쓰는 것을 원하지 않습니다.Here's a short video where I activate a rule set .
import * as cdk from '@aws-cdk/core';
import { Bucket } from '@aws-cdk/aws-s3';
import { Table } from '@aws-cdk/aws-dynamodb';
import { Function } from '@aws-cdk/aws-lambda';
import { ReceiptRuleSet } from '@aws-cdk/aws-ses';
import * as actions from '@aws-cdk/aws-ses-actions';

export class InboxApiStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // your-domain.com
    const domain = process.env.INBOX_DOMAIN; 

    const rawMailBucket = new Bucket(this, 'RawMail');

    const table = new Table(this, 'TempMailMetadata', {
        ...
    });

    const postProcessFunction = new Function(this, 'PostProcessor', {
        ...
        environment: {
            'TABLE': table.tableName,
        }
    });
    table.grantWriteData(postProcessFunction);

    // after deploying the cdk stack you need to activate this ruleset
    new ReceiptRuleSet(this, 'ReceiverRuleSet', {
      rules: [
        {
          recipients: [domain],
          actions: [
            new actions.S3({
              bucket: rawMailBucket
            }),
            new actions.Lambda({
              function: postProcessFunction
            })
          ],
        }
      ]
    });
  }
}
위의 CDK 코드가 있습니다. 새 메일이 도착했을 때 터치하는 Lambda 함수를 살펴보겠습니다.
import { SESHandler } from 'aws-lambda';
// the model uses dynamodb-toolbox
import { Mail } from './model';

export const handler: SESHandler = async(event) => {

    for (const record of event.Records) {
        const mail = record.ses.mail;

        const from = mail.source;
        const subject = mail.commonHeaders.subject;
        const timestamp = mail.timestamp;

        const now = new Date();
        // set the ttl as 7 days into the future and 
        // strip milliseconds (ddb expects seconds for the ttl)
        const ttl = now.setDate(now.getDate() + 7) / 1000;

        for (const to of mail.destination) {
            await Mail.put({
                id: to, timestamp,
                from, to,
                subject, ttl
            });
        }
    }
}
위의 함수는 SES 이벤트를 각 수신자의 레코드에 매핑하여 TTL 속성과 함께 데이터베이스에 저장합니다.You can find the full source code on GitHub .
현재 우리는 메일을 데이터베이스에 직접 수신하여 메일에 접근할 수 있는 API를 구축합니다.

읽기 API


읽기 API는 DynamoDB 테이블에 대한 읽기 액세스 권한이 있는 API 게이트웨이와 Lambda 함수로 구성됩니다.이전에 이러한 API를 구축한 적이 없는 경우
다음은 API 게이트웨이와 Lambda 함수를 설정하는 데 사용되는 줄임말 CDK 코드를 볼 수 있습니다.You can find the full source code on GitHub .
import * as cdk from '@aws-cdk/core';
import { LambdaRestApi } from '@aws-cdk/aws-apigateway';
import { Table } from '@aws-cdk/aws-dynamodb';

export class InboxApiStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const table = new Table(this, 'TempMailMetadata', {
        ...
    });

    const apiFunction = new Function(this, 'ApiLambda', {
        environment: {
            'TABLE': table.tableName,
        }
    });
    table.grantReadData(apiFunction);

    new LambdaRestApi(this, 'InboxApi', {
      handler: apiFunction,
    });
  }
}
API 게이트웨이는 DynamoDB와 직접 통합할 수 있지만 dynamodb-toolbox으로 구축한 데이터베이스 모델을 계속 사용하려면 Lambda 함수를 사용해야 합니다.나도 타자가 Apache Velocity Templates보다 더 편하다고 생각한다.
아래lambda 함수를 사용하면 특정한 수신자의 메일을 불러오고 주어진 시간 스탬프 이후에 도착한 메일만 되돌려줍니다.
import { APIGatewayProxyHandler } from 'aws-lambda';
// the model uses dynamodb-toolbox
import { Mail } from './model';

export const handler: APIGatewayProxyHandler = async(event) => {
    const queryParams = event.queryStringParameters;
    const recipient = queryParams?.recipient;
    if (!recipient) {
        return {
            statusCode: 400,
            body: 'Missing query parameter: recipient'
        }
    }
    const since = queryParams.since || '';
    const limit = +queryParams.limit || 1;

    const mails = (await Mail.query(
        recipient,
        {
            beginsWith: since,
            limit,
        }
    )).Items;

    return {
        statusCode: 200,
        body: JSON.stringify(mails)
    }
}
read API를 배치한 후 GET 요청을 실행할 수 있습니다. 이 요청은 수신자 메일을 recipient 조회 매개 변수로 합니다.since 타임 스탬프를 제공하거나 기본 limit보다 더 좋은 1으로 통화를 조정할 수 있습니다.
예를 들어 [email protected]에 주문 확인을 보내려면 https://YOUR_API_ENDPOINT/[email protected]에 대해 GET 요청을 실행해야 합니다.

한계 및 잠재적 개선


SES sandbox restricts how many emails you can send이지만 우편물의 제한은 없는 것 같습니다.
우리의 해결 방안은 아직 첨부 파일이나 우편 본문을 제공할 수 없다.SES S3 action은 이 버킷을 하나의 버킷에 저장했습니다. 이 버킷은 개선된 읽기 API 함수에 사용할 수 있습니다.
API 게이트웨이와 DynamoDB를 연결하는 Lambda 함수를 삭제하여 두 서비스 간의 직접 통합으로 대체할 수도 있습니다.

너 혼자 해봐.


Check out the source code on GitHub . 이 솔루션을 시험적으로 사용할 수 있는 단계별 안내서가 있습니다.

한층 더 읽다

  • Source code on GitHub
  • Receipt Rules
  • Test email edge cases with the AWS mailbox simulator
  • DynamoDB TTL
  • 이 문장을 좋아합니까?나는 매달 새로운 문장 한 편을 발표한다.subscribe과 연락을 통해 새로운 글을 얻으세요!

    좋은 웹페이지 즐겨찾기