Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| bbff717a24 | |||
| 6d8b2c33cb | |||
| 47eef3c35d | |||
| 7f51c4f310 | |||
| ad101a326f | |||
| 687d1abf1f | |||
| 0df5463a87 | |||
| 10b4db72f7 | |||
| fb9ada8f9c | |||
| 9a7dd03d5c | |||
| fa9149165d | |||
| ca3a5f8047 | |||
| 591ef8746e | |||
| 6c2e30deab | |||
| ce780adf10 | |||
| 680040e823 | |||
| 8fa8dce03d | |||
| c3bdbecee5 | |||
| 6ccca7b823 | |||
| 03d612a3f7 | |||
| 9830df7e97 | |||
| cecb90dffc | |||
| 9034275470 | |||
| 3f1e1e784b | |||
| 78d66e5e31 | |||
| f0cf5a741d |
@@ -1,7 +1,7 @@
|
||||
# Discord (mw-discord)
|
||||
MediaWiki extension for sending notifications to a Discord webhook from MediaWiki. When a certain event occurs on your MediaWiki wiki, including new edits, they can be sent as a message to a channel on a Discord server using a webhook.
|
||||
|
||||
Multiple webhook URLs are supported and messages will be sent to all of them using cURL, so your web server is required to have cURL installed (for most Linux distros, installing using `sudo apt install curl` should work).
|
||||
Multiple webhook URLs are supported and messages will be sent to all of them.
|
||||
|
||||
**Live demo**: https://runescape.wiki (https://discord.gg/runescapewiki)
|
||||
|
||||
@@ -12,7 +12,9 @@ Multiple webhook URLs are supported and messages will be sent to all of them usi
|
||||
## Requirements
|
||||
- **Discord webhook URL**: This can be obtained by editing a channel on a server with the correct permissions.
|
||||
- **MediaWiki 1.31+**
|
||||
- **cURL**
|
||||
|
||||
### Recommended
|
||||
- **cURL**: By default, this extension sends requests using cURL. If you don't have cURL, you could try setting `$wgDiscordUseFileGetContents` to `true` instead, but this is not recommended.
|
||||
|
||||
## Installation
|
||||
|
||||
@@ -49,6 +51,8 @@ This extension can be configured using the `LocalSettings.php` file in your Medi
|
||||
| `$wgDiscordDisabledHooks` | array | List of hooks to disable sending webhooks for (see [below](#hooks-used)) | `[]`
|
||||
| `$wgDiscordDisabledNS` | array | List of namespaces to disable sending webhooks for | `[]`
|
||||
| `$wgDiscordDisabledUsers` | array | List of users whose performed actions shouldn't send webhooks | `[]`
|
||||
| `$wgDiscordPrependTimestamp` | bool | Prepend a timestamp (in UTC) to all sent messages. The format can be changed by editing the MediaWiki message `discord-timestampformat` | `false`
|
||||
| `$wgDiscordUseFileGetContents` | bool | Use `file_get_contents` instead of cURL. Requires `allow_url_fopen` to be set to true in `php.ini`. Not recommended as cURL makes simultaneous calls instead. | `false`
|
||||
|
||||
## Hooks used
|
||||
- `PageContentSaveComplete` - New edits to pages and page creations
|
||||
@@ -64,6 +68,7 @@ This extension can be configured using the `LocalSettings.php` file in your Medi
|
||||
- `UploadComplete` - File was uploaded
|
||||
- `FileDeleteComplete` - File revision was deleted
|
||||
- `FileUndeleteComplete` - File revision was restored
|
||||
- `AfterImportPage` - Page was imported
|
||||
|
||||
## Translation
|
||||
This extension can be translated through the messages in the `ì18n` folder if you're a developer. As a wiki administrator, you may find it a better option to edit the messages on-site in the MediaWiki namespace.
|
||||
|
||||
+6
-3
@@ -4,7 +4,7 @@
|
||||
"[https://github.com/jaydenkieran Jayden Bailey]"
|
||||
],
|
||||
"url": "https://github.com/jaydenkieran/mw-discord",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.10",
|
||||
"descriptionmsg": "discord-desc",
|
||||
"license-name": "MIT",
|
||||
"manifest_version": 1,
|
||||
@@ -17,7 +17,9 @@
|
||||
"DiscordMaxChars": null,
|
||||
"DiscordDisabledHooks": [],
|
||||
"DiscordDisabledNS": [],
|
||||
"DiscordDisabledUsers": []
|
||||
"DiscordDisabledUsers": [],
|
||||
"DiscordPrependTimestamp": false,
|
||||
"DiscordUseFileGetContents": false
|
||||
},
|
||||
"AutoloadClasses": {
|
||||
"DiscordHooks": "src/DiscordHooks.php",
|
||||
@@ -39,6 +41,7 @@
|
||||
"UserGroupsChanged": "DiscordHooks::onUserGroupsChanged",
|
||||
"UploadComplete": "DiscordHooks::onUploadComplete",
|
||||
"FileDeleteComplete": "DiscordHooks::onFileDeleteComplete",
|
||||
"FileUndeleteComplete": "DiscordHooks::onFileUndeleteComplete"
|
||||
"FileUndeleteComplete": "DiscordHooks::onFileUndeleteComplete",
|
||||
"AfterImportPage": "DiscordHooks::onAfterImportPage"
|
||||
}
|
||||
}
|
||||
|
||||
+9
-1
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Jayden Bailey"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Sends messages to a Discord channel when certain events occur",
|
||||
"discord-userlinks": "$1 ($2|$3)",
|
||||
"discord-revisionlinks": "($1) $2 $3",
|
||||
@@ -8,6 +13,7 @@
|
||||
"discord-minor": "(m)",
|
||||
"discord-size": "($1)",
|
||||
"discord-edit": "$1 edited $2 $3 $4",
|
||||
"discord-create": "$1 created $2 $3 $4",
|
||||
"discord-articledelete": "$1 deleted $2 $3 ($4 revisions deleted)",
|
||||
"discord-undeleterev": "revisions for",
|
||||
"discord-articleundelete": "$1 undeleted $2 $3 $4",
|
||||
@@ -22,5 +28,7 @@
|
||||
"discord-uploadnewver": "new version of",
|
||||
"discord-uploadcomplete": "$1 uploaded $2 $3 $4 ($5, $6x$7, $8)",
|
||||
"discord-filedeletecomplete": "$1 deleted a version of file $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 restored some versions of file $2 $3"
|
||||
"discord-fileundeletecomplete": "$1 restored some versions of file $2 $3",
|
||||
"discord-afterimportpage": "$1 imported $2 (imported $4/$3 revisions)",
|
||||
"discord-timestampformat": "**H:i e:**"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Railfail536"
|
||||
]
|
||||
},
|
||||
"discord-desc": "Wysyła wiadomości o dokonywanych akcjach na serwer Discord",
|
||||
"discord-userlinks": "$1 ($2|$3)",
|
||||
"discord-revisionlinks": "($1) $2 $3",
|
||||
"discord-talk": "d",
|
||||
"discord-contribs": "w",
|
||||
"discord-diff": "różn.",
|
||||
"discord-minor": "(m)",
|
||||
"discord-size": "($1)",
|
||||
"discord-edit": "$1 edytował $2 $3 $4",
|
||||
"discord-articledelete": "$1 usunął $2 $3 ($4 wersje usunięte)",
|
||||
"discord-undeleterev": "wersje",
|
||||
"discord-articleundelete": "$1 odtworzył $2 $3 $4",
|
||||
"discord-revvisibility": "$1 zmienił widoczność $2 wersji $3",
|
||||
"discord-articleprotect": "$1 zmienił poziom zabezpoeczenia strony $2 $2 $3 ($4)",
|
||||
"discord-titlemove": "$1 przeniósł $2 na $3 $4 $5",
|
||||
"discord-localusercreated": "$1 założył konto",
|
||||
"discord-blocktimeformat": "d F Y H:i",
|
||||
"discord-blockipcomplete": "$1 zablokował $2 $3 ($4)",
|
||||
"discord-unblockusercomplete": "$1 zdjął blokadę z $2",
|
||||
"discord-usergroupschanged": "$1 zmienił uprawnienia użytkownika $2 $3 ($4) ($5)",
|
||||
"discord-uploadnewver": "nową wersję",
|
||||
"discord-uploadcomplete": "$1 przesłał $2 $3 $4 ($5, $6x$7, $8)",
|
||||
"discord-filedeletecomplete": "$1 usunął wersję pliku $2 $3",
|
||||
"discord-fileundeletecomplete": "$1 odtworzył wersje pliku $2 $3"
|
||||
}
|
||||
+10
-2
@@ -1,4 +1,9 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Jayden Bailey"
|
||||
]
|
||||
},
|
||||
"discord-desc": "The description used for the Discord extension",
|
||||
"discord-userlinks": "Used for display of the user links. Parameters\n* $1 - User page link\n* $2 - discord-talk\n* $3 - discord-contribs",
|
||||
"discord-revisionlinks": "Used for display of revision links. Parameters\n* $1 - discord-diff\n* $2 - discord-minor\n* $3 - discord-size",
|
||||
@@ -7,7 +12,8 @@
|
||||
"discord-diff": "Used as the text for $1 in discord-revisionlinks",
|
||||
"discord-minor": "Used as the text for $2 in discord-revisionlinks",
|
||||
"discord-size": "Used as the text for $3 in discord-revisionlinks. Parameters\n* $1 - Calculated revision size diff",
|
||||
"discord-edit": "Message sent to Discord for when a page edit/creation is made. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - discord-revisionlinks\n* $4 - Summary (always surrounded in tildes)",
|
||||
"discord-edit": "Message sent to Discord for when a page edit is made. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - discord-revisionlinks\n* $4 - Summary (always surrounded in tildes)",
|
||||
"discord-create": "Message sent to Discord for when a page creation is made. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - discord-revisionlinks\n* $4 - Summary (always surrounded in tildes)",
|
||||
"discord-articledelete": "Message sent to Discord when a page is deleted. Parameters:\n* $1 - discord-userlinks\n* $2 - Page link\n* $3 - Reason (always surrounded in tildes)\n* $4 - Number of revisions deleted",
|
||||
"discord-undeleterev": "Used as the text for $2 in discord-articleundelete if revisions are being undeleted rather than a page",
|
||||
"discord-articleundelete": "Message sent to Discord when pages/revisions are undeleted. Parameters:\n* $1 - discord-userlinks\n* $2 - discord-undeleterev\n* $3 - Page link\n* $4 - Comment (always surrounded in tildes)",
|
||||
@@ -22,5 +28,7 @@
|
||||
"discord-uploadnewver": "Used as the text for $2 in discord-uploadcomplete",
|
||||
"discord-uploadcomplete": "Message sent to Discord when an upload is made. Parameters:\n$1 - discord-userlinks\n$2 - discord-uploadnewver\n$3 - File link\n$4 - Comment (always surrounded in tildes)\n$5 - Size (formatted as KB/MB/GB)\n$6 - File width\n$7 - File height\n$8 - File MIME type",
|
||||
"discord-filedeletecomplete": "Message sent to Discord when a file version is deleted (not an entire file). Parameters:\n$1 - discord-userlinks\n$2 - File link\n$3 - Comment (always surrounded in tildes)",
|
||||
"discord-fileundeletecomplete": "Message sent to Discord when a file version is restored (not an entire file). Parameters:\n$1 - discord-userlinks\n$2 - File link\n$3 - Comment (always surrounded in tildes)"
|
||||
"discord-fileundeletecomplete": "Message sent to Discord when a file version is restored (not an entire file). Parameters:\n$1 - discord-userlinks\n$2 - File link\n$3 - Comment (always surrounded in tildes)",
|
||||
"discord-afterimportpage": "Message sent to Discord when a page is imported. Parameters:\n$1 - discord-userlinks\n$2 - Page link\n$3 - Number of revisions in XML file\n$4 - Number of revisions successfully imported",
|
||||
"discord-timestampformat": "The formatting used in the gmtime() function for displaying the time an event happened in UTC."
|
||||
}
|
||||
|
||||
+76
-15
@@ -37,7 +37,14 @@ class DiscordHooks {
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-edit', DiscordUtils::createUserLinks( $user ),
|
||||
$msgKey = 'discord-edit';
|
||||
|
||||
$isNew = $status->value['new'];
|
||||
if ($isNew == 1) { // is a new page
|
||||
$msgKey = 'discord-create';
|
||||
}
|
||||
|
||||
$msg = wfMessage( $msgKey, DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $wikiPage->getTitle(), $wikiPage->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
DiscordUtils::createRevisionText( $revision ),
|
||||
( $summary ? ('`' . DiscordUtils::truncateText( $summary ) . '`' ) : '' ) )->plain();
|
||||
@@ -50,7 +57,7 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleDeleteComplete
|
||||
*/
|
||||
public static function onArticleDeleteComplete( &$article, User &$user, $reason, $id, $content, LogEntry $logEntry, $archivedRevisionCount ) {
|
||||
global $wgDiscordNoBots, $wgDiscordNoMinor, $wgDiscordNoNull;
|
||||
global $wgDiscordNoBots;
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'ArticleDeleteComplete', $article->getTitle()->getNamespace(), $user ) ) {
|
||||
return true;
|
||||
@@ -64,7 +71,7 @@ class DiscordHooks {
|
||||
$msg = wfMessage( 'discord-articledelete', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $article->getTitle(), $article->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
|
||||
$archivedRevisionCount)->text();
|
||||
$archivedRevisionCount)->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
@@ -74,16 +81,21 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleUndelete
|
||||
*/
|
||||
public static function onArticleUndelete( Title $title, $create, $comment, $oldPageId, $restoredPages ) {
|
||||
global $wgUser;
|
||||
global $wgDiscordNoBots, $wgUser;
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'ArticleUndelete', $title->getNamespace(), $wgUser ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $wgUser->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-articleundelete', DiscordUtils::createUserLinks( $wgUser ),
|
||||
($create ? '' : wfMessage( 'discord-undeleterev' )->text() ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $comment ? ('`' . DiscordUtils::truncateText( $comment ) . '`' ) : '' ))->text();
|
||||
( $comment ? ('`' . DiscordUtils::truncateText( $comment ) . '`' ) : '' ))->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
@@ -93,15 +105,20 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/ArticleRevisionVisibilitySet
|
||||
*/
|
||||
public static function onArticleRevisionVisibilitySet( &$title, $ids, $visibilityChangeMap ) {
|
||||
global $wgUser;
|
||||
global $wgDiscordNoBots, $wgUser;
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'ArticleRevisionVisibilitySet', $title->getNamespace(), $wgUser ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $wgUser->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-revvisibility', DiscordUtils::createUserLinks( $wgUser ),
|
||||
count($visibilityChangeMap),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ) )->text();
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
@@ -125,7 +142,7 @@ class DiscordHooks {
|
||||
$msg = wfMessage( 'discord-articleprotect', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $article->getTitle(), $article->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
|
||||
implode(", ", $protect) )->text();
|
||||
implode(", ", $protect) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
@@ -150,7 +167,7 @@ class DiscordHooks {
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
DiscordUtils::createMarkdownLink( $newTitle, $newTitle->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
|
||||
DiscordUtils::createRevisionText( $revision ) )->text();
|
||||
DiscordUtils::createRevisionText( $revision ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
@@ -164,7 +181,7 @@ class DiscordHooks {
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-localusercreated', DiscordUtils::createUserLinks( $user ) )->text();
|
||||
$msg = wfMessage( 'discord-localusercreated', DiscordUtils::createUserLinks( $user ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
@@ -187,7 +204,7 @@ class DiscordHooks {
|
||||
|
||||
$msg = wfMessage( 'discord-blockipcomplete', DiscordUtils::createUserLinks( $user ), DiscordUtils::createUserLinks( $block->getTarget() ),
|
||||
( $block->mReason ? ('`' . DiscordUtils::truncateText( $block->mReason ) . '`' ) : '' ),
|
||||
$expiryMsg )->text();
|
||||
$expiryMsg )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
@@ -224,7 +241,7 @@ class DiscordHooks {
|
||||
DiscordUtils::createUserLinks( $user ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ),
|
||||
( ( count($added) > 0 ) ? ( '+ ' . join(', ', $added) ) : ''),
|
||||
( ( count($removed) > 0 ) ? ( '- ' . join(', ', $removed) ) : '' ) )->text();
|
||||
( ( count($removed) > 0 ) ? ( '- ' . join(', ', $removed) ) : '' ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
@@ -234,6 +251,8 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/UploadComplete
|
||||
*/
|
||||
public static function onUploadComplete( &$image ) {
|
||||
global $wgDiscordNoBots;
|
||||
|
||||
$lf = $image->getLocalFile();
|
||||
$user = $lf->getUser( $type = 'object' ); // only supported in MW 1.31+
|
||||
|
||||
@@ -241,6 +260,11 @@ class DiscordHooks {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
$comment = $lf->getDescription();
|
||||
$isNewRevision = count($lf->getHistory()) > 0;
|
||||
|
||||
@@ -251,7 +275,7 @@ class DiscordHooks {
|
||||
DiscordUtils::formatBytes($lf->getSize()),
|
||||
$lf->getWidth(),
|
||||
$lf->getHeight(),
|
||||
$lf->getMimeType() )->text();
|
||||
$lf->getMimeType() )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
@@ -261,10 +285,17 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/FileDeleteComplete
|
||||
*/
|
||||
public static function onFileDeleteComplete( $file, $oldimage, $article, $user, $reason ) {
|
||||
global $wgDiscordNoBots;
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'FileDeleteComplete', NS_FILE, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $article ) {
|
||||
// Entire page was deleted, onArticleDeleteComplete will handle this
|
||||
return true;
|
||||
@@ -272,7 +303,7 @@ class DiscordHooks {
|
||||
|
||||
$msg = wfMessage( 'discord-filedeletecomplete', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $file->getName(), $file->getTitle()->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ) )->text();
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
@@ -282,13 +313,43 @@ class DiscordHooks {
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/FileUndeleteComplete
|
||||
*/
|
||||
public static function onFileUndeleteComplete( $title, $fileVersions, $user, $reason ) {
|
||||
global $wgDiscordNoBots;
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'FileUndeleteComplete', NS_FILE, $user ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $user->isBot() ) {
|
||||
// Don't continue, this is a bot change
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-fileundeletecomplete', DiscordUtils::createUserLinks( $user ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ) )->text();
|
||||
( $reason ? ('`' . DiscordUtils::truncateText( $reason ) . '`' ) : '' ) )->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a page is imported
|
||||
* @see https://www.mediawiki.org/wiki/Manual:Hooks/AfterImportPage
|
||||
*/
|
||||
public static function onAfterImportPage( $title, $origTitle, $revCount, $sRevCount, $pageInfo ) {
|
||||
global $wgDiscordNoBots, $wgUser;
|
||||
|
||||
if ( DiscordUtils::isDisabled( 'AfterImportPage', $title->getNamespace(), $wgUser ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( $wgDiscordNoBots && $wgUser->isBot() ) {
|
||||
// Don't continue, this is a bot
|
||||
return true;
|
||||
}
|
||||
|
||||
$msg = wfMessage( 'discord-afterimportpage', DiscordUtils::createUserLinks( $wgUser ),
|
||||
DiscordUtils::createMarkdownLink( $title, $title->getFullUrl( '', '', $proto = PROTO_HTTP ) ),
|
||||
$revCount, $sRevCount)->plain();
|
||||
DiscordUtils::handleDiscord($msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
+76
-35
@@ -46,7 +46,7 @@ class DiscordUtils {
|
||||
* Handles sending a webhook to Discord using cURL
|
||||
*/
|
||||
public static function handleDiscord ($msg) {
|
||||
global $wgDiscordWebhookURL;
|
||||
global $wgDiscordWebhookURL, $wgDiscordPrependTimestamp, $wgDiscordUseFileGetContents;
|
||||
|
||||
if ( !$wgDiscordWebhookURL ) {
|
||||
// There's nothing in here, so we won't do anything
|
||||
@@ -67,41 +67,70 @@ class DiscordUtils {
|
||||
// Strip whitespace to just one space
|
||||
$stripped = preg_replace('/\s+/', ' ', $msg);
|
||||
|
||||
DeferredUpdates::addCallableUpdate( function() use ( $stripped, $urls ) {
|
||||
if ( $wgDiscordPrependTimestamp ) {
|
||||
// Add timestamp
|
||||
$dateString = gmdate( wfMessage( 'discord-timestampformat' )->text() );
|
||||
$stripped = $dateString . ' ' . $stripped;
|
||||
}
|
||||
|
||||
DeferredUpdates::addCallableUpdate( function() use ( $stripped, $urls, $wgDiscordUseFileGetContents ) {
|
||||
$user_agent = 'mw-discord/1.0 (github.com/jaydenkieran)';
|
||||
$json_data = [ 'content' => "$stripped" ];
|
||||
$json = json_encode($json_data);
|
||||
|
||||
// Set up cURL multi handlers
|
||||
$c_handlers = [];
|
||||
$result = [];
|
||||
$mh = curl_multi_init();
|
||||
if ( $wgDiscordUseFileGetContents ) {
|
||||
// They want to use file_get_contents
|
||||
foreach ($urls as &$value) {
|
||||
$contextOpts = [
|
||||
'http' => [
|
||||
'header' => 'Content-Type: application/x-www-form-urlencoded',
|
||||
'method' => 'POST', // Send as a POST request
|
||||
'user_agent' => $user_agent, // Add a unique user agent
|
||||
'content' => $json, // Send the JSON in the POST request
|
||||
'ignore_errors' => true // If the call fails, let's not do anything with it
|
||||
]
|
||||
];
|
||||
|
||||
foreach ($urls as &$value) {
|
||||
$c_handlers[$value] = curl_init( $value );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_POST, 1 ); // Send as a POST request
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_POSTFIELDS, $json ); // Send the JSON in the POST request
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_FOLLOWLOCATION, 1 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_HEADER, 0 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_RETURNTRANSFER, 1 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_CONNECTTIMEOUT, 10 ); // Add a timeout for connecting to the site
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_TIMEOUT, 20 ); // Do not allow cURL to run for a long time
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_USERAGENT, 'mw-discord/1.0 (github.com/jaydenkieran)' ); // Add a unique user agent
|
||||
curl_multi_add_handle( $mh, $c_handlers[$value] );
|
||||
$response = curl_exec( $ch );
|
||||
$context = stream_context_create( $contextOpts );
|
||||
$result = file_get_contents( $value, false, $context );
|
||||
}
|
||||
} else {
|
||||
// By default, we use cURL
|
||||
// Set up cURL multi handlers
|
||||
$c_handlers = [];
|
||||
$result = [];
|
||||
$mh = curl_multi_init();
|
||||
|
||||
foreach ($urls as &$value) {
|
||||
$c_handlers[$value] = curl_init( $value );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_POST, 1 ); // Send as a POST request
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_POSTFIELDS, $json ); // Send the JSON in the POST request
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_FOLLOWLOCATION, 1 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_HEADER, 0 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_RETURNTRANSFER, 1 );
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_CONNECTTIMEOUT, 10 ); // Add a timeout for connecting to the site
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_TIMEOUT, 10 ); // Do not allow cURL to run for a long time
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_USERAGENT, $user_agent ); // Add a unique user agent
|
||||
curl_setopt( $c_handlers[$value], CURLOPT_HTTPHEADER, array(
|
||||
'Content-Type: application/json'
|
||||
));
|
||||
curl_multi_add_handle( $mh, $c_handlers[$value] );
|
||||
}
|
||||
|
||||
$running = null;
|
||||
do {
|
||||
curl_multi_exec($mh, $running);
|
||||
} while ($running);
|
||||
|
||||
// Remove all handlers and then close the multi handler
|
||||
foreach($c_handlers as $k => $ch) {
|
||||
$result[$k] = curl_multi_getcontent($ch);
|
||||
wfDebugLog( 'discord', 'Result of cURL was: ' . $result[$k] );
|
||||
curl_multi_remove_handle($mh, $ch);
|
||||
}
|
||||
|
||||
curl_multi_close($mh);
|
||||
}
|
||||
|
||||
$running = null;
|
||||
do {
|
||||
curl_multi_exec($mh, $running);
|
||||
} while ($running);
|
||||
|
||||
// Remove all handlers and then close the multi handler
|
||||
foreach($c_handlers as $k => $ch) {
|
||||
$result[$k] = curl_multi_getcontent($ch);
|
||||
curl_multi_remove_handle($mh, $ch);
|
||||
}
|
||||
|
||||
curl_multi_close($mh);
|
||||
} );
|
||||
|
||||
return true;
|
||||
@@ -120,10 +149,19 @@ class DiscordUtils {
|
||||
* Creates links for a specific MediaWiki User object
|
||||
*/
|
||||
public static function createUserLinks ($user) {
|
||||
$userPage = DiscordUtils::createMarkdownLink( $user, $user->getUserPage()->getFullUrl( '', '', $proto = PROTO_HTTP ) );
|
||||
$userTalk = DiscordUtils::createMarkdownLink( wfMessage( 'discord-talk' )->text(), $user->getTalkPage()->getFullUrl( '', '', $proto = PROTO_HTTP ) );
|
||||
$userContribs = DiscordUtils::createMarkdownLink( wfMessage( 'discord-contribs' )->text(), Title::newFromText("Special:Contributions/" . $user)->getFullURL( '', '', $proto = PROTO_HTTP ) );
|
||||
$text = wfMessage( 'discord-userlinks', $userPage, $userTalk, $userContribs )->text();
|
||||
if ( $user instanceof User ) {
|
||||
$isAnon = $user->isAnon();
|
||||
$contribs = Title::newFromText("Special:Contributions/" . $user);
|
||||
|
||||
$userPage = DiscordUtils::createMarkdownLink( $user, ( $isAnon ? $contribs : $user->getUserPage() )->getFullUrl( '', '', $proto = PROTO_HTTP ) );
|
||||
$userTalk = DiscordUtils::createMarkdownLink( wfMessage( 'discord-talk' )->text(), $user->getTalkPage()->getFullUrl( '', '', $proto = PROTO_HTTP ) );
|
||||
$userContribs = DiscordUtils::createMarkdownLink( wfMessage( 'discord-contribs' )->text(), $contribs->getFullURL( '', '', $proto = PROTO_HTTP ) );
|
||||
$text = wfMessage( 'discord-userlinks', $userPage, $userTalk, $userContribs )->text();
|
||||
} else {
|
||||
// If it's a string, which can be likely (for example when range blocking a user)
|
||||
// We need to handle this differently.
|
||||
$text = wfMessage( 'discord-userlinks', $user, 'n/a', 'n/a' )->text();
|
||||
}
|
||||
return $text;
|
||||
}
|
||||
|
||||
@@ -147,6 +185,9 @@ class DiscordUtils {
|
||||
$size .= wfMessage( 'discord-size', sprintf( "%+d", $revision->getSize() - $previous->getSize() ) )->text();
|
||||
}
|
||||
}
|
||||
if ( $size == '' ) {
|
||||
$size .= wfMessage( 'discord-size', sprintf( "%d", $revision->getSize() ) )->text();
|
||||
}
|
||||
$text = wfMessage( 'discord-revisionlinks', $diff, $minor, $size )->text();
|
||||
return $text;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user