Passed
Push — master ( 718b7a...cab810 )
by George
04:41
created

handleSubscriptionConfirmation()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 6.087

Importance

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