├── .gitignore ├── LICENSE ├── Locale ├── cs_CZ │ └── translations.php ├── da_DK │ └── translations.php ├── de_DE │ └── translations.php ├── es_ES │ └── translations.php ├── fi_FI │ └── translations.php ├── fr_FR │ └── translations.php ├── hu_HU │ └── translations.php ├── id_ID │ └── translations.php ├── it_IT │ └── translations.php ├── ja_JP │ └── translations.php ├── nb_NO │ └── translations.php ├── nl_NL │ └── translations.php ├── pl_PL │ └── translations.php ├── pt_BR │ └── translations.php ├── pt_PT │ └── translations.php ├── ru_RU │ └── translations.php ├── sr_Latn_RS │ └── translations.php ├── sv_SE │ └── translations.php ├── th_TH │ └── translations.php ├── tr_TR │ └── translations.php └── zh_CN │ └── translations.php ├── Makefile ├── Notification └── Mattermost.php ├── Plugin.php ├── README.md ├── Template ├── config │ └── integration.php └── project │ └── integration.php ├── Test └── PluginTest.php └── mattermost-icon.png /.gitignore: -------------------------------------------------------------------------------- 1 | *.zip 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Frédéric Guillot 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 13 | all 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 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Locale/cs_CZ/translations.php: -------------------------------------------------------------------------------- 1 | 'Nápověda pro Mattermost integraci.', 5 | 'Channel/Group/User (Optional)' => 'Kanál/Skupina/Uživatel (volitelně)', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/da_DK/translations.php: -------------------------------------------------------------------------------- 1 | '', 5 | // 'Channel/Group/User (Optional)' => '', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/de_DE/translations.php: -------------------------------------------------------------------------------- 1 | 'Hilfe für Mattermost-Integration.', 5 | 'Channel/Group/User (Optional)' => 'Kanal/Gruppe/Benutzer (optional)', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/es_ES/translations.php: -------------------------------------------------------------------------------- 1 | 'Ayuda sobre integración Desatendida', 5 | 'Channel/Group/User (Optional)' => 'Canal/Grupo/Usuario (Opcional)', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/fi_FI/translations.php: -------------------------------------------------------------------------------- 1 | '', 5 | // 'Channel/Group/User (Optional)' => '', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/fr_FR/translations.php: -------------------------------------------------------------------------------- 1 | 'Aide sur l\'intégration avec Mattermost', 5 | 'Channel/Group/User (Optional)' => 'Canal/Groupe/Utilisateur (Optionnel)', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/hu_HU/translations.php: -------------------------------------------------------------------------------- 1 | 'Súgó a Mattermost integráláshoz', 5 | 'Channel/Group/User (Optional)' => 'Csatorna/csoport/felhasználó (opcionális)', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/id_ID/translations.php: -------------------------------------------------------------------------------- 1 | 'Bantuan pada integrasi Mattermost', 5 | 'Channel/Group/User (Optional)' => 'Kanal/Grup/Pengguna (pilihan)', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/it_IT/translations.php: -------------------------------------------------------------------------------- 1 | 'Guida all\'integrazione con Mattermost', 5 | // 'Channel/Group/User (Optional)' => '', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/ja_JP/translations.php: -------------------------------------------------------------------------------- 1 | 'Mattermost 連携のヘルプ', 5 | // 'Channel/Group/User (Optional)' => '', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/nb_NO/translations.php: -------------------------------------------------------------------------------- 1 | '', 5 | // 'Channel/Group/User (Optional)' => '', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/nl_NL/translations.php: -------------------------------------------------------------------------------- 1 | '', 5 | // 'Channel/Group/User (Optional)' => '', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/pl_PL/translations.php: -------------------------------------------------------------------------------- 1 | '', 5 | // 'Channel/Group/User (Optional)' => '', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/pt_BR/translations.php: -------------------------------------------------------------------------------- 1 | 'Ajuda sobre integração com o Mattermost', 5 | 'Channel/Group/User (Optional)' => 'Canal/Grupo/Utilizador (Opcional)', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/pt_PT/translations.php: -------------------------------------------------------------------------------- 1 | 'Ajuda na integração com o Mattermost', 5 | 'Channel/Group/User (Optional)' => 'Canal/Grupo/Utilizador (Opcional)', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/ru_RU/translations.php: -------------------------------------------------------------------------------- 1 | 'Помощь по интеграции Mattermost', 5 | 'Channel/Group/User (Optional)' => 'Канал/Группа/Пользователь (опционально)', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/sr_Latn_RS/translations.php: -------------------------------------------------------------------------------- 1 | '', 5 | // 'Channel/Group/User (Optional)' => '', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/sv_SE/translations.php: -------------------------------------------------------------------------------- 1 | 'Hjälp för Mattermost integration', 5 | 'Channel/Group/User (Optional)' => 'Kanal/Grupp/Användare (valfri)', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/th_TH/translations.php: -------------------------------------------------------------------------------- 1 | '', 5 | // 'Channel/Group/User (Optional)' => '', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/tr_TR/translations.php: -------------------------------------------------------------------------------- 1 | '', 5 | // 'Channel/Group/User (Optional)' => '', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Locale/zh_CN/translations.php: -------------------------------------------------------------------------------- 1 | 'Mattermost 整合帮助', 5 | // 'Channel/Group/User (Optional)' => '', 6 | ); 7 | 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | plugin=Mattermost 2 | 3 | all: 4 | @ echo "Build archive for plugin ${plugin} version=${version}" 5 | @ git archive HEAD --prefix=${plugin}/ --format=zip -o ${plugin}-${version}.zip 6 | -------------------------------------------------------------------------------- /Notification/Mattermost.php: -------------------------------------------------------------------------------- 1 | projectMetadataModel->get($project['id'], 'mattermost_webhook_url', $this->configModel->get('mattermost_webhook_url')); 39 | $channel = $this->projectMetadataModel->get($project['id'], 'mattermost_webhook_channel'); 40 | 41 | if (! empty($webhook)) { 42 | $this->sendMessage($webhook, $channel, $project, $event_name, $event_data); 43 | } 44 | } 45 | 46 | /** 47 | * Get message to send 48 | * 49 | * @access public 50 | * @param array $project 51 | * @param string $event_name 52 | * @param array $event_data 53 | * @return array 54 | */ 55 | public function getMessage(array $project, $event_name, array $event_data) 56 | { 57 | if ($this->userSession->isLogged()) { 58 | $author = $this->helper->user->getFullname(); 59 | $title = $this->notificationModel->getTitleWithAuthor($author, $event_name, $event_data); 60 | } else { 61 | $title = $this->notificationModel->getTitleWithoutAuthor($event_name, $event_data); 62 | } 63 | 64 | $message = '**['.$project['name']."]** "; 65 | 66 | if ($this->configModel->get('application_url') !== '') { 67 | $message .= '['.t($event_data['task']['title']."\n").']'; 68 | $message .= '('; 69 | $message .= $this->helper->url->to('TaskViewController', 'show', array('task_id' => $event_data['task']['id'], 'project_id' => $project['id']), '', true); 70 | $message .= ')'; 71 | } 72 | 73 | $message .= $title."\n"; 74 | 75 | return array( 76 | 'text' => $message, 77 | 'username' => 'Kanboard', 78 | 'icon_url' => 'https://raw.githubusercontent.com/kanboard/kanboard/master/assets/img/favicon.png', 79 | ); 80 | } 81 | 82 | /** 83 | * Send message to Mattermost 84 | * 85 | * @access private 86 | * @param string $webhook 87 | * @param string $channel 88 | * @param array $project 89 | * @param string $event_name 90 | * @param array $event_data 91 | */ 92 | private function sendMessage($webhook, $channel, array $project, $event_name, array $event_data) 93 | { 94 | $payload = $this->getMessage($project, $event_name, $event_data); 95 | 96 | if (! empty($channel)) { 97 | $payload['channel'] = $channel; 98 | } 99 | 100 | $this->httpClient->postJsonAsync($webhook, $payload); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Plugin.php: -------------------------------------------------------------------------------- 1 | template->hook->attach('template:config:integrations', 'mattermost:config/integration'); 19 | $this->template->hook->attach('template:project:integrations', 'mattermost:project/integration'); 20 | $this->projectNotificationTypeModel->setType('mattermost', t('Mattermost'), '\Kanboard\Plugin\Mattermost\Notification\Mattermost'); 21 | } 22 | 23 | public function onStartup() 24 | { 25 | Translator::load($this->languageModel->getCurrentLanguage(), __DIR__.'/Locale'); 26 | } 27 | 28 | public function getPluginDescription() 29 | { 30 | return 'Receive notifications on Mattermost'; 31 | } 32 | 33 | public function getPluginAuthor() 34 | { 35 | return 'Frédéric Guillot'; 36 | } 37 | 38 | public function getPluginVersion() 39 | { 40 | return '1.0.5'; 41 | } 42 | 43 | public function getPluginHomepage() 44 | { 45 | return 'https://github.com/kanboard/plugin-mattermost'; 46 | } 47 | 48 | public function getCompatibleVersion() 49 | { 50 | return '>=1.0.37'; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Mattermost plugin for Kanboard 2 | ============================== 3 | 4 | Receive Kanboard notifications on Mattermost. 5 | 6 | Author 7 | ------ 8 | 9 | - Frederic Guillot 10 | - License MIT 11 | 12 | Requirements 13 | ------------ 14 | 15 | - Kanboard >= 1.0.37 16 | - Mattermost server 17 | 18 | Installation 19 | ------------ 20 | 21 | You have the choice between 3 methods: 22 | 23 | 1. Install the plugin from the Kanboard plugin manager in one click 24 | 2. Download the zip file and decompress everything under the directory `plugins/Mattermost` 25 | 3. Clone this repository into the folder `plugins/Mattermost` 26 | 27 | Note: Plugin folder is case-sensitive. 28 | 29 | Configuration 30 | ------------- 31 | 32 | Firstly, you have to generate a new webhook url in Mattermost (**Integration Settings > Incoming Webhooks**). 33 | 34 | ### Receive project notifications to a room 35 | 36 | - Go to the project settings then choose **Integrations > Mattermost** 37 | - Copy and paste the webhook url from Mattermost or leave it blank if you want to use the global webhook url 38 | - Use `channel` to override the webhook channel, example: **off-topic** 39 | - Enable Mattermost in your project notifications **Notifications > Mattermost** 40 | 41 | You can also define the webhook URL globally in the **Application settings > Integrations > Mattermost**. 42 | 43 | ### Mattermost configuration 44 | 45 | - Change the config option `EnablePostUsernameOverride` to `true` to have Kanboard as username 46 | - Change `EnablePostIconOverride` to `true` to see Kanboard icon 47 | 48 | ## Troubleshooting 49 | 50 | - Enable the debug mode 51 | - All connection errors with the Mattermost API are recorded in the log files `data/debug.log` 52 | -------------------------------------------------------------------------------- /Template/config/integration.php: -------------------------------------------------------------------------------- 1 |

 Mattermost

2 |
3 | form->label(t('Webhook URL'), 'mattermost_webhook_url') ?> 4 | form->text('mattermost_webhook_url', $values) ?> 5 | 6 |

7 | 8 |
9 | 10 |
11 |
12 | -------------------------------------------------------------------------------- /Template/project/integration.php: -------------------------------------------------------------------------------- 1 |

 Mattermost

2 |
3 | form->label(t('Webhook URL'), 'mattermost_webhook_url') ?> 4 | form->text('mattermost_webhook_url', $values) ?> 5 | 6 | form->label(t('Channel/Group/User (Optional)'), 'mattermost_webhook_channel') ?> 7 | form->text('mattermost_webhook_channel', $values, array(), array('placeholder="channel"')) ?> 8 | 9 |

10 | 11 |
12 | 13 |
14 |
15 | -------------------------------------------------------------------------------- /Test/PluginTest.php: -------------------------------------------------------------------------------- 1 | container); 12 | $this->assertSame(null, $plugin->initialize()); 13 | $this->assertSame(null, $plugin->onStartup()); 14 | $this->assertNotEmpty($plugin->getPluginName()); 15 | $this->assertNotEmpty($plugin->getPluginDescription()); 16 | $this->assertNotEmpty($plugin->getPluginAuthor()); 17 | $this->assertNotEmpty($plugin->getPluginVersion()); 18 | $this->assertNotEmpty($plugin->getPluginHomepage()); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /mattermost-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kanboard/plugin-mattermost/774e162a6fac22be4e5198936371492254c17b7a/mattermost-icon.png --------------------------------------------------------------------------------