1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* This file is part of GitterBot package. |
5
|
|
|
* |
6
|
|
|
* @author Serafim <[email protected]> |
7
|
|
|
* @author butschster <[email protected]> |
8
|
|
|
* @date 24.09.2015 00:00 |
9
|
|
|
* |
10
|
|
|
* For the full copyright and license information, please view the LICENSE |
11
|
|
|
* file that was distributed with this source code. |
12
|
|
|
*/ |
13
|
|
|
|
14
|
|
|
namespace Interfaces\Slack; |
15
|
|
|
|
16
|
|
|
use Domains\Bot\ClientInterface; |
17
|
|
|
use Domains\Message; |
18
|
|
|
use Domains\Middleware\Storage; |
19
|
|
|
use Domains\Room\RoomInterface; |
20
|
|
|
use Domains\User; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* Class Client |
24
|
|
|
*/ |
25
|
|
|
class Client implements ClientInterface |
26
|
|
|
{ |
27
|
|
|
/** |
28
|
|
|
* @var string |
29
|
|
|
*/ |
30
|
|
|
protected $token; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @var \React\EventLoop\ExtEventLoop|\React\EventLoop\LibEventLoop|\React\EventLoop\LibEvLoop|\React\EventLoop\StreamSelectLoop |
34
|
|
|
*/ |
35
|
|
|
protected $loop; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @var \Slack\RealTimeClient |
39
|
|
|
*/ |
40
|
|
|
protected $client; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @var TextParser |
44
|
|
|
*/ |
45
|
|
|
protected $parser; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Client constructor. |
49
|
|
|
* |
50
|
|
|
* @param string $token |
51
|
|
|
*/ |
52
|
|
|
public function __construct($token) |
53
|
|
|
{ |
54
|
|
|
$this->token = $token; |
55
|
|
|
$this->loop = \React\EventLoop\Factory::create(); |
56
|
|
|
$this->client = new \Slack\RealTimeClient($this->loop); |
57
|
|
|
|
58
|
|
|
$this->client->setToken($token); |
59
|
|
|
$this->parser = new TextParser(''); |
|
|
|
|
60
|
|
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* @param RoomInterface $room |
64
|
|
|
* @param string $message |
65
|
|
|
* |
66
|
|
|
* @return void |
67
|
|
|
*/ |
68
|
|
|
public function sendMessage(RoomInterface $room, $message) |
69
|
|
|
{ |
70
|
|
|
$this->client->getChannelById($room->id())->then(function (\Slack\Channel $channel) use($message) { |
71
|
|
|
$this->client->apiCall('chat.postMessage', [ |
72
|
|
|
'text' => (string) $this->parser->parse($message), |
73
|
|
|
'channel' => $channel->getId(), |
74
|
|
|
'as_user' => true, |
75
|
|
|
]); |
76
|
|
|
}); |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* @param RoomInterface $room |
81
|
|
|
* |
82
|
|
|
* @return void |
83
|
|
|
*/ |
84
|
|
|
public function listen(RoomInterface $room) |
85
|
|
|
{ |
86
|
|
|
$this->client->on('message', function (\Slack\Payload $msg) use($room) { |
87
|
|
|
if ($msg->getData()['channel'] != $room->id()) { |
88
|
|
|
return; |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
$this->onMessage( |
92
|
|
|
$room->middleware(), |
93
|
|
|
Message::unguarded(function() use($room, $msg) { |
94
|
|
|
return new Message( |
|
|
|
|
95
|
|
|
(new MessageMapper($room, $msg->getData()))->toArray(), |
96
|
|
|
$room |
97
|
|
|
); |
98
|
|
|
}) |
99
|
|
|
); |
100
|
|
|
}); |
101
|
|
|
|
102
|
|
|
$this->client->on('reaction_added', function (\Slack\Payload $payload) use($room) { |
103
|
|
|
if ($payload->getData()['item']['type'] != 'message' and $payload->getData()['item']['channel'] != $room->id()) { |
|
|
|
|
104
|
|
|
return; |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
$this->onMessage( |
108
|
|
|
$room->middleware(), |
109
|
|
|
Message::unguarded(function() use($room, $payload) { |
110
|
|
|
$message = $payload->getData(); |
111
|
|
|
$message['mentions'] = [$message['item_user']]; |
112
|
|
|
$message['text'] = 'Спасибо'; |
113
|
|
|
|
114
|
|
|
return new Message( |
|
|
|
|
115
|
|
|
(new MessageMapper($room, $message))->toArray(), |
116
|
|
|
$room |
117
|
|
|
); |
118
|
|
|
}) |
119
|
|
|
); |
120
|
|
|
}); |
121
|
|
|
|
122
|
|
|
$this->client->connect(); |
123
|
|
|
} |
124
|
|
|
|
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* @param Storage $middleware |
128
|
|
|
* @param Message $message |
129
|
|
|
*/ |
130
|
|
|
public function onMessage(Storage $middleware, Message $message) |
131
|
|
|
{ |
132
|
|
|
try { |
133
|
|
|
$middleware->handle($message); |
134
|
|
|
} catch (\Exception $e) { |
135
|
|
|
$this->logException($e); |
136
|
|
|
} |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
protected function onClose() |
140
|
|
|
{ |
141
|
|
|
$this->client->disconnect(); |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
/** |
145
|
|
|
* @param \Exception $e |
146
|
|
|
*/ |
147
|
|
|
protected function onError(\Exception $e) |
148
|
|
|
{ |
149
|
|
|
$this->logException($e); |
150
|
|
|
} |
151
|
|
|
/** |
152
|
|
|
* @return string |
153
|
|
|
*/ |
154
|
|
|
public function version() |
155
|
|
|
{ |
156
|
|
|
return 'SlackBot v0.1b'; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
/** |
160
|
|
|
* @return ClientInterface |
161
|
|
|
*/ |
162
|
|
|
public function run(): ClientInterface |
163
|
|
|
{ |
164
|
|
|
$this->loop->run(); |
165
|
|
|
|
166
|
|
|
return $this; |
167
|
|
|
} |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* @param \Exception $e |
171
|
|
|
*/ |
172
|
|
View Code Duplication |
protected function logException(\Exception $e) |
|
|
|
|
173
|
|
|
{ |
174
|
|
|
\Log::error( |
175
|
|
|
$e->getMessage() . ' in ' . $e->getFile() . ':' . $e->getLine() . "\n" . |
176
|
|
|
$e->getTraceAsString() . "\n" . |
177
|
|
|
str_repeat('=', 80) . "\n" |
178
|
|
|
); |
179
|
|
|
} |
180
|
|
|
|
181
|
|
|
/** |
182
|
|
|
* @param string $id |
183
|
|
|
* |
184
|
|
|
* @return User |
185
|
|
|
*/ |
186
|
|
|
public function getUserById($id) |
187
|
|
|
{ |
188
|
|
|
$user = null; |
189
|
|
|
|
190
|
|
|
$this->client->getUserById($id)->then(function(\Slack\User $slackUser) use(&$user) { |
191
|
|
|
$user = UserMapper::fromSlackObject( |
192
|
|
|
$slackUser |
193
|
|
|
); |
194
|
|
|
}); |
195
|
|
|
|
196
|
|
|
return $user; |
197
|
|
|
} |
198
|
|
|
} |
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.