Passed
Push — master ( 80764e...bf7963 )
by George
04:22
created

AwsSesBounceComplaintHandler::test()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
1
<?php
2
3
namespace ag84ark\AwsSesBounceComplaintHandler;
4
5
use ag84ark\AwsSesBounceComplaintHandler\Models\WrongEmail;
6
use GuzzleHttp\Client;
0 ignored issues
show
Bug introduced by
The type GuzzleHttp\Client was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
7
use Illuminate\Http\JsonResponse;
8
use Illuminate\Http\Request;
9
use Illuminate\Support\Collection;
10
use Illuminate\Support\Facades\Response;
11
use Log;
12
13
class AwsSesBounceComplaintHandler
14
{
15 6
    public function handleBounceOrComplaint(Request $request): JsonResponse
16
    {
17 6
        if (! $request->json()) {
18
            return Response::json(['status' => 422, 'message' => 'error'], 422);
19
        }
20
21 6
        if (! $this->canPass($request)) {
22 1
            return Response::json(['status' => 403, 'message' => 'error'], 403);
23
        }
24
25 5
        $data = $request->json()->all() ?? [];
26
27 5
        $this->handleLoggingData($data);
28
29 5
        $this->handleSubscriptionConfirmation($request, $data);
30
31 5
        $message = $this->getMessageData($request, $data);
32
33 5
        if (! count($message)) {
34
            return Response::json(['status' => 422, 'data' => $data], 422);
35
        }
36
37 5
        if (! isset($message['notificationType'])) {
38
            return Response::json(['status' => 200, 'message' => 'no data']);
39
        }
40
41 5
        $this->storeEmailToDB($message);
42
43 5
        return Response::json(['status' => 200, 'message' => 'success']);
44
    }
45
46 2
    public static function canSendToEmail(string $email): bool
47
    {
48
        /** @var WrongEmail[]|Collection $emails */
49 2
        $emails = WrongEmail::active()
50 2
            ->bounced()
51 2
            ->where('email', '=', $email)
52 2
            ->get();
53
54 2
        foreach ($emails as $wrongEmail) {
55 1
            if (! $wrongEmail->canBouncedSend()) {
56 1
                return false;
57
            }
58
        }
59
60 1
        return true;
61
    }
62
63
    /**
64
     * @return array|mixed|\Symfony\Component\HttpFoundation\ParameterBag|null
65
     */
66 5
    private function getMessageData(Request $request, array $data)
67
    {
68 5
        $message = [];
69
70 5
        if (config('aws-ses-bounce-complaint-handler.via_sqs')) {
71 1
            if ('Notification' === $request->json('Type')) {
72 1
                $message = $request->json('Message');
73
            }
74
        } else {
75 4
            $message = $data;
76
        }
77
78 5
        return $message;
79
    }
80
81 6
    private function canPass(Request $request): bool
82
    {
83 6
        if (config('aws-ses-bounce-complaint-handler.via_sqs')) {
84 1
            return  true;
85
        }
86
87 5
        $secret = config('aws-ses-bounce-complaint-handler.route_secret');
88 5
        if (! $secret) {
89 3
            return  true;
90
        }
91
92 2
        if ($secret !== $request->get('secret')) {
93 1
            return  false;
94
        }
95
96 1
        return true;
97
    }
98
99 5
    private function handleSubscriptionConfirmation(Request $request, array $data): void
100
    {
101 5
        if ('SubscriptionConfirmation' !== $request->json('Type')) {
102 5
            return;
103
        }
104
        Log::info('SubscriptionConfirmation came at: '.$data['Timestamp']);
105
106
        $client = new Client();
107
        $res = $client->get($data['SubscribeURL']);
108
109
        if (200 === $res->getStatusCode()) {
110
            Log::info('SubscriptionConfirmation was auto confirmed!');
111
        } else {
112
            Log::warning('SubscriptionConfirmation could not be auto confirmed!');
113
            Log::info($data['SubscribeURL']);
114
        }
115
    }
116
117
    /**
118
     * @param $message
119
     */
120 5
    private function storeEmailToDB($message): void
121
    {
122 5
        switch ($message['notificationType']) {
123 5
            case 'Bounce':
124 4
                $bounce = $message['bounce'];
125 4
                $subtype = $bounce['bounceType'];
126 4
                foreach ($bounce['bouncedRecipients'] as $bouncedRecipient) {
127 4
                    $emailAddress = $bouncedRecipient['emailAddress'];
128
129 4
                    $emailRecord = WrongEmail::firstOrCreate(['email' => $emailAddress, 'problem_type' => 'Bounce', 'problem_subtype' => $subtype]);
130 4
                    if ($emailRecord) {
131 4
                        $emailRecord->increment('repeated_attempts', 1);
132
                    }
133
                }
134
135 4
                break;
136
137 1
            case 'Complaint':
138 1
                $complaint = $message['complaint'];
139 1
                $subtype = $complaint['complaintFeedbackType'] ?? '';
140 1
                foreach ($complaint['complainedRecipients'] as $complainedRecipient) {
141 1
                    $emailAddress = $complainedRecipient['emailAddress'];
142 1
                    $emailRecord = WrongEmail::firstOrCreate(['email' => $emailAddress, 'problem_type' => 'Complaint', 'problem_subtype' => $subtype]);
143 1
                    if ($emailRecord) {
144 1
                        $emailRecord->increment('repeated_attempts', 1);
145
                    }
146
                }
147
148 1
                break;
149
150
            default:
151
                // Do Nothing
152
                break;
153
        }
154 5
    }
155
156 5
    private function handleLoggingData(array $data): void
157
    {
158 5
        if (config('aws-ses-bounce-complaint-handler.log_requests')) {
159 1
            $dataCollection = collect($data);
160 1
            Log::info('Logging AWS SES DATA');
161 1
            Log::info($dataCollection->toJson());
162
        }
163 5
    }
164
}
165