aboutsummaryrefslogtreecommitdiff
path: root/services/docker/mail-server/aws-sendmail/deliver.ts
blob: e0c6e1c0a486e5e6c8e95b33f94407d5ae289be9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import { Mail } from "./mail.ts";

class MailDeliverError extends Error {
  constructor(
    message: string,
    options: ErrorOptions,
    public readonly mail: Mail,
  ) {
    super(message, options);
  }
}

type MailDeliverHook = (mail: Mail) => Promise<void>;

export abstract class MailDeliverer {
  preHooks: MailDeliverHook[] = [];
  postHooks: MailDeliverHook[] = [];

  constructor(public readonly destination: string) {}

  protected doPrepare(_mail: Mail): Promise<void> {
    return Promise.resolve();
  }
  protected abstract doDeliver(mail: Mail): Promise<void>;
  protected doFinalize(_mail: Mail): Promise<void> {
    return Promise.resolve();
  }

  async deliverRaw(raw: string): Promise<void> {
    const mail = new Mail(raw);
    await this.deliver(mail);
  }

  async deliver(mail: Mail): Promise<void> {
    this.doPrepare(mail);

    for (const hook of this.preHooks) {
      await hook(mail);
    }

    await this.doDeliver(mail);

    for (const hook of this.postHooks) {
      await hook(mail);
    }

    await this.doFinalize(mail);
  }

  protected throwError(
    reason: string,
    mail: Mail,
    cause?: unknown,
  ): never {
    throw new MailDeliverError(
      `Failed to deliver mail to ${this.destination}: ${reason}`,
      { cause },
      mail,
    );
  }
}