Skip to content

Commit 9828c73

Browse files
committed
Merge pull request #104 from MBoretto/feature/smartinterface
Feature/smartinterface
2 parents 3cddf7b + 7d434dd commit 9828c73

File tree

12 files changed

+1324
-53
lines changed

12 files changed

+1324
-53
lines changed

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ You can also store inline query and chosen inline query in the database.
348348
### Channels Support
349349

350350
All methods implemented can be used to manage channels.
351-
With [admin commands](#admin-commands) you can manage your channel directly with your bot private chat.
351+
With [admin commands](#admin-commands) you can manage your channels directly with your bot private chat.
352352

353353
### Commands
354354

@@ -397,7 +397,7 @@ $telegram->setCommandConfig('date', ['google_api_key' => 'your_google_api_key_he
397397
Enabling this feature, the admin bot can perform some super user commands like:
398398
- Send message to all chats */sendtoall*
399399
- List all the chats started with the bot */chats*
400-
- Send a message to a channel */sendtochannel* (NEW! see below how to configure it)
400+
- Send a message to your channels */sendtochannel* (NEW! see below how to configure it)
401401
You can specify one or more admins with this option:
402402

403403
```php
@@ -414,7 +414,11 @@ To enable this feature follow these steps:
414414
- Enable admin interface for your user as explained in the admin section above.
415415
- Enter your channel name as a parameter for the */sendtochannel* command:
416416
```php
417-
$telegram->setCommandConfig('sendtochannel', ['your_channel' => '@type_here_your_channel']);
417+
$telegram->setCommandConfig('sendtochannel', ['your_channel' => ['@type_here_your_channel']]);
418+
```
419+
- If you want to manage more channels:
420+
```php
421+
$telegram->setCommandConfig('sendtochannel', ['your_channel'=>['@type_here_your_channel', '@type_here_another_channel', '@and_so_on']]);
418422
```
419423
- Enjoy!
420424

src/Commands/AdminCommands/SendtochannelCommand.php

Lines changed: 292 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@
1010

1111
namespace Longman\TelegramBot\Commands\AdminCommands;
1212

13-
use Longman\TelegramBot\Commands\AdminCommand;
1413
use Longman\TelegramBot\Request;
14+
use Longman\TelegramBot\Conversation;
15+
use Longman\TelegramBot\Commands\AdminCommand;
16+
use Longman\TelegramBot\Entities\Message;
17+
use Longman\TelegramBot\Entities\ReplyKeyboardHide;
18+
use Longman\TelegramBot\Entities\ReplyKeyboardMarkup;
19+
use Longman\TelegramBot\Exception\TelegramException;
1520

16-
/**
17-
* Admin "/sendtochannel" command
18-
*/
1921
class SendtochannelCommand extends AdminCommand
2022
{
2123
/**#@+
@@ -24,46 +26,309 @@ class SendtochannelCommand extends AdminCommand
2426
protected $name = 'sendtochannel';
2527
protected $description = 'Send message to a channel';
2628
protected $usage = '/sendtochannel <message to send>';
27-
protected $version = '0.1.1';
28-
protected $need_mysql = false;
29+
protected $version = '0.1.4';
30+
protected $need_mysql = true;
2931
/**#@-*/
3032

3133
/**
32-
* Execute command
34+
* Conversation Object
3335
*
34-
* @todo Don't use empty, as a string of '0' is regarded to be empty
35-
*
36-
* @return boolean
36+
* @var Longman\TelegramBot\Conversation
37+
*/
38+
protected $conversation;
39+
40+
/**
41+
* {@inheritdoc}
3742
*/
3843
public function execute()
3944
{
4045
$message = $this->getMessage();
46+
$chat_id = $message->getChat()->getId();
47+
$user_id = $message->getFrom()->getId();
48+
$type = $message->getType();
49+
// 'Cast' the command type into message this protect the machine state
50+
// if the commmad is recolled when the conversation is already started
51+
$type = ($type == 'command') ? 'Message' : $type;
52+
$text = trim($message->getText(true));
53+
54+
$data = [];
55+
$data['chat_id'] = $chat_id;
56+
57+
// Conversation
58+
$this->conversation = new Conversation($user_id, $chat_id, $this->getName());
59+
60+
$channels = (array) $this->getConfig('your_channel');
61+
if (!isset($this->conversation->notes['state'])) {
62+
$state = (count($channels) == 0) ? -1 : 0;
63+
$this->conversation->notes['last_message_id'] = $message->getMessageId();
64+
} else {
65+
$state = $this->conversation->notes['state'];
66+
}
67+
switch ($state) {
68+
case -1:
69+
// getConfig has not been configured asking for channel to administer
70+
if ($type != 'Message' || empty($text)) {
71+
$this->conversation->notes['state'] = -1;
72+
$this->conversation->update();
73+
74+
$data['text'] = 'Insert the channel name: (@yourchannel)';
75+
$data['reply_markup'] = new ReplyKeyBoardHide(['selective' => true]);
76+
$result = Request::sendMessage($data);
4177

78+
break;
79+
}
80+
$this->conversation->notes['channel'] = $text;
81+
$this->conversation->notes['last_message_id'] = $message->getMessageId();
82+
// Jump to state 1
83+
goto insert;
84+
85+
// no break
86+
default:
87+
case 0:
88+
// getConfig has been configured choose channel
89+
if ($type != 'Message' || !in_array($text, $channels)) {
90+
$this->conversation->notes['state'] = 0;
91+
$this->conversation->update();
92+
93+
$keyboard = [];
94+
foreach ($channels as $channel) {
95+
$keyboard[] = [$channel];
96+
}
97+
$reply_keyboard_markup = new ReplyKeyboardMarkup(
98+
[
99+
'keyboard' => $keyboard ,
100+
'resize_keyboard' => true,
101+
'one_time_keyboard' => true,
102+
'selective' => true
103+
]
104+
);
105+
$data['reply_markup'] = $reply_keyboard_markup;
106+
$data['text'] = 'Select a channel';
107+
if ($type != 'Message' || !in_array($text, $channels)) {
108+
$data['text'] = 'Select a channel from the keyboard:';
109+
}
110+
$result = Request::sendMessage($data);
111+
break;
112+
}
113+
$this->conversation->notes['channel'] = $text;
114+
$this->conversation->notes['last_message_id'] = $message->getMessageId();
115+
116+
// no break
117+
case 1:
118+
insert:
119+
if ($this->conversation->notes['last_message_id'] == $message->getMessageId() || ($type == 'Message' && empty($text))) {
120+
$this->conversation->notes['state'] = 1;
121+
$this->conversation->update();
122+
123+
$data['reply_markup'] = new ReplyKeyBoardHide(['selective' => true]);
124+
$data['text'] = 'Insert the content you want to share: text, photo, audio...';
125+
$result = Request::sendMessage($data);
126+
break;
127+
}
128+
$this->conversation->notes['last_message_id'] = $message->getMessageId();
129+
$this->conversation->notes['message'] = $message->reflect();
130+
$this->conversation->notes['message_type'] = $type;
131+
132+
// no break
133+
case 2:
134+
if ($this->conversation->notes['last_message_id'] == $message->getMessageId() || !($text == 'Yes' || $text == 'No')) {
135+
$this->conversation->notes['state'] = 2;
136+
$this->conversation->update();
137+
138+
// Execute this just with object that allow caption
139+
if ($this->conversation->notes['message_type'] == 'Video' || $this->conversation->notes['message_type'] == 'Photo') {
140+
$keyboard = [['Yes', 'No']];
141+
$reply_keyboard_markup = new ReplyKeyboardMarkup(
142+
[
143+
'keyboard' => $keyboard ,
144+
'resize_keyboard' => true,
145+
'one_time_keyboard' => true,
146+
'selective' => true
147+
]
148+
);
149+
$data['reply_markup'] = $reply_keyboard_markup;
150+
151+
$data['text'] = 'Would you insert caption?';
152+
if ($this->conversation->notes['last_message_id'] != $message->getMessageId() && !($text == 'Yes' || $text == 'No')) {
153+
$data['text'] = 'Would you insert a caption?' . "\n" . 'Type Yes or No';
154+
}
155+
$result = Request::sendMessage($data);
156+
break;
157+
}
158+
}
159+
$this->conversation->notes['set_caption'] = false;
160+
if ($text == 'Yes') {
161+
$this->conversation->notes['set_caption'] = true;
162+
}
163+
$this->conversation->notes['last_message_id'] = $message->getMessageId();
164+
// no break
165+
case 3:
166+
if (($this->conversation->notes['last_message_id'] == $message->getMessageId() || $type != 'Message' ) && $this->conversation->notes['set_caption']) {
167+
$this->conversation->notes['state'] = 3;
168+
$this->conversation->update();
169+
170+
$data['text'] = 'Insert caption:';
171+
$data['reply_markup'] = new ReplyKeyBoardHide(['selective' => true]);
172+
$result = Request::sendMessage($data);
173+
break;
174+
}
175+
$this->conversation->notes['last_message_id'] = $message->getMessageId();
176+
$this->conversation->notes['caption'] = $text;
177+
// no break
178+
case 4:
179+
if ($this->conversation->notes['last_message_id'] == $message->getMessageId() || !($text == 'Yes' || $text == 'No')) {
180+
$this->conversation->notes['state'] = 4;
181+
$this->conversation->update();
182+
183+
$data['text'] = 'Message will look like this:';
184+
$result = Request::sendMessage($data);
185+
186+
if ($this->conversation->notes['message_type'] != 'command') {
187+
if ($this->conversation->notes['set_caption']) {
188+
$data['caption'] = $this->conversation->notes['caption'];
189+
}
190+
$result = $this->sendBack(new Message($this->conversation->notes['message'], 'thisbot'), $data);
191+
192+
$data['text'] = 'Would you post it?';
193+
if ($this->conversation->notes['last_message_id'] != $message->getMessageId() && !($text == 'Yes' || $text == 'No')) {
194+
$data['text'] = 'Would you post it?' . "\n" . 'Press Yes or No';
195+
}
196+
$keyboard = [['Yes', 'No']];
197+
$reply_keyboard_markup = new ReplyKeyboardMarkup(
198+
[
199+
'keyboard' => $keyboard ,
200+
'resize_keyboard' => true,
201+
'one_time_keyboard' => true,
202+
'selective' => true
203+
]
204+
);
205+
$data['reply_markup'] = $reply_keyboard_markup;
206+
$result = Request::sendMessage($data);
207+
}
208+
break;
209+
}
210+
211+
$this->conversation->notes['post_message'] = false;
212+
if ($text == 'Yes') {
213+
$this->conversation->notes['post_message'] = true;
214+
}
215+
$this->conversation->notes['last_message_id'] = $message->getMessageId();
216+
// no break
217+
case 5:
218+
$data['reply_markup'] = new ReplyKeyBoardHide(['selective' => true]);
219+
220+
if ($this->conversation->notes['post_message']) {
221+
$data['text'] = $this->publish(
222+
new Message($this->conversation->notes['message'], 'anystring'),
223+
$this->conversation->notes['channel'],
224+
$this->conversation->notes['caption']
225+
);
226+
} else {
227+
$data['text'] = 'Abort by user, message not sent..';
228+
}
229+
230+
$this->conversation->stop();
231+
$result = Request::sendMessage($data);
232+
}
233+
return $result;
234+
}
235+
236+
/**
237+
* {@inheritdoc}
238+
*/
239+
public function executeNoDB()
240+
{
241+
$message = $this->getMessage();
242+
$text = trim($message->getText(true));
42243
$chat_id = $message->getChat()->getId();
43-
$text = $message->getText(true);
244+
245+
$data = [];
246+
$data['chat_id'] = $chat_id;
44247

45248
if (empty($text)) {
46-
$text_back = 'Write the message to send: /sendtochannel <message>';
249+
$data['text'] = 'Usage: /sendtochannel <text>';
47250
} else {
48-
$your_channel = $this->getConfig('your_channel');
49-
//Send message to channel
50-
$data = [
51-
'chat_id' => $your_channel,
52-
'text' => $text,
53-
];
54-
55-
if (Request::sendMessage($data)->isOk()) {
56-
$text_back = 'Message sent succesfully to: ' . $your_channel;
57-
} else {
58-
$text_back = 'Sorry message not sent to: ' . $your_channel;
59-
}
251+
$channels = (array) $this->getConfig('your_channel');
252+
$first_channel = $channels[0];
253+
$data['text'] = $this->publish(new Message($message->reflect(), 'anystring'), $first_channel);
60254
}
255+
return Request::sendMessage($data);
256+
}
61257

258+
/**
259+
* Publish a message to a channel and return success or failure message
260+
*
261+
* @param Entities\Message $message
262+
* @param int $channel
263+
* @param string|null $caption
264+
*
265+
* @return string
266+
*/
267+
protected function publish(Message $message, $channel, $caption = null)
268+
{
62269
$data = [
63-
'chat_id' => $chat_id,
64-
'text' => $text_back,
270+
'chat_id' => $channel,
271+
'caption' => $caption,
65272
];
66273

67-
return Request::sendMessage($data);
274+
if ($this->sendBack($message, $data)->isOk()) {
275+
$response = 'Message sent successfully to: ' . $channel;
276+
} else {
277+
$response =
278+
'Message not sent to: ' . $channel . "\n" .
279+
'- Does the channel exist?' . "\n" .
280+
'- Is the bot an admin of the channel?';
281+
}
282+
return $response;
283+
}
284+
285+
/**
286+
* SendBack
287+
*
288+
* Received a message, the bot can send a copy of it to another chat/channel.
289+
* You don't have to care about the type of the message, the function detect it and use the proper
290+
* REQUEST:: function to send it.
291+
* $data include all the var that you need to send the message to the proper chat
292+
*
293+
* @todo This method will be moved at an higher level maybe in AdminCommand or Command
294+
* @todo Looking for a more significative name
295+
*
296+
* @param Entities\Message $message
297+
* @param array $data
298+
*
299+
* @return Entities\ServerResponse
300+
*/
301+
protected function sendBack(Message $message, array $data)
302+
{
303+
$type = $message->getType();
304+
$type = ($type == 'command') ? 'Message' : $type;
305+
if ($type == 'Message') {
306+
$data['text'] = $message->getText(true);
307+
} elseif ($type == 'Audio') {
308+
$data['audio'] = $message->getAudio()->getFileId();
309+
$data['duration'] = $message->getAudio()->getDuration();
310+
$data['performer'] = $message->getAudio()->getPerformer();
311+
$data['title'] = $message->getAudio()->getTitle();
312+
} elseif ($type == 'Document') {
313+
$data['document'] = $message->getDocument()->getFileId();
314+
} elseif ($type == 'Photo') {
315+
$data['photo'] = $message->getPhoto()[0]->getFileId();
316+
} elseif ($type == 'Sticker') {
317+
$data['sticker'] = $message->getSticker()->getFileId();
318+
} elseif ($type == 'Video') {
319+
$data['video'] = $message->getVideo()->getFileId();
320+
} elseif ($type == 'Voice') {
321+
$data['voice'] = $message->getVoice()->getFileId();
322+
} elseif ($type == 'Location') {
323+
$data['latitude'] = $message->getLocation()->getLatitude();
324+
$data['longitude'] = $message->getLocation()->getLongitude();
325+
}
326+
$callback_path = 'Longman\TelegramBot\Request';
327+
$callback_function = 'send' . $type;
328+
if (! method_exists($callback_path, $callback_function)) {
329+
throw new TelegramException('Methods: ' . $callback_function . ' not found in class Request.');
330+
}
331+
332+
return call_user_func_array($callback_path . '::' . $callback_function, [$data]);
68333
}
69334
}

src/Commands/Command.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@ public function executeNoDB()
159159
return Request::sendMessage($data);
160160
}
161161

162-
163162
/**
164163
* Get update object
165164
*

0 commit comments

Comments
 (0)