99use PhpTelegramBot \Core \ApiMethods \UpdatesMessages ;
1010use PhpTelegramBot \Core \Contracts \Factory ;
1111use PhpTelegramBot \Core \Entities \Update ;
12+ use PhpTelegramBot \Core \Events \Event ;
13+ use PhpTelegramBot \Core \Events \IncomingUpdate ;
14+ use PhpTelegramBot \Core \Exceptions \InvalidArgumentException ;
1215use PhpTelegramBot \Core \Exceptions \TelegramException ;
1316use Psr \Http \Message \StreamInterface ;
1417
@@ -101,6 +104,7 @@ protected function extractFiles(array $fields, array &$data): array
101104 foreach ($ data [$ key ] as &$ item ) {
102105 $ streams += $ this ->extractFiles ($ value , $ item );
103106 }
107+
104108 } else {
105109
106110 $ streams += $ this ->extractFiles ($ value , $ data [$ key ]);
@@ -114,7 +118,7 @@ protected function send(string $methodName, ?array $data = null, string|array|nu
114118 {
115119 $ requestUri = $ this ->apiBaseUri . '/bot ' . $ this ->botToken . '/ ' . $ methodName ;
116120
117- $ streams = $ this ->extractFiles (self ::inputFileFields ()[$ methodName ] ?? null , $ data );
121+ $ streams = $ this ->extractFiles (self ::inputFileFields ()[$ methodName ] ?? [] , $ data );
118122
119123 $ response = match (true ) {
120124 empty ($ data ) => $ this ->client ->get ($ requestUri ),
@@ -177,15 +181,210 @@ public function handleGetUpdates(int $pollingInterval = 30, ?array $allowedUpdat
177181 public function handle ()
178182 {
179183 $ data = file_get_contents ('php://input ' );
184+
185+ if (empty ($ data )) {
186+ return ;
187+ }
188+
180189 $ json = json_decode ($ data , true );
181190
182191 $ update = new Update ($ json );
183192
184193 $ this ->processUpdate ($ update );
185194 }
186195
196+ protected function dispatch (Event $ event )
197+ {
198+ $ listeners = $ this ->eventListeners [$ event ::class] ?? [];
199+
200+ foreach ($ listeners as $ callback ) {
201+ $ callback ($ event , $ this );
202+ }
203+ }
204+
187205 protected function processUpdate (Update $ update )
188206 {
189- //
207+ // IncomingUpdate Event
208+ $ this ->dispatch (new IncomingUpdate ($ update ));
209+
210+ // Update Types
211+ foreach ($ this ->updateTypeCallbacks as $ key => $ callbacks ) {
212+ if (! is_null ($ update ->$ key )) {
213+ foreach ($ callbacks as $ callback ) {
214+ $ callback ($ update , $ this );
215+ }
216+ }
217+ }
218+
219+ // Message Types
220+ $ message = $ update ->getMessage ();
221+ if ($ message !== null ) {
222+ foreach ($ this ->messageTypeCallbacks as $ key => $ callbacks ) {
223+ if (! is_null ($ message ->$ key )) {
224+ foreach ($ callbacks as $ callback ) {
225+ $ callback ($ update , $ this );
226+ }
227+ }
228+ }
229+ }
230+
231+ // Commands
232+ $ command = $ update ->getMessage ()?->getText() ?? null ;
233+ if ($ command !== null && str_starts_with ($ command , '/ ' )) {
234+ // Cut / from beginning
235+ $ command = ltrim ($ command , '/ ' );
236+
237+ // Cut username
238+ $ command = explode (' ' , $ command , 2 )[0 ];
239+ [$ command , $ username ] = explode ('@ ' , $ command , 2 ) + [null , null ];
240+
241+ // TODO: Check if the username belongs to this bot...
242+
243+ // Get callbacks
244+ $ callbacks = $ this ->commandCallbacks [$ command ] ?? [];
245+
246+ foreach ($ callbacks as $ callback ) {
247+ $ callback ($ update , $ this );
248+ }
249+ }
250+ }
251+
252+ /**
253+ * @var array<class-string<Event>, array<callable>>
254+ */
255+ protected array $ eventListeners = [];
256+
257+ /**
258+ * @param class-string<Event> $event
259+ * @param callable|array<callable> $callback
260+ * @return $this
261+ */
262+ public function registerEventListener (string $ event , callable |array $ callback ): static
263+ {
264+ if (is_callable ($ callback )) {
265+ $ callback = [$ callback ];
266+ }
267+
268+ if (! is_subclass_of ($ event , Event::class)) {
269+ throw new InvalidArgumentException ("$ event is not a PhpTelegramBot Event " );
270+ }
271+
272+ $ this ->eventListeners [$ event ] = array_merge ($ this ->eventListeners [$ event ] ?? [], $ callback );
273+
274+ return $ this ;
275+ }
276+
277+ /**
278+ * @param array<class-string<Event>, callable|array<callable>> $callbacks
279+ * @return $this
280+ */
281+ public function registerEventListeners (array $ callbacks ): static
282+ {
283+ foreach ($ callbacks as $ event => $ callback ) {
284+ $ this ->registerEventListener ($ event , $ callback );
285+ }
286+
287+ return $ this ;
288+ }
289+
290+ /**
291+ * @var array<string, array<callable>>
292+ */
293+ protected array $ updateTypeCallbacks = [];
294+
295+ /**
296+ * @param callable|array<callable> $callback
297+ * @return $this
298+ */
299+ public function registerUpdateType (string $ updateType , callable |array $ callback ): static
300+ {
301+ if (is_callable ($ callback )) {
302+ $ callback = [$ callback ];
303+ }
304+
305+ $ this ->updateTypeCallbacks [$ updateType ] = array_merge ($ this ->updateTypeCallbacks [$ updateType ] ?? [], $ callback );
306+
307+ return $ this ;
308+ }
309+
310+ /**
311+ * @param array<string, callable|array<callable>> $callbacks
312+ * @return $this
313+ */
314+ public function registerUpdateTypes (array $ callbacks ): Telegram
315+ {
316+ foreach ($ callbacks as $ type => $ callback ) {
317+ $ this ->registerUpdateType ($ type , $ callback );
318+ }
319+
320+ return $ this ;
321+ }
322+
323+ /**
324+ * @var array<string, array<callable>>
325+ */
326+ protected array $ messageTypeCallbacks = [];
327+
328+ /**
329+ * @param callable|array<callable> $callback
330+ * @return $this
331+ */
332+ public function registerMessageType (string $ messageType , array |callable $ callback ): static
333+ {
334+ if (is_callable ($ callback )) {
335+ $ callback = [$ callback ];
336+ }
337+
338+ $ this ->messageTypeCallbacks [$ messageType ] = array_merge ($ this ->messageTypeCallbacks [$ messageType ] ?? [], $ callback );
339+
340+ return $ this ;
341+ }
342+
343+ /**
344+ * @param array<string, callable|array<callable>> $callbacks
345+ * @return $this
346+ */
347+ public function registerMessageTypes (array $ callbacks ): static
348+ {
349+ foreach ($ callbacks as $ messageType => $ callback ) {
350+ $ this ->registerMessageType ($ messageType , $ callback );
351+ }
352+
353+ return $ this ;
354+ }
355+
356+ /**
357+ * @var array<string, array<callable>>
358+ */
359+ protected array $ commandCallbacks = [];
360+
361+ /**
362+ * @param callable|array<callable> $callback
363+ * @return $this
364+ */
365+ public function registerCommand (string $ command , callable |array $ callback ): static
366+ {
367+ $ command = ltrim ($ command , '/ ' );
368+
369+ if (is_callable ($ callback )) {
370+ $ callback = [$ callback ];
371+ }
372+
373+ $ this ->commandCallbacks [$ command ] = array_merge ($ this ->commandCallbacks [$ command ] ?? [], $ callback );
374+
375+ return $ this ;
376+ }
377+
378+ /**
379+ * @param array<string, callable|array<callable>> $callbacks
380+ * @return $this
381+ */
382+ public function registerCommands (array $ callbacks ): static
383+ {
384+ foreach ($ callbacks as $ command => $ callback ) {
385+ $ this ->registerCommand ($ command , $ callback );
386+ }
387+
388+ return $ this ;
190389 }
191390}
0 commit comments