diff --git a/src/applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php b/src/applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php index 0a04a29380..9a5f5b0ec5 100644 --- a/src/applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php +++ b/src/applications/transactions/feed/PhabricatorApplicationTransactionFeedStory.php @@ -1,51 +1,56 @@ getValue('objectPHID'); } public function getRequiredObjectPHIDs() { return array( $this->getPrimaryTransactionPHID(), ); } public function getRequiredHandlePHIDs() { $phids = array(); $phids[] = array($this->getValue('objectPHID')); $phids[] = $this->getPrimaryTransaction()->getRequiredHandlePHIDs(); return array_mergev($phids); } protected function getPrimaryTransactionPHID() { return head($this->getValue('transactionPHIDs')); } protected function getPrimaryTransaction() { return $this->getObject($this->getPrimaryTransactionPHID()); } public function renderView() { $view = new PhabricatorFeedStoryView(); $view->setViewed($this->getHasViewed()); $href = $this->getHandle($this->getPrimaryObjectPHID())->getURI(); $view->setHref($view); $xaction_phids = $this->getValue('transactionPHIDs'); $xaction = $this->getObject(head($xaction_phids)); $xaction->setHandles($this->getHandles()); $view->setTitle($xaction->getTitleForFeed()); $view->setOneLineStory(true); return $view; } + public function renderText() { + // TODO: This is grotesque; the feed notification handler relies on it. + return strip_tags($this->renderView()->render()); + } + } diff --git a/src/infrastructure/daemon/bot/handler/PhabricatorBotDifferentialNotificationHandler.php b/src/infrastructure/daemon/bot/handler/PhabricatorBotDifferentialNotificationHandler.php index 3a252cfc5e..2eddba29ad 100644 --- a/src/infrastructure/daemon/bot/handler/PhabricatorBotDifferentialNotificationHandler.php +++ b/src/infrastructure/daemon/bot/handler/PhabricatorBotDifferentialNotificationHandler.php @@ -1,56 +1,19 @@ getConfig('notification.actions'); - - if (!$this->skippedOldEvents) { - // Since we only want to post notifications about new events, skip - // everything that's happened in the past when we start up so we'll - // only process real-time events. - foreach ($iterator as $event) { - // Ignore all old events. - } - $this->skippedOldEvents = true; - return; - } - - foreach ($iterator as $event) { - $data = $event->getData(); - if (!$data || ($show !== null && !in_array($data['action'], $show))) { - continue; - } - - $actor_phid = $data['actor_phid']; - $phids = array($actor_phid); - $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles(); - $verb = DifferentialAction::getActionPastTenseVerb($data['action']); - - $actor_name = $handles[$actor_phid]->getName(); - $message_body = - "{$actor_name} {$verb} revision D".$data['revision_id']."."; - - $channels = $this->getConfig('notification.channels', array()); - foreach ($channels as $channel) { - $this->writeMessage( - id(new PhabricatorBotMessage()) - ->setCommand('MESSAGE') - ->setTarget($channel) - ->setBody($message_body)); - } + static $notified; + if (!$notified) { + phlog( + 'PhabricatorBotDifferentialNotificationHandler is deprecated, use '. + 'PhabricatorBotFeedNotificationHandler instead.'); + $notified = true; } } } diff --git a/src/infrastructure/daemon/bot/handler/PhabricatorBotFeedNotificationHandler.php b/src/infrastructure/daemon/bot/handler/PhabricatorBotFeedNotificationHandler.php index abec6a5664..eb4c5c6151 100644 --- a/src/infrastructure/daemon/bot/handler/PhabricatorBotFeedNotificationHandler.php +++ b/src/infrastructure/daemon/bot/handler/PhabricatorBotFeedNotificationHandler.php @@ -1,163 +1,167 @@ getConfig('notification.types'); if ($show) { $obj_type = str_replace('PhabricatorFeedStory', '', $story_class); if (!in_array(strtolower($obj_type), $show)) { return false; } } $verbosity = $this->getConfig('notification.verbosity', 3); $verbs = array(); switch ($verbosity) { case 2: $verbs[] = array( 'commented', 'added', 'changed', 'resigned', 'explained', 'modified', 'attached', 'edited', 'joined', 'left', 'removed' ); // fallthrough case 1: $verbs[] = array( 'updated', 'accepted', 'requested', 'planned', 'claimed', 'summarized', 'commandeered', 'assigned' ); // fallthrough case 0: $verbs[] = array( 'created', 'closed', 'raised', 'committed', 'reopened', 'deleted' ); break; case 3: default: return true; break; } $verbs = '/('.implode('|', array_mergev($verbs)).')/'; if (preg_match($verbs, $story_text)) { return true; } return false; } public function receiveMessage(PhabricatorBotMessage $message) { return; } public function runBackgroundTasks() { if ($this->startupDelay > 0) { // the event loop runs every 1s so delay enough to fully conenct $this->startupDelay--; return; } if ($this->lastSeenChronoKey == 0) { // Since we only want to post notifications about new stories, skip // everything that's happened in the past when we start up so we'll // only process real-time stories. $latest = $this->getConduit()->callMethodSynchronous( 'feed.query', array( 'limit'=>1 )); foreach ($latest as $story) { if ($story['chronologicalKey'] > $this->lastSeenChronoKey) { $this->lastSeenChronoKey = $story['chronologicalKey']; } } return; } $config_max_pages = $this->getConfig('notification.max_pages', 5); $config_page_size = $this->getConfig('notification.page_size', 10); $last_seen_chrono_key = $this->lastSeenChronoKey; $chrono_key_cursor = 0; // Not efficient but works due to feed.query API for ($max_pages = $config_max_pages; $max_pages > 0; $max_pages--) { $stories = $this->getConduit()->callMethodSynchronous( 'feed.query', array( 'limit'=>$config_page_size, 'after'=>$chrono_key_cursor, 'view'=>'text' )); foreach ($stories as $story) { if ($story['chronologicalKey'] == $last_seen_chrono_key) { // Caught up on feed return; } if ($story['chronologicalKey'] > $this->lastSeenChronoKey) { // Keep track of newest seen story $this->lastSeenChronoKey = $story['chronologicalKey']; } if (!$chrono_key_cursor || $story['chronologicalKey'] < $chrono_key_cursor) { // Keep track of oldest story on this page $chrono_key_cursor = $story['chronologicalKey']; } if (!$story['text'] || !$this->shouldShowStory($story)) { continue; } $channels = $this->getConfig('join'); - foreach ($channels as $channel) { + foreach ($channels as $channel_name) { + + $channel = id(new PhabricatorBotChannel()) + ->setName($channel_name); + $this->writeMessage( id(new PhabricatorBotMessage()) ->setCommand('MESSAGE') ->setTarget($channel) ->setBody($story['text'])); } } } } }