Passed
Push — master ( f780f9...8d5450 )
by Patrick
03:32
created

MattermostApi   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 94
Duplicated Lines 0 %

Test Coverage

Coverage 73.32%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 45
dl 0
loc 94
ccs 33
cts 45
cp 0.7332
rs 10
c 1
b 0
f 0
wmc 12

6 Methods

Rating   Name   Duplication   Size   Complexity  
A getPosts() 0 16 1
A isDirectChannel() 0 3 1
A applyChannelFilter() 0 14 5
A auth() 0 25 3
A __construct() 0 2 1
A getChannel() 0 16 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of forecast.it.fill project.
7
 * (c) Patrick Jaja <[email protected]>
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace ForecastAutomation\MattermostClient\Business;
13
14
use ForecastAutomation\MattermostClient\Shared\Dto\MattermostChannelFilterQueryDto;
15
use ForecastAutomation\MattermostClient\Shared\Dto\MattermostConfigDto;
16
use ForecastAutomation\MattermostClient\Shared\Dto\MattermostPostsQueryDto;
17
use GuzzleHttp\Client;
18
19
class MattermostApi
20
{
21
    private const AUTH_API = '/api/v4/users/login';
22
    private const CHANNEL_API = '/api/v4/users/me/teams/%s/channels';
23
    private const POSTS_API = '/api/v4/channels/%s/posts';
24
25
    public static string $token = '';
26
27 2
    public function __construct(private Client $guzzleClient, private MattermostConfigDto $mattermostConfigDto)
28
    {
29 2
    }
30
31 1
    public function getChannel(MattermostChannelFilterQueryDto $channelFilterQueryDto): array
32
    {
33 1
        $this->auth();
34 1
        $res = $this->guzzleClient->request(
35 1
            'GET',
36 1
            sprintf(self::CHANNEL_API, $this->mattermostConfigDto->teamId),
37
            [
38
                'headers' => [
39 1
                    'Authorization' => 'Bearer '.static::$token,
40 1
                    'Content-Type' => 'application/json',
41
                ],
42
            ]
43
        );
44 1
        $channelArray = json_decode((string) $res->getBody(), null, 512, JSON_THROW_ON_ERROR);
45
46 1
        return $this->applyChannelFilter($channelArray, $channelFilterQueryDto);
47
    }
48
49 1
    public function getPosts(MattermostPostsQueryDto $postsQueryDto): array
50
    {
51 1
        $this->auth();
52 1
        $res = $this->guzzleClient->request(
53 1
            'GET',
54 1
            sprintf(self::POSTS_API, $postsQueryDto->channelId),
55
            [
56 1
                'query' => ['since' => (int) $postsQueryDto->since->format('U') * 1000],
57
                'headers' => [
58 1
                    'Authorization' => 'Bearer '.static::$token,
59 1
                    'Content-Type' => 'application/json',
60
                ],
61
            ],
62
        );
63
64 1
        return json_decode((string) $res->getBody(), true, 512, JSON_THROW_ON_ERROR)["posts"];
65
    }
66
67 2
    private function auth(): string
68
    {
69 2
        if ('' !== static::$token) {
70 2
            return static::$token;
71
        }
72
        $res = $this->guzzleClient->request(
73
            'POST',
74
            self::AUTH_API,
75
            [
76
                'body' => json_encode(
77
                    [
78
                        'login_id' => $this->mattermostConfigDto->username,
79
                        'password' => $this->mattermostConfigDto->password,
80
                    ],
81
                    JSON_THROW_ON_ERROR
82
                ),
83
            ],
84
        );
85
        $token = $res->getHeader('token');
86
        if (0 === \count($token)) {
87
            throw new \Exception('could not auth to mattermost');
88
        }
89
        static::$token = $token[0];
90
91
        return static::$token;
92
    }
93
94 1
    private function applyChannelFilter(
95
        array $channelArray,
96
        MattermostChannelFilterQueryDto $channelFilterQueryDto
97
    ): array {
98 1
        $filteredChannel = [];
99 1
        foreach ($channelArray as $channel) {
100 1
            if ($channel->total_msg_count > 0
101 1
                && $this->isDirectChannel($channel)
102 1
                && $channel->last_post_at >= ((int) $channelFilterQueryDto->lastPostAt->format('U') * 1000)) {
103 1
                $filteredChannel[] = $channel;
104
            }
105
        }
106
107 1
        return $filteredChannel;
108
    }
109
110 1
    private function isDirectChannel(\stdClass $channel): bool
111
    {
112 1
        return 'D' === $channel->type;
113
    }
114
}
115