1
0
Markus-Rost 4 жил өмнө
parent
commit
18747a909d

+ 6 - 2
cmds/link.js

@@ -19,11 +19,15 @@ function cmd_link(lang, msg, title, wiki, cmd = '') {
 		title = title.substring( 2, title.length - 2);
 		var spoiler = '||';
 	}
+	if ( /^<[^<>]+>$/.test(title) ) {
+		title = title.substring( 1, title.length - 1);
+		var noEmbed = true;
+	}
 	msg.reactEmoji('⏳').then( reaction => {
 		if ( /^phabricator\.(wikimedia|miraheze)\.org$/.test(wiki.hostname) ) {
-			return phabricator(lang, msg, wiki, new URL('/' + title, wiki), reaction, spoiler);
+			return phabricator(lang, msg, wiki, new URL('/' + title, wiki), reaction, spoiler, noEmbed);
 		}
-		else check_wiki.general(lang, msg, title, wiki, cmd, reaction, spoiler);
+		else check_wiki.general(lang, msg, title, wiki, cmd, reaction, spoiler, noEmbed);
 	} );
 }
 

+ 35 - 28
cmds/minecraft/bug.js

@@ -11,8 +11,9 @@ const {escapeFormatting, limitLength} = require('../../util/functions.js');
  * @param {String} cmd - The command at this point.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  */
-function minecraft_bug(lang, msg, wiki, args, title, cmd, reaction, spoiler) {
+function minecraft_bug(lang, msg, wiki, args, title, cmd, reaction, spoiler, noEmbed) {
 	var invoke = args[0];
 	args = args.slice(1);
 	if ( invoke && /\d+$/.test(invoke) && !args.length ) {
@@ -48,21 +49,24 @@ function minecraft_bug(lang, msg, wiki, args, title, cmd, reaction, spoiler) {
 					var summary = escapeFormatting(body.fields.summary);
 					if ( summary.length > 250 ) summary = summary.substring(0, 250) + '\u2026';
 					var description = parse_links( ( body.fields.description || '' ).replace( /\{code\}/g, '```' ) );
-					var embed = new MessageEmbed().setAuthor( 'Mojira' ).setTitle( summary ).setURL( baseBrowseUrl + body.key ).setDescription( limitLength(description, 2000, 20) );
-					var links = body.fields.issuelinks.filter( link => link.outwardIssue || ( link.inwardIssue && link.type.name !== 'Duplicate' ) );
-					if ( links.length ) {
-						var linkList = lang.get('minecraft.issue_link');
-						var extralinks = [];
-						links.forEach( link => {
-							var ward = ( link.outwardIssue ? 'outward' : 'inward' );
-							var issue = link[ward + 'Issue']; // looks for property (in|out)wardIssue
-							var name = ( linkList?.[link.type.name]?.[ward]?.replaceSave( /\$1/g, issue.key ) || link.type[ward] + ' ' + issue.key );
-							var status = issue.fields.status.name;
-							var value = ( statusList?.[status] || status ) + ': [' + escapeFormatting(issue.fields.summary) + '](' + baseBrowseUrl + issue.key + ')';
-							if ( embed.fields.length < 25 && ( embed.length + name.length + value.length ) < 6000 ) embed.addField( name, value );
-							else extralinks.push({name,value,inline:false});
-						} );
-						if ( extralinks.length ) embed.setFooter( lang.get('minecraft.more', extralinks.length.toLocaleString(lang.get('dateformat')), extralinks.length) );
+					var embed = null;
+					if ( msg.showEmbed() && !noEmbed ) {
+						embed = new MessageEmbed().setAuthor( 'Mojira' ).setTitle( summary ).setURL( baseBrowseUrl + body.key ).setDescription( limitLength(description, 2000, 20) );
+						var links = body.fields.issuelinks.filter( link => link.outwardIssue || ( link.inwardIssue && link.type.name !== 'Duplicate' ) );
+						if ( links.length ) {
+							var linkList = lang.get('minecraft.issue_link');
+							var extralinks = [];
+							links.forEach( link => {
+								var ward = ( link.outwardIssue ? 'outward' : 'inward' );
+								var issue = link[ward + 'Issue']; // looks for property (in|out)wardIssue
+								var name = ( linkList?.[link.type.name]?.[ward]?.replaceSave( /\$1/g, issue.key ) || link.type[ward] + ' ' + issue.key );
+								var status = issue.fields.status.name;
+								var value = ( statusList?.[status] || status ) + ': [' + escapeFormatting(issue.fields.summary) + '](' + baseBrowseUrl + issue.key + ')';
+								if ( embed.fields.length < 25 && ( embed.length + name.length + value.length ) < 6000 ) embed.addField( name, value );
+								else extralinks.push({name,value,inline:false});
+							} );
+							if ( extralinks.length ) embed.setFooter( lang.get('minecraft.more', extralinks.length.toLocaleString(lang.get('dateformat')), extralinks.length) );
+						}
 					}
 					var status = ( body.fields.resolution ? body.fields.resolution.name : body.fields.status.name );
 					var fixed = '';
@@ -107,17 +111,20 @@ function minecraft_bug(lang, msg, wiki, args, title, cmd, reaction, spoiler) {
 					msg.reactEmoji('error');
 				}
 				else {
-					var embed = new MessageEmbed().setAuthor( 'Mojira' ).setTitle( args.join(' ') ).setURL( uri );
-					if ( body.total > 0 ) {
-						var statusList = lang.get('minecraft.status');
-						body.issues.forEach( bug => {
-							var status = ( bug.fields.resolution ? bug.fields.resolution.name : bug.fields.status.name );
-							var value = ( statusList?.[status] || status ) + ': [' + escapeFormatting(bug.fields.summary) + '](https://bugs.mojang.com/browse/' + bug.key + ')';
-							embed.addField( bug.key, value );
-						} );
-						if ( body.total > 25 ) {
-							var extrabugs = body.total - 25;
-							embed.setFooter( lang.get('minecraft.more', extrabugs.toLocaleString(lang.get('dateformat')), extrabugs) );
+					var embed = null;
+					if ( msg.showEmbed() && !noEmbed ) {
+						embed = new MessageEmbed().setAuthor( 'Mojira' ).setTitle( args.join(' ') ).setURL( uri );
+						if ( body.total > 0 ) {
+							var statusList = lang.get('minecraft.status');
+							body.issues.forEach( bug => {
+								var status = ( bug.fields.resolution ? bug.fields.resolution.name : bug.fields.status.name );
+								var value = ( statusList?.[status] || status ) + ': [' + escapeFormatting(bug.fields.summary) + '](https://bugs.mojang.com/browse/' + bug.key + ')';
+								embed.addField( bug.key, value );
+							} );
+							if ( body.total > 25 ) {
+								var extrabugs = body.total - 25;
+								embed.setFooter( lang.get('minecraft.more', extrabugs.toLocaleString(lang.get('dateformat')), extrabugs) );
+							}
 						}
 					}
 					var total = '**' + args.join(' ') + ':** ' + lang.get('minecraft.total', body.total.toLocaleString(lang.get('dateformat')), body.total);
@@ -133,7 +140,7 @@ function minecraft_bug(lang, msg, wiki, args, title, cmd, reaction, spoiler) {
 	}
 	else {
 		msg.notMinecraft = true;
-		this.WIKI.general(lang, msg, title, wiki, cmd, reaction, spoiler);
+		this.WIKI.general(lang, msg, title, wiki, cmd, reaction, spoiler, noEmbed);
 	}
 }
 

+ 5 - 4
cmds/minecraft/command.js

@@ -8,15 +8,16 @@
  * @param {String} cmd - The command at this point.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  */
-function minecraft_command(lang, msg, wiki, args, title, cmd, reaction, spoiler) {
+function minecraft_command(lang, msg, wiki, args, title, cmd, reaction, spoiler, noEmbed) {
 	if ( args.join('') ) {
-		if ( args[0].startsWith( '/' ) ) this.SYNTAX(lang, msg, wiki, args[0].substring(1), args.slice(1), title, cmd, reaction, spoiler);
-		else this.SYNTAX(lang, msg, wiki, args[0], args.slice(1), title, cmd, reaction, spoiler);
+		if ( args[0].startsWith( '/' ) ) this.SYNTAX(lang, msg, wiki, args[0].substring(1), args.slice(1), title, cmd, reaction, spoiler, noEmbed);
+		else this.SYNTAX(lang, msg, wiki, args[0], args.slice(1), title, cmd, reaction, spoiler, noEmbed);
 	}
 	else {
 		msg.notMinecraft = true;
-		this.WIKI.general(lang, msg, title, wiki, cmd, reaction, spoiler);
+		this.WIKI.general(lang, msg, title, wiki, cmd, reaction, spoiler, noEmbed);
 	}
 }
 

+ 3 - 2
cmds/minecraft/syntax.js

@@ -12,8 +12,9 @@ const commands = require('./commands.json');
  * @param {String} cmd - The command at this point.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  */
-function minecraft_syntax(lang, msg, wiki, mccmd, args, title, cmd, reaction, spoiler) {
+function minecraft_syntax(lang, msg, wiki, mccmd, args, title, cmd, reaction, spoiler, noEmbed) {
 	mccmd = mccmd.toLowerCase();
 	var aliasCmd = ( commands.aliases[mccmd] || mccmd );
 	var cmdpage = commands.wikis[wiki.href];
@@ -72,7 +73,7 @@ function minecraft_syntax(lang, msg, wiki, mccmd, args, title, cmd, reaction, sp
 	}
 	else {
 		msg.notMinecraft = true;
-		this.WIKI.general(lang, msg, title, wiki, cmd, reaction, spoiler);
+		this.WIKI.general(lang, msg, title, wiki, cmd, reaction, spoiler, noEmbed);
 	}
 }
 

+ 12 - 11
cmds/wiki/diff.js

@@ -12,9 +12,10 @@ const diffParser = require('../../util/edit_diff.js');
  * @param {import('../../util/wiki.js')} wiki - The wiki for the edit.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  * @param {MessageEmbed} [embed] - The embed for the page.
  */
-function gamepedia_diff(lang, msg, args, wiki, reaction, spoiler, embed) {
+function gamepedia_diff(lang, msg, args, wiki, reaction, spoiler, noEmbed, embed) {
 	if ( args[0] ) {
 		var error = false;
 		var title = '';
@@ -50,7 +51,7 @@ function gamepedia_diff(lang, msg, args, wiki, reaction, spoiler, embed) {
 			if ( reaction ) reaction.removeEmoji();
 		}
 		else if ( diff ) {
-			gamepedia_diff_send(lang, msg, [diff, revision], wiki, reaction, spoiler);
+			gamepedia_diff_send(lang, msg, [diff, revision], wiki, reaction, spoiler, noEmbed);
 		}
 		else {
 			got.get( wiki + 'api.php?action=compare&prop=ids|diff' + ( title ? '&fromtitle=' + encodeURIComponent( title ) : '&fromrev=' + revision ) + '&torelative=' + relative + '&format=json' ).then( response => {
@@ -111,7 +112,7 @@ function gamepedia_diff(lang, msg, args, wiki, reaction, spoiler, embed) {
 							else if ( ids.fromtexthidden !== undefined ) compare[0] = '__' + lang.get('diff.hidden') + '__';
 							else if ( ids.totexthidden !== undefined ) compare[1] = '__' + lang.get('diff.hidden') + '__';
 						}
-						gamepedia_diff_send(lang, msg, argids, wiki, reaction, spoiler, compare);
+						gamepedia_diff_send(lang, msg, argids, wiki, reaction, spoiler, noEmbed, compare);
 					}
 				}
 			}, error => {
@@ -129,7 +130,7 @@ function gamepedia_diff(lang, msg, args, wiki, reaction, spoiler, embed) {
 		}
 	}
 	else {
-		if ( embed ) msg.sendChannel( spoiler + '<' + embed.url + '>' + spoiler, {embed} );
+		if ( embed ) msg.sendChannel( spoiler + '<' + embed.url + '>' + spoiler, ( noEmbed ? {} : {embed} ) );
 		else msg.reactEmoji('error');
 		
 		if ( reaction ) reaction.removeEmoji();
@@ -144,9 +145,10 @@ function gamepedia_diff(lang, msg, args, wiki, reaction, spoiler, embed) {
  * @param {import('../../util/wiki.js')} wiki - The wiki for the edit.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  * @param {String[]} [compare] - The edit difference.
  */
-function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare) {
+function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, noEmbed, compare) {
 	got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general&list=tags&tglimit=500&tgprop=displayname&prop=revisions&rvslots=main&rvprop=ids|timestamp|flags|user|size|parsedcomment|tags' + ( args.length === 1 || args[0] === args[1] ? '|content' : '' ) + '&revids=' + args.join('|') + '&format=json' ).then( response => {
 		var body = response.body;
 		if ( body && body.warnings ) log_warn(body.warnings);
@@ -181,7 +183,7 @@ function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare)
 			var revisions = pages[0].revisions.sort( (first, second) => Date.parse(second.timestamp) - Date.parse(first.timestamp) );
 			var diff = revisions[0].revid;
 			var oldid = ( revisions[1] ? revisions[1].revid : 0 );
-			var editor = [lang.get('diff.info.editor'), ( revisions[0].userhidden !== undefined ? lang.get('diff.hidden') : ( msg.showEmbed() ? '[' + escapeFormatting(revisions[0].user) + '](' + wiki.toLink(( revisions[0].anon !== undefined ? 'Special:Contributions/' : 'User:' ) + revisions[0].user, '', '', true) + ')' : escapeFormatting(revisions[0].user) ) )];
+			var editor = [lang.get('diff.info.editor'), ( revisions[0].userhidden !== undefined ? lang.get('diff.hidden') : ( msg.showEmbed() && !noEmbed ? '[' + escapeFormatting(revisions[0].user) + '](' + wiki.toLink(( revisions[0].anon !== undefined ? 'Special:Contributions/' : 'User:' ) + revisions[0].user, '', '', true) + ')' : escapeFormatting(revisions[0].user) ) )];
 			try {
 				var dateformat = new Intl.DateTimeFormat(lang.get('dateformat'), Object.assign({
 					timeZone: body.query.general.timezone
@@ -196,14 +198,13 @@ function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare)
 			var timestamp = [lang.get('diff.info.timestamp'), dateformat.format(editDate), '<t:' + Math.trunc(editDate.getTime() / 1000) + ':R>'];
 			var difference = revisions[0].size - ( revisions[1] ? revisions[1].size : 0 );
 			var size = [lang.get('diff.info.size'), lang.get('diff.info.bytes', ( difference > 0 ? '+' : '' ) + difference.toLocaleString(lang.get('dateformat')), difference) + ( revisions[0].minor !== undefined ? lang.get('diff.info.minor').replace( /_/g, ' ' ) : '' )];
-			var comment = [lang.get('diff.info.comment'), ( revisions[0].commenthidden !== undefined ? lang.get('diff.hidden') : ( revisions[0].parsedcomment ? ( msg.showEmbed() ? htmlToDiscord(revisions[0].parsedcomment, wiki.toLink(title), true) : htmlToPlain(revisions[0].parsedcomment) ) : lang.get('diff.nocomment') ) )];
+			var comment = [lang.get('diff.info.comment'), ( revisions[0].commenthidden !== undefined ? lang.get('diff.hidden') : ( revisions[0].parsedcomment ? ( msg.showEmbed() && !noEmbed ? htmlToDiscord(revisions[0].parsedcomment, wiki.toLink(title), true) : htmlToPlain(revisions[0].parsedcomment) ) : lang.get('diff.nocomment') ) )];
 			if ( revisions[0].tags.length ) var tags = [lang.get('diff.info.tags'), body.query.tags.filter( tag => tag.displayname && revisions[0].tags.includes( tag.name ) ).map( tag => tag.displayname || tag.name ).join(', ')];
 			
 			var pagelink = wiki.toLink(title, {diff,oldid});
 			var text = '<' + pagelink + '>';
-			var embed = null;
-			if ( msg.showEmbed() ) {
-				embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( escapeFormatting( title + '?diff=' + diff + '&oldid=' + oldid ) ).setURL( pagelink ).addField( editor[0], editor[1], true ).addField( size[0], size[1], true ).addField( timestamp[0], timestamp[1] + '\n' + timestamp[2], true ).addField( comment[0], comment[1] ).setTimestamp( editDate );
+			if ( msg.showEmbed() && !noEmbed ) {
+				var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( escapeFormatting( title + '?diff=' + diff + '&oldid=' + oldid ) ).setURL( pagelink ).addField( editor[0], editor[1], true ).addField( size[0], size[1], true ).addField( timestamp[0], timestamp[1] + '\n' + timestamp[2], true ).addField( comment[0], comment[1] ).setTimestamp( editDate );
 				
 				var more = '\n__' + lang.get('diff.info.more') + '__';
 				var whitespace = '__' + lang.get('diff.info.whitespace') + '__';
@@ -276,7 +277,7 @@ function gamepedia_diff_send(lang, msg, args, wiki, reaction, spoiler, compare)
 				text += '\n\n' + editor.join(' ') + '\n' + timestamp.join(' ') + '\n' + size.join(' ') + '\n' + comment.join(' ');
 				if ( tags?.[1] ) text += htmlToDiscord( '\n' + tags.join(' ') );
 				
-				msg.sendChannel( spoiler + text + spoiler, {embed} );
+				msg.sendChannel( spoiler + text + spoiler );
 				
 				if ( reaction ) reaction.removeEmoji();
 			}

+ 35 - 34
cmds/wiki/general.js

@@ -38,12 +38,13 @@ fs.readdir( './cmds/minecraft', (error, files) => {
  * @param {String} cmd - The command at this point.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} [spoiler] - If the response is in a spoiler.
+ * @param {Boolean} [noEmbed] - If the response should be without an embed.
  * @param {URLSearchParams} [querystring] - The querystring for the link.
  * @param {String} [fragment] - The section for the link.
  * @param {String} [interwiki] - The fallback interwiki link.
  * @param {Number} [selfcall] - The amount of followed interwiki links.
  */
-function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '', querystring = new URLSearchParams(), fragment = '', interwiki = '', selfcall = 0) {
+function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '', noEmbed = false, querystring = new URLSearchParams(), fragment = '', interwiki = '', selfcall = 0) {
 	var full_title = title;
 	if ( title.includes( '#' ) ) {
 		fragment = title.split('#').slice(1).join('#').trim().replace( /(?:%[\dA-F]{2})+/g, partialURIdecode );
@@ -59,15 +60,15 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 		title = title.substring(0, 250);
 		msg.reactEmoji('⚠️');
 	}
-	var invoke = title.split(' ')[0].toLowerCase();
+	var invoke = full_title.split(' ')[0].toLowerCase();
 	var aliasInvoke = ( lang.aliases[invoke] || invoke );
-	var args = title.split(' ').slice(1);
+	var args = full_title.split(' ').slice(1);
 	
 	if ( aliasInvoke === 'random' && !args.join('') && !querystring.toString() && !fragment ) {
-		return fn.random(lang, msg, wiki, reaction, spoiler);
+		return fn.random(lang, msg, wiki, reaction, spoiler, noEmbed);
 	}
 	if ( aliasInvoke === 'overview' && !args.join('') && !querystring.toString() && !fragment ) {
-		return fn.overview(lang, msg, wiki, reaction, spoiler);
+		return fn.overview(lang, msg, wiki, reaction, spoiler, noEmbed);
 	}
 	if ( aliasInvoke === 'test' && !args.join('') && !querystring.toString() && !fragment ) {
 		this.test(lang, msg, args, '', wiki);
@@ -79,8 +80,8 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 		if ( reaction ) reaction.removeEmoji();
 		return;
 	}
-	if ( aliasInvoke === 'diff' && !wiki.isFandom(false) && args.join('') && !querystring.toString() && !fragment ) {
-		return fn.diff(lang, msg, args, wiki, reaction, spoiler);
+	if ( aliasInvoke === 'diff' && args.join('') && !querystring.toString() && !fragment ) {
+		return fn.diff(lang, msg, args, wiki, reaction, spoiler, noEmbed);
 	}
 	var noRedirect = ( querystring.getAll('redirect').pop() === 'no' || ( querystring.has('action') && querystring.getAll('action').pop() !== 'view' ) );
 	var uselang = ( querystring.get('variant') || querystring.get('uselang') || lang.lang );
@@ -89,7 +90,7 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 		var body = response.body;
 		if ( body && body.warnings ) log_warn(body.warnings);
 		if ( response.statusCode !== 200 || !body || body.batchcomplete === undefined || !body.query ) {
-			if ( interwiki ) msg.sendChannel( spoiler + ' ' + interwiki + ' ' + spoiler );
+			if ( interwiki ) msg.sendChannel( spoiler + ( noEmbed ? '<' : ' ' ) + interwiki + ( noEmbed ? '>' : ' ' ) + spoiler );
 			else if ( wiki.noWiki(response.url, response.statusCode) ) {
 				console.log( '- This wiki doesn\'t exist!' );
 				msg.reactEmoji('nowiki');
@@ -105,20 +106,17 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 		wiki.updateWiki(body.query.general);
 		if ( aliasInvoke === 'search' ) {
 			logging(wiki, msg.guild?.id, 'search');
-			return fn.search(lang, msg, full_title.split(' ').slice(1).join(' '), wiki, body.query, reaction, spoiler);
-		}
-		if ( aliasInvoke === 'diff' && args.join('') && !querystring.toString() && !fragment ) {
-			return fn.diff(lang, msg, args, wiki, reaction, spoiler);
+			return fn.search(lang, msg, full_title.split(' ').slice(1).join(' '), wiki, body.query, reaction, spoiler, noEmbed);
 		}
 		if ( aliasInvoke === 'discussion' && wiki.isFandom(false) && !querystring.toString() && !fragment ) {
 			logging(wiki, msg.guild?.id, 'discussion');
-			return fn.discussion(lang, msg, wiki, args.join(' '), body.query.general.sitename, reaction, spoiler);
+			return fn.discussion(lang, msg, wiki, args.join(' '), body.query.general.sitename, reaction, spoiler, noEmbed);
 		}
 		if ( !msg.notMinecraft && mcw.hasOwnProperty(wiki.href) && ( minecraft.hasOwnProperty(aliasInvoke) || invoke.startsWith( '/' ) ) && !querystring.toString() && !fragment ) {
 			logging(wiki, msg.guild?.id, 'minecraft', ( minecraft.hasOwnProperty(aliasInvoke) ? aliasInvoke : 'command' ));
 			minecraft.WIKI = this;
-			if ( minecraft.hasOwnProperty(aliasInvoke) ) minecraft[aliasInvoke](lang, msg, wiki, args, title, cmd, reaction, spoiler);
-			else minecraft.SYNTAX(lang, msg, wiki, invoke.substring(1), args, title, cmd, reaction, spoiler);
+			if ( minecraft.hasOwnProperty(aliasInvoke) ) minecraft[aliasInvoke](lang, msg, wiki, args, title, cmd, reaction, spoiler, noEmbed);
+			else minecraft.SYNTAX(lang, msg, wiki, invoke.substring(1), args, title, cmd, reaction, spoiler, noEmbed);
 			return;
 		}
 		if ( body.query.pages && body.query.pages?.['-1']?.title !== '%1F' ) {
@@ -144,7 +142,7 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 			if ( ( querypage.ns === 2 || querypage.ns === 202 || querypage.ns === 1200 ) && ( !querypage.title.includes( '/' ) || /^[^:]+:(?:(?:\d{1,3}\.){3}\d{1,3}\/\d{2}|(?:[\dA-F]{1,4}:){7}[\dA-F]{1,4}\/\d{2,3})$/.test(querypage.title) ) ) {
 				var userparts = querypage.title.split(':');
 				querypage.noRedirect = noRedirect;
-				return fn.user(lang, msg, userparts[0] + ':', userparts.slice(1).join(':'), wiki, querystring, fragment, querypage, contribs, reaction, spoiler);
+				return fn.user(lang, msg, userparts[0] + ':', userparts.slice(1).join(':'), wiki, querystring, fragment, querypage, contribs, reaction, spoiler, noEmbed);
 			}
 			if ( querypage.ns === -1 && querypage.title.startsWith( contribs ) && querypage.title.length > contribs.length ) {
 				var username = querypage.title.split('/').slice(1).join('/');
@@ -166,7 +164,7 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 							querypage.special = '';
 							querypage.uselang = uselang;
 							querypage.noRedirect = noRedirect;
-							fn.user(lang, msg, contribs, username, wiki, querystring, fragment, querypage, contribs, reaction, spoiler);
+							fn.user(lang, msg, contribs, username, wiki, querystring, fragment, querypage, contribs, reaction, spoiler, noEmbed);
 						}
 						else {
 							msg.reactEmoji('error');
@@ -189,9 +187,9 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 				var maxselfcall = interwikiLimit[( patreons[msg.guild?.id] ? 'patreon' : 'default' )];
 				if ( selfcall < maxselfcall ) {
 					selfcall++;
-					return this.general(lang, msg, iw_parts.slice(2).join(':'), iw, '!!' + iw.hostname + ' ', reaction, spoiler, querystring, fragment, iw_link, selfcall);
+					return this.general(lang, msg, iw_parts.slice(2).join(':'), iw, '!!' + iw.hostname + ' ', reaction, spoiler, noEmbed, querystring, fragment, iw_link, selfcall);
 				}
-				msg.sendChannel( spoiler + ' ' + iw_link + ' ' + spoiler ).then( message => {
+				msg.sendChannel( spoiler + ( noEmbed ? '<' : ' ' ) + iw_link + ( noEmbed ? '>' : ' ' ) + spoiler ).then( message => {
 					if ( message && selfcall === maxselfcall ) message.reactEmoji('⚠️');
 				} );
 				if ( reaction ) reaction.removeEmoji();
@@ -297,11 +295,11 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 					if ( querypage.categoryinfo.subcats > 0 ) {
 						category.push(lang.get('search.category.subcats', querypage.categoryinfo.subcats.toLocaleString(lang.get('dateformat')), querypage.categoryinfo.subcats));
 					}
-					if ( msg.showEmbed() ) embed.addField( category[0], category.slice(1).join('\n') );
+					if ( msg.showEmbed() && !noEmbed ) embed.addField( category[0], category.slice(1).join('\n') );
 					else text += '\n\n' + category.join('\n');
 				}
 
-				return parse_page(lang, msg, spoiler + '<' + pagelink + '>' + text + spoiler, embed, wiki, reaction, querypage, ( querypage.title === body.query.general.mainpage ? '' : new URL(body.query.general.logo, wiki).href ), fragment, pagelink);
+				return parse_page(lang, msg, spoiler + '<' + pagelink + '>' + text + spoiler, ( noEmbed ? null : embed ), wiki, reaction, querypage, ( querypage.title === body.query.general.mainpage ? '' : new URL(body.query.general.logo, wiki).href ), fragment, pagelink);
 			}, error => {
 				logging(wiki, msg.guild?.id, 'general', 'search');
 				console.log( '- Error while getting the search results: ' + error );
@@ -313,16 +311,19 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 				var specialpage = body.query.specialpagealiases.find( sp => body.query.namespaces['-1']['*'] + ':' + sp.aliases[0].replace( /\_/g, ' ' ) === querypage.title.split('/')[0] );
 				specialpage = ( specialpage ? specialpage.realname : querypage.title.replace( body.query.namespaces['-1']['*'] + ':', '' ).split('/')[0] ).toLowerCase();
 				if ( !['mylanguage'].includes( specialpage ) ) {
-					return fn.special_page(lang, msg, querypage, specialpage, body.query, wiki, querystring, fragment, reaction, spoiler);
+					return fn.special_page(lang, msg, querypage, specialpage, body.query, wiki, querystring, fragment, reaction, spoiler, noEmbed);
 				}
 			}
 			if ( querypage.ns === -2 ) {
 				logging(wiki, msg.guild?.id, 'general', 'media');
 				var filepath = body.query.specialpagealiases.find( sp => sp.realname === 'Filepath' );
 				var pagelink = wiki.toLink(body.query.namespaces['-1']['*'] + ':' + ( filepath?.aliases?.[0] || 'FilePath' ) + querypage.title.replace( body.query.namespaces['-2']['*'] + ':', '/' ), querystring, fragment);
-				var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( escapeFormatting(querypage.title) ).setURL( pagelink ).setDescription( '[' + lang.get('search.media') + '](' + wiki.toLink(querypage.title, '', '', true) + ')' );
-				if ( msg.showEmbed() && /\.(?:png|jpg|jpeg|gif)$/.test(querypage.title.toLowerCase()) ) embed.setImage( pagelink );
-				else if ( msg.uploadFiles() ) embed.attachFiles( [{attachment:pagelink,name:( spoiler ? 'SPOILER ' : '' ) + querypage.title}] );
+				var embed = null;
+				if ( !noEmbed ) {
+					embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( escapeFormatting(querypage.title) ).setURL( pagelink ).setDescription( '[' + lang.get('search.media') + '](' + wiki.toLink(querypage.title, '', '', true) + ')' );
+					if ( msg.showEmbed() && /\.(?:png|jpg|jpeg|gif)$/.test(querypage.title.toLowerCase()) ) embed.setImage( pagelink );
+					else if ( msg.uploadFiles() ) embed.attachFiles( [{attachment:pagelink,name:( spoiler ? 'SPOILER ' : '' ) + querypage.title}] );
+				}
 				
 				msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} );
 				
@@ -379,11 +380,11 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 				if ( querypage.categoryinfo.subcats > 0 ) {
 					category.push(lang.get('search.category.subcats', querypage.categoryinfo.subcats.toLocaleString(lang.get('dateformat')), querypage.categoryinfo.subcats));
 				}
-				if ( msg.showEmbed() ) embed.addField( category[0], category.slice(1).join('\n') );
+				if ( msg.showEmbed() && !noEmbed ) embed.addField( category[0], category.slice(1).join('\n') );
 				else text += '\n\n' + category.join('\n');
 			}
 			
-			return parse_page(lang, msg, spoiler + '<' + pagelink + '>' + text + spoiler, embed, wiki, reaction, querypage, ( querypage.title === body.query.general.mainpage ? '' : new URL(body.query.general.logo, wiki).href ), ( fragment || ( body.query.redirects && body.query.redirects[0].tofragment ) || '' ), pagelink);
+			return parse_page(lang, msg, spoiler + '<' + pagelink + '>' + text + spoiler, ( noEmbed ? null : embed ), wiki, reaction, querypage, ( querypage.title === body.query.general.mainpage ? '' : new URL(body.query.general.logo, wiki).href ), ( fragment || ( body.query.redirects && body.query.redirects[0].tofragment ) || '' ), pagelink);
 		}
 		if ( body.query.interwiki ) {
 			if ( msg.channel.isGuild() && pause[msg.guild.id] ) {
@@ -398,7 +399,7 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 			if ( fragment ) iw.hash = Wiki.toSection(fragment);
 			else fragment = iw.hash.substring(1);
 			if ( /^phabricator\.(wikimedia|miraheze)\.org$/.test(iw.hostname) ) {
-				return phabricator(lang, msg, wiki, iw, reaction, spoiler);
+				return phabricator(lang, msg, wiki, iw, reaction, spoiler, noEmbed);
 			}
 			logging(wiki, msg.guild?.id, 'interwiki');
 			var maxselfcall = interwikiLimit[( patreons[msg.guild?.id] ? 'patreon' : 'default' )];
@@ -407,7 +408,7 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 				if ( iw.hostname.endsWith( '.gamepedia.com' ) ) {
 					let iwtitle = decodeURIComponent( iw.pathname.substring(1) ).replace( /_/g, ' ' );
 					cmd = '!' + iw.hostname.replace( '.gamepedia.com', ' ' );
-					if ( cmd !== '!www ' ) return this.general(lang, msg, iwtitle, new Wiki(iw.origin), cmd, reaction, spoiler, iw.searchParams, fragment, iw.href, selfcall);
+					if ( cmd !== '!www ' ) return this.general(lang, msg, iwtitle, new Wiki(iw.origin), cmd, reaction, spoiler, noEmbed, iw.searchParams, fragment, iw.href, selfcall);
 				}
 				if ( iw.hostname.endsWith( '.fandom.com' ) || iw.hostname.endsWith( '.wikia.org' ) ) {
 					let regex = iw.pathname.match( /^(\/(?!wiki\/)[a-z-]{2,12})?(?:\/wiki\/|\/?$)/ );
@@ -415,7 +416,7 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 						let path = ( regex[1] || '' );
 						let iwtitle = decodeURIComponent( iw.pathname.replace( regex[0], '' ) ).replace( /_/g, ' ' );
 						cmd = ( iw.hostname.endsWith( '.wikia.org' ) ? '??' : '?' ) + ( path ? path.substring(1) + '.' : '' ) + iw.hostname.replace( /\.(?:fandom\.com|wikia\.org)/, ' ' );
-						return this.general(lang, msg, iwtitle, new Wiki(iw.origin + path + '/'), cmd, reaction, spoiler, iw.searchParams, fragment, iw.href, selfcall);
+						return this.general(lang, msg, iwtitle, new Wiki(iw.origin + path + '/'), cmd, reaction, spoiler, noEmbed, iw.searchParams, fragment, iw.href, selfcall);
 					}
 				}
 				let project = wikiProjects.find( project => iw.hostname.endsWith( project.name ) );
@@ -424,11 +425,11 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 					if ( regex ) {
 						let iwtitle = decodeURIComponent( ( iw.host + iw.pathname ).replace( regex[0], '' ) ).replace( /_/g, ' ' );
 						cmd = '!!' + regex[1] + ' ';
-						return this.general(lang, msg, iwtitle, new Wiki('https://' + regex[1] + project.scriptPath), cmd, reaction, spoiler, iw.searchParams, fragment, iw.href, selfcall);
+						return this.general(lang, msg, iwtitle, new Wiki('https://' + regex[1] + project.scriptPath), cmd, reaction, spoiler, noEmbed, iw.searchParams, fragment, iw.href, selfcall);
 					}
 				}
 			}
-			msg.sendChannel( spoiler + ' ' + iw + ' ' + spoiler ).then( message => {
+			msg.sendChannel( spoiler + ( noEmbed ? '<' : ' ' ) + iw + ( noEmbed ? '>' : ' ' ) + spoiler ).then( message => {
 				if ( message && selfcall === maxselfcall ) message.reactEmoji('⚠️');
 			} );
 			if ( reaction ) reaction.removeEmoji();
@@ -483,10 +484,10 @@ function gamepedia_check_wiki(lang, msg, title, wiki, cmd, reaction, spoiler = '
 		}, error => {
 			console.log( '- Error while getting the main page: ' + error );
 		} ).finally( () => {
-			parse_page(lang, msg, spoiler + '<' + pagelink + '>' + spoiler, embed, wiki, reaction, querypage, '', fragment, pagelink);
+			parse_page(lang, msg, spoiler + '<' + pagelink + '>' + spoiler, ( noEmbed ? null : embed ), wiki, reaction, querypage, '', fragment, pagelink);
 		} );
 	}, error => {
-		if ( interwiki ) msg.sendChannel( spoiler + ' ' + interwiki + ' ' + spoiler );
+		if ( interwiki ) msg.sendChannel( spoiler + ( noEmbed ? '<' : ' ' ) + interwiki + ( noEmbed ? '>' : ' ' ) + spoiler );
 		else if ( wiki.noWiki(error.message) ) {
 			console.log( '- This wiki doesn\'t exist!' );
 			msg.reactEmoji('nowiki');

+ 10 - 12
cmds/wiki/overview.js

@@ -10,10 +10,11 @@ const {toFormatting, toPlaintext, escapeFormatting} = require('../../util/functi
  * @param {import('../../util/wiki.js')} wiki - The wiki for the overview.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  * @param {URLSearchParams} [querystring] - The querystring for the link.
  * @param {String} [fragment] - The section for the link.
  */
-function gamepedia_overview(lang, msg, wiki, reaction, spoiler, querystring = new URLSearchParams(), fragment = '') {
+function gamepedia_overview(lang, msg, wiki, reaction, spoiler, noEmbed, querystring = new URLSearchParams(), fragment = '') {
 	var uselang = ( querystring.get('variant') || querystring.get('uselang') || lang.lang );
 	got.get( wiki + 'api.php?uselang=' + uselang + '&action=query&meta=allmessages|siteinfo&amenableparser=true&amtitle=Special:Statistics&ammessages=statistics' + ( wiki.isFandom() ? '|custom-GamepediaNotice|custom-FandomMergeNotice' : '' ) + '&siprop=general|statistics|languages|rightsinfo' + ( wiki.isFandom() ? '|variables' : '' ) + '&siinlanguagecode=' + uselang + '&list=logevents&ledir=newer&lelimit=1&leprop=timestamp&titles=Special:Statistics&format=json' ).then( response => {
 		var body = response.body;
@@ -68,7 +69,7 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler, querystring = ne
 			
 			if ( body.query.rightsinfo.text ) {
 				let licensetext = body.query.rightsinfo.text;
-				if ( msg.showEmbed() ) {
+				if ( msg.showEmbed() && !noEmbed ) {
 					license[1] = '[' + toPlaintext(licensetext, true) + '](' + licenseurl + ')';
 				}
 				else license[1] = toPlaintext(licensetext, true) + ' (<' + licenseurl + '>)';
@@ -76,14 +77,14 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler, querystring = ne
 			else license[1] = '<' + licenseurl + '>';
 		}
 		else if ( body.query.rightsinfo.text ) {
-			license[1] = toFormatting(body.query.rightsinfo.text, msg.showEmbed(), wiki, '', true);
+			license[1] = toFormatting(body.query.rightsinfo.text, ( msg.showEmbed() && !noEmbed ), wiki, '', true);
 		}
 		var misermode = [lang.get('overview.misermode'), lang.get('overview.' + ( body.query.general.misermode !== undefined ? 'yes' : 'no' ))];
 		var readonly = [lang.get('overview.readonly')];
 		if ( body.query.general.readonly !== undefined ) {
 			if ( body.query.general.readonlyreason ) {
 				let readonlyreason = body.query.general.readonlyreason;
-				readonly.push(toFormatting(readonlyreason, msg.showEmbed(), wiki, '', true));
+				readonly.push(toFormatting(readonlyreason, ( msg.showEmbed() && !noEmbed ), wiki, '', true));
 			}
 			else readonly = ['\u200b', '**' + lang.get('overview.readonly') + '**'];
 		}
@@ -92,7 +93,7 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler, querystring = ne
 		var pagelink = wiki.toLink(title, querystring, fragment);
 		var text = '<' + pagelink + '>';
 		var embed = null;
-		if ( msg.showEmbed() ) {
+		if ( msg.showEmbed() && !noEmbed ) {
 			embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( escapeFormatting(title) ).setURL( pagelink ).setThumbnail( new URL(body.query.general.logo, wiki).href );
 			if ( body.query.allmessages?.[0]?.['*']?.trim?.() ) {
 				let displaytitle = escapeFormatting(body.query.allmessages[0]['*'].trim());
@@ -161,7 +162,7 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler, querystring = ne
 						}
 						else {
 							var user = usbody.query.users[0].name;
-							if ( msg.showEmbed() ) founder[1] = '[' + user + '](' + wiki.toLink('User:' + user, '', '', true) + ')';
+							if ( msg.showEmbed() && !noEmbed ) founder[1] = '[' + user + '](' + wiki.toLink('User:' + user, '', '', true) + ')';
 							else founder[1] = user;
 						}
 					}, error => {
@@ -193,7 +194,7 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler, querystring = ne
 				console.log( '- Error while getting the wiki details: ' + error );
 				return;
 			} ).finally( () => {
-				if ( msg.showEmbed() ) {
+				if ( msg.showEmbed() && !noEmbed ) {
 					if ( vertical[1] ) embed.addField( vertical[0], vertical[1], true );
 					if ( topic[1] ) embed.addField( topic[0], topic[1], true );
 					if ( official[1] ) embed.addField( official[0], official[1], true );
@@ -228,10 +229,7 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler, querystring = ne
 					if ( crossover[1] ) text += '\n' + crossover.join(' ');
 					text += '\n' + license.join(' ') + '\n' + misermode.join(' ');
 					if ( description[1] ) text += '\n' + description.join(' ');
-					if ( image[1] ) {
-						text += '\n' + image.join(' ');
-						if ( msg.uploadFiles() ) embed.files = [{attachment:image[1],name:( spoiler ? 'SPOILER ' : '' ) + body.query.general.sitename + image[1].substring(image[1].lastIndexOf('.'))}];
-					}
+					if ( image[1] ) text += '\n' + image.join(' ');
 					if ( readonly[1] ) text += '\n\n' + ( readonly[0] === '\u200b' ? readonly[1] : readonly.join('\n') );
 					text += '\n\n*' + lang.get('overview.inaccurate') + '*';
 				}
@@ -241,7 +239,7 @@ function gamepedia_overview(lang, msg, wiki, reaction, spoiler, querystring = ne
 				if ( reaction ) reaction.removeEmoji();
 			} );
 		}
-		if ( msg.showEmbed() ) {
+		if ( msg.showEmbed() && !noEmbed ) {
 			embed.addField( version[0], version[1], true ).addField( language[0], language[1], true );
 			if ( rtl[1] ) embed.addField( rtl[0], rtl[1], true );
 			embed.addField( created[0], created[1] + '\n' + created[2], true ).addField( articles[0], articles[1], true ).addField( pages[0], pages[1], true ).addField( edits[0], edits[1], true ).addField( users[0], users[1], true ).addField( admins[0], admins[1], true ).addField( license[0], license[1], true ).addField( misermode[0], misermode[1], true ).setFooter( lang.get('overview.inaccurate') );

+ 17 - 13
cmds/wiki/random.js

@@ -11,11 +11,12 @@ const extract_desc = require('../../util/extract_desc.js');
  * @param {import('../../util/wiki.js')} wiki - The wiki for the page.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  * @param {String[]} [namespace] - The namespace to get a random page of.
  * @param {URLSearchParams} [querystring] - The querystring for the link.
  * @param {String} [fragment] - The section for the link.
  */
-function gamepedia_random(lang, msg, wiki, reaction, spoiler, namespace = ['0', '*'], querystring = new URLSearchParams(), fragment = '') {
+function gamepedia_random(lang, msg, wiki, reaction, spoiler, noEmbed, namespace = ['0', '*'], querystring = new URLSearchParams(), fragment = '') {
 	var uselang = ( querystring.get('variant') || querystring.get('uselang') || lang.lang );
 	got.get( wiki + 'api.php?uselang=' + uselang + '&action=query&meta=allmessages|siteinfo&amenableparser=true&amtitle=Special:Random&ammessages=randompage|randompage-nopages&amargs=%1F' + namespace[1] + '%1F' + namespace[0].split('|').length + '&siprop=general&prop=categoryinfo|info|pageprops|pageimages|extracts&piprop=original|name&ppprop=description|displaytitle|page_image_free|disambiguation|infoboxes&explaintext=true&exsectionformat=raw&exlimit=1&converttitles=true&generator=random&grnfilterredir=nonredirects&grnlimit=1&grnnamespace=' + namespace[0] + '&format=json' ).then( response => {
 		var body = response.body;
@@ -38,16 +39,19 @@ function gamepedia_random(lang, msg, wiki, reaction, spoiler, namespace = ['0',
 			var title = 'Special:Random';
 			if ( namespace[0] !== '0' && namespace[0].split('|').length === 1 ) title += '/' + namespace[1];
 			var pagelink = wiki.toLink(title, querystring, fragment);
-			var embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( escapeFormatting(title) ).setURL( pagelink ).setThumbnail( new URL(body.query.general.logo, wiki).href );
-			if ( body.query.allmessages?.[0]?.['*']?.trim?.() ) {
-				let displaytitle = escapeFormatting(body.query.allmessages[0]['*'].trim());
-				if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
-				embed.setTitle( displaytitle );
-			}
-			if ( body.query.allmessages?.[1]?.['*']?.trim?.() ) {
-				var description = toMarkdown(body.query.allmessages[1]['*'], wiki, title, true);
-				if ( description.length > 1000 ) description = description.substring(0, 1000) + '\u2026';
-				embed.setDescription( description );
+			var embed = null;
+			if ( msg.showEmbed() && !noEmbed ) {
+				embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( escapeFormatting(title) ).setURL( pagelink ).setThumbnail( new URL(body.query.general.logo, wiki).href );
+				if ( body.query.allmessages?.[0]?.['*']?.trim?.() ) {
+					let displaytitle = escapeFormatting(body.query.allmessages[0]['*'].trim());
+					if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';
+					embed.setTitle( displaytitle );
+				}
+				if ( body.query.allmessages?.[1]?.['*']?.trim?.() ) {
+					var description = toMarkdown(body.query.allmessages[1]['*'], wiki, title, true);
+					if ( description.length > 1000 ) description = description.substring(0, 1000) + '\u2026';
+					embed.setDescription( description );
+				}
 			}
 			msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} );
 			
@@ -104,11 +108,11 @@ function gamepedia_random(lang, msg, wiki, reaction, spoiler, namespace = ['0',
 			if ( querypage.categoryinfo.subcats > 0 ) {
 				category.push(lang.get('search.category.subcats', querypage.categoryinfo.subcats.toLocaleString(lang.get('dateformat')), querypage.categoryinfo.subcats));
 			}
-			if ( msg.showEmbed() ) embed.addField( category[0], category.slice(1).join('\n') );
+			if ( msg.showEmbed() && !noEmbed ) embed.addField( category[0], category.slice(1).join('\n') );
 			else text += '\n\n' + category.join('\n');
 		}
 		
-		return parse_page(lang, msg, '🎲 ' + spoiler + '<' + pagelink + '>' + text + spoiler, embed, wiki, reaction, querypage, ( querypage.title === body.query.general.mainpage ? '' : new URL(body.query.general.logo, wiki).href ), fragment, pagelink);
+		return parse_page(lang, msg, '🎲 ' + spoiler + '<' + pagelink + '>' + text + spoiler, ( noEmbed ? null : embed ), wiki, reaction, querypage, ( querypage.title === body.query.general.mainpage ? '' : new URL(body.query.general.logo, wiki).href ), fragment, pagelink);
 	}, error => {
 		if ( wiki.noWiki(error.message) ) {
 			console.log( '- This wiki doesn\'t exist!' );

+ 82 - 56
cmds/wiki/search.js

@@ -1,4 +1,5 @@
 const {MessageEmbed, Util} = require('discord.js');
+const {escapeFormatting} = require('../../util/functions.js');
 const {limit: {search: searchLimit}} = require('../../util/default.json');
 
 /**
@@ -10,29 +11,29 @@ const {limit: {search: searchLimit}} = require('../../util/default.json');
  * @param {Object} query - The siteinfo from the wiki.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  */
-function gamepedia_search(lang, msg, searchterm, wiki, query, reaction, spoiler) {
+function gamepedia_search(lang, msg, searchterm, wiki, query, reaction, spoiler, noEmbed) {
 	if ( searchterm.length > 250 ) {
 		searchterm = searchterm.substring(0, 250);
 		msg.reactEmoji('⚠️');
 	}
+	if ( !searchterm.trim() ) return this.special_page(lang, msg, {title: 'Special:Search'}, 'search', query, wiki, new URLSearchParams(), '', reaction, spoiler, noEmbed);
 	var pagelink = wiki.toLink('Special:Search', {search:searchterm,fulltext:1});
-	var embed = new MessageEmbed().setAuthor( query.general.sitename ).setTitle( '`' + searchterm + '`' ).setURL( pagelink );
-	if ( !searchterm.trim() ) {
-		pagelink = wiki.toLink('Special:Search');
-		embed.setTitle( 'Special:Search' ).setURL( pagelink );
-	}
+	var resultText = '<' + pagelink + '>';
+	var embed = null;
+	if ( msg.showEmbed() && !noEmbed ) embed = new MessageEmbed().setAuthor( query.general.sitename ).setTitle( '`' + searchterm + '`' ).setURL( pagelink );
+	else resultText += '\n\n**`' + searchterm + '`**';
 	var querypage = ( Object.values(( query.pages || {} ))?.[0] || {title:'',ns:0,invalid:''} );
-	var description = [];
 	var limit = searchLimit[( patreons[msg.guild?.id] ? 'patreon' : 'default' )];
-	got.get( wiki + 'api.php?action=query&titles=Special:Search&list=search&srinfo=totalhits&srprop=redirecttitle|sectiontitle&srnamespace=4|12|14|' + ( querypage.ns >= 0 ? querypage.ns + '|' : '' ) + Object.values(query.namespaces).filter( ns => ns.content !== undefined ).map( ns => ns.id ).join('|') + '&srlimit=' + limit + '&srsearch=' + encodeURIComponent( ( searchterm || ' ' ) ) + '&format=json' ).then( response => {
+	got.get( wiki + 'api.php?action=query&titles=Special:Search&list=search&srinfo=totalhits&srprop=redirecttitle|sectiontitle&srnamespace=4|12|14|' + ( querypage.ns >= 0 ? querypage.ns + '|' : '' ) + Object.values(query.namespaces).filter( ns => ns.content !== undefined ).map( ns => ns.id ).join('|') + '&srlimit=' + limit + '&srsearch=' + encodeURIComponent( searchterm ) + '&format=json' ).then( response => {
 		var body = response.body;
 		if ( body?.warnings ) log_warn(body.warnings);
 		if ( response.statusCode !== 200 || !body?.query?.search || body.batchcomplete === undefined ) {
 			return console.log( '- ' + response.statusCode + ': Error while getting the search results: ' + body?.error?.info );
 		}
 		if ( body.query.search.length < limit ) {
-			return got.get( wiki + 'api.php?action=query&titles=Special:Search&list=search&srwhat=text&srinfo=totalhits&srprop=redirecttitle|sectiontitle&srnamespace=4|12|14|' + ( querypage.ns >= 0 ? querypage.ns + '|' : '' ) + Object.values(query.namespaces).filter( ns => ns.content !== undefined ).map( ns => ns.id ).join('|') + '&srlimit=' + limit + '&srsearch=' + encodeURIComponent( ( searchterm || ' ' ) ) + '&format=json' ).then( tresponse => {
+			return got.get( wiki + 'api.php?action=query&list=search&srwhat=text&srinfo=totalhits&srprop=redirecttitle|sectiontitle&srnamespace=4|12|14|' + ( querypage.ns >= 0 ? querypage.ns + '|' : '' ) + Object.values(query.namespaces).filter( ns => ns.content !== undefined ).map( ns => ns.id ).join('|') + '&srlimit=' + limit + '&srsearch=' + encodeURIComponent( searchterm ) + '&format=json' ).then( tresponse => {
 				var tbody = tresponse.body;
 				if ( tbody?.warnings ) log_warn(tbody.warnings);
 				if ( tresponse.statusCode !== 200 || !tbody?.query?.search || tbody.batchcomplete === undefined ) {
@@ -52,73 +53,98 @@ function gamepedia_search(lang, msg, searchterm, wiki, query, reaction, spoiler)
 	} ).then( body => {
 		if ( !body?.query?.search ) return;
 		if ( body.query.pages?.['-1']?.title ) {
-			if ( searchterm.trim() ) {
-				pagelink = wiki.toLink(body.query.pages['-1'].title, {search:searchterm,fulltext:1});
-				embed.setURL( pagelink );
-			}
-			else {
-				pagelink = wiki.toLink(body.query.pages['-1'].title);
-				embed.setTitle( body.query.pages['-1'].title ).setURL( pagelink );
-			}
+			pagelink = wiki.toLink(body.query.pages['-1'].title, {search:searchterm,fulltext:1});
+			resultText = '<' + pagelink + '>';
+			if ( msg.showEmbed() && !noEmbed ) embed.setURL( pagelink );
+			else resultText += '\n\n**`' + searchterm + '`**';
 		}
-		if ( searchterm.trim() ) {
-			var hasExactMatch = false;
-			body.query.search.forEach( result => {
-				let text = '• ';
-				let bold = '';
-				if ( result.title.replace( /[_-]/g, ' ' ).toLowerCase() === querypage.title.replace( /-/g, ' ' ).toLowerCase() ) {
-					bold = '**';
-					hasExactMatch = true;
-					if ( query.redirects?.[0] ) {
-						if ( query.redirects[0].tofragment && !result.sectiontitle ) {
-							result.sectiontitle = query.redirects[0].tofragment;
-						}
-						if ( !result.redirecttitle ) result.redirecttitle = query.redirects[0].from;
+		var hasExactMatch = false;
+		var description = [];
+		body.query.search.forEach( result => {
+			let text = '• ';
+			let bold = '';
+			if ( result.title.replace( /[_-]/g, ' ' ).toLowerCase() === querypage.title.replace( /-/g, ' ' ).toLowerCase() ) {
+				bold = '**';
+				hasExactMatch = true;
+				if ( query.redirects?.[0] ) {
+					if ( query.redirects[0].tofragment && !result.sectiontitle ) {
+						result.sectiontitle = query.redirects[0].tofragment;
 					}
+					if ( !result.redirecttitle ) result.redirecttitle = query.redirects[0].from;
 				}
-				text += bold;
-				text += '[' + result.title + '](' + wiki.toLink(result.title, '', '', true) + ')';
+			}
+			text += bold;
+			if ( msg.showEmbed() && !noEmbed ) {
+				text += '[' + escapeFormatting(result.title) + '](' + wiki.toLink(result.title, '', '', true) + ')';
 				if ( result.sectiontitle ) {
-					text += ' § [' + result.sectiontitle + '](' + wiki.toLink(result.title, '', result.sectiontitle, true) + ')';
+					text += ' § [' + escapeFormatting(result.sectiontitle) + '](' + wiki.toLink(result.title, '', result.sectiontitle, true) + ')';
 				}
 				if ( result.redirecttitle ) {
-					text += ' (⤷ [' + result.redirecttitle + '](' + wiki.toLink(result.redirecttitle, 'redirect=no', '', true) + '))';
+					text += ' (⤷ [' + escapeFormatting(result.redirecttitle) + '](' + wiki.toLink(result.redirecttitle, 'redirect=no', '', true) + '))';
 				}
-				text += bold;
-				description.push( text );
-			} );
-			if ( !hasExactMatch ) {
-				if ( query.interwiki?.[0] ) {
-					let text = '• **⤷ ';
-					text += '__[' + query.interwiki[0].title + '](' + query.interwiki[0].url.replace( /[()]/g, '\\$&' ) + ')__';
+			}
+			else {
+				text += '<' + wiki.toLink(result.title) + '>';
+				if ( result.sectiontitle ) text += ' § ' + escapeFormatting(result.sectiontitle);
+				if ( result.redirecttitle ) text += ' (⤷ ' + escapeFormatting(result.redirecttitle) + ')';
+			}
+			text += bold;
+			description.push( text );
+		} );
+		if ( !hasExactMatch ) {
+			if ( query.interwiki?.[0] ) {
+				let text = '• **⤷ ';
+				if ( msg.showEmbed() && !noEmbed ) {
+					text += '__[' + escapeFormatting(query.interwiki[0].title) + '](' + query.interwiki[0].url.replace( /[()]/g, '\\$&' ) + ')__';
 					if ( query.redirects?.[0] ) {
-						text += ' (⤷ [' + query.redirects[0].from + '](' + wiki.toLink(query.redirects[0].from, 'redirect=no', '', true) + '))';
+						text += ' (⤷ [' + escapeFormatting(query.redirects[0].from) + '](' + wiki.toLink(query.redirects[0].from, 'redirect=no', '', true) + '))';
 					}
-					text += '**';
-					description.unshift( text );
 				}
-				else if ( querypage.invalid === undefined && ( querypage.missing === undefined || querypage.known !== undefined ) ) {
-					let text = '• **';
-					text += '[' + querypage.title + '](' + wiki.toLink(querypage.title, '', '', true) + ')';
+				else {
+					text += '__<' + query.interwiki[0].url.replace( /[()]/g, '\\$&' ) + '>__';
+					if ( query.redirects?.[0] ) text += ' (⤷ ' + escapeFormatting(query.redirects[0].from) + ')';
+				}
+				text += '**';
+				description.unshift( text );
+			}
+			else if ( querypage.invalid === undefined && ( querypage.missing === undefined || querypage.known !== undefined ) ) {
+				let text = '• **';
+				if ( msg.showEmbed() && !noEmbed ) {
+					text += '[' + escapeFormatting(querypage.title) + '](' + wiki.toLink(querypage.title, '', '', true) + ')';
 					if ( query.redirects?.[0] ) {
 						if ( query.redirects[0].tofragment ) {
-							text += ' § [' + query.redirects[0].tofragment + '](' + wiki.toLink(querypage.title, '', query.redirects[0].tofragment, true) + ')';
+							text += ' § [' + escapeFormatting(query.redirects[0].tofragment) + '](' + wiki.toLink(querypage.title, '', query.redirects[0].tofragment, true) + ')';
 						}
-						text += ' (⤷ [' + query.redirects[0].from + '](' + wiki.toLink(query.redirects[0].from, 'redirect=no', '', true) + '))';
+						text += ' (⤷ [' + escapeFormatting(query.redirects[0].from) + '](' + wiki.toLink(query.redirects[0].from, 'redirect=no', '', true) + '))';
 					}
-					text += '**';
-					description.unshift( text );
 				}
+				else {
+					text += '<' + wiki.toLink(querypage.title) + '>';
+					if ( query.redirects?.[0] ) {
+						if ( query.redirects[0].tofragment ) text += ' § ' + escapeFormatting(query.redirects[0].tofragment);
+						text += ' (⤷ ' + escapeFormatting(query.redirects[0].from) + ')';
+					}
+				}
+				text += '**';
+				description.unshift( text );
 			}
-			if ( body.query.searchinfo ) {
-				embed.setFooter( lang.get('search.results', body.query.searchinfo.totalhits.toLocaleString(lang.get('dateformat')), body.query.searchinfo.totalhits) );
-			}
+		}
+		var footer = '';
+		if ( body.query.searchinfo ) {
+			footer = lang.get('search.results', body.query.searchinfo.totalhits.toLocaleString(lang.get('dateformat')), body.query.searchinfo.totalhits);
+		}
+		if ( msg.showEmbed() && !noEmbed ) {
+			embed.setDescription( Util.splitMessage( description.join('\n') )[0] );
+			if ( footer ) embed.setFooter( footer );
+		}
+		else {
+			if ( description.length ) resultText += '\n' + Util.splitMessage( description.join('\n'), {maxLength: 1995 - resultText.length - footer.length} )[0];
+			if ( footer ) resultText += '\n' + footer;
 		}
 	}, error => {
 		console.log( '- Error while getting the search results.' + error );
 	} ).then( () => {
-		embed.setDescription( Util.splitMessage( description.join('\n') )[0] );
-		msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} );
+		msg.sendChannel( '🔍 ' + spoiler + resultText + spoiler, {embed} );
 		
 		if ( reaction ) reaction.removeEmoji();
 	} );

+ 23 - 22
cmds/wiki/user.js

@@ -20,8 +20,9 @@ const {toMarkdown, toPlaintext, htmlToDiscord, escapeFormatting} = require('../.
  * @param {String} contribs - The contributions page on the wiki.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  */
-function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragment, querypage, contribs, reaction, spoiler) {
+function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragment, querypage, contribs, reaction, spoiler, noEmbed) {
 	if ( /^(?:(?:\d{1,3}\.){3}\d{1,3}(?:\/\d{2})?|(?:[\dA-F]{1,4}:){7}[\dA-F]{1,4}(?:\/\d{2,3})?)$/.test(username) ) return got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general&list=blocks&bkprop=user|by|timestamp|expiry|reason&bkip=' + encodeURIComponent( username ) + '&format=json' ).then( response => {
 		logging(wiki, msg.guild?.id, 'user', 'ip');
 		var body = response.body;
@@ -61,7 +62,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 						embed.setThumbnail( wiki.toLink('Special:FilePath/' + querypage.pageprops.page_image_free, {version:Date.now()}) );
 					}
 					
-					return parse_page(lang, msg, spoiler + '<' + pagelink + '>' + spoiler, embed, wiki, reaction, querypage, new URL(body.query.general.logo, wiki).href, fragment, pagelink);
+					return parse_page(lang, msg, spoiler + '<' + pagelink + '>' + spoiler, ( noEmbed ? null : embed ), wiki, reaction, querypage, new URL(body.query.general.logo, wiki).href, fragment, pagelink);
 				}
 			}
 			else {
@@ -140,7 +141,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 			}
 			if ( isBlocked ) {
 				var text = 'user.block.' + ( isIndef ? 'indef_' : '' ) + ( block.reason ? 'text' : 'noreason' );
-				if ( msg.showEmbed() ) {
+				if ( msg.showEmbed() && !noEmbed ) {
 					text = lang.get(text, dateformat.format(blockedtimestamp), blockduration, blockexpiry, '[' + escapeFormatting(block.by) + '](' + wiki.toLink('User:' + block.by, '', '', true) + ')', toMarkdown(block.reason, wiki));
 				}
 				else {
@@ -191,7 +192,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 			var pagelink = wiki.toLink(namespace + username, querystring, fragment);
 			var text = '<' + pagelink + '>';
 			var embed = null;
-			if ( msg.showEmbed() ) {
+			if ( msg.showEmbed() && !noEmbed ) {
 				embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( username ).setURL( pagelink ).addField( editcount[0], '[' + editcount[1] + '](' + wiki.toLink(contribs + username, '', '', true) + ')' );
 				embed.forceTitle = true;
 				if ( querypage.pageprops && querypage.pageprops.description ) {
@@ -215,12 +216,12 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 			}
 			
 			if ( msg.channel.isGuild() && patreons[msg.guild?.id] && wiki.isFandom() ) {
-				if ( msg.showEmbed() ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
+				if ( msg.showEmbed() && !noEmbed ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
 				else text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 
-				parse_page(lang, msg, spoiler + text + spoiler, embed, wiki, reaction, querypage).then( message => global_block(lang, message, username, text, embed, wiki, spoiler) );
+				parse_page(lang, msg, spoiler + text + spoiler, ( noEmbed ? null : embed ), wiki, reaction, querypage).then( message => global_block(lang, message, username, text, ( noEmbed ? null : embed ), wiki, spoiler) );
 			}
-			else parse_page(lang, msg, spoiler + text + spoiler, embed, wiki, reaction, querypage);
+			else parse_page(lang, msg, spoiler + text + spoiler, ( noEmbed ? null : embed ), wiki, reaction, querypage);
 		}, error => {
 			if ( rangeprefix && !username.includes( '/' ) ) username = rangeprefix;
 			console.log( '- Error while getting the search results: ' + error );
@@ -277,7 +278,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 				}
 				else embed.setThumbnail( new URL(body.query.general.logo, wiki).href );
 				
-				return parse_page(lang, msg, spoiler + '<' + pagelink + '>' + spoiler, embed, wiki, reaction, querypage, new URL(body.query.general.logo, wiki).href, fragment, pagelink);
+				return parse_page(lang, msg, spoiler + '<' + pagelink + '>' + spoiler, ( noEmbed ? null : embed ), wiki, reaction, querypage, new URL(body.query.general.logo, wiki).href, fragment, pagelink);
 			}
 			
 			if ( reaction ) reaction.removeEmoji();
@@ -422,7 +423,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 			}
 			if ( isBlocked ) {
 				var blockedtext = 'user.block.' + ( isIndef ? 'indef_' : '' ) + ( queryuser.blockreason ? 'text' : 'noreason' );
-				if ( msg.showEmbed() ) {
+				if ( msg.showEmbed() && !noEmbed ) {
 					blockedtext = lang.get(blockedtext, ( blockedtimestamp ? dateformat.format(blockedtimestamp) : 'Invalid Date' ), blockduration, blockexpiry, '[' + escapeFormatting(queryuser.blockedby) + '](' + wiki.toLink('User:' + queryuser.blockedby, '', '', true) + ')', toMarkdown(queryuser.blockreason, wiki));
 				}
 				else {
@@ -436,7 +437,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 			var pagelink = wiki.toLink(namespace + username, querystring, fragment);
 			var text = '<' + pagelink + '>';
 			var embed = null;
-			if ( msg.showEmbed() ) {
+			if ( msg.showEmbed() && !noEmbed ) {
 				embed = new MessageEmbed().setAuthor( body.query.general.sitename ).setTitle( escapeFormatting(username) ).setURL( pagelink ).addField( editcount[0], '[' + editcount[1] + '](' + wiki.toLink(contribs + username, '', '', true) + ')', true );
 				embed.forceTitle = true;
 				if ( wiki.hasCentralAuth() ) {
@@ -474,7 +475,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 					console.log( '- ' + presponse.statusCode + ': Error while getting the user profile.' );
 					return;
 				}
-				if ( msg.showEmbed() ) {
+				if ( msg.showEmbed() && !noEmbed ) {
 					embed.spliceFields(0, 1, {
 						name: editcount[0],
 						value: '[' + pbody.userData.localEdits.toLocaleString(lang.get('dateformat')) + '](' + wiki.toLink(contribs + username, '', '', true) + ')',
@@ -524,7 +525,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 						var discordname = [lang.get('user.info.discord'),discord];
 						if ( discordmember ) discordname[1] = discordmember.toString();
 						
-						if ( msg.showEmbed() ) embed.addField( discordname[0], discordname[1], true );
+						if ( msg.showEmbed() && !noEmbed ) embed.addField( discordname[0], discordname[1], true );
 						else text += '\n' + discordname.join(' ');
 					}
 					if ( cpbody.profile['favwiki'] ) {
@@ -534,7 +535,7 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 								console.log( '- ' + favresponse.statusCode + ': Error while getting the favorite wiki: ' + ( favbody && ( favbody.error && favbody.error.info || favbody.errormsg ) ) );
 								return;
 							}
-							if ( msg.showEmbed() ) embed.addField( lang.get('user.info.favwiki'), '[' + favbody.data.wiki_name_display + '](<' + favbody.data.wiki_url + '>)', true );
+							if ( msg.showEmbed() && !noEmbed ) embed.addField( lang.get('user.info.favwiki'), '[' + favbody.data.wiki_name_display + '](<' + favbody.data.wiki_url + '>)', true );
 							else text += '\n' + lang.get('user.info.favwiki') + ' <' + favbody.data.wiki_url + '>';
 						}, error => {
 							console.log( '- Error while getting the favorite wiki: ' + error );
@@ -552,24 +553,24 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 					let discordname = [lang.get('user.info.discord'),discord];
 					if ( discordmember ) discordname[1] = discordmember.toString();
 					
-					if ( msg.showEmbed() ) embed.addField( discordname[0], discordname[1], true );
+					if ( msg.showEmbed() && !noEmbed ) embed.addField( discordname[0], discordname[1], true );
 					else text += '\n' + discordname.join(' ');
 				}
 			}, error => {
 				console.log( '- Error while getting the user profile: ' + error );
 			} ).finally( () => {
 				if ( isBlocked ) {
-					if ( msg.showEmbed() ) embed.addField( block.header, block.text );
+					if ( msg.showEmbed() && !noEmbed ) embed.addField( block.header, block.text );
 					else text += '\n\n**' + block.header + '**\n' + block.text;
 				}
 				
 				if ( msg.channel.isGuild() && patreons[msg.guild?.id] ) {
-					if ( msg.showEmbed() ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
+					if ( msg.showEmbed() && !noEmbed ) embed.addField( '\u200b', '<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**' );
 					else text += '\n\n<a:loading:641343250661113886> **' + lang.get('user.info.loading') + '**';
 					
-					parse_page(lang, msg, spoiler + text + spoiler, embed, wiki, reaction, querypage).then( message => global_block(lang, message, username, text, embed, wiki, spoiler, queryuser.gender) );
+					parse_page(lang, msg, spoiler + text + spoiler, ( noEmbed ? null : embed ), wiki, reaction, querypage).then( message => global_block(lang, message, username, text, ( noEmbed ? null : embed ), wiki, spoiler, queryuser.gender) );
 				}
-				else parse_page(lang, msg, spoiler + text + spoiler, embed, wiki, reaction, querypage);
+				else parse_page(lang, msg, spoiler + text + spoiler, ( noEmbed ? null : embed ), wiki, reaction, querypage);
 			} );
 			if ( body.query.pages ) {
 				let revision = Object.values(body.query.pages)[0]?.revisions?.[0];
@@ -582,20 +583,20 @@ function gamepedia_user(lang, msg, namespace, username, wiki, querystring, fragm
 					let discordname = [lang.get('user.info.discord'),escapeFormatting(discord)];
 					if ( discordmember ) discordname[1] = discordmember.toString();
 					
-					if ( msg.showEmbed() ) embed.addField( discordname[0], discordname[1], true );
+					if ( msg.showEmbed() && !noEmbed ) embed.addField( discordname[0], discordname[1], true );
 					else text += '\n' + discordname.join(' ');
 				}
 			}
 			if ( isBlocked ) {
-				if ( msg.showEmbed() ) embed.addField( block.header, block.text );
+				if ( msg.showEmbed() && !noEmbed ) embed.addField( block.header, block.text );
 				else text += '\n\n**' + block.header + '**\n' + block.text;
 			}
 			if ( wiki.hasCentralAuth() && body.query.globaluserinfo.locked !== undefined ) {
-				if ( msg.showEmbed() ) embed.addField( '\u200b', '**' + lang.get('user.gblock.header', escapeFormatting(username), gender) + '**' );
+				if ( msg.showEmbed() && !noEmbed ) embed.addField( '\u200b', '**' + lang.get('user.gblock.header', escapeFormatting(username), gender) + '**' );
 				else text += '\n\n**' + lang.get('user.gblock.header', escapeFormatting(username), gender) + '**';
 			}
 			
-			parse_page(lang, msg, spoiler + text + spoiler, embed, wiki, reaction, querypage);
+			parse_page(lang, msg, spoiler + text + spoiler, ( noEmbed ? null : embed ), wiki, reaction, querypage);
 		} );
 	}, error => {
 		console.log( '- Error while getting the search results: ' + error );

+ 25 - 17
functions/discussion.js

@@ -12,11 +12,18 @@ const {htmlToDiscord, escapeFormatting} = require('../util/functions.js');
  * @param {String} sitename - The sitename of the wiki.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  */
-function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler) {
+function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler, noEmbed) {
 	var limit = discussionLimit[( patreons[msg.guild?.id] ? 'patreon' : 'default' )];
 	if ( !title ) {
 		var pagelink = wiki + 'f';
+		if ( !msg.showEmbed() || noEmbed ) {
+			msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler );
+			
+			if ( reaction ) reaction.removeEmoji();
+			return;
+		}
 		var embed = new MessageEmbed().setAuthor( sitename ).setTitle( lang.get('discussion.main') ).setURL( pagelink );
 		got.get( wiki + 'f', {
 			responseType: 'text'
@@ -69,7 +76,7 @@ function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler)
 				var embed = new MessageEmbed().setAuthor( sitename );
 				
 				if ( posts.some( post => post.id === title ) ) {
-					discussion_send(lang, msg, wiki, posts.find( post => post.id === title ), embed, spoiler);
+					discussion_send(lang, msg, wiki, posts.find( post => post.id === title ), embed, spoiler, noEmbed);
 					
 					if ( reaction ) reaction.removeEmoji();
 				}
@@ -83,7 +90,7 @@ function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler)
 						if ( presponse.statusCode !== 200 || !pbody || pbody.id !== title ) {
 							if ( pbody && pbody.title === 'The requested resource was not found.' ) {
 								if ( posts.some( post => post.rawContent.toLowerCase().includes( title.toLowerCase() ) ) ) {
-									discussion_send(lang, msg, wiki, posts.find( post => post.rawContent.toLowerCase().includes( title.toLowerCase() ) ), embed, spoiler);
+									discussion_send(lang, msg, wiki, posts.find( post => post.rawContent.toLowerCase().includes( title.toLowerCase() ) ), embed, spoiler, noEmbed);
 								}
 								else msg.reactEmoji('🤷');
 							}
@@ -95,7 +102,7 @@ function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler)
 							if ( reaction ) reaction.removeEmoji();
 						}
 						else if ( pbody.title ) {
-							discussion_send(lang, msg, wiki, pbody, embed, spoiler);
+							discussion_send(lang, msg, wiki, pbody, embed, spoiler, noEmbed);
 							
 							if ( reaction ) reaction.removeEmoji();
 						}
@@ -114,7 +121,7 @@ function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler)
 							console.log( '- Error while getting the thread: ' + error );
 							embed.setTitle( '~~' + pbody.threadId + '~~' );
 						} ).finally( () => {
-							discussion_send(lang, msg, wiki, pbody, embed, spoiler);
+							discussion_send(lang, msg, wiki, pbody, embed, spoiler, noEmbed);
 							
 							if ( reaction ) reaction.removeEmoji();
 						} );
@@ -126,7 +133,7 @@ function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler)
 					} );
 				}
 				else if ( posts.some( post => post.rawContent.toLowerCase().includes( title.toLowerCase() ) ) ) {
-					discussion_send(lang, msg, wiki, posts.find( post => post.rawContent.toLowerCase().includes( title.toLowerCase() ) ), embed, spoiler);
+					discussion_send(lang, msg, wiki, posts.find( post => post.rawContent.toLowerCase().includes( title.toLowerCase() ) ), embed, spoiler, noEmbed);
 					
 					if ( reaction ) reaction.removeEmoji();
 				}
@@ -166,27 +173,27 @@ function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler)
 				var embed = new MessageEmbed().setAuthor( sitename );
 				
 				if ( threads.some( thread => thread.id === title ) ) {
-					discussion_send(lang, msg, wiki, threads.find( thread => thread.id === title ), embed, spoiler);
+					discussion_send(lang, msg, wiki, threads.find( thread => thread.id === title ), embed, spoiler, noEmbed);
 					
 					if ( reaction ) reaction.removeEmoji();
 				}
 				else if ( threads.some( thread => thread.title === title ) ) {
-					discussion_send(lang, msg, wiki, threads.find( thread => thread.title === title ), embed, spoiler);
+					discussion_send(lang, msg, wiki, threads.find( thread => thread.title === title ), embed, spoiler, noEmbed);
 					
 					if ( reaction ) reaction.removeEmoji();
 				}
 				else if ( threads.some( thread => thread.title.toLowerCase() === title.toLowerCase() ) ) {
-					discussion_send(lang, msg, wiki, threads.find( thread => thread.title.toLowerCase() === title.toLowerCase() ), embed, spoiler);
+					discussion_send(lang, msg, wiki, threads.find( thread => thread.title.toLowerCase() === title.toLowerCase() ), embed, spoiler, noEmbed);
 					
 					if ( reaction ) reaction.removeEmoji();
 				}
 				else if ( threads.some( thread => thread.title.includes( title ) ) ) {
-					discussion_send(lang, msg, wiki, threads.find( thread => thread.title.includes( title ) ), embed, spoiler);
+					discussion_send(lang, msg, wiki, threads.find( thread => thread.title.includes( title ) ), embed, spoiler, noEmbed);
 					
 					if ( reaction ) reaction.removeEmoji();
 				}
 				else if ( threads.some( thread => thread.title.toLowerCase().includes( title.toLowerCase() ) ) ) {
-					discussion_send(lang, msg, wiki, threads.find( thread => thread.title.toLowerCase().includes( title.toLowerCase() ) ), embed, spoiler);
+					discussion_send(lang, msg, wiki, threads.find( thread => thread.title.toLowerCase().includes( title.toLowerCase() ) ), embed, spoiler, noEmbed);
 					
 					if ( reaction ) reaction.removeEmoji();
 				}
@@ -200,7 +207,7 @@ function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler)
 						if ( thresponse.statusCode !== 200 || !thbody || thbody.id !== title ) {
 							if ( thbody && thbody.status === 404 ) {
 								if (threads.some( thread => thread.rawContent.toLowerCase().includes( title.toLowerCase() ) ) ) {
-									discussion_send(lang, msg, wiki, threads.find( thread => thread.rawContent.toLowerCase().includes( title.toLowerCase() ) ), embed, spoiler);
+									discussion_send(lang, msg, wiki, threads.find( thread => thread.rawContent.toLowerCase().includes( title.toLowerCase() ) ), embed, spoiler, noEmbed);
 								}
 								else msg.reactEmoji('🤷');
 							}
@@ -209,7 +216,7 @@ function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler)
 								msg.sendChannelError( spoiler + '<' + wiki + 'f/p/' + title + '>' + spoiler );
 							}
 						}
-						else discussion_send(lang, msg, wiki, thbody, embed, spoiler);
+						else discussion_send(lang, msg, wiki, thbody, embed, spoiler, noEmbed);
 					}, error => {
 						console.log( '- Error while getting the thread: ' + error );
 						msg.sendChannelError( spoiler + '<' + wiki + 'f/p/' + title + '>' + spoiler );
@@ -218,7 +225,7 @@ function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler)
 					} );
 				}
 				else if ( threads.some( thread => thread.rawContent.toLowerCase().includes( title.toLowerCase() ) ) ) {
-					discussion_send(lang, msg, wiki, threads.find( thread => thread.rawContent.toLowerCase().includes( title.toLowerCase() ) ), embed, spoiler);
+					discussion_send(lang, msg, wiki, threads.find( thread => thread.rawContent.toLowerCase().includes( title.toLowerCase() ) ), embed, spoiler, noEmbed);
 					
 					if ( reaction ) reaction.removeEmoji();
 				}
@@ -250,8 +257,9 @@ function fandom_discussion(lang, msg, wiki, title, sitename, reaction, spoiler)
  * @param {Object} discussion - The discussion post.
  * @param {import('discord.js').MessageEmbed} embed - The embed for the page.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  */
-function discussion_send(lang, msg, wiki, discussion, embed, spoiler) {
+function discussion_send(lang, msg, wiki, discussion, embed, spoiler, noEmbed) {
 	if ( discussion.title ) {
 		embed.setTitle( escapeFormatting(discussion.title) );
 		var pagelink = wiki + 'f/p/' + ( discussion.threadId || discussion.id );
@@ -260,7 +268,7 @@ function discussion_send(lang, msg, wiki, discussion, embed, spoiler) {
 		if ( discussion._embedded.thread ) embed.setTitle( escapeFormatting(discussion._embedded.thread[0].title) );
 		var pagelink = wiki + 'f/p/' + discussion.threadId + '/r/' + discussion.id;
 	}
-	var text = '<' + pagelink + '>';
+	if ( !msg.showEmbed() || noEmbed ) msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler );
 	embed.setURL( pagelink ).setFooter( discussion.createdBy.name, discussion.createdBy.avatarUrl ).setTimestamp( discussion.creationDate.epochSecond * 1000 );
 	var description = '';
 	switch ( discussion.funnel ) {
@@ -314,7 +322,7 @@ function discussion_send(lang, msg, wiki, discussion, embed, spoiler) {
 		embed.addField( lang.get('discussion.tags'), Util.splitMessage( discussion.tags.map( tag => '[' + escapeFormatting(tag.articleTitle) + '](' + wiki.toLink(tag.articleTitle, '', '', true) + ')' ).join(', '), {char:', ',maxLength:1000} )[0], false );
 	}
 	
-	msg.sendChannel( spoiler + text + spoiler, {embed} );
+	msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler, {embed} );
 }
 
 /**

+ 6 - 6
functions/global_block.js

@@ -21,7 +21,7 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler, gender) {
 		gender = 'unknown';
 	}
 	
-	if ( msg.showEmbed() ) embed.fields.pop();
+	if ( embed && msg.showEmbed() ) embed.fields.pop();
 	else {
 		let splittext = text.split('\n\n');
 		splittext.pop();
@@ -39,11 +39,11 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler, gender) {
 			else {
 				let $ = cheerio.load(body);
 				if ( $('#mw-content-text .errorbox').length ) {
-					if ( msg.showEmbed() ) embed.addField( '\u200b', '**' + lang.get('user.gblock.disabled') + '**' );
+					if ( embed && msg.showEmbed() ) embed.addField( '\u200b', '**' + lang.get('user.gblock.disabled') + '**' );
 					else text += '\n\n**' + lang.get('user.gblock.disabled') + '**';
 				}
 				else if ( $('#mw-content-text .userprofile.mw-warning-with-logexcerpt').length ) {
-					if ( msg.showEmbed() ) embed.addField( '\u200b', '**' + lang.get('user.gblock.header', escapeFormatting(username), gender) + '**' );
+					if ( embed && msg.showEmbed() ) embed.addField( '\u200b', '**' + lang.get('user.gblock.header', escapeFormatting(username), gender) + '**' );
 					else text += '\n\n**' + lang.get('user.gblock.header', escapeFormatting(username), gender) + '**';
 				}
 			}
@@ -62,7 +62,7 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler, gender) {
 				var wikisedited = $('.curseprofile .rightcolumn .section.stats dd').eq(0).text().replace( /[,\.]/g, '' );
 				if ( wikisedited ) {
 					wikisedited = parseInt(wikisedited, 10).toLocaleString(lang.get('dateformat'));
-					if ( msg.showEmbed() ) embed.spliceFields(1, 0, {
+					if ( embed && msg.showEmbed() ) embed.spliceFields(1, 0, {
 						name: lang.get('user.info.wikisedited'),
 						value: wikisedited,
 						inline: true
@@ -76,7 +76,7 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler, gender) {
 				var globaledits = $('.curseprofile .rightcolumn .section.stats dd').eq(2).text().replace( /[,\.]/g, '' );
 				if ( globaledits ) {
 					globaledits = parseInt(globaledits, 10).toLocaleString(lang.get('dateformat'));
-					if ( msg.showEmbed() ) embed.spliceFields(1, 0, {
+					if ( embed && msg.showEmbed() ) embed.spliceFields(1, 0, {
 						name: lang.get('user.info.globaleditcount'),
 						value: globaledits,
 						inline: true
@@ -87,7 +87,7 @@ function global_block(lang, msg, username, text, embed, wiki, spoiler, gender) {
 						text = splittext.join('\n');
 					}
 				}
-				if ( msg.showEmbed() ) {
+				if ( embed && msg.showEmbed() ) {
 					let avatar = $('.curseprofile .mainavatar img').prop('src');
 					if ( avatar ) {
 						embed.setThumbnail( avatar.replace( /^(?:https?:)?\/\//, 'https://' ).replace( '?d=mm&s=96', '?d=' + encodeURIComponent( embed?.thumbnail?.url || '404' ) ) );

+ 7 - 6
functions/phabricator.js

@@ -10,12 +10,13 @@ const {escapeFormatting, limitLength} = require('../util/functions.js');
  * @param {URL} link - The link.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} [spoiler] - If the response is in a spoiler.
+ * @param {Boolean} [noEmbed] - If the response should be without an embed.
  */
-function phabricator_task(lang, msg, wiki, link, reaction, spoiler = '') {
+function phabricator_task(lang, msg, wiki, link, reaction, spoiler = '', noEmbed = false) {
 	var regex = /^(?:https?:)?\/\/phabricator\.(wikimedia|miraheze)\.org\/T(\d+)(?:#|$)/.exec(link.href);
 	if ( !regex || !process.env['phabricator_' + regex[1]] ) {
 		logging(wiki, msg.guild?.id, 'interwiki');
-		msg.sendChannel( spoiler + ' ' + link + ' ' + spoiler );
+		msg.sendChannel( spoiler + ( noEmbed ? '<' : ' ' ) + link + ( noEmbed ? '>' : ' ' ) + spoiler );
 		if ( reaction ) reaction.removeEmoji();
 		return;
 	}
@@ -25,20 +26,20 @@ function phabricator_task(lang, msg, wiki, link, reaction, spoiler = '') {
 		var body = response.body;
 		if ( response.statusCode !== 200 || !body?.result?.data || body.error_code ) {
 			console.log( '- ' + response.statusCode + ': Error while getting the Phabricator task: ' + body?.error_info );
-			msg.sendChannelError( spoiler + ' ' + link + ' ' + spoiler );
+			msg.sendChannelError( spoiler + ( noEmbed ? '<' : ' ' ) + link + ( noEmbed ? '>' : ' ' ) + spoiler );
 
 			if ( reaction ) reaction.removeEmoji();
 			return;
 		}
 		if ( !body.result.data.length ) {
-			msg.sendChannel( spoiler + ' ' + link + ' ' + spoiler );
+			msg.sendChannel( spoiler + ( noEmbed ? '<' : ' ' ) + link + ( noEmbed ? '>' : ' ' ) + spoiler );
 
 			if ( reaction ) reaction.removeEmoji();
 			return;
 		}
 		var task = body.result.data[0];
 		var status = '**' + task.fields.status.name + ':** ' + escapeFormatting(task.fields.name) + '\n';
-		if ( !msg.showEmbed() ) {
+		if ( !msg.showEmbed() || noEmbed ) {
 			msg.sendChannel( spoiler + status + '<' + link + '>' + spoiler );
 			
 			if ( reaction ) reaction.removeEmoji();
@@ -92,7 +93,7 @@ function phabricator_task(lang, msg, wiki, link, reaction, spoiler = '') {
 		} );
 	}, error => {
 		console.log( '- Error while getting the Phabricator task: ' + error );
-		msg.sendChannelError( spoiler + ' ' + link + ' ' + spoiler );
+		msg.sendChannelError( spoiler + ( noEmbed ? '<' : ' ' ) + link + ( noEmbed ? '>' : ' ' ) + spoiler );
 
 		if ( reaction ) reaction.removeEmoji();
 	} );

+ 21 - 9
functions/special_page.js

@@ -4,7 +4,7 @@ const {timeoptions} = require('../util/default.json');
 const {toMarkdown, escapeFormatting} = require('../util/functions.js');
 
 const overwrites = {
-	randompage: (fn, lang, msg, wiki, querystring, fragment, reaction, spoiler, args, embed, query) => {
+	randompage: (fn, lang, msg, wiki, querystring, fragment, reaction, spoiler, noEmbed, args, embed, query) => {
 		let namespaces = Object.values(query.namespaces);
 		let contentNamespaces = namespaces.filter( ns => ns.content !== undefined );
 		let namespaceData = [contentNamespaces.map( ns => ns.id ).join('|'), contentNamespaces.map( ns => ( ns['*'] || '*' )  ).join(', ')];
@@ -25,13 +25,13 @@ const overwrites = {
 			}
 			else if ( args[0] === '*' ) namespaceData = ['*', '*'];
 		}
-		fn.random(lang, msg, wiki, reaction, spoiler, namespaceData, querystring, fragment, embed);
+		fn.random(lang, msg, wiki, reaction, spoiler, noEmbed, namespaceData, querystring, fragment, embed);
 	},
-	statistics: (fn, lang, msg, wiki, querystring, fragment, reaction, spoiler) => {
-		fn.overview(lang, msg, wiki, reaction, spoiler, querystring, fragment);
+	statistics: (fn, lang, msg, wiki, querystring, fragment, reaction, spoiler, noEmbed) => {
+		fn.overview(lang, msg, wiki, reaction, spoiler, noEmbed, querystring, fragment);
 	},
-	diff: (fn, lang, msg, wiki, querystring, fragment, reaction, spoiler, args, embed) => {
-		fn.diff(lang, msg, args, wiki, reaction, spoiler, embed);
+	diff: (fn, lang, msg, wiki, querystring, fragment, reaction, spoiler, noEmbed, args, embed) => {
+		fn.diff(lang, msg, args, wiki, reaction, spoiler, noEmbed, embed);
 	}
 }
 
@@ -157,26 +157,38 @@ const descriptions = {
  * @param {String} fragment - The section for the link.
  * @param {import('discord.js').MessageReaction} reaction - The reaction on the message.
  * @param {String} spoiler - If the response is in a spoiler.
+ * @param {Boolean} noEmbed - If the response should be without an embed.
  */
-function special_page(lang, msg, {title, uselang = lang.lang}, specialpage, query, wiki, querystring, fragment, reaction, spoiler) {
+function special_page(lang, msg, {title, uselang = lang.lang}, specialpage, query, wiki, querystring, fragment, reaction, spoiler, noEmbed) {
 	var pagelink = wiki.toLink(title, querystring, fragment);
 	var embed = new MessageEmbed().setAuthor( query.general.sitename ).setTitle( escapeFormatting(title) ).setURL( pagelink ).setThumbnail( new URL(query.general.logo, wiki).href );
 	if ( overwrites.hasOwnProperty(specialpage) ) {
 		var args = title.split('/').slice(1,3);
-		overwrites[specialpage](this, lang, msg, wiki, querystring, fragment, reaction, spoiler, args, embed, query);
+		overwrites[specialpage](this, lang, msg, wiki, querystring, fragment, reaction, spoiler, noEmbed, args, embed, query);
 		return;
 	}
 	logging(wiki, msg.guild?.id, 'general', 'special');
+	if ( !msg.showEmbed() || noEmbed ) {
+		msg.sendChannel( spoiler + '<' + pagelink + '>' + spoiler );
+		
+		if ( reaction ) reaction.removeEmoji();
+		return;
+	}
 	if ( specialpage === 'recentchanges' && msg.isAdmin() ) {
 		embed.addField( lang.get('rcscript.title'), lang.get('rcscript.ad', ( patreons[msg?.guild?.id] || process.env.prefix ), '[RcGcDw](https://gitlab.com/piotrex43/RcGcDw)') );
 	}
-	got.get( wiki + 'api.php?uselang=' + uselang + '&action=query&meta=allmessages|siteinfo&siprop=general&amenableparser=true&amtitle=' + encodeURIComponent( title ) + '&ammessages=' + encodeURIComponent( specialpage ) + '|' + ( descriptions.hasOwnProperty(specialpage) ? descriptions[specialpage] : encodeURIComponent( specialpage ) + '-summary' ) + ( querypages.hasOwnProperty(specialpage) ? querypages[specialpage][0] : '' ) + '&format=json' ).then( response => {
+	got.get( wiki + 'api.php?uselang=' + uselang + '&action=query&meta=allmessages|siteinfo&siprop=general&amenableparser=true&amtitle=' + encodeURIComponent( title ) + '&ammessages=' + encodeURIComponent( specialpage ) + '|' + ( descriptions.hasOwnProperty(specialpage) ? descriptions[specialpage] : encodeURIComponent( specialpage ) + '-summary' ) + ( querypages.hasOwnProperty(specialpage) ? querypages[specialpage][0] : '' ) + '&converttitles=true&titles=%1F' + encodeURIComponent( title ) + '&format=json' ).then( response => {
 		var body = response.body;
 		if ( body && body.warnings ) log_warn(body.warnings);
 		if ( response.statusCode !== 200 || body?.batchcomplete === undefined ) {
 			console.log( '- ' + response.statusCode + ': Error while getting the special page: ' + ( body && body.error && body.error.info ) );
 			return;
 		}
+		if ( body.query.pages?.['-1']?.title ) {
+			title = body.query.pages['-1'].title;
+			pagelink = wiki.toLink(title, querystring, fragment);
+			embed.setTitle( escapeFormatting(title) );
+		}
 		if ( body.query.allmessages?.[0]?.['*']?.trim?.() ) {
 			let displaytitle = escapeFormatting(body.query.allmessages[0]['*'].trim());
 			if ( displaytitle.length > 250 ) displaytitle = displaytitle.substring(0, 250) + '\u2026';