-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #62 from Callgent/fix/invocation
feat: sparkpost relay-webhook integration
- Loading branch information
Showing
28 changed files
with
540 additions
and
166 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,5 +51,11 @@ CALLGENT_SITE_URL=https://callgent.com | |
CALLGENT_SITE_NAME=Callgent.com | ||
|
||
EMAIL_DEFAULT_SENDER={"name": "Callgent", "email": "[email protected]"} | ||
EMAIL_RELAY_HOST=my.callgent.com | ||
|
||
# https://app.brevo.com/settings/keys/api | ||
EMAIL_BREVO_API_KEY=key | ||
EMAIL_SPARKPOST_API_KEY=xxx | ||
EMAIL_SPARKPOST_RELAY_CLIENT_ID=spark-post-relayer | ||
EMAIL_SPARKPOST_RELAY_CLIENT_SECRET=xxx | ||
EMAIL_SPARKPOST_RELAY_EXPIRES_IN=86400 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,5 +51,11 @@ CALLGENT_SITE_URL=https://callgent.com | |
CALLGENT_SITE_NAME=Callgent.com | ||
|
||
EMAIL_DEFAULT_SENDER={"name": "Callgent", "email": "[email protected]"} | ||
EMAIL_RELAY_HOST=my.callgent.com | ||
|
||
# https://app.brevo.com/settings/keys/api | ||
EMAIL_BREVO_API_KEY=key | ||
EMAIL_SPARKPOST_API_KEY=xxx | ||
EMAIL_SPARKPOST_RELAY_CLIENT_ID=spark-post-relayer | ||
EMAIL_SPARKPOST_RELAY_CLIENT_SECRET=xxx | ||
EMAIL_SPARKPOST_RELAY_EXPIRES_IN=86400 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/** | ||
* Represents a single email header. | ||
*/ | ||
interface Header { | ||
[key: string]: string; | ||
} | ||
|
||
/** | ||
* Represents the content parsed from the incoming message. | ||
*/ | ||
interface Content { | ||
/** | ||
* Contents of the last text/html part of the message. | ||
*/ | ||
html: string; | ||
|
||
/** | ||
* Contents of the last text/plain part of the message. | ||
*/ | ||
text: string; | ||
|
||
/** | ||
* "Subject" header value (decoded from email). | ||
*/ | ||
subject: string; | ||
|
||
/** | ||
* "To" header value (decoded from email), RFC2822 address list. | ||
*/ | ||
to: string[]; | ||
|
||
/** | ||
* "CC" header value (decoded from email), RFC2822 address list. | ||
*/ | ||
cc?: string[]; | ||
|
||
/** | ||
* Ordered array of email top-level headers. This array preserves ordering and allows for multiple occurrences of a header (e.g. to support trace headers such as "Received"). | ||
*/ | ||
headers: Header[]; | ||
|
||
/** | ||
* Raw MIME content for an email. If the Raw MIME content contains at least one non UTF-8 encoded character, the entire email_rfc822 value will be base64 encoded and email_rfc822_is_base64 will be set to true. | ||
*/ | ||
email_rfc822: string; | ||
|
||
/** | ||
* Whether the email_rfc822 value is base64 encoded. | ||
*/ | ||
email_rfc822_is_base64: boolean; | ||
} | ||
|
||
/** | ||
* Represents the relay message. | ||
*/ | ||
export interface RelayMessage { | ||
/** | ||
* The content parsed from the incoming message. | ||
*/ | ||
content: Content; | ||
|
||
/** | ||
* Customer ID of the customer that created the relay webhook. | ||
*/ | ||
customer_id: string; | ||
|
||
/** | ||
* Email address used to compose the "From" header. | ||
*/ | ||
friendly_from: string; | ||
|
||
/** | ||
* SMTP envelope "MAIL FROM", matches "Return-Path" header address. | ||
*/ | ||
msg_from: string; | ||
|
||
/** | ||
* SMTP envelope "RCPT TO". | ||
*/ | ||
rcpt_to: string; | ||
|
||
/** | ||
* ID of the relay webhook which triggered this relay message. | ||
*/ | ||
webhook_id: string; | ||
|
||
/** | ||
* Protocol of the originating inbound message. | ||
*/ | ||
protocol?: string; | ||
} | ||
|
||
export interface EmailRelayObject { | ||
msys: { | ||
relay_message: RelayMessage; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { Test, TestingModule } from '@nestjs/testing'; | ||
import { EmailsController } from './emails.controller'; | ||
|
||
describe('EmailsController', () => { | ||
let controller: EmailsController; | ||
|
||
beforeEach(async () => { | ||
const module: TestingModule = await Test.createTestingModule({ | ||
controllers: [EmailsController], | ||
}).compile(); | ||
|
||
controller = module.get<EmailsController>(EmailsController); | ||
}); | ||
|
||
it('should be defined', () => { | ||
expect(controller).toBeDefined(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import { | ||
BadRequestException, | ||
Body, | ||
Controller, | ||
Headers, | ||
HttpCode, | ||
HttpStatus, | ||
Post, | ||
} from '@nestjs/common'; | ||
import { ConfigService } from '@nestjs/config'; | ||
import { JwtAuthService } from '../infra/auth/jwt/jwt.service'; | ||
import { EmailsService } from './emails.service'; | ||
import { EmailRelayObject } from './dto/sparkpost-relay-object.interface'; | ||
|
||
@Controller('emails') | ||
export class EmailsController { | ||
constructor( | ||
private readonly jwtAuthService: JwtAuthService, | ||
private readonly configService: ConfigService, | ||
private readonly emailsService: EmailsService, | ||
) {} | ||
|
||
/** @see https://developers.sparkpost.com/api/relay-webhooks/ */ | ||
@HttpCode(HttpStatus.OK) | ||
@Post('relay/spark-post') | ||
async handleRelayEvent( | ||
@Headers('Authorization') authorization: string, | ||
@Body() relays: EmailRelayObject[], | ||
) { | ||
const { sub } = this.jwtAuthService.verify(authorization?.substring(7)); | ||
if (sub !== this.configService.get('EMAIL_SPARKPOST_RELAY_CLIENT_ID')) | ||
throw new BadRequestException('Invalid Client ID'); | ||
|
||
// handle relay event | ||
relays?.forEach((relay) => | ||
this.emailsService.handleRelayMessage(relay.msys.relay_message), | ||
); | ||
return; // return 200 to consume the event | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,10 +1,12 @@ | ||
import { Global, Module } from '@nestjs/common'; | ||
import { EmailTemplateProvider } from './email-template.provider'; | ||
import { EmailsService } from './emails.service'; | ||
import { EmailsController } from './emails.controller'; | ||
|
||
@Global() | ||
@Module({ | ||
providers: [EmailsService, EmailTemplateProvider], | ||
exports: [EmailsService], | ||
controllers: [EmailsController], | ||
}) | ||
export class EmailsModule {} |
Oops, something went wrong.