diff --git a/config/ProjectConfiguration.class.php b/config/ProjectConfiguration.class.php index 4f89521..2de4abe 100644 --- a/config/ProjectConfiguration.class.php +++ b/config/ProjectConfiguration.class.php @@ -11,6 +11,7 @@ public function setup() $this->enablePlugins('sfGuardPlugin'); $this->enablePlugins('crewLessPlugin'); require_once sfConfig::get('sf_root_dir') . '/lib/vendor/XMPPHP/XMPP.php'; + require_once sfConfig::get('sf_root_dir') . '/lib/vendor/HipChat/HipChat.php'; $this->dispatcher->connect('context.load_factories', array($this, 'listenLoadFactoriesEvent')); } diff --git a/config/notifiers.yml.dist b/config/notifiers.yml.dist index b12cb07..b2b8525 100644 --- a/config/notifiers.yml.dist +++ b/config/notifiers.yml.dist @@ -41,4 +41,23 @@ XmppNotifier: server: jabber.yourdomain.com to: team-chatroom@conference.jabber.yourdomain.com type: groupchat +HipchatNotifier: + review-request: + enabled: 0 + message: "New review request for branch %branch%" + add-links: 1 + notify: 0 + color: "purple" + comment: + enabled: 0 + branch_message: "%branch% - %author% : %message%" + file_message: "%branch% - %author% : %message%" + line_message: "%branch% - %author% : %message%" + add-links: 1 + notify: 0 + projects: + 2: + token: "2718a778gavde59a8fa51aa7aze" + room: "developers" + user: "Crew" diff --git a/lib/notifiers/HipchatNotifier.class.php b/lib/notifiers/HipchatNotifier.class.php new file mode 100644 index 0000000..58a6f5c --- /dev/null +++ b/lib/notifiers/HipchatNotifier.class.php @@ -0,0 +1,46 @@ +getCurrentProjectConfig(); + + $token = $configCurrentProject['token']; + $room = $configCurrentProject['room']; + $user = $configCurrentProject['user']; + + list(,$eventName) = explode('.', $this->name); + $eventConfig = $this->getEventConfig($eventName); + + $notify = isset($eventConfig['notify']) && $eventConfig['notify'] == '1'; + + $color = Hipchat::COLOR_YELLOW; + if (isset($eventConfig['color'])) + { + $color = $eventConfig['color']; + } + + $hipChat = new HipChat($token); + $hipChat->message_room($room, $user, $message, $notify, $color, Hipchat::FORMAT_TEXT); + + return $this; + } + +} diff --git a/lib/vendor/HipChat/HipChat.php b/lib/vendor/HipChat/HipChat.php new file mode 100644 index 0000000..71799dc --- /dev/null +++ b/lib/vendor/HipChat/HipChat.php @@ -0,0 +1,347 @@ +api_target = $api_target; + $this->auth_token = $auth_token; + $this->api_version = $api_version; + } + + + ///////////////////////////////////////////////////////////////////////////// + // Room functions + ///////////////////////////////////////////////////////////////////////////// + + /** + * Get information about a room + * + * @see http://api.hipchat.com/docs/api/method/rooms/show + */ + public function get_room($room_id) { + $response = $this->make_request("rooms/show", array( + 'room_id' => $room_id + )); + return $response->room; + } + + /** + * Get list of rooms + * + * @see http://api.hipchat.com/docs/api/method/rooms/list + */ + public function get_rooms() { + $response = $this->make_request('rooms/list'); + return $response->rooms; + } + + /** + * Send a message to a room + * + * @see http://api.hipchat.com/docs/api/method/rooms/message + */ + public function message_room($room_id, $from, $message, $notify = false, + $color = self::COLOR_YELLOW, + $message_format = self::FORMAT_HTML) { + $args = array( + 'room_id' => $room_id, + 'from' => $from, + 'message' => utf8_encode($message), + 'notify' => (int)$notify, + 'color' => $color, + 'message_format' => $message_format + ); + $response = $this->make_request("rooms/message", $args, 'POST'); + return ($response->status == 'sent'); + } + + /** + * Get chat history for a room + * + * @see https://www.hipchat.com/docs/api/method/rooms/history + */ + public function get_rooms_history($room_id, $date = 'recent') { + $response = $this->make_request('rooms/history', array( + 'room_id' => $room_id, + 'date' => $date + )); + return $response->messages; + } + + /** + * Set a room's topic + * + * @see http://api.hipchat.com/docs/api/method/rooms/topic + */ + public function set_room_topic($room_id, $topic, $from = null) { + $args = array( + 'room_id' => $room_id, + 'topic' => utf8_encode($topic), + ); + + if ($from) { + $args['from'] = utf8_encode($from); + } + + $response = $this->make_request("rooms/topic", $args, 'POST'); + return ($response->status == 'ok'); + } + + /** + * Create a room + * + * @see http://api.hipchat.com/docs/api/method/rooms/create + */ + public function create_room($name, $owner_user_id = null, $privacy = null, $topic = null, $guest_access = null) { + $args = array( + 'name' => $name + ); + + if ($owner_user_id) { + $args['owner_user_id'] = $owner_user_id; + } + + if ($privacy) { + $args['privacy'] = $privacy; + } + + if ($topic) { + $args['topic'] = utf8_encode($topic); + } + + if ($guest_access) { + $args['guest_access'] = (int) $guest_access; + } + + // Return the std object + return $this->make_request("rooms/create", $args, 'POST'); + } + + /** + * Delete a room + * + * @see http://api.hipchat.com/docs/api/method/rooms/delete + */ + public function delete_room($room_id){ + $args = array( + 'room_id' => $room_id + ); + + $response = $this->make_request("rooms/delete", $args, 'POST'); + + return ($response->deleted == 'true'); + } + + ///////////////////////////////////////////////////////////////////////////// + // User functions + ///////////////////////////////////////////////////////////////////////////// + + /** + * Get information about a user + * + * @see http://api.hipchat.com/docs/api/method/users/show + */ + public function get_user($user_id) { + $response = $this->make_request("users/show", array( + 'user_id' => $user_id + )); + return $response->user; + } + + /** + * Get list of users + * + * @see http://api.hipchat.com/docs/api/method/users/list + */ + public function get_users() { + $response = $this->make_request('users/list'); + return $response->users; + } + + + ///////////////////////////////////////////////////////////////////////////// + // Helper functions + ///////////////////////////////////////////////////////////////////////////// + + /** + * Performs a curl request + * + * @param $url URL to hit. + * @param $post_data Data to send via POST. Leave null for GET request. + * + * @throws HipChat_Exception + * @return string + */ + public function curl_request($url, $post_data = null) { + + if (is_array($post_data)) { + $post_data = array_map(array($this, "sanitize_curl_parameter"), $post_data); + } + + $ch = curl_init($url); + curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 15); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verify_ssl); + if (is_array($post_data)) { + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); + } + $response = curl_exec($ch); + + // make sure we got a real response + if (strlen($response) == 0) { + $errno = curl_errno($ch); + $error = curl_error($ch); + throw new HipChat_Exception(self::STATUS_BAD_RESPONSE, + "CURL error: $errno - $error", $url); + } + + // make sure we got a 200 + $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); + if ($code != self::STATUS_OK) { + throw new HipChat_Exception($code, + "HTTP status code: $code, response=$response", $url); + } + + curl_close($ch); + + return $response; + } + + /** + * Sanitizes the given value as cURL parameter. + * + * The first value may not be a "@". PHP would treat this as a file upload + * + * @link http://www.php.net/manual/en/function.curl-setopt.php CURLOPT_POSTFIELDS + * + * @param string $value + * @return string + */ + private function sanitize_curl_parameter ($value) { + + if ((strlen($value) > 0) && ($value[0] === "@")) { + return substr_replace($value, '@', 0, 1); + } + + return $value; + } + + /** + * Make an API request using curl + * + * @param string $api_method Which API method to hit, like 'rooms/show'. + * @param array $args Data to send. + * @param string $http_method HTTP method (GET or POST). + * + * @throws HipChat_Exception + * @return mixed + */ + public function make_request($api_method, $args = array(), + $http_method = 'GET') { + $args['format'] = 'json'; + $args['auth_token'] = $this->auth_token; + $url = "$this->api_target/$this->api_version/$api_method"; + $post_data = null; + + // add args to url for GET + if ($http_method == 'GET') { + $url .= '?'.http_build_query($args); + } else { + $post_data = $args; + } + + $response = $this->curl_request($url, $post_data); + + // make sure response is valid json + $response = json_decode($response); + if (!$response) { + throw new HipChat_Exception(self::STATUS_BAD_RESPONSE, + "Invalid JSON received: $response", $url); + } + + return $response; + } + + /** + * Enable/disable verify_ssl. + * This is useful when curl spits back ssl verification errors, most likely + * due to outdated SSL CA bundle file on server. If you are able to, update + * that CA bundle. If not, call this method with false for $bool param before + * interacting with the API. + * + * @param bool $bool + * @return bool + * @link http://davidwalsh.name/php-ssl-curl-error + */ + public function set_verify_ssl($bool = true) { + $this->verify_ssl = (bool)$bool; + return $this->verify_ssl; + } + +} + + +class HipChat_Exception extends \Exception { + public function __construct($code, $info, $url) { + $message = "HipChat API error: code=$code, info=$info, url=$url"; + parent::__construct($message, (int)$code); + } +}