|
|
@@ -0,0 +1,209 @@ |
|
|
<?php |
|
|
/** |
|
|
* Mediawiki Slack integration extension. |
|
|
* @version 1.0.1 |
|
|
* |
|
|
* Copyright (C) 2014-2015 George Goldberg <[email protected]> |
|
|
* @author George Goldberg <[email protected]> |
|
|
* |
|
|
* @license MIT |
|
|
* |
|
|
* @file The hooks of the Mediawiki Slack integration extension. |
|
|
* For more information on Slack, see http://www.slack.com. |
|
|
* @ingroup Extensions |
|
|
*/ |
|
|
|
|
|
class SlackHooks { |
|
|
|
|
|
public static function isCreate() { |
|
|
global $wgSlackIsCreate; |
|
|
|
|
|
if ($wgSlackIsCreate === true) { |
|
|
return true; |
|
|
} |
|
|
|
|
|
$wgSlackIsCreate = true; |
|
|
return false; |
|
|
} |
|
|
|
|
|
public static function encodeSlackChars($in) { |
|
|
// This function encodes chars that the Slack API expects to be encoded in the JSON values. |
|
|
// See https://api.slack.com/docs/formatting for details. |
|
|
$o = str_replace("&", "&", $in); |
|
|
$o = str_replace("<", "<", $o); |
|
|
$o = str_replace(">", ">", $o); |
|
|
$o = str_replace('"', """, $o); |
|
|
|
|
|
return $o; |
|
|
} |
|
|
|
|
|
public static function sendToRedis($payload) { |
|
|
/*global $wgSlackWebhookURL; |
|
|
|
|
|
wfDebug("Slack URL: ".$wgSlackWebhookURL."\n"); |
|
|
wfDebug("Slack Payload: ".$payload."\n"); |
|
|
|
|
|
$post = "payload=".urlencode($payload); |
|
|
|
|
|
// POST it to Slack. |
|
|
$options = array( |
|
|
'http' => array( |
|
|
'header' => "Content-type: application/x-www-form-urlencoded\r\n", |
|
|
'method' => 'POST', |
|
|
'content' => $post, |
|
|
'timeout' => 0.5, // don't wait for Slack's response |
|
|
), |
|
|
); */ |
|
|
|
|
|
try { |
|
|
global $redis; |
|
|
$redis->lPush('slack:recent-changes', $payload); |
|
|
} catch (Exception $e) { |
|
|
wfDebug('sendToRedis failed: '.$e->getMessage()."\n"); |
|
|
} |
|
|
|
|
|
/*$context = stream_context_create($options); |
|
|
$result = file_get_contents($wgSlackWebhookURL, false, $context); |
|
|
|
|
|
if (!$result) { |
|
|
wfDebug("API call failed!\n"); |
|
|
} else { |
|
|
wfDebug("Slack Result: ".$result."\n"); |
|
|
}*/ |
|
|
} |
|
|
|
|
|
public static function buildMessage($wikiPage, $user, $summary, $verb) { |
|
|
global $wgSlackLinkUsers; |
|
|
|
|
|
// Build the message we're going to post to Slack. |
|
|
$message = '*<'.SlackHooks::encodeSlackChars($wikiPage->getTitle()->getFullURL()) |
|
|
.'|'.SlackHooks::encodeSlackChars($wikiPage->getTitle()).'>* ' |
|
|
.$verb.' by *'; |
|
|
if ($wgSlackLinkUsers) { |
|
|
$message .= '@'; |
|
|
} |
|
|
$message .= SlackHooks::encodeSlackChars(strtolower($user->getName())).'*'; |
|
|
if (!empty($summary)) { |
|
|
$message .= ': '.$summary; |
|
|
} |
|
|
$message .= '.'; |
|
|
|
|
|
return $message; |
|
|
} |
|
|
|
|
|
public static function buildPayload($message) { |
|
|
global $wgSlackChannel, $wgSlackLinkUsers, $wgSlackUserName, $wgSlackIconURL; |
|
|
|
|
|
// Build the WebHook Payload. |
|
|
// NB: The Slack parser chokes if there is a trailing , at the end of the list of items |
|
|
// in the payload. Make sure any optional items are in the middle to avoid this. |
|
|
$payload = '{"channel": "'.$wgSlackChannel.'",'; |
|
|
if ($wgSlackLinkUsers) { |
|
|
$payload .= '"link_names": "1",'; |
|
|
} |
|
|
if ($wgSlackIconURL) { |
|
|
$payload .= '"icon_url": "'.$wgSlackIconURL.'",'; |
|
|
} |
|
|
$payload .= '"username": "'.$wgSlackUserName.'",' |
|
|
.'"text": "'.$message.'"' |
|
|
.'}'; |
|
|
|
|
|
return $payload; |
|
|
} |
|
|
|
|
|
public static function buildRichPayload($wikiPage, $user, $summary, $diff, $verb) { |
|
|
global $wgSlackUserName, $wgSlackIconURL, $wgSlackLinkUsers; |
|
|
$attachment = array(); |
|
|
$attachment['fallback'] = sprintf('%s %s by %s', $wikiPage->getTitle(), $verb, strtolower($user->getName())); |
|
|
$attachment['title'] = $wikiPage->getTitle()->getFullText(); |
|
|
$attachment['title_link'] = $wikiPage->getTitle()->GetFullURL(); |
|
|
if (!empty($summary)) { |
|
|
$attachment['fallback'] .= ': '.SlackHooks::encodeSlackChars($summary); |
|
|
} |
|
|
$attachment['fallback'] .= '.'; |
|
|
$attachment['pretext'] = SlackHooks::encodeSlackChars($summary); |
|
|
$attachment['text'] = $diff; |
|
|
$attachment['author_name'] = strtolower($user->getName()); |
|
|
$attachment['author_link'] = sprintf('https://wiki.metakgp.org/w/User:%s', $user->getName()); |
|
|
$attachment['color'] = 'good'; |
|
|
$payload['attachments'] = array($attachment); |
|
|
$payload['username'] = $wgSlackUserName; |
|
|
$payload['icon_url'] = $wgSlackIconURL; |
|
|
$payload['link_names'] = "1"; |
|
|
|
|
|
return json_encode($payload, JSON_UNESCAPED_SLASHES|JSON_HEX_APOS|JSON_HEX_QUOTE); |
|
|
|
|
|
} |
|
|
|
|
|
private static function isBot($user) { |
|
|
if (in_array("bot", $user->getGroups())) { |
|
|
return true; |
|
|
} |
|
|
return false; |
|
|
} |
|
|
|
|
|
public static function onPageContentSaveComplete($wikiPage, $user, $content, $summary, $isMinor, |
|
|
$isWatch, $section, $flags, $revision, $status, $baseRevId) { |
|
|
global $wgSlackIgnoreMinor; |
|
|
|
|
|
// If this is a bot, return now |
|
|
if (SlackHooks::isBot($user)) { |
|
|
return true; |
|
|
} |
|
|
|
|
|
// If this is a minor edit and we want to ignore minor edits, return now. |
|
|
if ($wgSlackIgnoreMinor && $isMinor) { |
|
|
return true; |
|
|
} |
|
|
|
|
|
// If this is a page creation, don't notify it as being modified too. |
|
|
if (true === SlackHooks::isCreate()) { |
|
|
return true; |
|
|
} |
|
|
|
|
|
|
|
|
// Build the Slack Message. |
|
|
$message = SlackHooks::buildMessage($wikiPage, $user, $summary, "modified"); |
|
|
|
|
|
//$oldRevision = $revision->getPrevious(); |
|
|
|
|
|
|
|
|
// Build the Slack Payload. |
|
|
//$payload = SlackHooks::buildPayload($wikiPage, $user, $summary, $content->getNativeData(), "modified"); |
|
|
|
|
|
$payload = SlackHooks::buildPayload($message); |
|
|
|
|
|
// Send the message to Slack. |
|
|
SlackHooks::sendToRedis($payload); |
|
|
|
|
|
return true; |
|
|
} |
|
|
|
|
|
public static function onPageContentInsertComplete($wikiPage, $user, $content, $summary, $isMinor, $isWatch, $section, $flags, $revision) { |
|
|
global $wgSlackIsCreate, $wgSlackIgnoreMinor; |
|
|
|
|
|
// If this is a bot, return now |
|
|
if (SlackHooks::isBot($user)) { |
|
|
return true; |
|
|
} |
|
|
// If this is a minor edit and we want to ignore minor edits, return now. |
|
|
if ($wgSlackIgnoreMinor && $isMinor) { |
|
|
return true; |
|
|
} |
|
|
|
|
|
// Flag this as a page creation so we don't notify it's been modified as well. |
|
|
$wgSlackIsCreate = true; |
|
|
|
|
|
// Build the Slack Message. |
|
|
$message = SlackHooks::buildMessage($wikiPage, $user, $summary, "created"); |
|
|
|
|
|
// Build the Slack Payload. |
|
|
$payload = SlackHooks::buildPayload($message); |
|
|
|
|
|
// Send the message to Slack. |
|
|
SlackHooks::sendToRedis($payload); |
|
|
|
|
|
return true; |
|
|
} |
|
|
|
|
|
} |