Completed
Push — master ( daaf64...6e4339 )
by Dan
02:16
created

Client::on()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
1
<?php
2
3
namespace Nopolabs\Yabot\Slack;
4
5
6
use Closure;
7
use Nopolabs\Yabot\Helpers\ConfigTrait;
8
use Nopolabs\Yabot\Helpers\LogTrait;
9
use Psr\Log\LoggerInterface;
10
use React\Promise\PromiseInterface;
11
use Slack\Channel;
12
use Slack\ChannelInterface;
13
use Slack\Payload;
14
use Slack\RealTimeClient;
15
use Slack\User;
16
17
class Client
18
{
19
    use ConfigTrait;
20
    use LogTrait;
21
22
    /** @var RealTimeClient */
23
    private $realTimeClient;
24
25
    /** @var Users */
26
    private $users;
27
28
    /** @var Channels */
29
    private $channels;
30
31
    /** @var User */
32
    protected $authedUser;
33
34
    public function __construct(
35
        RealTimeClient $realTimeClient,
36
        Users $users,
37
        Channels $channels,
38
        array $config = [],
39
        LoggerInterface $log = null)
40
    {
41
        $this->realTimeClient = $realTimeClient;
42
        $this->users = $users;
43
        $this->channels = $channels;
44
        $this->setConfig($config);
45
        $this->setLog($log);
46
    }
47
48
    public function getRealTimeClient()
49
    {
50
        return $this->realTimeClient;
51
    }
52
53
    public function init() : Client
54
    {
55
        $this->initChannelUpdateHandlers();
56
        $this->initUserUpdateHandlers();
57
58
        return $this;
59
    }
60
61
    public function update(Closure $authedUserUpdated)
62
    {
63
        $this->updateUsers();
64
        $this->updateChannels();
65
        $this->updateAuthedUser($authedUserUpdated);
66
    }
67
68
    public function getAuthedUser()
69
    {
70
        return $this->authedUser;
71
    }
72
73
    public function getAuthedUsername()
74
    {
75
        return $this->authedUser->getUsername();
76
    }
77
78
    public function connect() : PromiseInterface
79
    {
80
        return $this->realTimeClient->connect();
81
    }
82
83
    public function disconnect()
84
    {
85
        return $this->realTimeClient->disconnect();
86
    }
87
88
    public function say($text, $channelOrName, array $additionalParameters = [])
89
    {
90
        $channel = $channelOrName;
91
        if (!($channel instanceof ChannelInterface)) {
92
            $channel = $this->getChannelByName($channelOrName);
93
            if (!($channel instanceof ChannelInterface)) {
94
                $channel = $this->getChannelById($channelOrName);
95
                if (!($channel instanceof ChannelInterface)) {
96
                    $this->warning('No channel, trying to say: '.$text);
97
                    return;
98
                }
99
            }
100
        }
101
102
        if (empty($additionalParameters) && $this->useWebSocket()) {
103
            // WebSocket send does not support message formatting.
104
            $this->send($text, $channel);
105
            return;
106
        }
107
108
        // Http post send supports message formatting.
109
        $this->post($text, $channel, $additionalParameters);
110
    }
111
112
    public function send($text, ChannelInterface $channel)
113
    {
114
        $this->realTimeClient->send($text, $channel);
115
    }
116
117
    public function post($text, ChannelInterface $channel, array $additionalParameters = [])
118
    {
119
        $parameters = array_merge([
120
            'text' => $text,
121
            'channel' => $channel->getId(),
122
            'as_user' => true,
123
        ], $additionalParameters);
124
125
        $this->realTimeClient->apiCall('chat.postMessage', $parameters);
126
    }
127
128
    public function onMessage($event, array $onMessage)
129
    {
130
        $this->realTimeClient->on($event, function(Payload $payload) use ($onMessage) {
131
            call_user_func($onMessage, $payload);
132
        });
133
    }
134
135
    /**
136
     * @param $id
137
     * @return null|User
138
     */
139
    public function getUserById($id)
140
    {
141
        return $this->users->byId($id);
142
    }
143
144
    /**
145
     * @param $name
146
     * @return null|User
147
     */
148
    public function getUserByName($name)
149
    {
150
        return $this->users->byName($name);
151
    }
152
153
    /**
154
     * @param $id
155
     * @return null|Channel
156
     */
157
    public function getChannelById($id)
158
    {
159
        return $this->channels->byId($id);
160
    }
161
162
    /**
163
     * @param $name
164
     * @return null|Channel
165
     */
166
    public function getChannelByName($name)
167
    {
168
        return $this->channels->byName($name);
169
    }
170
171
    protected function useWebSocket() : bool
172
    {
173
        return (bool) $this->get('use.websocket', false);
174
    }
175
176
    protected function updateUsers()
177
    {
178
        $this->realTimeClient->getUsers()->then(function(array $users) {
179
            $this->users->update($users);
180
        });
181
    }
182
183
    protected function updateChannels()
184
    {
185
        $this->realTimeClient->getChannels()->then(function(array $channels) {
186
            $this->channels->update($channels);
187
        });
188
    }
189
190
    protected function updateAuthedUser(Closure $authedUserUpdated)
191
    {
192
        $this->realTimeClient->getAuthedUser()->then(function(User $user) use ($authedUserUpdated) {
193
            $this->authedUser = $user;
194
            $authedUserUpdated($user);
195
        });
196
    }
197
198
    protected function initChannelUpdateHandlers()
199
    {
200
        $events = ['channel_created', 'channel_deleted', 'channel_rename'];
201
        foreach ($events as $event) {
202
            $this->onMessage($event, [$this, 'updateChannels']);
203
        }
204
    }
205
206
    protected function initUserUpdateHandlers()
207
    {
208
        $events = ['user_change'];
209
        foreach ($events as $event) {
210
            $this->onMessage($event, [$this, 'updateUsers']);
211
        }
212
    }
213
}