mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2025-07-09 03:14:30 -04:00
updates mailgun webhook loading message data on runtime
This commit is contained in:
parent
0aaaf27314
commit
73bcf928e4
@ -1,47 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Invoice Ninja (https://invoiceninja.com).
|
||||
*
|
||||
* @link https://github.com/invoiceninja/invoiceninja source repository
|
||||
*
|
||||
* @copyright Copyright (c) 2023. Invoice Ninja LLC (https://invoiceninja.com)
|
||||
*
|
||||
* @license https://www.elastic.co/licensing/elastic-license
|
||||
*/
|
||||
|
||||
namespace App\Helpers\IngresMail\Transformer;
|
||||
|
||||
use App\Services\IngresEmail\IngresEmail;
|
||||
use App\Utils\TempFile;
|
||||
use Illuminate\Support\Carbon;
|
||||
|
||||
class MailgunInboundWebhookTransformer
|
||||
{
|
||||
public function transform($data)
|
||||
{
|
||||
$ingresEmail = new IngresEmail();
|
||||
|
||||
$ingresEmail->from = $data["sender"]; // TODO: maybe a fallback have to be used to extract email from $data["From"]
|
||||
$ingresEmail->to = $data["recipient"]; // TODO: maybe a fallback have to be used to extract email from $data["To"]
|
||||
$ingresEmail->subject = $data["Subject"];
|
||||
$ingresEmail->body = $data["body-html"];
|
||||
$ingresEmail->text_body = $data["body-plain"];
|
||||
$ingresEmail->date = Carbon::createFromTimestamp((int) $data["timestamp"]);
|
||||
|
||||
// parse documents as UploadedFile from webhook-data
|
||||
foreach (json_decode($data["attachments"]) as $attachment) {
|
||||
|
||||
// prepare url with credentials before downloading :: https://github.com/mailgun/mailgun.js/issues/24
|
||||
$url = $attachment->url;
|
||||
$credentials = config('services.mailgun.domain') . ":" . config('services.mailgun.secret') . "@";
|
||||
$url = str_replace("http://", "http://" . $credentials, $url);
|
||||
$url = str_replace("https://", "https://" . $credentials, $url);
|
||||
|
||||
// download file and save to tmp dir
|
||||
$ingresEmail->documents[] = TempFile::UploadedFileFromUrl($url, $attachment->name, $attachment->{"content-type"});
|
||||
|
||||
}
|
||||
|
||||
return $ingresEmail;
|
||||
}
|
||||
}
|
@ -115,19 +115,24 @@ class MailgunController extends BaseController
|
||||
{
|
||||
$input = $request->all();
|
||||
|
||||
if (!array_key_exists('recipient', $input) || !array_key_exists('message-url', $input)) {
|
||||
Log::info('Failed: Message could not be parsed, because required parameters are missing. Please ensure contacting this api-endpoint with a store & notify operation instead of a forward operation!');
|
||||
return response()->json(['message' => 'Failed. Missing Parameters'], 400);
|
||||
}
|
||||
|
||||
if (!array_key_exists('attachments', $input) || count(json_decode($input['attachments'])) == 0) {
|
||||
Log::info('Message ignored because of missing attachments. Please ensure contacting this api-endpoint with a store & notify operation instead of a forward operation');
|
||||
Log::info('Message ignored because of missing attachments. No Actions would have been taken...');
|
||||
return response()->json(['message' => 'Sucess. Soft Fail. Missing Attachments.'], 200);
|
||||
}
|
||||
|
||||
if (\abs(\time() - (int) $request['timestamp']) > 150) {
|
||||
if (\abs(\time() - (int) $input['timestamp']) > 150) {
|
||||
Log::info('Message ignored because of request body is too old.');
|
||||
return response()->json(['message' => 'Success. Soft Fail. Message too old.'], 200);
|
||||
}
|
||||
|
||||
// @turbo124 TODO: how to check for services.mailgun.webhook_signing_key on company level, when custom credentials are defined
|
||||
if (\hash_equals(\hash_hmac('sha256', $input['timestamp'] . $input['token'], config('services.mailgun.webhook_signing_key')), $input['signature'])) {
|
||||
ProcessMailgunInboundWebhook::dispatch($input)->delay(10);
|
||||
ProcessMailgunInboundWebhook::dispatch($input["recipient"] . "|" . $input["message-url"])->delay(10);
|
||||
|
||||
return response()->json(['message' => 'Success'], 201);
|
||||
}
|
||||
|
@ -11,9 +11,11 @@
|
||||
|
||||
namespace App\Jobs\Mailgun;
|
||||
|
||||
use App\Helpers\IngresMail\Transformer\MailgunInboundWebhookTransformer;
|
||||
use App\Libraries\MultiDB;
|
||||
use App\Services\IngresEmail\IngresEmail;
|
||||
use App\Services\IngresEmail\IngresEmailEngine;
|
||||
use App\Utils\TempFile;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Contracts\Queue\ShouldQueue;
|
||||
use Illuminate\Foundation\Bus\Dispatchable;
|
||||
@ -29,9 +31,9 @@ class ProcessMailgunInboundWebhook implements ShouldQueue
|
||||
|
||||
/**
|
||||
* Create a new job instance.
|
||||
*
|
||||
* $input consists of 2 informations: recipient|messageUrl
|
||||
*/
|
||||
public function __construct(private array $request)
|
||||
public function __construct(private string $input)
|
||||
{
|
||||
}
|
||||
|
||||
@ -43,21 +45,48 @@ class ProcessMailgunInboundWebhook implements ShouldQueue
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if (!array_key_exists('To', $this->request) || !array_key_exists('attachments', $this->request) || !array_key_exists('timestamp', $this->request) || !array_key_exists('Subject', $this->request) || !(array_key_exists('body-html', $this->request) || array_key_exists('body-plain', $this->request)))
|
||||
throw new \Exception('invalid body');
|
||||
$recipient = explode("|", $this->input)[0];
|
||||
|
||||
// match company
|
||||
$company = MultiDB::findAndSetDbByExpenseMailbox($this->request["To"]);
|
||||
$company = MultiDB::findAndSetDbByExpenseMailbox($recipient);
|
||||
if (!$company) {
|
||||
Log::info('unknown Expense Mailbox occured while handling an inbound email from mailgun: ' . $this->request["To"]);
|
||||
Log::info('unknown Expense Mailbox occured while handling an inbound email from mailgun: ' . $recipient);
|
||||
return;
|
||||
}
|
||||
|
||||
// prepare
|
||||
$ingresMail = (new MailgunInboundWebhookTransformer())->transform($this->request);
|
||||
Log::info(json_encode($ingresMail));
|
||||
// fetch message from mailgun-api
|
||||
$mailgun_domain = $company->settings?->email_sending_method === 'client_mailgun' && $company->settings?->mailgun_domain ? $company->settings?->mailgun_domain : config('services.mailgun.domain');
|
||||
$mailgun_secret = $company->settings?->email_sending_method === 'client_mailgun' && $company->settings?->mailgun_secret ? $company->settings?->mailgun_secret : config('services.mailgun.secret');
|
||||
$credentials = $mailgun_domain . ":" . $mailgun_secret . "@";
|
||||
$messageUrl = explode("|", $this->input)[1];
|
||||
$messageUrl = str_replace("http://", "http://" . $credentials, $messageUrl);
|
||||
$messageUrl = str_replace("https://", "https://" . $credentials, $messageUrl);
|
||||
$mail = json_decode(file_get_contents($messageUrl));
|
||||
|
||||
// prepare data for ingresEngine
|
||||
$ingresEmail = new IngresEmail();
|
||||
|
||||
$ingresEmail->from = $mail->sender;
|
||||
$ingresEmail->to = $recipient; // usage of data-input, because we need a single email here
|
||||
$ingresEmail->subject = $mail->Subject;
|
||||
$ingresEmail->body = $mail->{"body-html"};
|
||||
$ingresEmail->text_body = $mail->{"body-plain"};
|
||||
$ingresEmail->date = Carbon::createFromTimeString($mail->Date);
|
||||
|
||||
// parse documents as UploadedFile from webhook-data
|
||||
foreach ($mail->attachments as $attachment) {
|
||||
|
||||
// prepare url with credentials before downloading :: https://github.com/mailgun/mailgun.js/issues/24
|
||||
$url = $attachment->url;
|
||||
$url = str_replace("http://", "http://" . $credentials, $url);
|
||||
$url = str_replace("https://", "https://" . $credentials, $url);
|
||||
|
||||
// download file and save to tmp dir
|
||||
$ingresEmail->documents[] = TempFile::UploadedFileFromUrl($url, $attachment->name, $attachment->{"content-type"});
|
||||
|
||||
}
|
||||
|
||||
// perform
|
||||
(new IngresEmailEngine($ingresMail))->handle();
|
||||
(new IngresEmailEngine($ingresEmail))->handle();
|
||||
}
|
||||
}
|
||||
|
@ -182,8 +182,6 @@ class IngresEmailEngine
|
||||
|
||||
$expense->saveQuietly();
|
||||
|
||||
Log::info(json_encode($documents));
|
||||
|
||||
$this->saveDocuments($documents, $expense);
|
||||
|
||||
event(new ExpenseWasCreated($expense, $expense->company, Ninja::eventVars(null))); // @turbo124 please check, I copied from API-Controller
|
||||
|
Loading…
x
Reference in New Issue
Block a user