update acc. to bounces
This commit is contained in:
parent
6df8674b72
commit
1d1a384d1b
|
|
@ -0,0 +1,137 @@
|
|||
{
|
||||
"version": "0",
|
||||
"id": "68eb43ad-3ad6-25ef-2b49-2389fc4460cc",
|
||||
"detail-type": "Email Bounced",
|
||||
"source": "aws.ses",
|
||||
"account": "339712845857",
|
||||
"time": "2025-12-19T02:24:37Z",
|
||||
"region": "us-east-2",
|
||||
"resources": [
|
||||
"arn:aws:ses:us-east-2:339712845857:configuration-set/relay-outbound"
|
||||
],
|
||||
"detail": {
|
||||
"eventType": "Bounce",
|
||||
"bounce": {
|
||||
"feedbackId": "010f019b346c64dc-ebd1959f-ac85-4d28-b2c2-e2db414889d2-000000",
|
||||
"bounceType": "Permanent",
|
||||
"bounceSubType": "General",
|
||||
"bouncedRecipients": [
|
||||
{
|
||||
"emailAddress": "pishing@paypal.com",
|
||||
"action": "failed",
|
||||
"status": "5.0.0",
|
||||
"diagnosticCode": "smtp; 5.1.0 - Unknown address error 550-'5.4.1 Recipient address rejected: Access denied. For more information see https: //aka.ms/EXOSmtpErrors [DS2PEPF00003441.namprd04.prod.outlook.com 2025-12-19T02:24:36.588Z 08DE3C04B3813774] (delivery attempts: 0)"
|
||||
}
|
||||
],
|
||||
"timestamp": "2025-12-19T02:24:37.521Z",
|
||||
"reportingMTA": "dns; mx2.paypalcorp.com"
|
||||
},
|
||||
"mail": {
|
||||
"timestamp": "2025-12-19T02:24:34.082Z",
|
||||
"source": "andreas.knuth@bayarea-cc.com",
|
||||
"sourceArn": "arn:aws:ses:us-east-2:339712845857:identity/bayarea-cc.com",
|
||||
"sendingAccountId": "339712845857",
|
||||
"messageId": "010f019b346c5722-7f94b168-0d66-444c-8333-99f80801ee6e-000000",
|
||||
"destination": [
|
||||
"pishing@paypal.com"
|
||||
],
|
||||
"headersTruncated": False,
|
||||
"headers": [
|
||||
{
|
||||
"name": "Received",
|
||||
"value": "from mail.email-srvr.com (mail.email-srvr.com [2.56.188.138]) by email-smtp.amazonaws.com with SMTP (SimpleEmailService-d-4T8YRF3HF) id JWwKWtbMKwPcuMJWmawg for pishing@paypal.com; Fri, 19 Dec 2025 02:24:34 +0000 (UTC)"
|
||||
},
|
||||
{
|
||||
"name": "DKIM-Signature",
|
||||
"value": "v=1; a=rsa-sha256; c=relaxed/simple; d=bayarea-cc.com; s=mail; t=1766111073; bh=489KasDOSypdn6kagJw8c/vBfll20acGANR7WEnsNq8=; h=From:To:Subject:Reply-To:In-Reply-To:References; b=axFSO5cJaEy+bSCreaVfYY8ThHUvEAJmiVV26Qpw2sZG4YFoYglcNry2Gv2B+99ctJwcTAlxa/XzB0mJzzSpyU7WU0D03Kw/4k+8Mdl0mu+Li8icoINPJ0v5Kap2hVMRVp+ge6w7wAZR+rS46oAvL++piRZYr+85FGiHpFtJIK8e4a06sXtkHB4kDDNTDzKiTM7tTH6/oD4LV3LxeL29notQih5atTUOSo5LHN1QNp5Hq05A4sih7rM6J7CNKIouvqm1ku8I2+xUsgNu0neWnddBDV8njD24Gc70Flab22q5GDqVQ0caql7odpMlrCQjdmAgyEmeVP+JWjB3EnZ3DQ=="
|
||||
},
|
||||
{
|
||||
"name": "Received",
|
||||
"value": "from app.email-bayarea.com (roundcube-new.mail_network [172.18.0.5]) (Authenticated sender: andreas.knuth@bayarea-cc.com) by mail.email-srvr.com (Postfix) with ESMTPSA id 6CD2F2E60092 for <pishing@paypal.com>; Thu, 18 Dec 2025 20:24:33 -0600 (CST)"
|
||||
},
|
||||
{
|
||||
"name": "MIME-Version",
|
||||
"value": "1.0"
|
||||
},
|
||||
{
|
||||
"name": "Date",
|
||||
"value": "Thu, 18 Dec 2025 20:24:33 -0600"
|
||||
},
|
||||
{
|
||||
"name": "From",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "To",
|
||||
"value": "pishing@paypal.com"
|
||||
},
|
||||
{
|
||||
"name": "Subject",
|
||||
"value": "Fwd: A one-time merchant setup fee of $249.99 has been applied and will appear on your bank statement wit"
|
||||
},
|
||||
{
|
||||
"name": "Reply-To",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "Mail-Reply-To",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "In-Reply-To",
|
||||
"value": "<6061d865685c1bb406c127f32451d22d@bayarea-cc.com>"
|
||||
},
|
||||
{
|
||||
"name": "References",
|
||||
"value": "<boLgON9OSkmzVWOPwCp8qQ@geopod-ismtpd-45> <6061d865685c1bb406c127f32451d22d@bayarea-cc.com>"
|
||||
},
|
||||
{
|
||||
"name": "Message-ID",
|
||||
"value": "<bf937f16310bd1be5350425b2dfc3d65@bayarea-cc.com>"
|
||||
},
|
||||
{
|
||||
"name": "X-Sender",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "multipart/alternative; boundary='=_d6bdf41daf974c2c1b77e9250e4348a7'"
|
||||
}
|
||||
],
|
||||
"commonHeaders": {
|
||||
"from": [
|
||||
"andreas.knuth@bayarea-cc.com"
|
||||
],
|
||||
"replyTo": [
|
||||
"andreas.knuth@bayarea-cc.com"
|
||||
],
|
||||
"date": "Thu, 18 Dec 2025 20:24:33 -0600",
|
||||
"to": [
|
||||
"pishing@paypal.com"
|
||||
],
|
||||
"messageId": "010f019b346c5722-7f94b168-0d66-444c-8333-99f80801ee6e-000000",
|
||||
"subject": "Fwd: A one-time merchant setup fee of $249.99 has been applied and will appear on your bank statement wit"
|
||||
},
|
||||
"tags": {
|
||||
"ses:source-tls-version": [
|
||||
"TLSv1.3"
|
||||
],
|
||||
"ses:operation": [
|
||||
"SendSmtpEmail"
|
||||
],
|
||||
"ses:configuration-set": [
|
||||
"relay-outbound"
|
||||
],
|
||||
"ses:source-ip": [
|
||||
"2.56.188.138"
|
||||
],
|
||||
"ses:from-domain": [
|
||||
"bayarea-cc.com"
|
||||
],
|
||||
"ses:caller-identity": [
|
||||
"bizmatch.net"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
{
|
||||
"version": "0",
|
||||
"id": "b1198c79-d4df-6d77-a472-12c05eb99a39",
|
||||
"detail-type": "Email Bounced",
|
||||
"source": "aws.ses",
|
||||
"account": "339712845857",
|
||||
"time": "2025-12-19T01:59:01Z",
|
||||
"region": "us-east-2",
|
||||
"resources": [
|
||||
"arn:aws:ses:us-east-2:339712845857:configuration-set/relay-outbound"
|
||||
],
|
||||
"detail": {
|
||||
"eventType": "Bounce",
|
||||
"bounce": {
|
||||
"feedbackId": "010f019b3454f3b9-6b92ce4e-e1f2-420b-8dd3-e48e062f0f88-000000",
|
||||
"bounceType": "Transient",
|
||||
"bounceSubType": "General",
|
||||
"bouncedRecipients": [
|
||||
{
|
||||
"emailAddress": "frankie@iitwelders.com"
|
||||
}
|
||||
],
|
||||
"timestamp": "2025-12-19T01:59:01.245Z"
|
||||
},
|
||||
"mail": {
|
||||
"timestamp": "2025-12-19T01:58:58.255Z",
|
||||
"source": "andreas.knuth@bayarea-cc.com",
|
||||
"sourceArn": "arn:aws:ses:us-east-2:339712845857:identity/bayarea-cc.com",
|
||||
"sendingAccountId": "339712845857",
|
||||
"messageId": "010f019b3454e7cf-36b8560d-7880-4913-9e5d-dd87f336b0dd-000000",
|
||||
"destination": [
|
||||
"frankie@iitwelders.com"
|
||||
],
|
||||
"headersTruncated": False,
|
||||
"headers": [
|
||||
{
|
||||
"name": "Received",
|
||||
"value": "from mail.email-srvr.com (mail.email-srvr.com [2.56.188.138]) by email-smtp.amazonaws.com with SMTP (SimpleEmailService-d-Z6YSX0FGF) id d7Quc01fG0CsS9eS7yfX for frankie@iitwelders.com; Fri, 19 Dec 2025 01:58:58 +0000 (UTC)"
|
||||
},
|
||||
{
|
||||
"name": "DKIM-Signature",
|
||||
"value": "v=1; a=rsa-sha256; c=relaxed/simple; d=bayarea-cc.com; s=mail; t=1766109537; bh=S/AVMjQHFbdT0GdJ56RlBKNMvace1V8iv+n0iBHTPYQ=; h=From:To:Subject:Reply-To; b=CX4lHSxen4aqQ5+3mlfl51hmyoK3mkP3gVu9mfILqPaxafH8aXNYfUYBxpRct9sQHNuN2OhgUfdjrTM/75WnKrV50wo13HeKw3D2b3d/N3zj447KG2eAGycm/guNibrcjhduLDERGVwMFaeWAAKHbbWfWnAw68yEFKkcnTCNB1imyAn9diDew5zO9q2ZuA0fOm3YXZ7qFmVtmmX4z6la0Rfa39gEM6wBiOhpZTtODyTqkmABFolVTEqc1VqYH27jB8ZVHi1bO4M42VGoRcDzvjOfkxq5ad/UQeho7HOsLuWnVG7H3BarTom/TdZYMrt2ZllH5N+nf2ec90/lH20CxA=="
|
||||
},
|
||||
{
|
||||
"name": "Received",
|
||||
"value": "from app.email-bayarea.com (roundcube-new.mail_network [172.18.0.5]) (Authenticated sender: andreas.knuth@bayarea-cc.com) by mail.email-srvr.com (Postfix) with ESMTPSA id EC1B02E5FD51 for <frankie@iitwelders.com>; Thu, 18 Dec 2025 19:58:56 -0600 (CST)"
|
||||
},
|
||||
{
|
||||
"name": "MIME-Version",
|
||||
"value": "1.0"
|
||||
},
|
||||
{
|
||||
"name": "Date",
|
||||
"value": "Thu, 18 Dec 2025 19:58:56 -0600"
|
||||
},
|
||||
{
|
||||
"name": "From",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "To",
|
||||
"value": "Frankie <frankie@iitwelders.com>"
|
||||
},
|
||||
{
|
||||
"name": "Subject",
|
||||
"value": "12/18/25 7:58"
|
||||
},
|
||||
{
|
||||
"name": "Reply-To",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "Mail-Reply-To",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "Message-ID",
|
||||
"value": "<17a781e80ecae12285697c536cc46033@bayarea-cc.com>"
|
||||
},
|
||||
{
|
||||
"name": "X-Sender",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "multipart/alternative; boundary='=_46eb06b0a62a2efa142c40c5eadbbc54'"
|
||||
}
|
||||
],
|
||||
"commonHeaders": {
|
||||
"from": [
|
||||
"andreas.knuth@bayarea-cc.com"
|
||||
],
|
||||
"replyTo": [
|
||||
"andreas.knuth@bayarea-cc.com"
|
||||
],
|
||||
"date": "Thu, 18 Dec 2025 19:58:56 -0600",
|
||||
"to": [
|
||||
"Frankie <frankie@iitwelders.com>"
|
||||
],
|
||||
"messageId": "010f019b3454e7cf-36b8560d-7880-4913-9e5d-dd87f336b0dd-000000",
|
||||
"subject": "12/18/25 7:58"
|
||||
},
|
||||
"tags": {
|
||||
"ses:source-tls-version": [
|
||||
"TLSv1.3"
|
||||
],
|
||||
"ses:operation": [
|
||||
"SendSmtpEmail"
|
||||
],
|
||||
"ses:configuration-set": [
|
||||
"relay-outbound"
|
||||
],
|
||||
"ses:source-ip": [
|
||||
"2.56.188.138"
|
||||
],
|
||||
"ses:from-domain": [
|
||||
"bayarea-cc.com"
|
||||
],
|
||||
"ses:caller-identity": [
|
||||
"bizmatch.net"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
{
|
||||
"version": "0",
|
||||
"id": "4d37ae3d-e411-2b83-8a83-6489a5fa1a00",
|
||||
"detail-type": "Email Bounced",
|
||||
"source": "aws.ses",
|
||||
"account": "339712845857",
|
||||
"time": "2025-12-19T02:10:33Z",
|
||||
"region": "us-east-2",
|
||||
"resources": [
|
||||
"arn:aws:ses:us-east-2:339712845857:configuration-set/relay-outbound"
|
||||
],
|
||||
"detail": {
|
||||
"eventType": "Bounce",
|
||||
"bounce": {
|
||||
"feedbackId": "010f019b345f8461-3382d3a0-42bb-4861-977f-e62606a24cb7-000000",
|
||||
"bounceType": "Transient",
|
||||
"bounceSubType": "General",
|
||||
"bouncedRecipients": [
|
||||
{
|
||||
"emailAddress": "remote@gregknoppcpa.com"
|
||||
}
|
||||
],
|
||||
"timestamp": "2025-12-19T02:10:33.636Z"
|
||||
},
|
||||
"mail": {
|
||||
"timestamp": "2025-12-19T02:10:32.560Z",
|
||||
"source": "andreas.knuth@bayarea-cc.com",
|
||||
"sourceArn": "arn:aws:ses:us-east-2:339712845857:identity/bayarea-cc.com",
|
||||
"sendingAccountId": "339712845857",
|
||||
"messageId": "010f019b345f7ff0-e22c2d38-c499-48ed-8992-abbf1c44b6a1-000000",
|
||||
"destination": [
|
||||
"remote@gregknoppcpa.com"
|
||||
],
|
||||
"headersTruncated": False,
|
||||
"headers": [
|
||||
{
|
||||
"name": "Received",
|
||||
"value": "from mail.email-srvr.com (mail.email-srvr.com [2.56.188.138]) by email-smtp.amazonaws.com with SMTP (SimpleEmailService-d-V0JPVCFGF) id 6KbS70pRiY9lOcyjIONV for remote@gregknoppcpa.com; Fri, 19 Dec 2025 02:10:32 +0000 (UTC)"
|
||||
},
|
||||
{
|
||||
"name": "DKIM-Signature",
|
||||
"value": "v=1; a=rsa-sha256; c=relaxed/simple; d=bayarea-cc.com; s=mail; t=1766110231; bh=sU5OepBQM0PVwu+hgNjl2gP+fBXM9lfNeDiFo9j+0BQ=; h=From:To:Subject:Reply-To; b=lK1PWF722nu9AuCE0SRq7VBVHBrznhyiozlM2kxSSVFVUNHtV4abBKHMPdzE0c6oYN4blSogNMi9/qJA4EKSpoegMHertvETZpHHTM51M083wtzodojc5ZPKoOZjLpjWOVf3oqomccwUxTwqNXmyEdQcUH/lYz52o+b6GFFb7X7MkxQfA0VXgIYL5v0rIKszOoLAour3lfx99uoJSwIIVLZi4f5LFWa+FB48bGH67FaojHRqQzeioMQyLwa9fSKMG/bifT1/jPSmCauRPMSxzsdDBvk0nuVitr8/RgAno8FqfBH+UWJIw8Wt3gVQDLNL82hi5qWUgsXKwY3LFo2LkA=="
|
||||
},
|
||||
{
|
||||
"name": "Received",
|
||||
"value": "from app.email-bayarea.com (roundcube-new.mail_network [172.18.0.5]) (Authenticated sender: andreas.knuth@bayarea-cc.com) by mail.email-srvr.com (Postfix) with ESMTPSA id D9D3F2E5FD51 for <remote@gregknoppcpa.com>; Thu, 18 Dec 2025 20:10:31 -0600 (CST)"
|
||||
},
|
||||
{
|
||||
"name": "MIME-Version",
|
||||
"value": "1.0"
|
||||
},
|
||||
{
|
||||
"name": "Date",
|
||||
"value": "Thu, 18 Dec 2025 20:10:31 -0600"
|
||||
},
|
||||
{
|
||||
"name": "From",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "To",
|
||||
"value": "remote@gregknoppcpa.com"
|
||||
},
|
||||
{
|
||||
"name": "Subject",
|
||||
"value": "testing out-of-office messages"
|
||||
},
|
||||
{
|
||||
"name": "Reply-To",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "Mail-Reply-To",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "Message-ID",
|
||||
"value": "<95264ff6f55b9cc3ffcd451d6b27f7f0@bayarea-cc.com>"
|
||||
},
|
||||
{
|
||||
"name": "X-Sender",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "multipart/alternative; boundary='=_7ffce281e198378b2420ed61fd6b9156'"
|
||||
}
|
||||
],
|
||||
"commonHeaders": {
|
||||
"from": [
|
||||
"andreas.knuth@bayarea-cc.com"
|
||||
],
|
||||
"replyTo": [
|
||||
"andreas.knuth@bayarea-cc.com"
|
||||
],
|
||||
"date": "Thu, 18 Dec 2025 20:10:31 -0600",
|
||||
"to": [
|
||||
"remote@gregknoppcpa.com"
|
||||
],
|
||||
"messageId": "010f019b345f7ff0-e22c2d38-c499-48ed-8992-abbf1c44b6a1-000000",
|
||||
"subject": "testing out-of-office messages"
|
||||
},
|
||||
"tags": {
|
||||
"ses:source-tls-version": [
|
||||
"TLSv1.3"
|
||||
],
|
||||
"ses:operation": [
|
||||
"SendSmtpEmail"
|
||||
],
|
||||
"ses:configuration-set": [
|
||||
"relay-outbound"
|
||||
],
|
||||
"ses:source-ip": [
|
||||
"2.56.188.138"
|
||||
],
|
||||
"ses:from-domain": [
|
||||
"bayarea-cc.com"
|
||||
],
|
||||
"ses:caller-identity": [
|
||||
"bizmatch.net"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,133 @@
|
|||
{
|
||||
"version": "0",
|
||||
"id": "ddfd563e-49f6-1f59-6d1e-c67158ab5eec",
|
||||
"detail-type": "Email Bounced",
|
||||
"source": "aws.ses",
|
||||
"account": "339712845857",
|
||||
"time": "2025-12-19T02:33:55Z",
|
||||
"region": "us-east-2",
|
||||
"resources": [
|
||||
"arn:aws:ses:us-east-2:339712845857:configuration-set/relay-outbound"
|
||||
],
|
||||
"detail": {
|
||||
"eventType": "Bounce",
|
||||
"bounce": {
|
||||
"feedbackId": "010f019b3474e821-12fa60c3-e47e-4289-a4b6-47ac55d996a2-000000",
|
||||
"bounceType": "Undetermined",
|
||||
"bounceSubType": "Undetermined",
|
||||
"bouncedRecipients": [
|
||||
{
|
||||
"emailAddress": "phishing@paypal.com"
|
||||
}
|
||||
],
|
||||
"timestamp": "2025-12-19T02:33:55.434Z"
|
||||
},
|
||||
"mail": {
|
||||
"timestamp": "2025-12-19T02:33:53.244Z",
|
||||
"source": "andreas.knuth@bayarea-cc.com",
|
||||
"sourceArn": "arn:aws:ses:us-east-2:339712845857:identity/bayarea-cc.com",
|
||||
"sendingAccountId": "339712845857",
|
||||
"messageId": "010f019b3474df5c-c634e6cc-8ebb-4b13-957e-0e9b84e39917-000000",
|
||||
"destination": [
|
||||
"phishing@paypal.com"
|
||||
],
|
||||
"headersTruncated": False,
|
||||
"headers": [
|
||||
{
|
||||
"name": "Received",
|
||||
"value": "from mail.email-srvr.com (mail.email-srvr.com [2.56.188.138]) by email-smtp.amazonaws.com with SMTP (SimpleEmailService-d-V0JPVCFGF) id XSfVNEIjPhLtO2NEYG88 for phishing@paypal.com; Fri, 19 Dec 2025 02:33:53 +0000 (UTC)"
|
||||
},
|
||||
{
|
||||
"name": "DKIM-Signature",
|
||||
"value": "v=1; a=rsa-sha256; c=relaxed/simple; d=bayarea-cc.com; s=mail; t=1766111632; bh=ycI1TnY3sqcJF4JmY2LCeBTlZ8Zv+aR+7YbjD2Y1n0Y=; h=From:To:Subject:Reply-To:In-Reply-To:References; b=YQ/EtiYxQIi4Ykwx4ELKXP6gd5u+sev5/GnN97t2rkfxFjrGAZHFdUS9IHipOi/KG5VCAbW89ocW6vPZrdC9SpSxrxr+NMncceSBfvun7SgMQM7ja12clsMfOPebbLsp+TEoSwo43QW4IYsNJep8B7OTInTpadABgeiKd+yWe0BLfsa56tGr6OdIcCBKmxXm/qEZoEjkXooYWu0A5yWCrfpfpdvgZTKKaArturPAtiPUcQiUuDRx7jMkDQkofmBNTtrDbmaLzfEbPqfI2usavV7DCDpa70N6/fbVY2RgnFpcDYP3zd1gf4qDGdnsy9+8B848D1QV/HrEVDsh/Opoxw=="
|
||||
},
|
||||
{
|
||||
"name": "Received",
|
||||
"value": "from app.email-bayarea.com (roundcube-new.mail_network [172.18.0.5]) (Authenticated sender: andreas.knuth@bayarea-cc.com) by mail.email-srvr.com (Postfix) with ESMTPSA id 9685E2E60092 for <phishing@paypal.com>; Thu, 18 Dec 2025 20:33:52 -0600 (CST)"
|
||||
},
|
||||
{
|
||||
"name": "MIME-Version",
|
||||
"value": "1.0"
|
||||
},
|
||||
{
|
||||
"name": "Date",
|
||||
"value": "Thu, 18 Dec 2025 20:33:52 -0600"
|
||||
},
|
||||
{
|
||||
"name": "From",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "To",
|
||||
"value": "phishing@paypal.com"
|
||||
},
|
||||
{
|
||||
"name": "Subject",
|
||||
"value": "Fwd: A one-time merchant setup fee of $249.99 has been applied and will appear on your bank statement wit"
|
||||
},
|
||||
{
|
||||
"name": "Reply-To",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "Mail-Reply-To",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "In-Reply-To",
|
||||
"value": "<6061d865685c1bb406c127f32451d22d@bayarea-cc.com>"
|
||||
},
|
||||
{
|
||||
"name": "References",
|
||||
"value": "<boLgON9OSkmzVWOPwCp8qQ@geopod-ismtpd-45> <6061d865685c1bb406c127f32451d22d@bayarea-cc.com>"
|
||||
},
|
||||
{
|
||||
"name": "Message-ID",
|
||||
"value": "<e7ec8070400b953e735b6fbe5439fa1e@bayarea-cc.com>"
|
||||
},
|
||||
{
|
||||
"name": "X-Sender",
|
||||
"value": "andreas.knuth@bayarea-cc.com"
|
||||
},
|
||||
{
|
||||
"name": "Content-Type",
|
||||
"value": "multipart/alternative; boundary='=_eb88e98e1904b7ce5ebf2be21b8909fd'"
|
||||
}
|
||||
],
|
||||
"commonHeaders": {
|
||||
"from": [
|
||||
"andreas.knuth@bayarea-cc.com"
|
||||
],
|
||||
"replyTo": [
|
||||
"andreas.knuth@bayarea-cc.com"
|
||||
],
|
||||
"date": "Thu, 18 Dec 2025 20:33:52 -0600",
|
||||
"to": [
|
||||
"phishing@paypal.com"
|
||||
],
|
||||
"messageId": "010f019b3474df5c-c634e6cc-8ebb-4b13-957e-0e9b84e39917-000000",
|
||||
"subject": "Fwd: A one-time merchant setup fee of $249.99 has been applied and will appear on your bank statement wit"
|
||||
},
|
||||
"tags": {
|
||||
"ses:source-tls-version": [
|
||||
"TLSv1.3"
|
||||
],
|
||||
"ses:operation": [
|
||||
"SendSmtpEmail"
|
||||
],
|
||||
"ses:configuration-set": [
|
||||
"relay-outbound"
|
||||
],
|
||||
"ses:source-ip": [
|
||||
"2.56.188.138"
|
||||
],
|
||||
"ses:from-domain": [
|
||||
"bayarea-cc.com"
|
||||
],
|
||||
"ses:caller-identity": [
|
||||
"bizmatch.net"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,74 +1,97 @@
|
|||
import json
|
||||
import boto3
|
||||
import os
|
||||
from datetime import datetime
|
||||
|
||||
dynamo = boto3.resource('dynamodb', region_name='us-east-2')
|
||||
table = dynamo.Table('ses-outbound-messages')
|
||||
# AWS Clients
|
||||
s3 = boto3.client('s3')
|
||||
sqs = boto3.client('sqs')
|
||||
dynamodb = boto3.resource('dynamodb')
|
||||
|
||||
# DynamoDB Table
|
||||
OUTBOUND_TABLE = os.environ.get('OUTBOUND_TABLE', 'ses-outbound-messages')
|
||||
table = dynamodb.Table(OUTBOUND_TABLE)
|
||||
|
||||
def lambda_handler(event, context):
|
||||
print(f"Received event: {event}")
|
||||
"""
|
||||
Verarbeitet SES Events:
|
||||
- Bounce Events: Speichert bounce details in DynamoDB
|
||||
- Send Events: Ignoriert (nicht mehr benötigt)
|
||||
"""
|
||||
|
||||
detail = event.get('detail', {})
|
||||
mail = detail.get('mail', {})
|
||||
msg_id = mail.get('messageId')
|
||||
print(f"Received event: {json.dumps(event)}")
|
||||
|
||||
if not msg_id:
|
||||
print("No MessageId in event")
|
||||
return
|
||||
# SNS Wrapper entpacken
|
||||
for record in event.get('Records', []):
|
||||
if 'Sns' in record:
|
||||
message = json.loads(record['Sns']['Message'])
|
||||
else:
|
||||
message = record
|
||||
|
||||
event_type = message.get('eventType')
|
||||
|
||||
if event_type == 'Bounce':
|
||||
handle_bounce(message)
|
||||
elif event_type == 'Send':
|
||||
# Ignorieren - wird nicht mehr benötigt
|
||||
print(f"Ignoring Send event (no longer needed)")
|
||||
else:
|
||||
print(f"Unknown event type: {event_type}")
|
||||
|
||||
# Event-Type aus dem Event extrahieren
|
||||
event_type = detail.get('eventType')
|
||||
|
||||
if event_type == 'Send':
|
||||
source = mail.get('source')
|
||||
destinations = mail.get('destination', [])
|
||||
return {'statusCode': 200}
|
||||
|
||||
|
||||
def handle_bounce(message):
|
||||
"""
|
||||
Verarbeitet Bounce Events und speichert Details in DynamoDB
|
||||
"""
|
||||
try:
|
||||
bounce = message.get('bounce', {})
|
||||
mail = message.get('mail', {})
|
||||
|
||||
# Extrahiere relevante Daten
|
||||
feedback_id = bounce.get('feedbackId') # Das ist die Message-ID!
|
||||
bounce_type = bounce.get('bounceType', 'Unknown')
|
||||
bounce_subtype = bounce.get('bounceSubType', 'Unknown')
|
||||
bounced_recipients = [r['emailAddress'] for r in bounce.get('bouncedRecipients', [])]
|
||||
timestamp = bounce.get('timestamp')
|
||||
|
||||
# Original Message Daten
|
||||
original_source = mail.get('source')
|
||||
original_message_id = mail.get('messageId')
|
||||
|
||||
if not feedback_id:
|
||||
print(f"Warning: No feedbackId in bounce event")
|
||||
return
|
||||
|
||||
print(f"Processing bounce: feedbackId={feedback_id}, type={bounce_type}/{bounce_subtype}")
|
||||
print(f"Bounced recipients: {bounced_recipients}")
|
||||
|
||||
# Speichere in DynamoDB (feedback_id ist die Message-ID der Bounce-Mail!)
|
||||
table.put_item(
|
||||
Item={
|
||||
'MessageId': msg_id,
|
||||
'source': source,
|
||||
'destinations': destinations,
|
||||
'timestamp': mail.get('timestamp')
|
||||
'MessageId': feedback_id, # Primary Key
|
||||
'original_message_id': original_message_id, # SES MessageId der Original-Mail
|
||||
'original_source': original_source,
|
||||
'bounceType': bounce_type,
|
||||
'bounceSubType': bounce_subtype,
|
||||
'bouncedRecipients': bounced_recipients, # Liste von Email-Adressen
|
||||
'timestamp': timestamp or datetime.utcnow().isoformat(),
|
||||
'event_type': 'bounce'
|
||||
}
|
||||
)
|
||||
print(f"Stored SEND event for {msg_id}")
|
||||
return
|
||||
|
||||
print(f"✓ Stored bounce info for feedbackId {feedback_id}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"Error handling bounce: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
if event_type == 'Bounce':
|
||||
bounce = detail.get('bounce', {})
|
||||
bounced = [
|
||||
r.get('emailAddress')
|
||||
for r in bounce.get('bouncedRecipients', [])
|
||||
if r.get('emailAddress')
|
||||
]
|
||||
if not bounced:
|
||||
print("No bouncedRecipients in bounce event")
|
||||
return
|
||||
|
||||
table.update_item(
|
||||
Key={'MessageId': msg_id},
|
||||
UpdateExpression="ADD bouncedRecipients :b",
|
||||
ExpressionAttributeValues={
|
||||
':b': set(bounced)
|
||||
}
|
||||
)
|
||||
print(f"Updated {msg_id} with bouncedRecipients={bounced}")
|
||||
return
|
||||
|
||||
if event_type == 'Complaint':
|
||||
complaint = detail.get('complaint', {})
|
||||
complained = [
|
||||
r.get('emailAddress')
|
||||
for r in complaint.get('complainedRecipients', [])
|
||||
if r.get('emailAddress')
|
||||
]
|
||||
if not complained:
|
||||
return
|
||||
|
||||
table.update_item(
|
||||
Key={'MessageId': msg_id},
|
||||
UpdateExpression="ADD complaintRecipients :c",
|
||||
ExpressionAttributeValues={
|
||||
':c': set(complained)
|
||||
}
|
||||
)
|
||||
print(f"Updated {msg_id} with complaintRecipients={complained}")
|
||||
return
|
||||
def handle_send(message):
|
||||
"""
|
||||
DEPRECATED - Wird nicht mehr benötigt
|
||||
Send Events werden jetzt ignoriert
|
||||
"""
|
||||
pass
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test script für Message-ID Extraktion - VERBESSERTE VERSION
|
||||
Kann lokal ausgeführt werden ohne AWS-Verbindung
|
||||
"""
|
||||
|
||||
import re
|
||||
from email.parser import BytesParser
|
||||
from email.policy import SMTP as SMTPPolicy
|
||||
|
||||
def log(message: str, level: str = 'INFO'):
|
||||
"""Dummy log für Tests"""
|
||||
print(f"[{level}] {message}")
|
||||
|
||||
def extract_original_message_id(parsed):
|
||||
"""
|
||||
Extrahiert Original SES Message-ID aus Email
|
||||
SES Format: 010f[hex32]-[hex8]-[hex4]-[hex4]-[hex4]-[hex12]-000000
|
||||
"""
|
||||
import re
|
||||
|
||||
# SES Message-ID Pattern (endet immer mit -000000)
|
||||
ses_pattern = re.compile(r'010f[0-9a-f]{12}-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}-000000')
|
||||
|
||||
# Die Message-ID der aktuellen Email (Bounce selbst) - diese wollen wir NICHT
|
||||
current_msg_id = (parsed.get('Message-ID') or '').strip()
|
||||
current_match = ses_pattern.search(current_msg_id)
|
||||
current_id = current_match.group(0) if current_match else None
|
||||
|
||||
log(f"Current Message-ID: {current_id}", 'DEBUG')
|
||||
|
||||
# 1. Versuche Standard-Header (In-Reply-To, References)
|
||||
for header in ['In-Reply-To', 'References']:
|
||||
value = (parsed.get(header) or '').strip()
|
||||
if value:
|
||||
match = ses_pattern.search(value)
|
||||
if match:
|
||||
found_id = match.group(0)
|
||||
# Nur nehmen wenn es NICHT die aktuelle Bounce-ID ist
|
||||
if found_id != current_id:
|
||||
log(f" Found Message-ID in {header}: {found_id}")
|
||||
return found_id
|
||||
|
||||
# 2. Durchsuche den kompletten Email-Body (inkl. ALLE Attachments/Parts)
|
||||
try:
|
||||
body_text = ''
|
||||
|
||||
# Hole den kompletten Body als String
|
||||
if parsed.is_multipart():
|
||||
for part in parsed.walk():
|
||||
content_type = part.get_content_type()
|
||||
|
||||
# SPEZIALFALL: message/rfc822 (eingebettete Messages)
|
||||
if content_type == 'message/rfc822':
|
||||
log(f" Processing embedded message/rfc822", 'DEBUG')
|
||||
try:
|
||||
# get_payload() gibt eine Liste mit einem EmailMessage-Objekt zurück!
|
||||
payload = part.get_payload()
|
||||
if isinstance(payload, list) and len(payload) > 0:
|
||||
embedded_msg = payload[0]
|
||||
# Hole Message-ID aus dem eingebetteten Message
|
||||
embedded_id = (embedded_msg.get('Message-ID') or '').strip()
|
||||
match = ses_pattern.search(embedded_id)
|
||||
if match:
|
||||
found_id = match.group(0)
|
||||
log(f" Found ID in embedded msg: {found_id}", 'DEBUG')
|
||||
# Nur nehmen wenn es NICHT die aktuelle Bounce-ID ist
|
||||
if found_id != current_id:
|
||||
log(f" ✓ Found Message-ID in embedded message: {found_id}")
|
||||
return found_id
|
||||
# Fallback: Konvertiere eingebettete Message zu String
|
||||
body_text += embedded_msg.as_string()
|
||||
except Exception as e:
|
||||
log(f" Warning: Could not process embedded message: {e}", 'WARNING')
|
||||
|
||||
# Durchsuche ALLE anderen Parts (außer Binärdaten wie images)
|
||||
elif content_type.startswith('text/') or content_type.startswith('application/'):
|
||||
try:
|
||||
payload = part.get_payload(decode=True)
|
||||
if payload:
|
||||
# Versuche als UTF-8, fallback auf Latin-1
|
||||
try:
|
||||
body_text += payload.decode('utf-8', errors='ignore')
|
||||
except:
|
||||
try:
|
||||
body_text += payload.decode('latin-1', errors='ignore')
|
||||
except:
|
||||
# Letzter Versuch: als ASCII mit ignore
|
||||
body_text += str(payload, errors='ignore')
|
||||
except:
|
||||
# Falls decode fehlschlägt, String-Payload holen
|
||||
payload = part.get_payload()
|
||||
if isinstance(payload, str):
|
||||
body_text += payload
|
||||
else:
|
||||
# Nicht-Multipart Message
|
||||
payload = parsed.get_payload(decode=True)
|
||||
if payload:
|
||||
try:
|
||||
body_text = payload.decode('utf-8', errors='ignore')
|
||||
except:
|
||||
body_text = payload.decode('latin-1', errors='ignore')
|
||||
|
||||
# Suche alle SES Message-IDs im Body
|
||||
matches = ses_pattern.findall(body_text)
|
||||
if matches:
|
||||
log(f" Found {len(matches)} total IDs in body: {matches}", 'DEBUG')
|
||||
# Filtere die aktuelle Bounce-ID raus
|
||||
candidates = [m for m in matches if m != current_id]
|
||||
|
||||
if candidates:
|
||||
# Nehme die ERSTE der verbleibenden (meist die Original-ID)
|
||||
log(f" Found {len(matches)} SES Message-ID(s) in body, using first (not bounce): {candidates[0]}")
|
||||
return candidates[0]
|
||||
else:
|
||||
log(f" Found {len(matches)} SES Message-ID(s) but all match the bounce ID")
|
||||
|
||||
except Exception as e:
|
||||
log(f" Warning: Could not search body for Message-ID: {e}", 'WARNING')
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def test_with_file(filepath: str):
|
||||
"""Test mit einer echten Email-Datei"""
|
||||
print(f"\n{'='*70}")
|
||||
print(f"Testing: {filepath}")
|
||||
print('='*70)
|
||||
|
||||
with open(filepath, 'rb') as f:
|
||||
raw_bytes = f.read()
|
||||
|
||||
parsed = BytesParser(policy=SMTPPolicy).parsebytes(raw_bytes)
|
||||
|
||||
print(f"\nEmail Headers:")
|
||||
print(f" From: {parsed.get('From')}")
|
||||
print(f" To: {parsed.get('To')}")
|
||||
print(f" Subject: {parsed.get('Subject')}")
|
||||
print(f" Message-ID: {parsed.get('Message-ID')}")
|
||||
print(f" In-Reply-To: {parsed.get('In-Reply-To')}")
|
||||
print(f" References: {parsed.get('References')}")
|
||||
|
||||
print(f"\n--- EXTRACTION ---")
|
||||
result = extract_original_message_id(parsed)
|
||||
|
||||
print(f"\n{'='*70}")
|
||||
print(f"RESULT: {result}")
|
||||
print('='*70)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
# Email-Datei als Argument
|
||||
result = test_with_file(sys.argv[1])
|
||||
|
||||
# Exit code: 0 = success (ID found), 1 = failure (no ID)
|
||||
sys.exit(0 if result else 1)
|
||||
else:
|
||||
print("Usage: python3 test_extract_v2.py <email_file>")
|
||||
sys.exit(1)
|
||||
188
worker.py
188
worker.py
|
|
@ -51,145 +51,99 @@ def get_bucket_name(domain):
|
|||
"""Konvention: domain.tld -> domain-tld-emails"""
|
||||
return domain.replace('.', '-') + '-emails'
|
||||
|
||||
def is_ses_bounce_or_autoreply(parsed):
|
||||
"""Erkennt SES Bounces"""
|
||||
def is_ses_bounce_notification(parsed):
|
||||
"""
|
||||
Prüft ob Email von SES MAILER-DAEMON ist
|
||||
"""
|
||||
from_h = (parsed.get('From') or '').lower()
|
||||
auto_sub = (parsed.get('Auto-Submitted') or '').lower()
|
||||
is_mailer_daemon = 'mailer-daemon@' in from_h and 'amazonses.com' in from_h
|
||||
is_auto_replied = 'auto-replied' in auto_sub or 'auto-generated' in auto_sub
|
||||
return is_mailer_daemon or is_auto_replied
|
||||
return 'mailer-daemon@us-east-2.amazonses.com' in from_h
|
||||
|
||||
def extract_original_message_id(parsed):
|
||||
|
||||
def get_bounce_info_from_dynamodb(message_id):
|
||||
"""
|
||||
Extrahiert Original SES Message-ID aus Email
|
||||
SES Format: 010f[hex32]-[hex8]-[hex4]-[hex4]-[hex4]-[hex12]-[hex6]
|
||||
Sucht Bounce-Info in DynamoDB anhand der Message-ID
|
||||
Returns: dict mit bounce info oder None
|
||||
"""
|
||||
import re
|
||||
|
||||
# SES Message-ID Pattern (endet immer mit -000000)
|
||||
ses_pattern = re.compile(r'010f[0-9a-f]{12}-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}-000000')
|
||||
|
||||
# 1. Versuche Standard-Header (In-Reply-To, References)
|
||||
for header in ['In-Reply-To', 'References']:
|
||||
value = (parsed.get(header) or '').strip()
|
||||
if value:
|
||||
match = ses_pattern.search(value)
|
||||
if match:
|
||||
log(f" Found Message-ID in {header}: {match.group(0)}")
|
||||
return match.group(0)
|
||||
|
||||
# 2. Durchsuche Message-ID Header (manchmal steht dort die Original-ID)
|
||||
msg_id_header = (parsed.get('Message-ID') or '').strip()
|
||||
if msg_id_header:
|
||||
match = ses_pattern.search(msg_id_header)
|
||||
if match:
|
||||
# Aber nur wenn es nicht die ID der aktuellen Bounce-Message ist
|
||||
# (die beginnt oft auch mit 010f...)
|
||||
pass # Wir überspringen das erstmal
|
||||
|
||||
# 3. Durchsuche den kompletten Email-Body (inkl. ALLE Attachments/Parts)
|
||||
# Das fängt auch attached messages, text attachments, etc. ab
|
||||
try:
|
||||
body_text = ''
|
||||
response = msg_table.get_item(Key={'MessageId': message_id})
|
||||
item = response.get('Item')
|
||||
|
||||
# Hole den kompletten Body als String
|
||||
if parsed.is_multipart():
|
||||
for part in parsed.walk():
|
||||
content_type = part.get_content_type()
|
||||
|
||||
# Durchsuche ALLE Parts (außer Binärdaten wie images)
|
||||
# Text-Parts, HTML, attached messages, und auch application/* Parts
|
||||
if content_type.startswith('text/') or \
|
||||
content_type == 'message/rfc822' or \
|
||||
content_type.startswith('application/'):
|
||||
try:
|
||||
payload = part.get_payload(decode=True)
|
||||
if payload:
|
||||
# Versuche als UTF-8, fallback auf Latin-1
|
||||
try:
|
||||
body_text += payload.decode('utf-8', errors='ignore')
|
||||
except:
|
||||
try:
|
||||
body_text += payload.decode('latin-1', errors='ignore')
|
||||
except:
|
||||
# Letzter Versuch: als ASCII mit ignore
|
||||
body_text += str(payload, errors='ignore')
|
||||
except:
|
||||
# Falls decode fehlschlägt, String-Payload holen
|
||||
payload = part.get_payload()
|
||||
if isinstance(payload, str):
|
||||
body_text += payload
|
||||
else:
|
||||
# Nicht-Multipart Message
|
||||
payload = parsed.get_payload(decode=True)
|
||||
if payload:
|
||||
try:
|
||||
body_text = payload.decode('utf-8', errors='ignore')
|
||||
except:
|
||||
body_text = payload.decode('latin-1', errors='ignore')
|
||||
if not item:
|
||||
log(f"⚠ No bounce record found for Message-ID: {message_id}")
|
||||
return None
|
||||
|
||||
# Suche alle SES Message-IDs im Body
|
||||
matches = ses_pattern.findall(body_text)
|
||||
if matches:
|
||||
# Nehme die ERSTE gefundene ID (meist die Original-ID)
|
||||
# Die letzte ist oft die Bounce-Message selbst
|
||||
log(f" Found {len(matches)} SES Message-ID(s) in body, using first: {matches[0]}")
|
||||
return matches[0]
|
||||
return {
|
||||
'original_source': item.get('original_source', ''),
|
||||
'bounceType': item.get('bounceType', 'Unknown'),
|
||||
'bounceSubType': item.get('bounceSubType', 'Unknown'),
|
||||
'bouncedRecipients': item.get('bouncedRecipients', []),
|
||||
'timestamp': item.get('timestamp', '')
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
log(f" Warning: Could not search body for Message-ID: {e}", 'WARNING')
|
||||
|
||||
return None
|
||||
log(f"⚠ DynamoDB Error: {e}", 'ERROR')
|
||||
return None
|
||||
|
||||
|
||||
def apply_bounce_logic(parsed, subject):
|
||||
"""
|
||||
Prüft auf Bounce, sucht in DynamoDB und schreibt Header um.
|
||||
Prüft auf SES Bounce, sucht in DynamoDB und schreibt Header um.
|
||||
Returns: (parsed_email_object, was_modified_bool)
|
||||
"""
|
||||
if not is_ses_bounce_or_autoreply(parsed):
|
||||
if not is_ses_bounce_notification(parsed):
|
||||
return parsed, False
|
||||
|
||||
log("🔍 Detected auto-response/bounce. Checking DynamoDB...")
|
||||
original_msg_id = extract_original_message_id(parsed)
|
||||
log("🔍 Detected SES MAILER-DAEMON bounce notification")
|
||||
|
||||
if not original_msg_id:
|
||||
log("⚠ Could not extract original Message-ID")
|
||||
# Message-ID aus Header extrahieren
|
||||
message_id = (parsed.get('Message-ID') or '').strip('<>')
|
||||
|
||||
if not message_id:
|
||||
log("⚠ Could not extract Message-ID from bounce notification")
|
||||
return parsed, False
|
||||
|
||||
try:
|
||||
# Lookup in DynamoDB
|
||||
result = msg_table.get_item(Key={'MessageId': original_msg_id})
|
||||
item = result.get('Item')
|
||||
log(f" Looking up Message-ID: {message_id}")
|
||||
|
||||
# Lookup in DynamoDB
|
||||
bounce_info = get_bounce_info_from_dynamodb(message_id)
|
||||
|
||||
if not bounce_info:
|
||||
return parsed, False
|
||||
|
||||
# Bounce Info ausgeben
|
||||
original_source = bounce_info['original_source']
|
||||
bounced_recipients = bounce_info['bouncedRecipients']
|
||||
bounce_type = bounce_info['bounceType']
|
||||
bounce_subtype = bounce_info['bounceSubType']
|
||||
|
||||
log(f"✓ Found bounce info:")
|
||||
log(f" Original sender: {original_source}")
|
||||
log(f" Bounce type: {bounce_type}/{bounce_subtype}")
|
||||
log(f" Bounced recipients: {bounced_recipients}")
|
||||
|
||||
# Nehme den ersten bounced recipient als neuen Absender
|
||||
# (bei Multiple Recipients kann es mehrere geben)
|
||||
if bounced_recipients:
|
||||
new_from = bounced_recipients[0]
|
||||
|
||||
if not item:
|
||||
log(f"⚠ No DynamoDB record found for {original_msg_id}")
|
||||
return parsed, False
|
||||
|
||||
# Treffer!
|
||||
orig_source = item.get('source', '')
|
||||
orig_destinations = item.get('destinations', [])
|
||||
original_recipient = orig_destinations[0] if orig_destinations else ''
|
||||
|
||||
if original_recipient:
|
||||
log(f"✓ Found original sender: {orig_source} -> intended for {original_recipient}")
|
||||
|
||||
# Rewrite Headers
|
||||
parsed['X-Original-SES-From'] = parsed.get('From', '')
|
||||
parsed.replace_header('From', original_recipient)
|
||||
|
||||
if not parsed.get('Reply-To'):
|
||||
parsed['Reply-To'] = original_recipient
|
||||
|
||||
if 'delivery status notification' in subject.lower():
|
||||
parsed.replace_header('Subject', f"Delivery Status: {original_recipient}")
|
||||
|
||||
return parsed, True
|
||||
|
||||
except Exception as e:
|
||||
log(f"⚠ DynamoDB Error: {e}")
|
||||
# Rewrite Headers
|
||||
parsed['X-Original-SES-From'] = parsed.get('From', '')
|
||||
parsed['X-Bounce-Type'] = f"{bounce_type}/{bounce_subtype}"
|
||||
parsed.replace_header('From', new_from)
|
||||
|
||||
if not parsed.get('Reply-To'):
|
||||
parsed['Reply-To'] = new_from
|
||||
|
||||
# Subject anpassen
|
||||
if 'delivery status notification' in subject.lower() or 'thanks for your submission' in subject.lower():
|
||||
parsed.replace_header('Subject', f"Delivery Status: {new_from}")
|
||||
|
||||
log(f"✓ Rewritten FROM: {new_from}")
|
||||
return parsed, True
|
||||
|
||||
log("⚠ No bounced recipients found in bounce info")
|
||||
return parsed, False
|
||||
|
||||
|
||||
def signal_handler(signum, frame):
|
||||
global shutdown_requested
|
||||
print(f"\n⚠ Shutdown signal received (signal {signum})")
|
||||
|
|
|
|||
Loading…
Reference in New Issue