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

Add SMTP2GO provider support #256

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion app/Bindings.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
'gmail' => 'FluentMail\App\Services\Mailer\Providers\Gmail\Handler',
'outlook' => 'FluentMail\App\Services\Mailer\Providers\Outlook\Handler',
'postmark' => 'FluentMail\App\Services\Mailer\Providers\Postmark\Handler',
'elasticmail' => 'FluentMail\App\Services\Mailer\Providers\ElasticMail\Handler'
'elasticmail' => 'FluentMail\App\Services\Mailer\Providers\ElasticMail\Handler',
'smtp2go' => 'FluentMail\App\Services\Mailer\Providers\Smtp2Go\Handler',
];

foreach ($singletons as $key => $className) {
Expand Down
2 changes: 1 addition & 1 deletion app/Services/Converter.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ private function maybeWPMailSmtp()
];
$commonSettings = wp_parse_args($commonSettings, $localSettings);
unset($commonSettings['force_from_email']);
} else if ($mailer == 'sendinblue' || $mailer == 'sendgrid' || $mailer == 'pepipostapi') {
} else if ($mailer == 'sendinblue' || $mailer == 'sendgrid' || $mailer == 'pepipostapi' || $mailer == 'smtp2go') {
$local = Arr::get($wpMailSettings, $mailer, []);
$localSettings = [
'api_key' => $this->maybeFromWPMailDefined($mailer, 'api_key', Arr::get($local, 'api_key')),
Expand Down
171 changes: 171 additions & 0 deletions app/Services/Mailer/Providers/Smtp2Go/Handler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
<?php

namespace FluentMail\App\Services\Mailer\Providers\Smtp2Go;

use WP_Error as WPError;
use FluentMail\Includes\Support\Arr;
use FluentMail\Includes\Core\Application;
use FluentMail\App\Services\Mailer\Manager;
use FluentMail\App\Services\Mailer\BaseHandler;
use FluentMail\App\Services\Mailer\Providers\SendGrid\ValidatorTrait;

class Handler extends BaseHandler {
use ValidatorTrait;

protected $emailSentCode = 200;

protected $url = 'https://api.smtp2go.com/v3/email/send';

public function send() {
if ($this->preSend()) {
return $this->postSend();
}

return $this->handleResponse(new \WP_Error(422, __('Something went wrong!', 'fluent-smtp'), []));
}

public function postSend() {
$body = [
'sender' => $this->getFrom(),
'to' => $this->getTo(),
'cc' => $this->getCarbonCopy(),
'bcc' => $this->getBlindCarbonCopy(),
'subject' => $this->getSubject(),
'html_body' => $this->getBody(),
'text_body' => $this->phpMailer->AltBody
];

if ($replyTo = $this->getReplyTo()) {
$body['custom_headers'] = [
'Reply-To' => $replyTo
];
}


if (!empty($this->getParam('attachments'))) {
$body['attachments'] = $this->getAttachments();
}

$params = [
'body' => json_encode($body),
'headers' => $this->getRequestHeaders()
];

$params = array_merge($params, $this->getDefaultParams());

$response = wp_safe_remote_post($this->url, $params);

if (is_wp_error($response)) {
$returnResponse = new \WP_Error($response->get_error_code(), $response->get_error_message(), $response->get_error_messages());
} else {
$responseBody = wp_remote_retrieve_body($response);
$responseCode = wp_remote_retrieve_response_code($response);
$isOKCode = $responseCode == $this->emailSentCode;
$responseBody = \json_decode($responseBody, true);

if ($isOKCode) {
$returnResponse = [
'email_id' => Arr::get($responseBody, 'data.email_id'),
'succeeded' => Arr::get($responseBody, 'data.succeeded'),
];
} else {
$returnResponse = new \WP_Error($responseCode, Arr::get($responseBody, 'data.error', 'Unknown Error'), $responseBody);
}
}

$this->response = $returnResponse;

return $this->handleResponse($this->response);
}

protected function getFrom() {
$from = $this->getParam('sender_email');

if ($name = $this->getParam('sender_name')) {
$from = $name . ' <' . $from . '>';
}

return $from;
}

protected function getReplyTo() {
if ($replyTo = $this->getParam('headers.reply-to')) {
return reset($replyTo);
}
}

protected function getRecipients($recipients) {
return array_map(function ($recipient) {
return isset($recipient['name'])
? $recipient['name'] . ' <' . $recipient['email'] . '>'
: $recipient['email'];
}, $recipients);
}

protected function getTo() {
return $this->getRecipients($this->getParam('to'));
}

protected function getCarbonCopy() {
return $this->getRecipients($this->getParam('headers.cc'));
}

protected function getBlindCarbonCopy() {
return $this->getRecipients($this->getParam('headers.bcc'));
}

protected function getBody() {
return $this->getParam('message');
}

protected function getAttachments() {
$data = [];

foreach ($this->getParam('attachments') as $attachment) {
$file = false;

try {
if (is_file($attachment[0]) && is_readable($attachment[0])) {
$fileName = basename($attachment[0]);
$file = file_get_contents($attachment[0]);
$mimeType = mime_content_type($attachment[0]);
$filetype = str_replace(';', '', trim($mimeType));
}
} catch (\Exception $e) {
$file = false;
}

if ($file === false) {
continue;
}

$data[] = [
'mimetype' => $filetype,
'filename' => $fileName,
'fileblob' => base64_encode($file)
];
}

return $data;
}

protected function getCustomEmailHeaders() {
return [];
}

protected function getRequestHeaders() {
return [
'Content-Type' => 'application/json',
'X-Smtp2go-Api-Key' => $this->getSetting('api_key')
];
}

public function setSettings($settings) {
if ($settings['key_store'] == 'wp_config') {
$settings['api_key'] = defined('FLUENTMAIL_SMTP2GO_API_KEY') ? FLUENTMAIL_SMTP2GO_API_KEY : '';
}
$this->settings = $settings;

return $this;
}
}
37 changes: 37 additions & 0 deletions app/Services/Mailer/Providers/Smtp2Go/ValidatorTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace FluentMail\App\Services\Mailer\Providers\Smtp2Go;

use FluentMail\Includes\Support\Arr;
use FluentMail\App\Services\Mailer\ValidatorTrait as BaseValidatorTrait;

trait ValidatorTrait
{
use BaseValidatorTrait;

public function validateProviderInformation($connection)
{
$errors = [];

$keyStoreType = $connection['key_store'];

if($keyStoreType == 'db') {
if (! Arr::get($connection, 'api_key')) {
$errors['api_key']['required'] = __('Api key is required.', 'fluent-smtp');
}
} else if($keyStoreType == 'wp_config') {
if(!defined('FLUENTMAIL_SMTP2GO_API_KEY') || !FLUENTMAIL_SMTP2GO_API_KEY) {
$errors['api_key']['required'] = __('Please define FLUENTMAIL_SMTP2GO_API_KEY in wp-config.php file.', 'fluent-smtp');
}
}

if ($errors) {
$this->throwValidationException($errors);
}
}

public function checkConnection($connection)
{
return true;
}
}
13 changes: 13 additions & 0 deletions app/Services/Mailer/Providers/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,19 @@
],
'note' => '<a href="https://fluentsmtp.com/docs/configure-elastic-email-in-fluent-smtp/" target="_blank" rel="noopener">' . __('Read the documentation', 'fluent-smtp') . '</a>' . __(' for how to configure Elastic Email with FluentSMTP.', 'fluent-smtp')
],
'smtp2go' => [
'key' => 'smtp2go',
'title' => __('SMTP2GO', 'fluent-smtp'),
'image' => fluentMailAssetUrl('images/provider-smtp2go.svg'),
'provider' => 'Smtp2Go',
'options' => [
'sender_name' => '',
'sender_email' => '',
'force_from_name' => 'no',
'api_key' => '',
'key_store' => 'db'
]
],
'gmail' => [
'key' => 'gmail',
'title' => __('Gmail or Google Workspace', 'fluent-smtp'),
Expand Down
2 changes: 2 additions & 0 deletions resources/admin/Modules/Settings/ConnectionWizard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
import outlook from './Partials/Providers/Outlook';
import postmark from './Partials/Providers/PostMark';
import elasticmail from './Partials/Providers/ElasticMail';
import smtp2go from './Partials/Providers/Smtp2Go';
import Errors from '@/Bits/Errors';
import Error from '@/Pieces/Error';
import each from 'lodash/each';
Expand All @@ -125,6 +126,7 @@
outlook,
postmark,
elasticmail,
smtp2go,
Error,
ConnectionProvider
},
Expand Down
58 changes: 58 additions & 0 deletions resources/admin/Modules/Settings/Partials/Providers/Smtp2Go.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<template>
<div>
<h3 class="fs_config_title">{{ $t('SMTP2GO API Settings') }}</h3>
<el-radio-group size="mini" v-model="connection.key_store">
<el-radio-button label="db">{{ $t('Store API Keys in DB') }}</el-radio-button>
<el-radio-button label="wp_config">{{ $t('Store API Keys in Config File') }}</el-radio-button>
</el-radio-group>

<el-form-item v-if="connection.key_store == 'db'">
<label for="smtp2go-key">
{{ $t('API Key') }}
</label>
<InputPassword
id="smtp2go-key"
v-model="connection.api_key"
/>
<error :error="errors.get('api_key')" />
</el-form-item>
<div class="fss_condesnippet_wrapper" v-else-if="connection.key_store == 'wp_config'">
<el-form-item>
<label>{{ $t('__WP_CONFIG_INSTRUCTION') }}</label>
<div class="code_snippet">
<textarea readonly style="width: 100%;">define( 'FLUENTMAIL_SMTP2GO_API_KEY', '********************' );</textarea>
</div>
<error :error="errors.get('api_key')" />
</el-form-item>
</div>

<span class="small-help-text" style="display:block;margin-top:-10px">
{{ $t('Follow this link to get an API Key from SMTP2GO:') }}
<a target="_blank" href="https://app-eu.smtp2go.com/sending/apikeys/">{{ $t('Create API Key.') }}</a>
</span>
</div>
</template>

<script>
import InputPassword from '@/Pieces/InputPassword';
import Error from '@/Pieces/Error';

export default {
name: 'Smtp2Go',
props: ['connection', 'errors'],
components: {
InputPassword,
Error
},
'connection.key_store'(value) {
if (value === 'wp_config') {
this.connection.api_key = '';
}
},
data() {
return {
// ...
};
}
};
</script>
2 changes: 2 additions & 0 deletions resources/admin/Modules/Settings/Partials/Second.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import pepipost from './Providers/PepiPost';
import sendgrid from './Providers/SendGrid';
import sendinblue from './Providers/SendInBlue';
import smtp2go from './Providers/Smtp2Go';
import AmazonSes from './Providers/AmazonSes';
import smtp from './Providers/Smtp';

Expand All @@ -23,6 +24,7 @@
pepipost,
sendgrid,
sendinblue,
smtp2go,
smtp
},
data() {
Expand Down
1 change: 1 addition & 0 deletions resources/images/provider-smtp2go.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.