- <?php
- /**
- * Perforce Swarm
- *
- * @copyright 2015 Perforce Software. All rights reserved.
- * @license Please see LICENSE.txt in top-level readme folder of this distribution.
- * @version <release>/<patch>
- */
- namespace Slack;
- use Activity\Model\Activity;
- use Comments\Model\Comment;
- use P4\Spec\Change;
- use Projects\Model\Project;
- use Zend\Mvc\MvcEvent;
- use Zend\Http\Client;
- use Zend\Http\Request;
- use Zend\Json\Json;
- class Module
- {
- /**
- * Connect to queue event manager to handle changes.
- *
- * @param MvcEvent $event the bootstrap event
- * @return void
- */
- public function onBootstrap(MvcEvent $event)
- {
- $application = $event->getApplication();
- $services = $application->getServiceManager();
- $manager = $services->get('queue');
- $events = $manager->getEventManager();
- $logger = $services->get('logger');
- $filters = $services->get('InputFilterManager');
- $projectFilter = $filters->get('ProjectFilter');
- $projectFilter->add(
- array(
- 'name' => 'slack',
- 'required' => false,
- 'filters' => array(
- array(
- 'name' => 'Callback',
- 'options' => array(
- 'callback' => function ($value) {
- $value = (array)$value + array('enabled' => false, 'url' => '');
- return array(
- 'enabled' => (bool)$value['enabled'],
- 'url' => (string)$value['url']
- );
- }
- )
- )
- )
- )
- );
- $filters->setService('ProjectFilter', $projectFilter);
- $helpers = $services->get('ViewHelperManager');
- $helpers->get('headScript')->prependFile('/module/Slack/js/Slack.js', $type = 'text/javascript');
- // connect to all tasks and write activity data
- // we do this late (low-priority) so all handlers have
- // a chance to influence the activity model.
- $events->attach(
- array('task.commit', 'task.change'),
- function ($event) use ($services, $logger) {
- $logger->info("Slack: activity...");
- // task.change doesn't include the change object; fetch it if we need to
- $p4Admin = $services->get('p4_admin');
- $change = $event->getParam('change');
- if (!$change instanceof Change) {
- try {
- $change = Change::fetch($event->getParam('id'), $p4Admin);
- $event->setParam('change', $change);
- } catch (SpecNotFoundException $e) {
- } catch (\InvalidArgumentException $e) {
- }
- }
- // if this isn't a submitted change; nothing to do
- if (!$change instanceof Change || !$change->isSubmitted()) {
- $logger->info("Slack: not a change...");
- return;
- }
- // prepare list of projects affected by the change
- $impacted = Project::getAffectedByChange($change, $p4Admin);
- if ($impacted) {
- $logger->info("Slack: impacted...");
- $projects = Project::fetchAll(array(Project::FETCH_BY_IDS => array_keys($impacted)), $p4Admin);
- foreach ($projects as $projectId => $project) {
- $logger->info("Slack: impacted: $projectId");
- // URL to POST messages to Slack
- $slack = $project->getRawValue('slack');
- $enabled = $slack['enabled'];
- $url = $slack['url'];
- // Skip projects with no Slack URL
- if (!$enabled || !isset($url) || trim($url) === '') {
- continue;
- }
- // Host address of Swarm for link back URLs
- $host = $services->get('viewhelpermanager')->get('qualifiedUrl');
- // Icon and User for messages in feed Slack
- $config = $services->get('config');
- $max = (int) $config['slack']['max_length'];
- $message = new Message($host, $change, $max);
- $text = $message->toString();
- $this->postSlack($url, $text, $services);
- }
- }
- $logger->info("Slack: end.");
- },
- // set our priority, -110 puts us right before the end, but before the activity is published
- -110
- );
- }
- private function postSlack($url, $msg, $services)
- {
- $logger = $services->get('logger');
- $config = $services->get('config');
- $icon = $config['slack']['icon'];
- $user = $config['slack']['user'];
- $logger->info("Slack: POST to $url");
- $logger->info("Slack: user=$user");
- $logger->info("Slack: icon=$icon");
- try {
- $json = array(
- 'payload' => json_encode(
- array(
- 'username' => $user,
- 'icon_url' => $icon,
- 'text' => $msg
- )
- )
- );
- $request = new Request();
- $request->setMethod('POST');
- $request->setUri($url);
- $request->getPost()->fromArray($json);
- $client = new Client();
- $client->setEncType(Client::ENC_FORMDATA);
- // set the http client options; including any special overrides for our host
- $options = $config + array('http_client_options' => array());
- $options = (array) $options['http_client_options'];
- if (isset($options['hosts'][$client->getUri()->getHost()])) {
- $options = (array) $options['hosts'][$client->getUri()->getHost()] + $options;
- }
- unset($options['hosts']);
- $client->setOptions($options);
- // POST request
- $response = $client->dispatch($request);
- if (!$response->isSuccess()) {
- $logger->err(
- 'Slack failed to POST resource: ' . $url . ' (' .
- $response->getStatusCode() . " - " . $response->getReasonPhrase() . ').',
- array(
- 'request' => $client->getLastRawRequest(),
- 'response' => $client->getLastRawResponse()
- )
- );
- return false;
- }
- return true;
- } catch (\Exception $e) {
- $logger->err($e);
- }
- }
- public function getConfig()
- {
- return include __DIR__ . '/config/module.config.php';
- }
- public function getAutoloaderConfig()
- {
- return array(
- 'Zend\Loader\StandardAutoloader' => array(
- 'namespaces' => array(
- __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__,
- ),
- ),
- );
- }
- }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#6 | 19740 | Paul Allen | Load http client options from config and use in POST. Set SSL as required or disab...le as shown below: 'http_client_options' => array( 'sslverifypeer' => false, 'timeout' => 5, ), « |
9 years ago | |
#5 | 19537 | Paul Allen | Updated default icon and use Raw access to config data (Swarm no longer inserts the setter...s/getters). « | 9 years ago | |
#4 | 16611 | Paul Allen | Updates changes from Internal Swarm review. Use JS injection for dynamic Project Config...uration. « |
9 years ago | |
#3 | 16472 | Paul Allen | Minor fix for cropping change description and testing if the Slack Webhook is defined in t...he project. « | 9 years ago | |
#2 | 16469 | Paul Allen |
Trim Change description. Config option (default 80) |
9 years ago | |
#1 | 16466 | Paul Allen | Simple Change Activity Slack integration. | 9 years ago |