2023-12-14 16:40:43 +01:00
< ? 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
*/
2024-03-18 08:04:54 +01:00
namespace App\Jobs\Mailgun ;
2023-12-14 16:40:43 +01:00
use App\Libraries\MultiDB ;
2024-03-19 12:56:39 +01:00
use App\Services\IngresEmail\IngresEmail ;
2024-03-18 08:04:54 +01:00
use App\Services\IngresEmail\IngresEmailEngine ;
2024-03-19 12:56:39 +01:00
use App\Utils\TempFile ;
use Illuminate\Support\Carbon ;
2023-12-14 16:40:43 +01:00
use Illuminate\Bus\Queueable ;
use Illuminate\Contracts\Queue\ShouldQueue ;
use Illuminate\Foundation\Bus\Dispatchable ;
use Illuminate\Queue\InteractsWithQueue ;
use Illuminate\Queue\SerializesModels ;
2024-03-18 08:04:54 +01:00
use Log ;
2023-12-14 16:40:43 +01:00
class ProcessMailgunInboundWebhook implements ShouldQueue
{
use Dispatchable , InteractsWithQueue , Queueable , SerializesModels ;
public $tries = 1 ;
/**
* Create a new job instance .
2024-03-19 12:56:39 +01:00
* $input consists of 2 informations : recipient | messageUrl
2023-12-14 16:40:43 +01:00
*/
2024-03-19 12:56:39 +01:00
public function __construct ( private string $input )
2023-12-14 16:40:43 +01:00
{
}
/**
* Execute the job .
*
2024-03-19 13:02:51 +01:00
* Mail from Storage
* {
* " Content-Type " : " multipart/related; boundary= \" 00000000000022bfbe0613e8b7f5 \" " ,
* " Date " : " Mon, 18 Mar 2024 06:34:09 +0100 " ,
* " Dkim-Signature " : " v=1; a=rsa-sha256; c=relaxed/relaxed; d=wer-ner.de; s=google; t=1710740086; x=1711344886; darn=domain.example; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=tkxC+ZzDSJJXLVgjDyvQZyDt6wkWKFHS50z4ZWiWT9U=; b=P1Sz54Djj1LHtPF7+cAKGRaN4IRjUT3bOyYAD/kbC0Tx2yNejPrjCPy3+a6R6MShgJ odYhoLRqylPPs1DQolNO6xgamsoEiR8jnII4QjJUBut4VirMlSO+RLxzpO7pt/Hr6j93 z0G1Yffpbz44l5GhndgXsa4Hf30Q8yy0p7fqMNABB/smscj7DJDu1os2cB1JazKYsmAE X4HtU5IgCOS++xbQPqZSNwjrFWlbgal2t2yAeTKAMdGX/nNKtfgZ5imqNwJWerpAYwgk 3qvUcgTw2MpeghcPpTiflPGp4fT/f1kUjes0dcqrvkE+6oTPvo0pi76QNoVs7peWKr/c JvaA== " ,
* " From " : " Paul Werner <test@sender.example> " ,
* " In-Reply-To " : " <CADfEuNuk6m=RUmo+R4K65Rfskox_LOTT+pnBwTnmA_gPaf1eUQ@mail.gmail.com> " ,
* " Message-Id " : " <CADfEuNu6nBJYqNSJ-suey3a0FazJELYkNSO5JUGiiGs9hsFvGg@mail.gmail.com> " ,
* " Mime-Version " : " 1.0 " ,
* " Received " : " by mail-lj1-f175.google.com with SMTP id 38308e7fff4ca-2d4a901e284so12524521fa.1 for <test@domain.example>; Sun, 17 Mar 2024 22:34:47 -0700 (PDT) " ,
* " References " : " <CADfEuNvN_DcTU99WY-7332iPmPuYW-CfvJfirQ6YY30e3y-XeA@mail.gmail.com> <CADfEuNupjxUivY++FnD7b1SHdNY6YZCA9b4iVW6xNbmic=B6Zw@mail.gmail.com> <CADfEuNuk6m=RUmo+R4K65Rfskox_LOTT+pnBwTnmA_gPaf1eUQ@mail.gmail.com> " ,
* " Subject " : " Fwd: TEST " ,
* " To " : " test@domain.example " ,
* " X-Envelope-From " : " test@sender.example " ,
* " X-Gm-Message-State " : " AOJu0Yy6rgBIPLGjnD293mVB5vBWQIraVAOnfa/GtyM6S/JIqe4rHbrx OqRe7oFFyCDyCjL/+2AFFkB9ljxgt7MWvpdec69dEn3BNQMlxuyGkpyxZUY8PDm4XRCyIy4vGxK 6Oddl7nWV5DM4zN4eLvZH+DPteyUq9A9ET9bowZnCrP8ZcQOP5js= " ,
* " X-Google-Dkim-Signature " : " v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710740086; x=1711344886; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=tkxC+ZzDSJJXLVgjDyvQZyDt6wkWKFHS50z4ZWiWT9U=; b=cyDJAeNEaU2CvWAX/d9E3LMDrceXyLe01lbsYvwY6ZNTchr/0vzrxQFTVxos2DQR7u jSKpaNqI958H1oZJY36XZV0+8MY2w6DjB1F3FUHbD1q5gxJUitXNuOvvpna/q0ZaqlQf 5n3kIkakV19uxu4pcrcLxO67744pBzEmVk+IJtI9FEoZy9253v09CfkzNZo68u2VxJVD TDFVVkZuIO5xi3flUVoD3CP0Bw/0BqpDuxVvOFy+qOaItTZ5Na+OPfUJcFG2j6T0rXFQ 1vXPxodqjllLwc/V+O1TmS46H/RhsHGAae5tWk+51KX8T2ZgTkfwKPV1YeSRl0QtDhYS gU0Q== " ,
* " X-Google-Smtp-Source " : " AGHT+IFspt+3tKf94kXs48nOb58GzuV+pJ8oE3ZNwEcx6PG53wJeW858lyh2PiYIzSEPQTY2ykatvu2fqs8Bj+9d5rw= " ,
* " X-Mailgun-Incoming " : " Yes " ,
* " X-Received " : " by 2002:a2e:9847:0:b0:2d4:7455:89f6 with SMTP id e7-20020a2e9847000000b002d4745589f6mr4283454ljj.40.1710740086045; Sun, 17 Mar 2024 22:34:46 -0700 (PDT) " ,
* " sender " : " test@sender.example " ,
* " recipients " : " test@domain.example " ,
* " from " : " Paul Werner <test@sender.example> " ,
* " subject " : " Fwd: TEST " ,
* " body-html " : " <div dir= \" ltr \" >TESTAGAIN<img src= \" cid:ii_ltwigc770 \" alt= \" Unbenannt.png \" width= \" 562 \" height= \" 408 \" ><br><br><div class= \" gmail_quote \" ><div dir= \" ltr \" class= \" gmail_attr \" >---------- Forwarded message ---------<br>Von: <strong class= \" gmail_sendername \" dir= \" auto \" >Paul Werner</strong> <span dir= \" auto \" ><<a href= \" mailto:test@sender.example \" >test@sender.example</a>></span><br>Date: Mo., 18. März 2024 um 06:30 Uhr<br>Subject: Fwd: TEST<br>To: <<a href= \" mailto:test@domain.example \" >test@domain.example</a>><br></div><br><br><div dir= \" ltr \" >Hallöööö<br><br><div class= \" gmail_quote \" ><div dir= \" ltr \" class= \" gmail_attr \" >---------- Forwarded message ---------<br>Von: <strong class= \" gmail_sendername \" dir= \" auto \" >Paul Werner</strong> <span dir= \" auto \" ><<a href= \" mailto:test@sender.example \" target= \" _blank \" >test@sender.example</a>></span><br>Date: Mo., 18. März 2024 um 06:23 Uhr<br>Subject: Fwd: TEST<br>To: <<a href= \" mailto:test@domain.example \" target= \" _blank \" >test@domain.example</a>><br></div><br><br><div dir= \" ltr \" >asjkdahwdaiohdawdawdawwwww!!!<br><br><div class= \" gmail_quote \" ><div dir= \" ltr \" class= \" gmail_attr \" >---------- Forwarded message ---------<br>Von: <strong class= \" gmail_sendername \" dir= \" auto \" >Paul Werner</strong> <span dir= \" auto \" ><<a href= \" mailto:test@sender.example \" target= \" _blank \" >test@sender.example</a>></span><br>Date: Mo., 18. März 2024 um 06:22 Uhr<br>Subject: TEST<br>To: <<a href= \" mailto:test@domain.example \" target= \" _blank \" >test@domain.example</a>><br></div><br><br><div dir= \" ltr \" >TEST</div> \r \n </div></div> \r \n </div></div> \r \n </div></div> \r \n " ,
* " body-plain " : " TESTAGAIN[image: Unbenannt.png] \r \n \r \n ---------- Forwarded message --------- \r \n Von: Paul Werner <test@sender.example> \r \n Date: Mo., 18. März 2024 um 06:30 Uhr \r \n Subject: Fwd: TEST \r \n To: <test@domain.example> \r \n \r \n \r \n Hallöööö \r \n \r \n ---------- Forwarded message --------- \r \n Von: Paul Werner <test@sender.example> \r \n Date: Mo., 18. März 2024 um 06:23 Uhr \r \n Subject: Fwd: TEST \r \n To: <test@domain.example> \r \n \r \n \r \n asjkdahwdaiohdawdawdawwwww!!! \r \n \r \n ---------- Forwarded message --------- \r \n Von: Paul Werner <test@sender.example> \r \n Date: Mo., 18. März 2024 um 06:22 Uhr \r \n Subject: TEST \r \n To: <test@domain.example> \r \n \r \n \r \n TEST \r \n " ,
* " attachments " : [
* {
* " name " : " Unbenannt.png " ,
* " content-type " : " image/png " ,
* " size " : 197753 ,
* " url " : " https://storage-europe-west1.api.mailgun.net/v3/domains/domain.example/messages/BAAFAgVMamdcBboOIOtFyJ5B5NGEkkffYQ/attachments/0 "
* }
* ],
* " content-id-map " : {
* " <ii_ltwigc770> " : {
* " name " : " Unbenannt.png " ,
* " content-type " : " image/png " ,
* " size " : 197753 ,
* " url " : " https://storage-europe-west1.api.mailgun.net/v3/domains/domain.example/messages/BAAFAgVMamdcBboOIOtFyJ5B5NGEkkffYQ/attachments/0 "
* }
* },
* " message-headers " : [
* [
* " Received " ,
* " from mail-lj1-f175.google.com (mail-lj1-f175.google.com [209.85.208.175]) by 634f26f73cf3 with SMTP id <undefined> (version=TLS1.3, cipher=TLS_AES_128_GCM_SHA256); Mon, 18 Mar 2024 05:34:47 GMT "
* ],
* [
* " Received " ,
* " by mail-lj1-f175.google.com with SMTP id 38308e7fff4ca-2d4a901e284so12524521fa.1 for <test@domain.example>; Sun, 17 Mar 2024 22:34:47 -0700 (PDT) "
* ],
* [
* " X-Envelope-From " ,
* " test@sender.example "
* ],
* [
* " X-Mailgun-Incoming " ,
* " Yes "
* ],
* [
* " Dkim-Signature " ,
* " v=1; a=rsa-sha256; c=relaxed/relaxed; d=wer-ner.de; s=google; t=1710740086; x=1711344886; darn=domain.example; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :from:to:cc:subject:date:message-id:reply-to; bh=tkxC+ZzDSJJXLVgjDyvQZyDt6wkWKFHS50z4ZWiWT9U=; b=P1Sz54Djj1LHtPF7+cAKGRaN4IRjUT3bOyYAD/kbC0Tx2yNejPrjCPy3+a6R6MShgJ odYhoLRqylPPs1DQolNO6xgamsoEiR8jnII4QjJUBut4VirMlSO+RLxzpO7pt/Hr6j93 z0G1Yffpbz44l5GhndgXsa4Hf30Q8yy0p7fqMNABB/smscj7DJDu1os2cB1JazKYsmAE X4HtU5IgCOS++xbQPqZSNwjrFWlbgal2t2yAeTKAMdGX/nNKtfgZ5imqNwJWerpAYwgk 3qvUcgTw2MpeghcPpTiflPGp4fT/f1kUjes0dcqrvkE+6oTPvo0pi76QNoVs7peWKr/c JvaA== "
* ],
* [
* " X-Google-Dkim-Signature " ,
* " v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1710740086; x=1711344886; h=to:subject:message-id:date:from:in-reply-to:references:mime-version :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=tkxC+ZzDSJJXLVgjDyvQZyDt6wkWKFHS50z4ZWiWT9U=; b=cyDJAeNEaU2CvWAX/d9E3LMDrceXyLe01lbsYvwY6ZNTchr/0vzrxQFTVxos2DQR7u jSKpaNqI958H1oZJY36XZV0+8MY2w6DjB1F3FUHbD1q5gxJUitXNuOvvpna/q0ZaqlQf 5n3kIkakV19uxu4pcrcLxO67744pBzEmVk+IJtI9FEoZy9253v09CfkzNZo68u2VxJVD TDFVVkZuIO5xi3flUVoD3CP0Bw/0BqpDuxVvOFy+qOaItTZ5Na+OPfUJcFG2j6T0rXFQ 1vXPxodqjllLwc/V+O1TmS46H/RhsHGAae5tWk+51KX8T2ZgTkfwKPV1YeSRl0QtDhYS gU0Q== "
* ],
* [
* " X-Gm-Message-State " ,
* " AOJu0Yy6rgBIPLGjnD293mVB5vBWQIraVAOnfa/GtyM6S/JIqe4rHbrx OqRe7oFFyCDyCjL/+2AFFkB9ljxgt7MWvpdec69dEn3BNQMlxuyGkpyxZUY8PDm4XRCyIy4vGxK 6Oddl7nWV5DM4zN4eLvZH+DPteyUq9A9ET9bowZnCrP8ZcQOP5js= "
* ],
* [
* " X-Google-Smtp-Source " ,
* " AGHT+IFspt+3tKf94kXs48nOb58GzuV+pJ8oE3ZNwEcx6PG53wJeW858lyh2PiYIzSEPQTY2ykatvu2fqs8Bj+9d5rw= "
* ],
* [
* " X-Received " ,
* " by 2002:a2e:9847:0:b0:2d4:7455:89f6 with SMTP id e7-20020a2e9847000000b002d4745589f6mr4283454ljj.40.1710740086045; Sun, 17 Mar 2024 22:34:46 -0700 (PDT) "
* ],
* [
* " Mime-Version " ,
* " 1.0 "
* ],
* [
* " References " ,
* " <CADfEuNvN_DcTU99WY-7332iPmPuYW-CfvJfirQ6YY30e3y-XeA@mail.gmail.com> <CADfEuNupjxUivY++FnD7b1SHdNY6YZCA9b4iVW6xNbmic=B6Zw@mail.gmail.com> <CADfEuNuk6m=RUmo+R4K65Rfskox_LOTT+pnBwTnmA_gPaf1eUQ@mail.gmail.com> "
* ],
* [
* " In-Reply-To " ,
* " <CADfEuNuk6m=RUmo+R4K65Rfskox_LOTT+pnBwTnmA_gPaf1eUQ@mail.gmail.com> "
* ],
* [
* " From " ,
* " Paul Werner <test@sender.example> "
* ],
* [
* " Date " ,
* " Mon, 18 Mar 2024 06:34:09 +0100 "
* ],
* [
* " Message-Id " ,
* " <CADfEuNu6nBJYqNSJ-suey3a0FazJELYkNSO5JUGiiGs9hsFvGg@mail.gmail.com> "
* ],
* [
* " Subject " ,
* " Fwd: TEST "
* ],
* [
* " To " ,
* " test@domain.example "
* ],
* [
* " Content-Type " ,
* " multipart/related; boundary= \" 00000000000022bfbe0613e8b7f5 \" "
* ]
* ],
* " stripped-html " : " <html><head></head><body><div dir= \" ltr \" >TESTAGAIN<img src= \" cid:ii_ltwigc770 \" alt= \" Unbenannt.png \" width= \" 562 \" height= \" 408 \" ><br><br></div> \n </body></html> " ,
* " stripped-text " : " TESTAGAIN[image: Unbenannt.png] \r \n \r \n ---------- Forwarded message --------- \r \n Von: Paul Werner <test@sender.example> \r \n Date: Mo., 18. März 2024 um 06:30 Uhr \r \n Subject: Fwd: TEST \r \n To: <test@domain.example> \r \n \r \n \r \n Hallöööö \r \n \r \n ---------- Forwarded message --------- \r \n Von: Paul Werner <test@sender.example> \r \n Date: Mo., 18. März 2024 um 06:23 Uhr \r \n Subject: Fwd: TEST \r \n To: <test@domain.example> \r \n \r \n \r \n asjkdahwdaiohdawdawdawwwww!!! \r \n \r \n ---------- Forwarded message --------- \r \n Von: Paul Werner <test@sender.example> \r \n Date: Mo., 18. März 2024 um 06:22 Uhr \r \n Subject: TEST \r \n To: <test@domain.example> \r \n \r \n \r \n TEST " ,
* " stripped-signature " : " "
* }
2023-12-14 16:40:43 +01:00
* @ return void
*/
public function handle ()
{
2024-03-19 12:56:39 +01:00
$recipient = explode ( " | " , $this -> input )[ 0 ];
2023-12-14 16:40:43 +01:00
2024-03-19 13:05:12 +01:00
// match company
2024-03-19 12:56:39 +01:00
$company = MultiDB :: findAndSetDbByExpenseMailbox ( $recipient );
2024-03-18 08:04:54 +01:00
if ( ! $company ) {
2024-03-24 12:51:24 +01:00
Log :: info ( '[ProcessMailgunInboundWebhook] unknown Expense Mailbox occured while handling an inbound email from mailgun: ' . $recipient );
2024-03-18 08:04:54 +01:00
return ;
}
2023-12-14 16:40:43 +01:00
2024-03-19 13:05:12 +01:00
// fetch message from mailgun-api
2024-03-24 10:53:20 +01:00
$company_mailgun_domain = $company -> settings ? -> email_sending_method === 'client_mailgun' && $company -> settings ? -> mailgun_domain ? $company -> settings ? -> mailgun_domain : null ;
$company_mailgun_secret = $company -> settings ? -> email_sending_method === 'client_mailgun' && $company -> settings ? -> mailgun_secret ? $company -> settings ? -> mailgun_secret : null ;
if ( ! ( $company_mailgun_domain && $company_mailgun_secret ) && ! ( config ( 'services.mailgun.domain' ) && config ( 'services.mailgun.secret' )))
2024-03-24 12:51:24 +01:00
throw new \Error ( " [ProcessMailgunInboundWebhook] no mailgun credenitals found, we cannot get the attachements and files " );
2024-03-24 10:53:20 +01:00
$mail = null ;
if ( $company_mailgun_domain && $company_mailgun_secret ) {
$credentials = $company_mailgun_domain . " : " . $company_mailgun_secret . " @ " ;
$messageUrl = explode ( " | " , $this -> input )[ 1 ];
$messageUrl = str_replace ( " http:// " , " http:// " . $credentials , $messageUrl );
$messageUrl = str_replace ( " https:// " , " https:// " . $credentials , $messageUrl );
try {
$mail = json_decode ( file_get_contents ( $messageUrl ));
} catch ( \Error $e ) {
if ( config ( 'services.mailgun.secret' )) {
2024-03-24 12:51:24 +01:00
Log :: info ( " [ProcessMailgunInboundWebhook] Error while downloading with company credentials, we try to use default credentials now... " );
2024-03-24 10:53:20 +01:00
$credentials = config ( 'services.mailgun.domain' ) . " : " . config ( 'services.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 ));
} else
throw $e ;
}
} else {
$credentials = config ( 'services.mailgun.domain' ) . " : " . config ( 'services.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 ));
}
2024-03-19 12:56:39 +01:00
2024-03-19 13:05:12 +01:00
// prepare data for ingresEngine
2024-03-19 12:56:39 +01:00
$ingresEmail = new IngresEmail ();
$ingresEmail -> from = $mail -> sender ;
2024-03-19 13:05:12 +01:00
$ingresEmail -> to = $recipient ; // usage of data-input, because we need a single email here
2024-03-19 12:56:39 +01:00
$ingresEmail -> subject = $mail -> Subject ;
$ingresEmail -> body = $mail -> { " body-html " };
$ingresEmail -> text_body = $mail -> { " body-plain " };
$ingresEmail -> date = Carbon :: createFromTimeString ( $mail -> Date );
2024-03-19 13:05:12 +01:00
// parse documents as UploadedFile from webhook-data
2024-03-24 10:53:20 +01:00
foreach ( $mail -> attachments as $attachment ) { // prepare url with credentials before downloading :: https://github.com/mailgun/mailgun.js/issues/24
2024-03-19 12:56:39 +01:00
2024-03-19 13:05:12 +01:00
// download file and save to tmp dir
2024-03-24 10:53:20 +01:00
if ( $company_mailgun_domain && $company_mailgun_secret ) {
try {
$credentials = $company_mailgun_domain . " : " . $company_mailgun_secret . " @ " ;
$url = $attachment -> url ;
$url = str_replace ( " http:// " , " http:// " . $credentials , $url );
$url = str_replace ( " https:// " , " https:// " . $credentials , $url );
$ingresEmail -> documents [] = TempFile :: UploadedFileFromUrl ( $url , $attachment -> name , $attachment -> { " content-type " });
} catch ( \Error $e ) {
if ( config ( 'services.mailgun.secret' )) {
2024-03-24 12:51:24 +01:00
Log :: info ( " [ProcessMailgunInboundWebhook] Error while downloading with company credentials, we try to use default credentials now... " );
2024-03-24 10:53:20 +01:00
$credentials = config ( 'services.mailgun.domain' ) . " : " . config ( 'services.mailgun.secret' ) . " @ " ;
$url = $attachment -> url ;
$url = str_replace ( " http:// " , " http:// " . $credentials , $url );
$url = str_replace ( " https:// " , " https:// " . $credentials , $url );
$ingresEmail -> documents [] = TempFile :: UploadedFileFromUrl ( $url , $attachment -> name , $attachment -> { " content-type " });
} else
throw $e ;
}
} else {
$credentials = config ( 'services.mailgun.domain' ) . " : " . config ( 'services.mailgun.secret' ) . " @ " ;
$url = $attachment -> url ;
$url = str_replace ( " http:// " , " http:// " . $credentials , $url );
$url = str_replace ( " https:// " , " https:// " . $credentials , $url );
$ingresEmail -> documents [] = TempFile :: UploadedFileFromUrl ( $url , $attachment -> name , $attachment -> { " content-type " });
}
2024-03-19 12:56:39 +01:00
}
2023-12-14 16:40:43 +01:00
2024-03-19 13:05:12 +01:00
// perform
2024-03-19 12:56:39 +01:00
( new IngresEmailEngine ( $ingresEmail )) -> handle ();
2023-12-14 16:40:43 +01:00
}
}