├── LICENSE ├── README.md ├── app ├── code │ └── community │ │ └── Mhauri │ │ └── HipChat │ │ ├── Helper │ │ └── Data.php │ │ ├── Model │ │ ├── Abstract.php │ │ ├── Notification.php │ │ ├── Observer.php │ │ ├── Queue.php │ │ └── Resource │ │ │ ├── Queue.php │ │ │ └── Queue │ │ │ └── Collection.php │ │ ├── etc │ │ ├── adminhtml.xml │ │ ├── config.xml │ │ └── system.xml │ │ └── sql │ │ └── mhauri_hipchat_setup │ │ └── upgrade-0.2.0-0.3.0.php ├── etc │ └── modules │ │ └── Mhauri_HipChat.xml └── locale │ └── en_US │ └── Mhauri_HipChat.csv ├── composer.json ├── lib └── Atlassian │ └── HipChat │ └── HipChat.php └── modman /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Marcel Hauri 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Magento HipChat 2 | ============= 3 | 4 | Magento HipChat allows you to send notifications to a HipChat room. 5 | 6 | Facts 7 | ----- 8 | - version: 0.3.0 9 | - extension key: magento-hipchat 10 | - [extension on GitHub](https://github.com/mhauri/magento-hipchat) 11 | - [direct download link](https://github.com/mhauri/magento-hipchat/archive/master.zip) 12 | 13 | Description 14 | ----------- 15 | This extension currently uses Version 1 of the HipChat API. 16 | 17 | For more information check the [API Documentation](https://www.hipchat.com/docs/api) 18 | It is recommended to use the message queue. A [configured CronJob](http://www.magentocommerce.com/wiki/1_-_installation_and_configuration/how_to_setup_a_cron_job) is a precondition for the message queue. 19 | 20 | **Available Notifications** 21 | 22 | - Admin User Login Failed 23 | - New Customer Account Created 24 | - New Orders 25 | 26 | Requirements 27 | ------------ 28 | - PHP >= 5.3.0 29 | 30 | Compatibility 31 | ------------- 32 | - Magento >= 1.8 33 | 34 | Installation Instructions 35 | ------------------------- 36 | 1. Install the extension via Composer or copy all the files into your document root. 37 | 2. Clear the cache, logout from the admin panel and then login again. 38 | 39 | Uninstallation 40 | -------------- 41 | 1. Remove all extension files from your Magento installation. 42 | 43 | Support 44 | ------- 45 | If you have any issues with this extension, open an issue on [GitHub](https://github.com/mhauri/magento-hipchat/issues). 46 | 47 | Contribution 48 | ------------ 49 | Any contribution is highly appreciated. The best way to contribute code is to open a [pull request on GitHub](https://help.github.com/articles/using-pull-requests). 50 | 51 | Developer 52 | --------- 53 | Marcel Hauri and all other [contributors](https://github.com/mhauri/magento-hipchat/contributors) 54 | 55 | License 56 | ------- 57 | Magento HipChat is licensed under the MIT License - see the LICENSE file for details 58 | 59 | Copyright 60 | --------- 61 | (c) 2015, Marcel Hauri -------------------------------------------------------------------------------- /app/code/community/Mhauri/HipChat/Helper/Data.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | 25 | class Mhauri_HipChat_Helper_Data extends Mage_Core_Helper_Abstract 26 | { 27 | 28 | } 29 | -------------------------------------------------------------------------------- /app/code/community/Mhauri/HipChat/Model/Abstract.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | 25 | require_once(Mage::getBaseDir('lib') . '/Atlassian/HipChat/HipChat.php'); 26 | 27 | abstract class Mhauri_HipChat_Model_Abstract extends Mage_Core_Model_Abstract 28 | { 29 | const LOG_FILE = 'hipchat.log'; 30 | const DEFAULT_SENDER = 'Magento HipChat'; 31 | 32 | const ENABLE_NOTIFICATION_PATH = 'hipchat/general/enable_notification'; 33 | const ENABLE_LOG_PATH = 'hipchat/general/enable_log'; 34 | const USE_QUEUE = 'hipchat/general/use_queue'; 35 | 36 | const TOKEN_PATH = 'hipchat/api/token'; 37 | const ROOM_ID_PATH = 'hipchat/api/room_id'; 38 | const FROM_NAME_PATH = 'hipchat/api/from_name'; 39 | 40 | const NEW_ORDER_PATH = 'hipchat/notification/new_order'; 41 | const NEW_CUSTOMER_ACCOUNT_PATH = 'hipchat/notification/new_customer_account'; 42 | const ADMIN_USER_LOGIN_FAILED_PATH = 'hipchat/notification/admin_user_login_failed'; 43 | 44 | const COLOR_YELLOW = 'yellow'; 45 | const COLOR_RED = 'red'; 46 | const COLOR_GRAY = 'gray'; 47 | const COLOR_GREEN = 'green'; 48 | const COLOR_PURPLE = 'purple'; 49 | const COLOR_RANDOM = 'random'; 50 | 51 | /** 52 | * Store the HipChat Model 53 | * @var null 54 | */ 55 | private $_hipchat = null; 56 | 57 | /** 58 | * Store the Message 59 | * @var string 60 | */ 61 | private $_message = ''; 62 | 63 | /** 64 | * Store the from name 65 | * @var string 66 | */ 67 | private $_fromName = null; 68 | 69 | /** 70 | * Store room id 71 | * @var null 72 | */ 73 | private $_roomId = null; 74 | 75 | /** 76 | * @var string 77 | */ 78 | private $_color = self::COLOR_YELLOW; 79 | 80 | /** 81 | * @var bool 82 | */ 83 | private $_notify = false; 84 | 85 | /** 86 | * Store token 87 | * @var null 88 | */ 89 | private $_token = null; 90 | 91 | 92 | protected function _construct() 93 | { 94 | $this->setToken(Mage::getStoreConfig(self::TOKEN_PATH, 0)); 95 | $this->setFromName(Mage::getStoreConfig(self::FROM_NAME_PATH, 0)); 96 | $this->setRoomId(Mage::getStoreConfig(self::ROOM_ID_PATH, 0)); 97 | 98 | if($this->isEnabled()) { 99 | $this->_hipchat = new HipChat\HipChat($this->getToken()); 100 | } 101 | parent::_construct(); 102 | } 103 | 104 | public function getHipChatModel() 105 | { 106 | return $this->_hipchat; 107 | } 108 | 109 | /** 110 | * @param string $token 111 | * @return $this 112 | */ 113 | public function setToken($token) 114 | { 115 | if(is_string($token)) { 116 | $this->_token = $token; 117 | } 118 | 119 | return $this; 120 | } 121 | 122 | /** 123 | * @return null|string 124 | */ 125 | public function getToken() 126 | { 127 | return $this->_token; 128 | } 129 | 130 | /** 131 | * @param $name 132 | * @return $this 133 | */ 134 | public function setFromName($name) 135 | { 136 | if(is_string($name)) { 137 | $this->_fromName = $name; 138 | } 139 | 140 | return $this; 141 | } 142 | 143 | /** 144 | * @return string 145 | */ 146 | public function getFromName() 147 | { 148 | if($this->_fromName) { 149 | return $this->_fromName; 150 | } 151 | 152 | return ''; 153 | } 154 | 155 | /** 156 | * @param $id 157 | * @return $this 158 | */ 159 | public function setRoomId($id) 160 | { 161 | if(is_numeric($id)) { 162 | $this->_roomId = $id; 163 | } 164 | 165 | return $this; 166 | } 167 | 168 | /** 169 | * @return null 170 | */ 171 | public function getRoomId() 172 | { 173 | return $this->_roomId; 174 | } 175 | 176 | /** 177 | * @param $color 178 | * @return $this 179 | */ 180 | public function setColor($color) 181 | { 182 | $allowedColors = array( 183 | self::COLOR_GRAY, 184 | self::COLOR_GREEN, 185 | self::COLOR_PURPLE, 186 | self::COLOR_RED, 187 | self::COLOR_YELLOW, 188 | self::COLOR_RANDOM 189 | ); 190 | 191 | if(is_string($color) && in_array($color, $allowedColors)) { 192 | $this->_color = $color; 193 | } 194 | return $this; 195 | } 196 | 197 | /** 198 | * @param bool $notify 199 | * @return $this 200 | */ 201 | public function setNotify($notify = false) 202 | { 203 | if(is_bool($notify)) { 204 | $this->_notify = $notify; 205 | } 206 | 207 | return $this; 208 | } 209 | 210 | /** 211 | * @return bool 212 | */ 213 | public function getNotify() 214 | { 215 | return $this->_notify; 216 | } 217 | 218 | /** 219 | * @return string 220 | */ 221 | public function getColor() 222 | { 223 | return $this->_color; 224 | } 225 | 226 | /** 227 | * @param $message 228 | * @return $this 229 | */ 230 | public function setMessage($message) 231 | { 232 | if(is_string($message)) { 233 | $this->_message = $message; 234 | } 235 | return $this; 236 | } 237 | 238 | /** 239 | * @return string 240 | */ 241 | public function getMessage() 242 | { 243 | return $this->_message; 244 | } 245 | 246 | /** 247 | * @return mixed 248 | */ 249 | public function isEnabled() 250 | { 251 | return Mage::getStoreConfig(self::ENABLE_NOTIFICATION_PATH, 0); 252 | } 253 | 254 | /** 255 | * send the message 256 | * @param $params 257 | */ 258 | public function sendMessage($params) 259 | { 260 | try { 261 | $this->getHipChatModel()->message_room( 262 | $params['room_id'], 263 | $params['from_name'], 264 | $params['message'], 265 | $params['notify'], 266 | $params['color'] 267 | ); 268 | if(Mage::getStoreConfig(self::ENABLE_LOG_PATH, 0)) { 269 | Mage::log('Message sent: ' . $this->_message, Zend_Log::INFO, self::LOG_FILE, true); 270 | } 271 | } catch(Exception $e) { 272 | Mage::log($params, Zend_Log::ERR, self::LOG_FILE, true); 273 | Mage::log($e->getMessage(), Zend_Log::ERR, self::LOG_FILE, true); 274 | } 275 | } 276 | } -------------------------------------------------------------------------------- /app/code/community/Mhauri/HipChat/Model/Notification.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | 25 | class Mhauri_HipChat_Model_Notification extends Mhauri_HipChat_Model_Abstract 26 | { 27 | 28 | /** 29 | * send message to room 30 | */ 31 | public function send() 32 | { 33 | if(!$this->isEnabled()) { 34 | Mage::log('HipChat Notifications are not enabled!', Zend_Log::ERR, self::LOG_FILE, true); 35 | return false; 36 | } 37 | 38 | $params = array( 39 | 'room_id' => $this->getRoomId(), 40 | 'from_name' => $this->getFromName(), 41 | 'message' => $this->getMessage(), 42 | 'notify' => $this->getNotify(), 43 | 'color' => $this->getColor() 44 | ); 45 | 46 | if(Mage::getStoreConfig(Mhauri_HipChat_Model_Abstract::USE_QUEUE, 0)) { 47 | Mage::getModel('mhauri_hipchat/queue')->addMessageToQueue($params); 48 | } else { 49 | try { 50 | $this->sendMessage($params); 51 | } catch (Exception $e) { 52 | Mage::log($e->getMessage(), Zend_Log::ERR, Mhauri_HipChat_Model_Abstract::LOG_FILE); 53 | } 54 | } 55 | return true; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /app/code/community/Mhauri/HipChat/Model/Observer.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | 25 | class Mhauri_HipChat_Model_Observer 26 | { 27 | private $_notificationModel = null; 28 | 29 | private $_helper = null; 30 | 31 | public function __construct() 32 | { 33 | $this->_notificationModel = Mage::getSingleton('mhauri_hipchat/notification'); 34 | $this->_helper = Mage::helper('mhauri_hipchat'); 35 | } 36 | 37 | /** 38 | * Send a notification when a new order was placed 39 | * @param $observer 40 | */ 41 | public function notifyNewOrder($observer) 42 | { 43 | if($this->_getConfig(Mhauri_HipChat_Model_Notification::NEW_ORDER_PATH)) { 44 | $message = $this->_helper->__('A new order has been placed.
Order ID: %s, Name: %s %s, Amount: %s %s', 45 | $observer->getOrder()->getIncrementId(), 46 | $observer->getOrder()->getCustomer()->getFirstname(), 47 | $observer->getOrder()->getCustomer()->getLastname(), 48 | $observer->getOrder()->getQuoteBaseGrandTotal(), 49 | $observer->getOrder()->getOrderCurrencyCode() 50 | ); 51 | 52 | $this->_notificationModel 53 | ->setMessage($message) 54 | ->setColor(Mhauri_HipChat_Model_Notification::COLOR_GREEN) 55 | ->send(); 56 | } 57 | } 58 | 59 | /** 60 | * Send a notification when a new customer account is created 61 | * @param $observer 62 | */ 63 | public function notifyNewCustomer($observer) 64 | { 65 | if($this->_getConfig(Mhauri_HipChat_Model_Notification::NEW_CUSTOMER_ACCOUNT_PATH)) { 66 | $this->_notificationModel 67 | ->setMessage($this->_helper->__('A new customer account was created')) 68 | ->setColor(Mhauri_HipChat_Model_Notification::COLOR_YELLOW) 69 | ->send(); 70 | } 71 | } 72 | 73 | /** 74 | * Send a notification when admin user login failed 75 | * @param $observer 76 | */ 77 | public function notifyAdminUserLoginFailed($observer) 78 | { 79 | if($this->_getConfig(Mhauri_HipChat_Model_Notification::ADMIN_USER_LOGIN_FAILED_PATH)) { 80 | $this->_notificationModel 81 | ->setMessage($this->_helper->__('Admin user login failed with username: %s', $observer->getUserName())) 82 | ->setColor(Mhauri_HipChat_Model_Notification::COLOR_RED) 83 | ->send(); 84 | } 85 | } 86 | 87 | private function _getConfig($path) 88 | { 89 | return Mage::getStoreConfig($path, 0); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /app/code/community/Mhauri/HipChat/Model/Queue.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | 25 | class Mhauri_HipChat_Model_Queue extends Mhauri_HipChat_Model_Abstract 26 | { 27 | const MESSAGES_LIMIT_PER_CRON_RUN = 30; 28 | 29 | protected function _construct() 30 | { 31 | $this->_init('mhauri_hipchat/queue'); 32 | parent::_construct(); 33 | } 34 | 35 | /** 36 | * @param $params 37 | */ 38 | public function addMessageToQueue($params) 39 | { 40 | $this->setMessageParams(serialize($params)); 41 | 42 | try { 43 | $this->save(); 44 | } catch(Exception $e) { 45 | Mage::log($e->getMessage(), Zend_log::ERR, Mhauri_HipChat_Model_Abstract::LOG_FILE); 46 | } 47 | } 48 | 49 | /** 50 | * Send all queued Messages 51 | */ 52 | public function sendQueuedMessages() 53 | { 54 | $collection = Mage::getModel('mhauri_hipchat/queue')->getCollection() 55 | ->addOnlyForSendingFilter() 56 | ->setPageSize(self::MESSAGES_LIMIT_PER_CRON_RUN) 57 | ->setCurPage(1) 58 | ->load(); 59 | 60 | foreach($collection as $message) { 61 | try { 62 | $this->sendMessage(unserialize($message->getMessageParams())); 63 | $message->setProcessedAt(Varien_Date::formatDate(true)); 64 | $message->save(); 65 | } 66 | catch (Exception $e) { 67 | Mage::log($e->getMessage(), Zend_Log::ERR, Mhauri_HipChat_Model_Abstract::LOG_FILE); 68 | } 69 | sleep(1); 70 | } 71 | } 72 | 73 | /** 74 | * Remove sent messages 75 | * @return $this 76 | */ 77 | public function cleanQueue() 78 | { 79 | $this->_getResource()->removeSentMessages(); 80 | return $this; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/code/community/Mhauri/HipChat/Model/Resource/Queue.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | 25 | class Mhauri_HipChat_Model_Resource_Queue extends Mage_Core_Model_Resource_Db_Abstract 26 | { 27 | protected function _construct() 28 | { 29 | $this->_init('mhauri_hipchat/queue', 'message_id'); 30 | } 31 | 32 | /** 33 | * @param Mage_Core_Model_Abstract $object 34 | * @return Mage_Core_Model_Resource_Db_Abstract 35 | */ 36 | protected function _beforeSave(Mage_Core_Model_Abstract $object) 37 | { 38 | if ($object->isObjectNew()) { 39 | $object->setCreatedAt($this->formatDate(true)); 40 | } 41 | return parent::_beforeSave($object); 42 | } 43 | 44 | /** 45 | * Remove the sent messages from queue 46 | * 47 | * @return $this 48 | */ 49 | public function removeSentMessages() 50 | { 51 | $this->_getWriteAdapter()->delete($this->getMainTable(), 'processed_at IS NOT NULL'); 52 | return $this; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/code/community/Mhauri/HipChat/Model/Resource/Queue/Collection.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | 25 | class Mhauri_HipChat_Model_Resource_Queue_Collection extends Mage_Core_Model_Resource_Db_Collection_Abstract 26 | { 27 | protected function _construct() 28 | { 29 | $this->_init('mhauri_hipchat/queue', 'message_id'); 30 | } 31 | 32 | public function addOnlyForSendingFilter() 33 | { 34 | $this->getSelect()->where('main_table.processed_at IS NULL'); 35 | return $this; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/code/community/Mhauri/HipChat/etc/adminhtml.xml: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | HipChat 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app/code/community/Mhauri/HipChat/etc/config.xml: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 26 | 27 | 0.3.0 28 | 29 | 30 | 31 | 32 | 33 | Mhauri_HipChat_Helper 34 | 35 | 36 | 37 | 38 | Mhauri_HipChat_Model 39 | mhauri_hipchat_resource 40 | 41 | 42 | Mhauri_HipChat_Model_Resource 43 | 44 | 45 | hipchat_queue
46 |
47 |
48 |
49 |
50 | 51 | 52 | 53 | Mhauri_HipChat 54 | Mage_Core_Model_Resource_Setup 55 | 56 | 57 | core_setup 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | singleton 66 | Mhauri_HipChat_Model_Observer 67 | notifyNewOrder 68 | 69 | 70 | 71 | 72 | 73 | 74 | singleton 75 | Mhauri_HipChat_Model_Observer 76 | notifyAdminUserLoginFailed 77 | 78 | 79 | 80 | 81 | 82 | 83 | singleton 84 | Mhauri_HipChat_Model_Observer 85 | notifyNewCustomer 86 | 87 | 88 | 89 | 90 |
91 | 92 | 93 | 94 | 95 | 96 | 97 | Mhauri_HipChat.csv 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 0 108 | 0 109 | 1 110 | 111 | 112 | Magento HipChat 113 | 114 | 115 | 116 | 117 | 0 118 | 0 119 | 0 120 | 121 | 122 | 123 | 124 | 125 | 126 | */1 * * * * 127 | mhauri_hipchat/queue::sendQueuedMessages 128 | 129 | 130 | 0 0 * * * 131 | mhauri_hipchat/queue::cleanQueue 132 | 133 | 134 | 135 | 136 |
-------------------------------------------------------------------------------- /app/code/community/Mhauri/HipChat/etc/system.xml: -------------------------------------------------------------------------------- 1 | 2 | 24 | 25 | 26 | 27 | separator-top 28 | 29 | service 30 | text 31 | 40 32 | 1 33 | 0 34 | 0 35 | 36 | 37 | 38 | text 39 | 10 40 | 1 41 | 0 42 | 0 43 | 44 | 45 | 46 | select 47 | adminhtml/system_config_source_yesno 48 | 10 49 | 1 50 | 0 51 | 0 52 | 53 | 54 | 55 | select 56 | adminhtml/system_config_source_yesno 57 | 20 58 | 1 59 | 0 60 | 0 61 | 62 | 63 | 64 | select 65 | Preferred way as it is more safe an will not block any interactions (cronjob must run!) 66 | adminhtml/system_config_source_yesno 67 | 30 68 | 1 69 | 0 70 | 0 71 | 72 | 73 | 74 | 75 | 76 | text 77 | 10 78 | 1 79 | 0 80 | 0 81 | 82 | 83 | 84 | text 85 | 30 86 | 1 87 | 0 88 | 0 89 | 90 | 91 | 92 | text 93 | 40 94 | validate-number 95 | 1 96 | 0 97 | 0 98 | 99 | 100 | 101 | text 102 | 50 103 | From name must be between 1 and 15 characters. 104 | 1 105 | 0 106 | 0 107 | 108 | 109 | 110 | 111 | 112 | text 113 | 100 114 | 1 115 | 0 116 | 0 117 | 118 | 119 | 120 | select 121 | adminhtml/system_config_source_yesno 122 | 10 123 | 1 124 | 0 125 | 0 126 | 127 | 128 | 129 | select 130 | adminhtml/system_config_source_yesno 131 | 10 132 | 1 133 | 0 134 | 0 135 | 136 | 137 | 138 | select 139 | adminhtml/system_config_source_yesno 140 | 20 141 | 1 142 | 0 143 | 0 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /app/code/community/Mhauri/HipChat/sql/mhauri_hipchat_setup/upgrade-0.2.0-0.3.0.php: -------------------------------------------------------------------------------- 1 | 23 | */ 24 | 25 | /* @var $installer Mage_Core_Model_Resource_Setup */ 26 | $installer = $this; 27 | $installer->startSetup(); 28 | 29 | $table = $installer->getConnection() 30 | ->newTable($installer->getTable('mhauri_hipchat/queue')) 31 | ->addColumn('message_id', Varien_Db_Ddl_Table::TYPE_INTEGER, null, array( 32 | 'identity' => true, 33 | 'unsigned' => true, 34 | 'nullable' => false, 35 | 'primary' => true, 36 | ), 'Message Id') 37 | ->addColumn('message_params', Varien_Db_Ddl_Table::TYPE_TEXT, null, array( 38 | 'nullable' => false, 39 | 'default' => '', 40 | ), 'Message Parameters') 41 | ->addColumn('created_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array( 42 | 'nullable' => true, 43 | ), 'Created At') 44 | ->addColumn('processed_at', Varien_Db_Ddl_Table::TYPE_TIMESTAMP, null, array( 45 | 'nullable' => true, 46 | ), 'Processed At') 47 | ->setComment('HipChat Message Queue'); 48 | 49 | $installer->getConnection()->createTable($table); 50 | 51 | $installer->endSetup(); 52 | -------------------------------------------------------------------------------- /app/etc/modules/Mhauri_HipChat.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | true 6 | community 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/locale/en_US/Mhauri_HipChat.csv: -------------------------------------------------------------------------------- 1 | "Enable HipChat notifications","Enable HipChat notifications" 2 | "Log notifications","Log notifications" 3 | "API Settings","API Settings" 4 | "Token","Token" 5 | "Room ID","Room ID" 6 | "From name","From name" 7 | "From name must be between 1 and 15 characters.","From name must be between 1 and 15 characters." 8 | "Notification Settings","Notification Settings" 9 | "A new order has been placed.
Order ID: %s, Name: %s %s, Amount: %s %s","A new order has been placed.
Order ID: %s, Name: %s %s, Amount: %s %s" 10 | "Admin user login failed with username: %s","Admin user login failed with username: %s" 11 | "A new customer account was created","A new customer account was created" -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mhauri/mhauri-hipchat", 3 | "license": "MIT", 4 | "type": "magento-module", 5 | "description": "Magento HipChat allows you to send notifications to a HipChat room.", 6 | "suggest": { 7 | "magento-hackathon/magento-composer-installer": "*" 8 | }, 9 | "authors":[ 10 | { 11 | "name":"Marcel Hauri", 12 | "email":"marcel@hauri.me" 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /lib/Atlassian/HipChat/HipChat.php: -------------------------------------------------------------------------------- 1 | api_target = $api_target; 90 | $this->auth_token = $auth_token; 91 | $this->api_version = $api_version; 92 | } 93 | 94 | 95 | ///////////////////////////////////////////////////////////////////////////// 96 | // Room functions 97 | ///////////////////////////////////////////////////////////////////////////// 98 | 99 | /** 100 | * Get information about a room 101 | * 102 | * @see http://api.hipchat.com/docs/api/method/rooms/show 103 | */ 104 | public function get_room($room_id) { 105 | $response = $this->make_request('rooms/show', array( 106 | 'room_id' => $room_id 107 | )); 108 | return $response->room; 109 | } 110 | 111 | /** 112 | * Determine if the given room name or room id already exists. 113 | * 114 | * @param mixed $room_id 115 | * @return boolean 116 | */ 117 | public function room_exists($room_id) { 118 | try { 119 | $this->get_room($room_id); 120 | } 121 | catch (HipChat_Exception $e) { 122 | if ($e->code === self::STATUS_NOT_FOUND) { 123 | return false; 124 | } 125 | throw $e; 126 | } 127 | return true; 128 | } 129 | 130 | /** 131 | * Get list of rooms 132 | * 133 | * @see http://api.hipchat.com/docs/api/method/rooms/list 134 | */ 135 | public function get_rooms() { 136 | $response = $this->make_request('rooms/list'); 137 | return $response->rooms; 138 | } 139 | 140 | /** 141 | * Send a message to a room 142 | * 143 | * @see http://api.hipchat.com/docs/api/method/rooms/message 144 | */ 145 | public function message_room($room_id, $from, $message, $notify = false, 146 | $color = self::COLOR_YELLOW, 147 | $message_format = self::FORMAT_HTML) { 148 | $args = array( 149 | 'room_id' => $room_id, 150 | 'from' => $from, 151 | 'message' => $message, 152 | 'notify' => (int)$notify, 153 | 'color' => $color, 154 | 'message_format' => $message_format 155 | ); 156 | $response = $this->make_request('rooms/message', $args, 'POST'); 157 | return ($response->status == 'sent'); 158 | } 159 | 160 | /** 161 | * Get chat history for a room 162 | * 163 | * @see https://www.hipchat.com/docs/api/method/rooms/history 164 | */ 165 | public function get_rooms_history($room_id, $date = 'recent') { 166 | $response = $this->make_request('rooms/history', array( 167 | 'room_id' => $room_id, 168 | 'date' => $date 169 | )); 170 | return $response->messages; 171 | } 172 | 173 | /** 174 | * Set a room's topic 175 | * 176 | * @see http://api.hipchat.com/docs/api/method/rooms/topic 177 | */ 178 | public function set_room_topic($room_id, $topic, $from = null) { 179 | $args = array( 180 | 'room_id' => $room_id, 181 | 'topic' => $topic, 182 | ); 183 | 184 | if ($from) { 185 | $args['from'] = $from; 186 | } 187 | 188 | $response = $this->make_request('rooms/topic', $args, 'POST'); 189 | return ($response->status == 'ok'); 190 | } 191 | 192 | /** 193 | * Create a room 194 | * 195 | * @see http://api.hipchat.com/docs/api/method/rooms/create 196 | */ 197 | public function create_room($name, $owner_user_id = null, $privacy = null, $topic = null, $guest_access = null) { 198 | $args = array( 199 | 'name' => $name 200 | ); 201 | 202 | if ($owner_user_id) { 203 | $args['owner_user_id'] = $owner_user_id; 204 | } 205 | 206 | if ($privacy) { 207 | $args['privacy'] = $privacy; 208 | } 209 | 210 | if ($topic) { 211 | $args['topic'] = $topic; 212 | } 213 | 214 | if ($guest_access) { 215 | $args['guest_access'] = (int)$guest_access; 216 | } 217 | 218 | // Return the std object 219 | return $this->make_request('rooms/create', $args, 'POST'); 220 | } 221 | 222 | /** 223 | * Delete a room 224 | * 225 | * @see http://api.hipchat.com/docs/api/method/rooms/delete 226 | */ 227 | public function delete_room($room_id){ 228 | $args = array( 229 | 'room_id' => $room_id 230 | ); 231 | 232 | $response = $this->make_request('rooms/delete', $args, 'POST'); 233 | 234 | return ($response->deleted == 'true'); 235 | } 236 | 237 | ///////////////////////////////////////////////////////////////////////////// 238 | // User functions 239 | ///////////////////////////////////////////////////////////////////////////// 240 | 241 | /** 242 | * Get information about a user 243 | * 244 | * @see http://api.hipchat.com/docs/api/method/users/show 245 | */ 246 | public function get_user($user_id) { 247 | $response = $this->make_request('users/show', array( 248 | 'user_id' => $user_id 249 | )); 250 | return $response->user; 251 | } 252 | 253 | /** 254 | * Get list of users 255 | * 256 | * @see http://api.hipchat.com/docs/api/method/users/list 257 | */ 258 | public function get_users() { 259 | $response = $this->make_request('users/list'); 260 | return $response->users; 261 | } 262 | 263 | /** 264 | * Create a new user in your group. 265 | * 266 | * @see http://api.hipchat.com/docs/api/method/users/create 267 | */ 268 | public function create_user($email, $name, $mention_name = null, 269 | $title = null, $is_group_admin = 0, 270 | $password = null, $timezone = null) { 271 | $args = array( 272 | 'email' => $email, 273 | 'name' => $name, 274 | ); 275 | 276 | if ($mention_name) { 277 | $args['mention_name'] = $mention_name; 278 | } 279 | 280 | if ($title) { 281 | $args['title'] = $title; 282 | } 283 | 284 | if ($is_group_admin) { 285 | $args['is_group_admin'] = (int)$is_group_admin; 286 | } 287 | 288 | if ($password) { 289 | $args['password'] = $password; 290 | } 291 | 292 | // @see http://api.hipchat.com/docs/api/timezones 293 | if ($timezone) { 294 | $args['timezone'] = $timezone; 295 | } 296 | 297 | // Return the std object 298 | return $this->make_request('users/create', $args, 'POST'); 299 | } 300 | 301 | /** 302 | * Update a user. 303 | * 304 | * @see http://api.hipchat.com/docs/api/method/users/update 305 | */ 306 | public function update_user($user_id, $email = null, $name = null, 307 | $mention_name = null, $title = null, 308 | $is_group_admin = 0, $password = null, 309 | $timezone = null) { 310 | $args = array( 311 | 'user_id' => $user_id, 312 | ); 313 | 314 | if ($email) { 315 | $args['email'] = $email; 316 | } 317 | 318 | if ($name) { 319 | $args['name'] = $name; 320 | } 321 | 322 | if ($mention_name) { 323 | $args['mention_name'] = $mention_name; 324 | } 325 | 326 | if ($title) { 327 | $args['title'] = $title; 328 | } 329 | 330 | if ($is_group_admin) { 331 | $args['is_group_admin'] = (int)$is_group_admin; 332 | } 333 | 334 | if ($password) { 335 | $args['password'] = $password; 336 | } 337 | 338 | // @see http://api.hipchat.com/docs/api/timezones 339 | if ($timezone) { 340 | $args['timezone'] = $timezone; 341 | } 342 | 343 | // Return the std object 344 | return $this->make_request('users/update', $args, 'POST'); 345 | } 346 | 347 | /** 348 | * Delete a user. 349 | * 350 | * @see http://api.hipchat.com/docs/api/method/users/delete 351 | */ 352 | public function delete_user($user_id) { 353 | return $this->make_request('users/delete', array( 354 | 'user_id' => $user_id 355 | ), 'POST'); 356 | } 357 | 358 | /** 359 | * Undelete a user. They will be sent an email requiring them to click a link to reactivate the account. 360 | * 361 | * @see http://api.hipchat.com/docs/api/method/users/undelete 362 | */ 363 | public function undelete_user($user_id) { 364 | return $this->make_request('users/undelete', array( 365 | 'user_id' => $user_id 366 | ), 'POST'); 367 | } 368 | 369 | ///////////////////////////////////////////////////////////////////////////// 370 | // Helper functions 371 | ///////////////////////////////////////////////////////////////////////////// 372 | 373 | /** 374 | * Performs a curl request 375 | * 376 | * @param $url URL to hit. 377 | * @param $post_data Data to send via POST. Leave null for GET request. 378 | * 379 | * @throws HipChat_Exception 380 | * @return string 381 | */ 382 | public function curl_request($url, $post_data = null) { 383 | 384 | if (is_array($post_data)) { 385 | $post_data = array_map(array($this, 'sanitize_curl_parameter'), $post_data); 386 | } 387 | 388 | $ch = curl_init($url); 389 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); 390 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 391 | curl_setopt($ch, CURLOPT_TIMEOUT, 15); 392 | curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $this->verify_ssl); 393 | if (isset($this->proxy)) { 394 | curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1); 395 | curl_setopt($ch, CURLOPT_PROXY, $this->proxy); 396 | } 397 | if (is_array($post_data)) { 398 | curl_setopt($ch, CURLOPT_POST, 1); 399 | curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data); 400 | } 401 | $response = curl_exec($ch); 402 | 403 | // make sure we got a real response 404 | if (strlen($response) == 0) { 405 | $errno = curl_errno($ch); 406 | $error = curl_error($ch); 407 | throw new HipChat_Exception(self::STATUS_BAD_RESPONSE, 408 | "CURL error: $errno - $error", $url); 409 | } 410 | 411 | // make sure we got a 200 412 | $code = (int)curl_getinfo($ch, CURLINFO_HTTP_CODE); 413 | if ($code != self::STATUS_OK) { 414 | throw new HipChat_Exception($code, 415 | "HTTP status code: $code, response=$response", $url); 416 | } 417 | 418 | curl_close($ch); 419 | 420 | return $response; 421 | } 422 | 423 | /** 424 | * Sanitizes the given value as cURL parameter. 425 | * 426 | * The first value may not be a "@". PHP would treat this as a file upload 427 | * 428 | * @link http://www.php.net/manual/en/function.curl-setopt.php CURLOPT_POSTFIELDS 429 | * 430 | * @param string $value 431 | * @return string 432 | */ 433 | private function sanitize_curl_parameter ($value) { 434 | 435 | if ((strlen($value) > 0) && ($value[0] === '@')) { 436 | return substr_replace($value, '@', 0, 1); 437 | } 438 | 439 | return $value; 440 | } 441 | 442 | /** 443 | * Make an API request using curl 444 | * 445 | * @param string $api_method Which API method to hit, like 'rooms/show'. 446 | * @param array $args Data to send. 447 | * @param string $http_method HTTP method (GET or POST). 448 | * 449 | * @throws HipChat_Exception 450 | * @return mixed 451 | */ 452 | public function make_request($api_method, $args = array(), 453 | $http_method = 'GET') { 454 | $args['format'] = 'json'; 455 | $args['auth_token'] = $this->auth_token; 456 | $url = "$this->api_target/$this->api_version/$api_method"; 457 | $post_data = null; 458 | 459 | // add args to url for GET 460 | if ($http_method == 'GET') { 461 | $url .= '?' . http_build_query($args); 462 | } else { 463 | $post_data = $args; 464 | } 465 | 466 | $response = $this->curl_request($url, $post_data); 467 | 468 | // make sure response is valid json 469 | $response = json_decode($response); 470 | if (!$response) { 471 | throw new HipChat_Exception(self::STATUS_BAD_RESPONSE, 472 | "Invalid JSON received: $response", $url); 473 | } 474 | 475 | return $response; 476 | } 477 | 478 | /** 479 | * Enable/disable verify_ssl. 480 | * This is useful when curl spits back ssl verification errors, most likely 481 | * due to outdated SSL CA bundle file on server. If you are able to, update 482 | * that CA bundle. If not, call this method with false for $bool param before 483 | * interacting with the API. 484 | * 485 | * @param bool $bool 486 | * @return bool 487 | * @link http://davidwalsh.name/php-ssl-curl-error 488 | */ 489 | public function set_verify_ssl($bool = true) { 490 | $this->verify_ssl = (bool)$bool; 491 | return $this->verify_ssl; 492 | } 493 | 494 | /** 495 | * Set an outbound proxy to use as a curl option 496 | * To disable proxy usage, set $proxy to null 497 | * 498 | * @param string $proxy 499 | */ 500 | public function set_proxy($proxy) { 501 | $this->proxy = $proxy; 502 | } 503 | 504 | } 505 | 506 | 507 | class HipChat_Exception extends \Exception { 508 | public $code; 509 | public function __construct($code, $info, $url) { 510 | $message = "HipChat API error: code=$code, info=$info, url=$url"; 511 | parent::__construct($message, (int)$code); 512 | } 513 | } -------------------------------------------------------------------------------- /modman: -------------------------------------------------------------------------------- 1 | # Modman file generated by 'generate-modman' (https://github.com/mhauri/generate-modman) 2 | # app/code 3 | app/code/community/Mhauri/HipChat app/code/community/Mhauri/HipChat 4 | # app/etc 5 | app/etc/modules/Mhauri_HipChat.xml app/etc/modules/Mhauri_HipChat.xml 6 | # lib 7 | lib/Atlassian/HipChat/HipChat.php lib/Atlassian/HipChat/HipChat.php 8 | --------------------------------------------------------------------------------