private function setReminder(Command $command, string $commandName) : Promise { return resolve(function () use($command, $commandName) { $intervalParser = new IntervalParser(); switch ($commandName) { case 'in': $parameters = $intervalParser->normalizeTimeInterval(implode(" ", $command->getParameters())); $expression = IntervalParser::$intervalSeparatorDefinitions . IntervalParser::$intervalWithTrailingData; if (preg_match($expression, $parameters, $matches)) { $time = $matches['interval'] ?? false; $text = $matches['trailing'] ?? false; } break; case 'at': $time = $command->getParameter(0) ?? false; // 24hrs if ($time && preg_match(self::TIME_FORMAT_REGEX, $time)) { // maybe @TODO support !!at monday next week remind? $text = implode(" ", array_diff($command->getParameters(), array($time))); } break; case 'reminder': $parameters = implode(" ", $command->getParameters()); if (!preg_match(self::REMINDER_REGEX, $parameters, $matches)) { return $this->chatClient->postMessage($command->getRoom(), self::USAGE); } $time = $matches[2] ?? ''; $text = $matches[1] ?? false; if ($time !== '') { $time = $intervalParser->normalizeTimeInterval($time); } break; } if (!isset($time) || !$time) { return $this->chatClient->postMessage($command->getRoom(), "Have a look at the time again, yo!"); } if (!isset($text) || !$text) { return $this->chatClient->postMessage($command->getRoom(), self::USAGE); } $timestamp = strtotime($time) ?: strtotime("+{$time}"); // false|int if (!$timestamp) { return $this->chatClient->postMessage($command->getRoom(), "Have a look at the time again, yo!"); } $key = (string) $command->getId(); $value = ['id' => $key, 'text' => $text, 'delay' => $time, 'userId' => $command->getUserId(), 'username' => $command->getUserName(), 'timestamp' => $timestamp]; $seconds = $timestamp - time(); if ($seconds <= 0) { return $this->chatClient->postReply($command, "I guess I'm late: " . $text); } if ((yield $this->storage->set($key, $value, $command->getRoom()))) { $watcher = once(function () use($command, $value, $key) { (yield $this->storage->unset($key, $command->getRoom())); return $this->chatClient->postReply($command, $value['text']); }, $seconds * 1000); $this->watchers[] = $watcher; return $this->chatClient->postMessage($command->getRoom(), "Reminder set."); } return $this->chatClient->postMessage($command->getRoom(), "Dunno what happened but I couldn't set the reminder."); }); }