Skip to content

Commit

Permalink
DEVEXP-642: Implement Mailgun Messages endpoints
Browse files Browse the repository at this point in the history
  • Loading branch information
asein-sinch committed Nov 13, 2024
1 parent b7c45c7 commit de5f193
Show file tree
Hide file tree
Showing 81 changed files with 2,241 additions and 3 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/run-ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
mkdir -p ./packages/sms/tests/e2e/features
mkdir -p ./packages/verification/tests/e2e/features
mkdir -p ./packages/voice/tests/e2e/features
mkdir -p ./packages/mailgun/tests/e2e/features
- name: Copy feature files
run: |
Expand All @@ -64,6 +65,7 @@ jobs:
cp sinch-sdk-mockserver/features/sms/*.feature ./packages/sms/tests/e2e/features/
cp sinch-sdk-mockserver/features/verification/*.feature ./packages/verification/tests/e2e/features/
cp sinch-sdk-mockserver/features/voice/*.feature ./packages/voice/tests/e2e/features/
cp sinch-sdk-mockserver/features/mailgun/*.feature ./packages/mailgun/tests/e2e/features/
- name: Run e2e tests
run: yarn run e2e
Expand Down
9 changes: 8 additions & 1 deletion examples/simple-examples/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@
"fax:fax-to-email:listNumbers": "ts-node src/fax/fax-to-email/listNumbers.ts",
"fax:fax-to-email:update": "ts-node src/fax/fax-to-email/update.ts",
"fax:fax-to-email:delete": "ts-node src/fax/fax-to-email/delete.ts",
"mailgun:email:sendEmail": "ts-node src/mailgun/emails/sendEmail.ts",
"mailgun:email:sendMimeEmail": "ts-node src/mailgun/emails/sendMimeEmail.ts",
"mailgun:email:getEmail": "ts-node src/mailgun/emails/getEmail.ts",
"mailgun:email:purgeDomainQueues": "ts-node src/mailgun/emails/purgeDomainQueues.ts",
"mailgun:email:getSendingQueuesStatus": "ts-node src/mailgun/emails/getSendingQueuesStatus.ts",
"numbers:regions:list": "ts-node src/numbers/regions/list.ts",
"numbers:available:list": "ts-node src/numbers/available/list.ts",
"numbers:available:checkAvailability": "ts-node src/numbers/available/checkAvailability.ts",
Expand Down Expand Up @@ -184,10 +189,12 @@
},
"dependencies": {
"@sinch/sdk-core": "^1.2.0",
"dotenv": "^16.3.1"
"dotenv": "^16.3.1",
"nodemailer": "^6.9.16"
},
"devDependencies": {
"@types/node": "^20.8.7",
"@types/nodemailer": "^6.4.16",
"ts-node": "^10.9.1",
"typescript": "^5.2.2"
}
Expand Down
26 changes: 26 additions & 0 deletions examples/simple-examples/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
SmsRegion,
ConversationService,
FaxService,
MailgunService,
NumbersService,
SmsService,
VerificationService,
Expand Down Expand Up @@ -30,6 +31,15 @@ export const initFaxService = (): FaxService => {
return initClient().fax;
};

const initMailgunClient = (): Pick<SinchClient, 'mailgun'> => {
const mailgunApiKey = process.env.MAILGUN_API_KEY || '';
return new SinchClient({ mailgunApiKey });
};

export const initMailgunService = (): MailgunService => {
return initMailgunClient().mailgun;
};

export const initNumbersService = (): NumbersService => {
return initClient().numbers;
};
Expand Down Expand Up @@ -219,6 +229,22 @@ export const getIpRangeIdFromConfig = () => {
return readVariable('IP_RANGE_ID');
};

export const getMailgunDomainFromConfig = () => {
return readVariable('MAILGUN_DOMAIN');
};

export const getMailgunSenderFromConfig = () => {
return readVariable('MAILGUN_SENDER_ADDRESS');
};

export const getMailgunRecipientFromConfig = () => {
return readVariable('MAILGUN_RECIPIENT_ADDRESS');
};

export const getMailgunStorageKeyFromConfig = () => {
return readVariable('MAILGUN_STORAGE_KEY');
};

const readVariable = ( name: string): string => {
const value = process.env[name];
if (!value) {
Expand Down
27 changes: 27 additions & 0 deletions examples/simple-examples/src/mailgun/emails/getEmail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {
getMailgunDomainFromConfig,
getMailgunStorageKeyFromConfig,
initMailgunService,
printFullResponse,
} from '../../config';

(async () => {
console.log('************');
console.log('* GetEmail *');
console.log('************');

const domainName = getMailgunDomainFromConfig();
const storageKey = getMailgunStorageKeyFromConfig();

const mailgunService = initMailgunService();
let response;
try {
response = await mailgunService.emails.getEmail(domainName, storageKey);
} catch (error) {
console.error('Error when retrieving a message');
throw error;
}

printFullResponse(response);

})();
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { getMailgunDomainFromConfig, initMailgunService, printFullResponse } from '../../config';

(async () => {
console.log('**************************');
console.log('* GetSendingQueuesStatus *');
console.log('**************************');

const domainName = getMailgunDomainFromConfig();

const mailgunService = initMailgunService();
let response;
try {
response = await mailgunService.emails.getSendingQueuesStatus(domainName);
} catch (error) {
console.error('Error when fetching the sending queue status');
throw error;
}

printFullResponse(response);

})();
21 changes: 21 additions & 0 deletions examples/simple-examples/src/mailgun/emails/purgeDomainQueues.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { getMailgunDomainFromConfig, initMailgunService, printFullResponse } from '../../config';

(async () => {
console.log('*********************');
console.log('* PurgeDomainQueues *');
console.log('*********************');

const domainName = getMailgunDomainFromConfig();

const mailgunService = initMailgunService();
let response;
try {
response = await mailgunService.emails.purgeDomainQueues(domainName);
} catch (error) {
console.error('Error when trying to purge the domain queues');
throw error;
}

printFullResponse(response);

})();
37 changes: 37 additions & 0 deletions examples/simple-examples/src/mailgun/emails/sendEmail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import {
getMailgunDomainFromConfig,
getMailgunRecipientFromConfig,
getMailgunSenderFromConfig,
initMailgunService,
printFullResponse,
} from '../../config';
import { Mailgun } from '@sinch/sdk-core';

(async () => {
console.log('*************');
console.log('* SendEmail *');
console.log('*************');

const domainName = getMailgunDomainFromConfig();
const sender = getMailgunSenderFromConfig();
const recipient = getMailgunRecipientFromConfig();

const requestData: Mailgun.SendEmailRequest = {
from: sender,
to: recipient,
subject: 'First email from the Node.js SDK',
html: 'Hello!<br>This is an email sent with the <span color="blue">Node.js SDK</span>.',
};

const mailgunService = initMailgunService();
let response;
try {
response = await mailgunService.emails.sendEmail(domainName, requestData);
} catch (error) {
console.error('Error when sending a message');
throw error;
}

printFullResponse(response);

})();
47 changes: 47 additions & 0 deletions examples/simple-examples/src/mailgun/emails/sendMimeEmail.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import {
getMailgunDomainFromConfig,
getMailgunRecipientFromConfig,
getMailgunSenderFromConfig,
initMailgunService,
printFullResponse,
} from '../../config';
import { Mailgun } from '@sinch/sdk-core';
import MailComposer from 'nodemailer/lib/mail-composer';

(async () => {
console.log('*****************');
console.log('* SendMimeEmail *');
console.log('*****************');

const domainName = getMailgunDomainFromConfig();
const sender = getMailgunSenderFromConfig();
const recipient = getMailgunRecipientFromConfig();

const data = {
message: {
from: sender,
subject: 'Test Sending mime messages from node',
text: 'This is a mime message',
html: 'HTML<br>version<br>of<br>the<br><span style="color: blue">body</span>',
},
};
const mail = new MailComposer(data.message);
const compiledMessage = await mail.compile().build();

const requestData: Mailgun.SendMimeEmailRequest= {
to: recipient,
message: compiledMessage.toString(),
};

const mailgunService = initMailgunService();
let response;
try {
response = await mailgunService.emails.sendMimeEmail(domainName, requestData);
} catch (error) {
console.error('Error when sending a message');
throw error;
}

printFullResponse(response);

})();
5 changes: 5 additions & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ const config: Config.InitialOptions = {
testMatch: ['<rootDir>/packages/fax/tests/**/*.test.ts'],
coveragePathIgnorePatterns: ['node_modules', 'tests'],
},
{
displayName: 'Mailgun',
testMatch: ['<rootDir>/packages/mailgun/tests/**/*.test.ts'],
coveragePathIgnorePatterns: ['node_modules', 'tests'],
},
{
displayName: 'Numbers',
testMatch: ['<rootDir>/packages/numbers/tests/**/*.test.ts'],
Expand Down
3 changes: 3 additions & 0 deletions packages/mailgun/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Version X.Y.Z

- Initial version
113 changes: 113 additions & 0 deletions packages/mailgun/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# Sinch Mailgun SDK for Node.js

This package contains the Sinch Mailgun SDK for Node.js for use with [Sinch APIs](https://developers.sinch.com/). To use it, you will need a Sinch account. Please [sign up](https://dashboard.sinch.com/signup) or [log in](https://dashboard.sinch.com/login) if you already have one.

In case Mailgun is not yet integrated with Sinch in your market, you will need to [create a Mailgun account](https://signup.mailgun.com/new/signup?) or [log in](https://login.mailgun.com/login/) if you already have one.

## Installation

We recommend to use this SDK as part of the `@sinch/sdk-core` package as it will take care about the authentication plugins to use.

However, it's still possible to use this SDK standalone is you need to access the Mailgun API only.

### With NPM

```bash
npm install @sinch/mailgun
```

### With Yarn

```bash
yarn add @sinch/mailgun
```

## Usage

### Credentials

The `Mailgun` API uses an API key to identify and authenticate the caller: it can be found in your [Mailgun Dashboard](https://app.mailgun.com/settings/api_security).

### As part of the Sinch SDK

If you are using this SDK as part of the Sinch SDK (`@sinch/sdk-core`) you can access it as the `mailgun` property of the client that you would have instantiated.

```typescript
import {
Mailgun,
SinchClient,
SinchClientParameters,
} from '@sinch/sdk-core';

const credentials: SinchClientParameters = {
mailgunApiKey: 'MAILGUN_API_KEY',
};

const sinch = new SinchClient(credentials);

const requestData: Mailgun.SendEmailRequest = {
from: '[email protected]',
to: '[email protected]',
subject: 'First email from the Node.js SDK',
html: 'Hello!<br>This is an email sent with the <span color="blue">Node.js SDK</span>.',
};

// Access the 'mailgun' domain registered on the Sinch Client
const result: Mailgun.SendEmailResponse
= await sinch.mailgun.emails.sendEmail(requestData);
```

### Standalone

The SDK can be used standalone if you need to use only the Mailgun APIs.

```typescript
import {
Mailgun,
SinchClientParameters,
} from '@sinch/sdk-client';
import {

} from '@sinch/mailgun';

const credentials: SinchClientParameters = {
mailgunApiKey: 'MAILGUN_API_KEY',
};

// Declare the 'mailgun' service in a standalone way
const mailgun = new Mailgun(credentials);

const requestData: Mailgun.SendEmailRequest = {
from: '[email protected]',
to: '[email protected]',
subject: 'First email from the Node.js SDK',
html: 'Hello!<br>This is an email sent with the <span color="blue">Node.js SDK</span>.',
};

// Use the standalone declaration of the 'mailgun' domain
const result: Mailgun.SendEmailResponse
= await mailgun.emails.sendEmail(requestData);
```

## Promises

All the methods that interact with the Sinch APIs use Promises. You can use `await` in an `async` method to wait for the response or you can resolve them yourself with `then()` / `catch()`.

```typescript
// Method 1: Wait for the Promise to complete
let sendEmailResponse: Mailgun.SendEmailResponse;
try {
sendEmailResponse = await sinch.mailgun.emails.sendEmail(requestData);
console.log(`Message id = ${sendEmailResponse.id}`);
} catch (error: any) {
console.error(`ERROR ${error.statusCode}: `);
}

// Method 2: Resolve the promise
sinch.mailgun.emails.sendEmail(requestData)
.then(response => console.log(`Message id = ${response.id}`))
.catch(error => console.error(`ERROR ${error.statusCode}: `));
```

## Contact
Developer Experience team: [[email protected]](mailto:[email protected])
8 changes: 8 additions & 0 deletions packages/mailgun/cucumber.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
default: [
'tests/e2e/features/**/*.feature',
'--require-module ts-node/register',
'--require tests/rest/v1/**/*.steps.ts',
`--format-options '{"snippetInterface": "synchronous"}'`,
].join(' '),
};
Loading

0 comments on commit de5f193

Please sign in to comment.