Passed
Push — master ( b9e179...1762c3 )
by George
04:42
created

PackageController::canPass()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 16
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 4

Importance

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