Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mailgun release - DO NOT MERGE #150

Closed
wants to merge 12 commits into from
Closed
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"
JPPortier marked this conversation as resolved.
Show resolved Hide resolved
},
"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);
JPPortier marked this conversation as resolved.
Show resolved Hide resolved
} 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
Loading