-
-
Save tobsn/acf2ca35768c5d566cd433367bbd6796 to your computer and use it in GitHub Desktop.
Slack integration using Redis
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Slack integration | |
require_once "$IP/extensions/Slack/Slack.php"; | |
# Slack extension configuration options | |
$wgSlackWebhookURL = "https://hooks.slack.com/services/some-webhook-url" | |
$wgSlackUserName = "batman"; | |
$wgSlackChannel = "#recent-changes"; | |
$wgSlackIconURL = "http://i.picresize.com/images/2015/09/20/tdpsU.jpg"; | |
$wgSlackLinkUsers = true; | |
# Redis | |
$redis = new Redis(); | |
$redis->pconnect('127.0.0.1'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Mediawiki Slack integration extension. | |
* @version 1.0.1 | |
* | |
* Copyright (C) 2014-2015 George Goldberg <george@grundleborg.com> | |
* @author George Goldberg <george@grundleborg.com> | |
* | |
* @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; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment