You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

258 lines
7.4 KiB

1 year ago
  1. <?php
  2. /**
  3. * This file is part of the PHP Telegram Bot example-bot package.
  4. * https://github.com/php-telegram-bot/example-bot/
  5. *
  6. * (c) PHP Telegram Bot Team
  7. *
  8. * For the full copyright and license information, please view the LICENSE
  9. * file that was distributed with this source code.
  10. */
  11. /**
  12. * User "/survey" command
  13. *
  14. * Example of the Conversation functionality in form of a simple survey.
  15. */
  16. namespace Longman\TelegramBot\Commands\UserCommands;
  17. use Longman\TelegramBot\Commands\UserCommand;
  18. use Longman\TelegramBot\Conversation;
  19. use Longman\TelegramBot\Entities\Keyboard;
  20. use Longman\TelegramBot\Entities\KeyboardButton;
  21. use Longman\TelegramBot\Entities\ServerResponse;
  22. use Longman\TelegramBot\Exception\TelegramException;
  23. use Longman\TelegramBot\Request;
  24. class SurveyCommand extends UserCommand
  25. {
  26. /**
  27. * @var string
  28. */
  29. protected $name = 'survey';
  30. /**
  31. * @var string
  32. */
  33. protected $description = 'Survey for bot users';
  34. /**
  35. * @var string
  36. */
  37. protected $usage = '/survey';
  38. /**
  39. * @var string
  40. */
  41. protected $version = '0.4.0';
  42. /**
  43. * @var bool
  44. */
  45. protected $need_mysql = true;
  46. /**
  47. * @var bool
  48. */
  49. protected $private_only = true;
  50. /**
  51. * Conversation Object
  52. *
  53. * @var Conversation
  54. */
  55. protected $conversation;
  56. /**
  57. * Main command execution
  58. *
  59. * @return ServerResponse
  60. * @throws TelegramException
  61. */
  62. public function execute(): ServerResponse
  63. {
  64. $message = $this->getMessage();
  65. $chat = $message->getChat();
  66. $user = $message->getFrom();
  67. $text = trim($message->getText(true));
  68. $chat_id = $chat->getId();
  69. $user_id = $user->getId();
  70. // Preparing response
  71. $data = [
  72. 'chat_id' => $chat_id,
  73. // Remove any keyboard by default
  74. 'reply_markup' => Keyboard::remove(['selective' => true]),
  75. ];
  76. if ($chat->isGroupChat() || $chat->isSuperGroup()) {
  77. // Force reply is applied by default so it can work with privacy on
  78. $data['reply_markup'] = Keyboard::forceReply(['selective' => true]);
  79. }
  80. // Conversation start
  81. $this->conversation = new Conversation($user_id, $chat_id, $this->getName());
  82. // Load any existing notes from this conversation
  83. $notes = &$this->conversation->notes;
  84. !is_array($notes) && $notes = [];
  85. // Load the current state of the conversation
  86. $state = $notes['state'] ?? 0;
  87. $result = Request::emptyResponse();
  88. // State machine
  89. // Every time a step is achieved the state is updated
  90. switch ($state) {
  91. case 0:
  92. if ($text === '') {
  93. $notes['state'] = 0;
  94. $this->conversation->update();
  95. $data['text'] = 'Type your name:';
  96. $result = Request::sendMessage($data);
  97. break;
  98. }
  99. $notes['name'] = $text;
  100. $text = '';
  101. // No break!
  102. case 1:
  103. if ($text === '') {
  104. $notes['state'] = 1;
  105. $this->conversation->update();
  106. $data['text'] = 'Type your surname:';
  107. $result = Request::sendMessage($data);
  108. break;
  109. }
  110. $notes['surname'] = $text;
  111. $text = '';
  112. // No break!
  113. case 2:
  114. if ($text === '' || !is_numeric($text)) {
  115. $notes['state'] = 2;
  116. $this->conversation->update();
  117. $data['text'] = 'Type your age:';
  118. if ($text !== '') {
  119. $data['text'] = 'Age must be a number';
  120. }
  121. $result = Request::sendMessage($data);
  122. break;
  123. }
  124. $notes['age'] = $text;
  125. $text = '';
  126. // No break!
  127. case 3:
  128. if ($text === '' || !in_array($text, ['M', 'F'], true)) {
  129. $notes['state'] = 3;
  130. $this->conversation->update();
  131. $data['reply_markup'] = (new Keyboard(['M', 'F']))
  132. ->setResizeKeyboard(true)
  133. ->setOneTimeKeyboard(true)
  134. ->setSelective(true);
  135. $data['text'] = 'Select your gender:';
  136. if ($text !== '') {
  137. $data['text'] = 'Choose a keyboard option to select your gender';
  138. }
  139. $result = Request::sendMessage($data);
  140. break;
  141. }
  142. $notes['gender'] = $text;
  143. // No break!
  144. case 4:
  145. if ($message->getLocation() === null) {
  146. $notes['state'] = 4;
  147. $this->conversation->update();
  148. $data['reply_markup'] = (new Keyboard(
  149. (new KeyboardButton('Share Location'))->setRequestLocation(true)
  150. ))
  151. ->setOneTimeKeyboard(true)
  152. ->setResizeKeyboard(true)
  153. ->setSelective(true);
  154. $data['text'] = 'Share your location:';
  155. $result = Request::sendMessage($data);
  156. break;
  157. }
  158. $notes['longitude'] = $message->getLocation()->getLongitude();
  159. $notes['latitude'] = $message->getLocation()->getLatitude();
  160. // No break!
  161. case 5:
  162. if ($message->getPhoto() === null) {
  163. $notes['state'] = 5;
  164. $this->conversation->update();
  165. $data['text'] = 'Insert your picture:';
  166. $result = Request::sendMessage($data);
  167. break;
  168. }
  169. $photo = $message->getPhoto()[0];
  170. $notes['photo_id'] = $photo->getFileId();
  171. // No break!
  172. case 6:
  173. if ($message->getContact() === null) {
  174. $notes['state'] = 6;
  175. $this->conversation->update();
  176. $data['reply_markup'] = (new Keyboard(
  177. (new KeyboardButton('Share Contact'))->setRequestContact(true)
  178. ))
  179. ->setOneTimeKeyboard(true)
  180. ->setResizeKeyboard(true)
  181. ->setSelective(true);
  182. $data['text'] = 'Share your contact information:';
  183. $result = Request::sendMessage($data);
  184. break;
  185. }
  186. $notes['phone_number'] = $message->getContact()->getPhoneNumber();
  187. // No break!
  188. case 7:
  189. $this->conversation->update();
  190. $out_text = '/Survey result:' . PHP_EOL;
  191. unset($notes['state']);
  192. foreach ($notes as $k => $v) {
  193. $out_text .= PHP_EOL . ucfirst($k) . ': ' . $v;
  194. }
  195. $data['photo'] = $notes['photo_id'];
  196. $data['caption'] = $out_text;
  197. $this->conversation->stop();
  198. $result = Request::sendPhoto($data);
  199. break;
  200. }
  201. return $result;
  202. }
  203. }