You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

213 lines
9.5 KiB
PHP

<?php
/*******
GitScord --- a middleman webhook between Gitlab and Discord
https://gitlab.crans.org/elkmaennchen/gitscord-webhook
Copyright (C) 2020 CROSIO Gauthier
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*******/
// get the gitlab data
$phpInput = 'php://input';
$plainJSON = file_get_contents($phpInput);
// if call by a webhook (not GET method)
if ($plainJSON != '') {
// get configuration
$configJSON = json_decode(file_get_contents("./gitscord_webhook_config.json"), true);
$url = $configJSON['discord_url']; // Discord webhook url
$languages = array("fr", "es", "en");
$lang = $configJSON['language']; // language used for messages
if (!in_array($lang, $languages)) {
$lang="en"; // default language if asked language not available
}
$messageJSON = array(); // JSON to send to Discord
if ($configJSON['bot_name'] != '') {
$messageJSON['username'] = $configJSON['bot_name'] ;
}
if ($configJSON['bot_avatar'] != '') {
$messageJSON['avatar_url'] = $configJSON['bot_avatar'] ;
}
// process Gitlab data
$JSON = json_decode($plainJSON, true);
if (is_array($JSON)) { // valid JSON
switch ($JSON['object_kind']){ // type of event
case "push": // push event
$messageJSON = push_layout($messageJSON,$JSON,$lang);
break;
case "tag_push":
$messageJSON = tag_layout($messageJSON,$JSON,$lang);
break;
case "issue": // do the same weather its confidential or not
case "confidential_issue":
$messageJSON = issue_layout($messageJSON,$JSON,$lang);
break;
case "note": // do the same weather its confidential or not
case "confidential_note":
$messageJSON = note_layout($messageJSON,$JSON,$lang);
break;
case "merge_request":
// if somebody/somerole to hl, add him/it in the message
if ($configJSON['MR_manager'] != '') { $hl = " @".$configJSON['MR_manager']." "; }
else { $hl = ""; }
$messageJSON = MR_layout($messageJSON,$JSON,$lang,$hl);
break;
case "job":
break;
case "pipeline":
break;
case "wiki_page":
break;
default:
send_error($url,"Unknown type of event");
}
// sending post request to Discord
send_to_discord($url,$messageJSON);
exit;
}
}
// if call by GET method (not a webhook)
echo("42");
/*****
Functions declaration
*****/
function send_to_discord($url,$messageJSON){
$ch = curl_init($url); // initiate cURL
$tosendJSON = json_encode($messageJSON);
curl_setopt($ch, CURLOPT_POST, 1); // ask for POST method
curl_setopt($ch, CURLOPT_POSTFIELDS, $tosendJSON); // attach JSON
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$result = curl_exec($ch); // request itself
}
function send_error($url,$message="") { // showing an error on Discord chan
send_to_discord($url, array('content' => "**An error occurred with GitScord**\nPlease report in Issues tab on cr@ns Gitlab (gitlab.crans.org/elkmaennchen/gitscord-webhook)\n".$message, 'username' => 'GitScord in fail'));
}
// _layout functions : markdown and JSON encapsulation for Discord
function push_layout($messageJSON,$JSON,$lang) {
$txt_ligne_push=["fr"=>'nouveau(x) commit(s)',"es"=>'nuevo(s) commit(s)',"en"=>'new commit(s)',];
$txt_title_push=["fr"=>'a push dans',"es"=>'hizo un push en',"en"=>'pushed in',];
$txt_add_push=["fr"=>'Ajoutés',"es"=>'Añadidos',"en"=>'Added',];
$txt_mod_push=["fr"=>'Modifiés',"es"=>'Modificados',"en"=>'Modified',];
$txt_suppr_push=["fr"=>'Supprimés',"es"=>'Suprimidos',"en"=>'Deleted',];
$messageJSON['content'] = $JSON['total_commits_count'].' '.$txt_ligne_push[$lang] ;
$messageJSON['embeds'] = array();
for ($numCommit=$JSON['total_commits_count']-1; $numCommit>=0; $numCommit--) {
// strings of added, modified and deleted files in a single commit
$lst_added = "";
$lst_modified = "";
$lst_deleted = "";
foreach ($JSON['commits'][$numCommit]['added'] as $filename) {
$lst_added = $lst_added.$filename."\n";
}
foreach ($JSON['commits'][$numCommit]['modified'] as $filename) {
$lst_modified = $lst_modified.$filename."\n";
}
foreach ($JSON['commits'][$numCommit]['removed'] as $filename) {
$lst_deleted = $lst_deleted.$filename."\n";
}
// an embed message for each commit
array_push($messageJSON['embeds'],
array('title'=> $txt_title_push[$lang].' *'.$JSON['project']['name'].'*',
'description'=> "**".$JSON['commits'][$numCommit]['message']."**\n\n__".$txt_add_push[$lang]."__\n".$lst_added."\n__".$txt_mod_push[$lang]."__\n".$lst_modified."\n__".$txt_suppr_push[$lang]."__\n".$lst_deleted,
'url'=> $JSON['commits'][$numCommit]['url'],
'timestamp'=> $JSON['commits'][$numCommit]['timestamp'],
'author'=> array('name'=> $JSON['commits'][$numCommit]['author']['name']))
);
}
return($messageJSON);
}
function tag_layout($messageJSON,$JSON,$lang) {
$txt_ligne_tag=["fr"=>'Nouveau tag',"es"=>'Nuevo tag',"en"=>'New tag',];
$txt_title_tag=["fr"=>'a tagué un commit dans',"es"=>'hizo un tag en',"en"=>'tagged a commit in',];
$messageJSON['content'] = $txt_ligne_tag[$lang] ;
$messageJSON['embeds'] = array(array('title'=> $txt_title_tag[$lang].' *'.$JSON['project']['name'].'*',
'description'=> $JSON['message'],
'url'=> $JSON['project']['web_url'],
'timestamp'=> $JSON['commits'][0]['timestamp'],
'author'=> array('name'=> $JSON['user_name'])),);
return($messageJSON);
}
function issue_layout($messageJSON,$JSON,$lang) {
$txt_ligne_issue=["fr"=>'Nouveau problème',"es"=>'Nuevo problema',"en"=>'New issue',];
$txt_title_open_issue=["fr"=>'a ouvert une issue dans',"es"=>'abrió un asunto en',"en"=>'opened an issue in',];
$txt_title_update_issue=["fr"=>'a mis à jour une issue dans',"es"=>'actualizó un asunto en',"en"=>'modified an issue in',];
$txt_title_close_issue=["fr"=>'a fermé une issue dans',"es"=>'cierró un asunto en',"en"=>'closed an issue in',];
if ($JSON['object_attributes']['action'] == "open") {
$txt_title_issue=$txt_title_open_issue[$lang];
}
else if ($JSON['object_attributes']['action'] == "close") {
$txt_title_issue=$txt_title_close_issue[$lang];
}
else {
$txt_title_issue=$txt_title_update_issue[$lang];
}
$messageJSON['content'] = $txt_ligne_issue[$lang] ;
$messageJSON['embeds'] = array(array('title'=> $txt_title_issue.' *'.$JSON['project']['name'].'*',
'description'=> "**".$JSON['object_attributes']['title']."**\n".$JSON['object_attributes']['description'],
'url'=> $JSON['object_attributes']['url'],
'timestamp'=> $JSON['object_attributes']['last_edited_at'],
'author'=> array('name'=> $JSON['user']['name'])),);
return($messageJSON);
}
function note_layout($messageJSON,$JSON,$lang) {
$txt_ligne_note=["fr"=>'Nouvelle note',"es"=>'Nueva note',"en"=>'New note',];
$txt_title_note=["fr"=>'a noté quelque chose dans',"es"=>'marcó algo en',"en"=>'noted something in',];
$txt_object_name="";
if ($JSON['object_attributes']['noteable_type'] == "Issue") {
$txt_object_name=$JSON['issue']['title'];
}
else if ($JSON['object_attributes']['noteable_type'] == "Commit") {
$txt_object_name=$JSON['commit']['message'];
}
else if ($JSON['object_attributes']['noteable_type'] == "MergeRequest") {
$txt_object_name=$JSON['merge_request']['title'];
}
$messageJSON['content'] = $txt_ligne_note[$lang] ;
$messageJSON['embeds'] = array(array('title'=> $txt_title_note[$lang].' *'.$JSON['project']['name'].'*',
'description'=> "**".$JSON['object_attributes']['noteable_type']." *".$txt_object_name."***\n".$JSON['object_attributes']['note'],
'url'=> $JSON['object_attributes']['url'],
'timestamp'=> $JSON['object_attributes']['created_at'],
'author'=> array('name'=> $JSON['user']['name'])),);
return($messageJSON);
}
function MR_layout($messageJSON,$JSON,$lang,$hl) {
$txt_ligne_MR=["fr"=>'Nouvelle merge request',"es"=>'Nueva merge request',"en"=>'New merge request',];
$txt_open_action=["fr"=>'a ouvert une MR dans',"es"=>'abrió una MR en',"en"=>'opened a MR in',];
$txt_merge_action=["fr"=>'a mergé une MR dans',"es"=>'ejecutó una MR en',"en"=>'merged a MR in',];
$txt_unknown_action=["fr"=>'a modifié une MR dans',"es"=>'cambió una MR en',"en"=>'modified a MR in',];
if ($JSON['object_attributes']['action'] == "open") {
$txt_action=$txt_open_action[$lang];
$txt_action_description=$JSON['object_attributes']['description'];
}
else if ($JSON['object_attributes']['action'] == "merge") {
$txt_action=$txt_merge_action[$lang];
$txt_action_description=$JSON['object_attributes']['source_branch'].'->'.$JSON['object_attributes']['target_branch'];
}
else {
$txt_action=$txt_unkown_action[$lang];
$txt_action_description="*Problem with GitScord, please report.*";
}
$messageJSON['content'] = $txt_ligne_MR[$lang].$hl;
$messageJSON['allowed_mentions'] = array('parse'=>array("users","roles","everyone"),);
$messageJSON['embeds'] = array(array('title'=> $txt_action.' *'.$JSON['project']['name'].'*',
'description'=> "**".$JSON['object_attributes']['title']."**\n".$txt_action_description,
'url'=> $JSON['object_attributes']['url'],
'timestamp'=> $JSON['object_attributes']['created_at'],
'author'=> array('name'=> $JSON['user']['name'])),);
return($messageJSON);
}
?>