Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Slack integration using Redis
# 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');
<?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("&", "&amp;", $in);
$o = str_replace("<", "&lt;", $o);
$o = str_replace(">", "&gt;", $o);
$o = str_replace('"', "&quot;", $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
You can’t perform that action at this time.