浏览代码

Add /verify

Markus-Rost 4 年之前
父节点
当前提交
827b701f41
共有 8 个文件被更改,包括 201 次插入73 次删除
  1. 2 1
      bot.js
  2. 9 14
      cmds/verify.js
  3. 32 37
      functions/verify.js
  4. 3 1
      i18n/en.json
  5. 14 0
      interactions/commands.json
  6. 1 17
      interactions/inline.js
  7. 118 0
      interactions/verify.js
  8. 22 3
      util/functions.js

+ 2 - 1
bot.js

@@ -204,7 +204,7 @@ fs.readdir( './interactions', (error, files) => {
 	} );
 	} );
 } );
 } );
 /*
 /*
-!test eval client.api.applications(client.user.id).commands.post( {
+!test eval msg.client.api.applications(msg.client.user.id).commands.post( {
 	data: require('../interactions/commands.json')[0]
 	data: require('../interactions/commands.json')[0]
 } )
 } )
 */
 */
@@ -230,6 +230,7 @@ client.ws.on( 'INTERACTION_CREATE', interaction => {
 	if ( !interaction.guild_id ) {
 	if ( !interaction.guild_id ) {
 		return slash[interaction.data.name](interaction, new Lang(), new Wiki(), channel);
 		return slash[interaction.data.name](interaction, new Lang(), new Wiki(), channel);
 	}
 	}
+	else interaction.user = interaction.member.user;
 	db.query( 'SELECT wiki, lang, role FROM discord WHERE guild = $1 AND (channel = $2 OR channel = $3 OR channel IS NULL) ORDER BY channel DESC NULLS LAST LIMIT 1', [interaction.guild_id, interaction.channel_id, '#' + channel?.parentID] ).then( ({rows:[row]}) => {
 	db.query( 'SELECT wiki, lang, role FROM discord WHERE guild = $1 AND (channel = $2 OR channel = $3 OR channel IS NULL) ORDER BY channel DESC NULLS LAST LIMIT 1', [interaction.guild_id, interaction.channel_id, '#' + channel?.parentID] ).then( ({rows:[row]}) => {
 		var lang = new Lang(( row?.lang || channel?.guild?.preferredLocale ));
 		var lang = new Lang(( row?.lang || channel?.guild?.preferredLocale ));
 		if ( row?.role && !interaction.member.roles.includes( row.role ) && channel?.guild?.roles.cache.has(row.role) && ( !interaction.member.roles.length || !interaction.member.roles.some( role => channel.guild.roles.cache.get(role)?.comparePositionTo(row.role) >= 0 ) ) ) {
 		if ( row?.role && !interaction.member.roles.includes( row.role ) && channel?.guild?.roles.cache.has(row.role) && ( !interaction.member.roles.length || !interaction.member.roles.some( role => channel.guild.roles.cache.get(role)?.comparePositionTo(row.role) >= 0 ) ) ) {

+ 9 - 14
cmds/verify.js

@@ -20,17 +20,17 @@ function cmd_verify(lang, msg, args, line, wiki) {
 		return;
 		return;
 	}
 	}
 	
 	
-	var username = args.join(' ').replace( /_/g, ' ' ).trim().replace( /^<\s*(.*)\s*>$/, '$1' ).replace( /^@/, '' ).split('#')[0].substring(0, 250).trim();
-	if ( /^(?:https?:)?\/\/([a-z\d-]{1,50})\.(?:gamepedia\.com\/|(?:fandom\.com|wikia\.org)\/(?:[a-z-]{1,8}\/)?wiki\/)/.test(username) ) {
-		username = decodeURIComponent( username.replace( /^(?:https?:)?\/\/([a-z\d-]{1,50})\.(?:gamepedia\.com\/|(?:fandom\.com|wikia\.org)\/(?:[a-z-]{1,8}\/)?wiki\/)/, '' ) );
-	}
-	if ( wiki.isGamepedia() ) username = username.replace( /^userprofile\s*:/i, '' );
-	
 	db.query( 'SELECT role, editcount, postcount, usergroup, accountage, rename FROM verification WHERE guild = $1 AND channel LIKE $2 ORDER BY configid ASC', [msg.guild.id, '%|' + msg.channel.id + '|%'] ).then( ({rows}) => {
 	db.query( 'SELECT role, editcount, postcount, usergroup, accountage, rename FROM verification WHERE guild = $1 AND channel LIKE $2 ORDER BY configid ASC', [msg.guild.id, '%|' + msg.channel.id + '|%'] ).then( ({rows}) => {
 		if ( !rows.length ) {
 		if ( !rows.length ) {
 			if ( msg.onlyVerifyCommand ) return;
 			if ( msg.onlyVerifyCommand ) return;
 			return msg.replyMsg( lang.get('verify.missing') + ( msg.isAdmin() ? '\n`' + ( patreons[msg.guild.id] || process.env.prefix ) + 'verification`' : '' ) );
 			return msg.replyMsg( lang.get('verify.missing') + ( msg.isAdmin() ? '\n`' + ( patreons[msg.guild.id] || process.env.prefix ) + 'verification`' : '' ) );
 		}
 		}
+	
+		var username = args.join(' ').replace( /_/g, ' ' ).trim().replace( /^<\s*(.*)\s*>$/, '$1' ).replace( /^@/, '' ).split('#')[0].substring(0, 250).trim();
+		if ( /^(?:https?:)?\/\/([a-z\d-]{1,50})\.(?:gamepedia\.com\/|(?:fandom\.com|wikia\.org)\/(?:[a-z-]{1,8}\/)?(?:wiki\/)?)/.test(username) ) {
+			username = decodeURIComponent( username.replace( /^(?:https?:)?\/\/([a-z\d-]{1,50})\.(?:gamepedia\.com\/|(?:fandom\.com|wikia\.org)\/(?:[a-z-]{1,8}\/)?(?:wiki\/)?)/, '' ) );
+		}
+		if ( wiki.isGamepedia() ) username = username.replace( /^userprofile\s*:\s*/i, '' );
 		
 		
 		if ( !username.trim() ) {
 		if ( !username.trim() ) {
 			args[0] = line.split(' ')[0];
 			args[0] = line.split(' ')[0];
@@ -38,14 +38,9 @@ function cmd_verify(lang, msg, args, line, wiki) {
 			return this.help(lang, msg, args, line, wiki);
 			return this.help(lang, msg, args, line, wiki);
 		}
 		}
 		msg.reactEmoji('⏳').then( reaction => {
 		msg.reactEmoji('⏳').then( reaction => {
-			verify(lang, msg, username, wiki, rows).then( result => {
-				if ( result.reaction ) {
-					if ( result.content ) msg.replyMsg( result.content, result.options, false, false ).then( message => {
-						if ( message ) message.reactEmoji(result.reaction);
-					} );
-					else msg.reactEmoji(result.reaction);
-				}
-				else msg.replyMsg( result.content, result.options, false, false );
+			verify(lang, msg.channel, msg.member, username, wiki, rows).then( result => {
+				if ( result.reaction ) msg.reactEmoji(result.reaction);
+				else msg.replyMsg( result.content, {embed: result.embed}, false, false );
 				if ( reaction ) reaction.removeEmoji();
 				if ( reaction ) reaction.removeEmoji();
 			}, error => {
 			}, error => {
 				console.log( '- Error during the verifications: ' + error );
 				console.log( '- Error during the verifications: ' + error );

+ 32 - 37
functions/verify.js

@@ -6,18 +6,18 @@ const toTitle = require('../util/wiki.js').toTitle;
 /**
 /**
  * Processes the "verify" command.
  * Processes the "verify" command.
  * @param {import('../util/i18n.js')} lang - The user language.
  * @param {import('../util/i18n.js')} lang - The user language.
- * @param {import('discord.js').Message} msg - The Discord message.
+ * @param {import('discord.js').TextChannel} channel - The Discord channel.
+ * @param {import('discord.js').GuildMember} member - The Discord guild member.
  * @param {String} username - The username.
  * @param {String} username - The username.
  * @param {import('../util/wiki.js')} wiki - The wiki for the message.
  * @param {import('../util/wiki.js')} wiki - The wiki for the message.
  * @param {Object[]} rows - The verification settings.
  * @param {Object[]} rows - The verification settings.
  * @param {String} [old_username] - The username before the search.
  * @param {String} [old_username] - The username before the search.
- * @returns {Promise<{content:String,options:Object,reaction:String}>}
+ * @returns {Promise<{content:String,embed:MessageEmbed,reaction:String}>}
  */
  */
-function verify(lang, msg, username, wiki, rows, old_username = '') {
+function verify(lang, channel, member, username, wiki, rows, old_username = '') {
 	var embed = new MessageEmbed().setFooter( lang.get('verify.footer') ).setTimestamp();
 	var embed = new MessageEmbed().setFooter( lang.get('verify.footer') ).setTimestamp();
 	var result = {
 	var result = {
-		content: '',
-		options: {embed},
+		content: '', embed,
 		reaction: ''
 		reaction: ''
 	};
 	};
 	return got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general&list=users&usprop=blockinfo|groups|editcount|registration&ususers=' + encodeURIComponent( username ) + '&format=json' ).then( response => {
 	return got.get( wiki + 'api.php?action=query&meta=siteinfo&siprop=general&list=users&usprop=blockinfo|groups|editcount|registration&ususers=' + encodeURIComponent( username ) + '&format=json' ).then( response => {
@@ -29,7 +29,7 @@ function verify(lang, msg, username, wiki, rows, old_username = '') {
 				result.reaction = 'nowiki';
 				result.reaction = 'nowiki';
 			}
 			}
 			else if ( body?.error?.code === 'us400' ) { // special catch for Fandom
 			else if ( body?.error?.code === 'us400' ) { // special catch for Fandom
-				if ( !old_username ) logging(wiki, msg.guild?.id, 'verification');
+				if ( !old_username ) logging(wiki, channel.guild.id, 'verification');
 				embed.setTitle( ( old_username || username ).escapeFormatting() ).setColor('#0000FF').setDescription( lang.get('verify.user_missing', ( old_username || username ).escapeFormatting()) );
 				embed.setTitle( ( old_username || username ).escapeFormatting() ).setColor('#0000FF').setDescription( lang.get('verify.user_missing', ( old_username || username ).escapeFormatting()) );
 				result.content = lang.get('verify.user_missing_reply', ( old_username || username ).escapeFormatting());
 				result.content = lang.get('verify.user_missing_reply', ( old_username || username ).escapeFormatting());
 			}
 			}
@@ -37,12 +37,11 @@ function verify(lang, msg, username, wiki, rows, old_username = '') {
 				console.log( '- ' + response.statusCode + ': Error while getting the user: ' + ( body && body.error && body.error.info ) );
 				console.log( '- ' + response.statusCode + ': Error while getting the user: ' + ( body && body.error && body.error.info ) );
 				embed.setColor('#000000').setDescription( lang.get('verify.error') );
 				embed.setColor('#000000').setDescription( lang.get('verify.error') );
 				result.content = lang.get('verify.error_reply');
 				result.content = lang.get('verify.error_reply');
-				result.reaction = 'error';
 			}
 			}
 			return;
 			return;
 		}
 		}
 		wiki.updateWiki(body.query.general);
 		wiki.updateWiki(body.query.general);
-		if ( !old_username ) logging(wiki, msg.guild?.id, 'verification');
+		if ( !old_username ) logging(wiki, channel.guild.id, 'verification');
 		var queryuser = body.query.users[0];
 		var queryuser = body.query.users[0];
 		embed.setAuthor( body.query.general.sitename );
 		embed.setAuthor( body.query.general.sitename );
 		if ( body.query.users.length !== 1 || queryuser.missing !== undefined || queryuser.invalid !== undefined ) {
 		if ( body.query.users.length !== 1 || queryuser.missing !== undefined || queryuser.invalid !== undefined ) {
@@ -55,7 +54,7 @@ function verify(lang, msg, username, wiki, rows, old_username = '') {
 					result.content = lang.get('verify.user_missing_reply', username.escapeFormatting());
 					result.content = lang.get('verify.user_missing_reply', username.escapeFormatting());
 					return;
 					return;
 				}
 				}
-				return verify(lang, msg, wsbody.users[0].name.split(' '), wiki, rows, username);
+				return verify(lang, channel, member, wsbody.users[0].name.split(' '), wiki, rows, username);
 			}, error => {
 			}, error => {
 				console.log( '- Error while searching the user: ' + error );
 				console.log( '- Error while searching the user: ' + error );
 				result.content = lang.get('verify.user_missing_reply', username.escapeFormatting());
 				result.content = lang.get('verify.user_missing_reply', username.escapeFormatting());
@@ -126,12 +125,13 @@ function verify(lang, msg, username, wiki, rows, old_username = '') {
 				return Promise.reject();
 				return Promise.reject();
 			} ).then( () => {
 			} ).then( () => {
 				if ( discordname.length > 100 ) discordname = discordname.substring(0, 100) + '\u2026';
 				if ( discordname.length > 100 ) discordname = discordname.substring(0, 100) + '\u2026';
-				embed.addField( lang.get('verify.discord', ( msg.author.tag.escapeFormatting() === discordname ? queryuser.gender : 'unknown' )), msg.author.tag.escapeFormatting(), true ).addField( lang.get('verify.wiki', queryuser.gender), ( discordname || lang.get('verify.empty') ), true );
-				if ( msg.author.tag.escapeFormatting() !== discordname ) {
-					embed.setColor('#FFFF00').setDescription( lang.get('verify.user_failed', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
+				var authortag = member.user.tag.escapeFormatting();
+				embed.addField( lang.get('verify.discord', ( authortag === discordname ? queryuser.gender : 'unknown' )), authortag, true ).addField( lang.get('verify.wiki', queryuser.gender), ( discordname || lang.get('verify.empty') ), true );
+				if ( authortag !== discordname ) {
+					embed.setColor('#FFFF00').setDescription( lang.get('verify.user_failed', member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
 					var help_link = '';
 					var help_link = '';
-					if ( wiki.isGamepedia() ) help_link = lang.get('verify.help_gamepedia') + '?c=' + ( patreons[msg.guild.id] && patreons[msg.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[msg.guild.id] + ' verify' ) : 'wb' ) + ( msg.channel.name !== 'verification' ? '&ch=' + encodeURIComponent( msg.channel.name ) : '' ) + '&user=' + toTitle(username) + '&discord=' + encodeURIComponent( msg.author.username ) + '&tag=' + msg.author.discriminator;
-					else if ( wiki.isFandom() ) help_link = lang.get('verify.help_fandom') + '/' + toTitle(username) + '?c=' + ( patreons[msg.guild.id] && patreons[msg.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[msg.guild.id] + ' verify' ) : 'wb' ) + ( msg.channel.name !== 'verification' ? '&ch=' + encodeURIComponent( msg.channel.name ) : '' ) + '&user=' + encodeURIComponent( msg.author.username ) + '&tag=' + msg.author.discriminator + '&useskin=oasis';
+					if ( wiki.isGamepedia() ) help_link = lang.get('verify.help_gamepedia') + '?c=' + ( patreons[channel.guild.id] && patreons[channel.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[channel.guild.id] + ' verify' ) : 'wb' ) + ( channel.name !== 'verification' ? '&ch=' + encodeURIComponent( channel.name ) : '' ) + '&user=' + toTitle(username) + '&discord=' + encodeURIComponent( member.user.username ) + '&tag=' + member.user.discriminator;
+					else if ( wiki.isFandom() ) help_link = lang.get('verify.help_fandom') + '/' + toTitle(username) + '?c=' + ( patreons[channel.guild.id] && patreons[channel.guild.id] !== process.env.prefix ? encodeURIComponent( patreons[channel.guild.id] + ' verify' ) : 'wb' ) + ( channel.name !== 'verification' ? '&ch=' + encodeURIComponent( channel.name ) : '' ) + '&user=' + encodeURIComponent( member.user.username ) + '&tag=' + member.user.discriminator + '&useskin=oasis';
 					if ( help_link.length ) embed.addField( lang.get('verify.notice'), lang.get('verify.help_guide', help_link, queryuser.gender) + '\n' + help_link );
 					if ( help_link.length ) embed.addField( lang.get('verify.notice'), lang.get('verify.help_guide', help_link, queryuser.gender) + '\n' + help_link );
 					result.content = lang.get('verify.user_failed_reply', username.escapeFormatting(), queryuser.gender);
 					result.content = lang.get('verify.user_failed_reply', username.escapeFormatting(), queryuser.gender);
 					return;
 					return;
@@ -157,31 +157,31 @@ function verify(lang, msg, username, wiki, rows, old_username = '') {
 						if ( row.rename ) rename = true;
 						if ( row.rename ) rename = true;
 						row.role.split('|').forEach( role => {
 						row.role.split('|').forEach( role => {
 							if ( !roles.includes( role ) ) {
 							if ( !roles.includes( role ) ) {
-								if ( msg.guild.roles.cache.has(role) && msg.guild.me.roles.highest.comparePositionTo(role) > 0 ) roles.push(role);
+								if ( channel.guild.roles.cache.has(role) && channel.guild.me.roles.highest.comparePositionTo(role) > 0 ) roles.push(role);
 								else if ( !missing.includes( role ) ) missing.push(role);
 								else if ( !missing.includes( role ) ) missing.push(role);
 							}
 							}
 						} );
 						} );
 					}
 					}
 				} );
 				} );
 				if ( verified ) {
 				if ( verified ) {
-					embed.setColor('#00FF00').setDescription( lang.get('verify.user_verified', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) + ( rename ? '\n' + lang.get('verify.user_renamed', queryuser.gender) : '' ) );
+					embed.setColor('#00FF00').setDescription( lang.get('verify.user_verified', member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) + ( rename ? '\n' + lang.get('verify.user_renamed', queryuser.gender) : '' ) );
 					var text = lang.get('verify.user_verified_reply', username.escapeFormatting(), queryuser.gender);
 					var text = lang.get('verify.user_verified_reply', username.escapeFormatting(), queryuser.gender);
 					var verify_promise = [
 					var verify_promise = [
-						msg.member.roles.add( roles, lang.get('verify.audit_reason', username) ).catch( error => {
+						member.roles.add( roles, lang.get('verify.audit_reason', username) ).catch( error => {
 							log_error(error);
 							log_error(error);
 							embed.setColor('#008800');
 							embed.setColor('#008800');
 							comment.push(lang.get('verify.failed_roles'));
 							comment.push(lang.get('verify.failed_roles'));
 						} )
 						} )
 					];
 					];
 					if ( rename ) {
 					if ( rename ) {
-						verify_promise.push(msg.member.setNickname( username.substring(0, 32), lang.get('verify.audit_reason', username) ).catch( error => {
+						verify_promise.push(member.setNickname( username.substring(0, 32), lang.get('verify.audit_reason', username) ).catch( error => {
 							log_error(error);
 							log_error(error);
 							embed.setColor('#008800');
 							embed.setColor('#008800');
 							comment.push(lang.get('verify.failed_rename', queryuser.gender));
 							comment.push(lang.get('verify.failed_rename', queryuser.gender));
 						} ));
 						} ));
 					}
 					}
 					return Promise.all(verify_promise).finally( () => {
 					return Promise.all(verify_promise).finally( () => {
-						if ( msg.showEmbed() ) {
+						if ( channel.permissionsFor(channel.guild.me).has('EMBED_LINKS') ) {
 							if ( roles.length ) embed.addField( lang.get('verify.qualified'), roles.map( role => '<@&' + role + '>' ).join('\n') );
 							if ( roles.length ) embed.addField( lang.get('verify.qualified'), roles.map( role => '<@&' + role + '>' ).join('\n') );
 							if ( missing.length ) embed.setColor('#008800').addField( lang.get('verify.qualified_error'), missing.map( role => '<@&' + role + '>' ).join('\n') );
 							if ( missing.length ) embed.setColor('#008800').addField( lang.get('verify.qualified_error'), missing.map( role => '<@&' + role + '>' ).join('\n') );
 							if ( comment.length ) embed.setColor('#008800').addField( lang.get('verify.notice'), comment.join('\n') );
 							if ( comment.length ) embed.setColor('#008800').addField( lang.get('verify.notice'), comment.join('\n') );
@@ -192,17 +192,15 @@ function verify(lang, msg, username, wiki, rows, old_username = '') {
 							if ( comment.length ) text += '\n\n' + comment.join('\n');
 							if ( comment.length ) text += '\n\n' + comment.join('\n');
 						}
 						}
 						result.content = text;
 						result.content = text;
-						result.options.split = true;
 					} );
 					} );
 				}
 				}
 				
 				
-				embed.setColor('#FFFF00').setDescription( lang.get('verify.user_matches', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
+				embed.setColor('#FFFF00').setDescription( lang.get('verify.user_matches', member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
 				result.content = lang.get('verify.user_matches_reply', username.escapeFormatting(), queryuser.gender);
 				result.content = lang.get('verify.user_matches_reply', username.escapeFormatting(), queryuser.gender);
 			}, error => {
 			}, error => {
 				if ( error ) console.log( '- Error while getting the Discord tag: ' + error );
 				if ( error ) console.log( '- Error while getting the Discord tag: ' + error );
 				embed.setColor('#000000').setDescription( lang.get('verify.error') );
 				embed.setColor('#000000').setDescription( lang.get('verify.error') );
 				result.content = lang.get('verify.error_reply');
 				result.content = lang.get('verify.error_reply');
-				result.reaction = 'error';
 			} );
 			} );
 		}, error => {
 		}, error => {
 			embed.setColor('#FF0000').setDescription( error.desc );
 			embed.setColor('#FF0000').setDescription( error.desc );
@@ -216,7 +214,6 @@ function verify(lang, msg, username, wiki, rows, old_username = '') {
 				console.log( '- ' + mwresponse.statusCode + ': Error while getting the Discord tag: ' + ( mwbody && mwbody.error && mwbody.error.info ) );
 				console.log( '- ' + mwresponse.statusCode + ': Error while getting the Discord tag: ' + ( mwbody && mwbody.error && mwbody.error.info ) );
 				embed.setColor('#000000').setDescription( lang.get('verify.error') );
 				embed.setColor('#000000').setDescription( lang.get('verify.error') );
 				result.content = lang.get('verify.error_reply');
 				result.content = lang.get('verify.error_reply');
-				result.reaction = 'error';
 				return;
 				return;
 			}
 			}
 			if ( wiki.hasCentralAuth() ) {
 			if ( wiki.hasCentralAuth() ) {
@@ -234,10 +231,11 @@ function verify(lang, msg, username, wiki, rows, old_username = '') {
 				discordname = ( revision?.slots?.main || revision )['*'].escapeFormatting().replace( /^\s*([^@#:]{2,32}?)\s*#(\d{4,6})\s*$/u, '$1#$2' );
 				discordname = ( revision?.slots?.main || revision )['*'].escapeFormatting().replace( /^\s*([^@#:]{2,32}?)\s*#(\d{4,6})\s*$/u, '$1#$2' );
 			}
 			}
 			if ( discordname.length > 100 ) discordname = discordname.substring(0, 100) + '\u2026';
 			if ( discordname.length > 100 ) discordname = discordname.substring(0, 100) + '\u2026';
-			embed.addField( lang.get('verify.discord', ( msg.author.tag.escapeFormatting() === discordname ? queryuser.gender : 'unknown' )), msg.author.tag.escapeFormatting(), true ).addField( lang.get('verify.wiki', queryuser.gender), ( discordname || lang.get('verify.empty') ), true );
-			if ( msg.author.tag.escapeFormatting() !== discordname ) {
-				embed.setColor('#FFFF00').setDescription( lang.get('verify.user_failed', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
-				embed.addField( lang.get('verify.notice'), lang.get('verify.help_subpage', '**`' + msg.author.tag + '`**', queryuser.gender) + '\n' + wiki.toLink('Special:MyPage/Discord', 'action=edit') );
+			var authortag = member.user.tag.escapeFormatting();
+			embed.addField( lang.get('verify.discord', ( authortag === discordname ? queryuser.gender : 'unknown' )), authortag, true ).addField( lang.get('verify.wiki', queryuser.gender), ( discordname || lang.get('verify.empty') ), true );
+			if ( authortag !== discordname ) {
+				embed.setColor('#FFFF00').setDescription( lang.get('verify.user_failed', member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
+				embed.addField( lang.get('verify.notice'), lang.get('verify.help_subpage', '**`' + member.user.tag + '`**', queryuser.gender) + '\n' + wiki.toLink('Special:MyPage/Discord', 'action=edit') );
 				result.content = lang.get('verify.user_failed_reply', username.escapeFormatting(), queryuser.gender);
 				result.content = lang.get('verify.user_failed_reply', username.escapeFormatting(), queryuser.gender);
 				return;
 				return;
 			}
 			}
@@ -258,31 +256,31 @@ function verify(lang, msg, username, wiki, rows, old_username = '') {
 					if ( row.rename ) rename = true;
 					if ( row.rename ) rename = true;
 					row.role.split('|').forEach( role => {
 					row.role.split('|').forEach( role => {
 						if ( !roles.includes( role ) ) {
 						if ( !roles.includes( role ) ) {
-							if ( msg.guild.roles.cache.has(role) && msg.guild.me.roles.highest.comparePositionTo(role) > 0 ) roles.push(role);
+							if ( channel.guild.roles.cache.has(role) && channel.guild.me.roles.highest.comparePositionTo(role) > 0 ) roles.push(role);
 							else if ( !missing.includes( role ) ) missing.push(role);
 							else if ( !missing.includes( role ) ) missing.push(role);
 						}
 						}
 					} );
 					} );
 				}
 				}
 			} );
 			} );
 			if ( verified ) {
 			if ( verified ) {
-				embed.setColor('#00FF00').setDescription( lang.get('verify.user_verified', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) + ( rename ? '\n' + lang.get('verify.user_renamed', queryuser.gender) : '' ) );
+				embed.setColor('#00FF00').setDescription( lang.get('verify.user_verified', member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) + ( rename ? '\n' + lang.get('verify.user_renamed', queryuser.gender) : '' ) );
 				var text = lang.get('verify.user_verified_reply', username.escapeFormatting(), queryuser.gender);
 				var text = lang.get('verify.user_verified_reply', username.escapeFormatting(), queryuser.gender);
 				var verify_promise = [
 				var verify_promise = [
-					msg.member.roles.add( roles, lang.get('verify.audit_reason', username) ).catch( error => {
+					member.roles.add( roles, lang.get('verify.audit_reason', username) ).catch( error => {
 						log_error(error);
 						log_error(error);
 						embed.setColor('#008800');
 						embed.setColor('#008800');
 						comment.push(lang.get('verify.failed_roles'));
 						comment.push(lang.get('verify.failed_roles'));
 					} )
 					} )
 				];
 				];
 				if ( rename ) {
 				if ( rename ) {
-					verify_promise.push(msg.member.setNickname( username.substring(0, 32), lang.get('verify.audit_reason', username) ).catch( error => {
+					verify_promise.push(member.setNickname( username.substring(0, 32), lang.get('verify.audit_reason', username) ).catch( error => {
 						log_error(error);
 						log_error(error);
 						embed.setColor('#008800');
 						embed.setColor('#008800');
 						comment.push(lang.get('verify.failed_rename', queryuser.gender));
 						comment.push(lang.get('verify.failed_rename', queryuser.gender));
 					} ));
 					} ));
 				}
 				}
 				return Promise.all(verify_promise).finally( () => {
 				return Promise.all(verify_promise).finally( () => {
-					if ( msg.showEmbed() ) {
+					if ( channel.permissionsFor(channel.guild.me).has('EMBED_LINKS') ) {
 						if ( roles.length ) embed.addField( lang.get('verify.qualified'), roles.map( role => '<@&' + role + '>' ).join('\n') );
 						if ( roles.length ) embed.addField( lang.get('verify.qualified'), roles.map( role => '<@&' + role + '>' ).join('\n') );
 						if ( missing.length ) embed.setColor('#008800').addField( lang.get('verify.qualified_error'), missing.map( role => '<@&' + role + '>' ).join('\n') );
 						if ( missing.length ) embed.setColor('#008800').addField( lang.get('verify.qualified_error'), missing.map( role => '<@&' + role + '>' ).join('\n') );
 						if ( comment.length ) embed.setColor('#008800').addField( lang.get('verify.notice'), comment.join('\n') );
 						if ( comment.length ) embed.setColor('#008800').addField( lang.get('verify.notice'), comment.join('\n') );
@@ -293,26 +291,23 @@ function verify(lang, msg, username, wiki, rows, old_username = '') {
 						if ( comment.length ) text += '\n\n' + comment.join('\n');
 						if ( comment.length ) text += '\n\n' + comment.join('\n');
 					}
 					}
 					result.content = text;
 					result.content = text;
-					result.options.split = true;
 				} );
 				} );
 			}
 			}
 			
 			
-			embed.setColor('#FFFF00').setDescription( lang.get('verify.user_matches', msg.member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
+			embed.setColor('#FFFF00').setDescription( lang.get('verify.user_matches', member.toString(), '[' + username.escapeFormatting() + '](' + pagelink + ')', queryuser.gender) );
 			result.content = lang.get('verify.user_matches_reply', username.escapeFormatting(), queryuser.gender);
 			result.content = lang.get('verify.user_matches_reply', username.escapeFormatting(), queryuser.gender);
 		}, error => {
 		}, error => {
 			console.log( '- Error while getting the Discord tag: ' + error );
 			console.log( '- Error while getting the Discord tag: ' + error );
 			embed.setColor('#000000').setDescription( lang.get('verify.error') );
 			embed.setColor('#000000').setDescription( lang.get('verify.error') );
 			result.content = lang.get('verify.error_reply');
 			result.content = lang.get('verify.error_reply');
-			result.reaction = 'error';
 		} );
 		} );
 	}, error => {
 	}, error => {
 		console.log( '- Error while getting the user: ' + error );
 		console.log( '- Error while getting the user: ' + error );
 		embed.setColor('#000000').setDescription( lang.get('verify.error') );
 		embed.setColor('#000000').setDescription( lang.get('verify.error') );
 		result.content = lang.get('verify.error_reply');
 		result.content = lang.get('verify.error_reply');
-		result.reaction = 'error';
 	} ).then( () => {
 	} ).then( () => {
 		return result;
 		return result;
 	} );
 	} );
 }
 }
 
 
-module.exports = verify;
+module.exports = verify;

+ 3 - 1
i18n/en.json

@@ -393,7 +393,9 @@
     },
     },
     "interaction": {
     "interaction": {
         "inline": "Please provide some text with [[wikitext]] links to use this command.",
         "inline": "Please provide some text with [[wikitext]] links to use this command.",
-        "missingrole": "You need to have the $1 role or any higher one to use this command."
+        "missingrole": "You need to have the $1 role or any higher one to use this command.",
+        "nowiki": "The used wiki doesn't exist!",
+        "verify": "Please provide your wiki username to use this command to verify your Discord account with your wiki account and get roles matching your wiki account."
     },
     },
     "invite": {
     "invite": {
         "bot": "Use this link to invite me to another server:"
         "bot": "Use this link to invite me to another server:"

+ 14 - 0
interactions/commands.json

@@ -2,6 +2,7 @@
 	{
 	{
 		"name": "inline",
 		"name": "inline",
 		"description": "Post a message with inline wiki links.",
 		"description": "Post a message with inline wiki links.",
+		"default_permission": true,
 		"options": [
 		"options": [
 			{
 			{
 				"type": 3,
 				"type": 3,
@@ -10,5 +11,18 @@
 				"required": true
 				"required": true
 			}
 			}
 		]
 		]
+	},
+	{
+		"name": "verify",
+		"description": "Verify your Discord account with your wiki account.",
+		"default_permission": false,
+		"options": [
+			{
+				"type": 3,
+				"name": "username",
+				"description": "Your username on the wiki.",
+				"required": true
+			}
+		]
 	}
 	}
 ]
 ]

+ 1 - 17
interactions/inline.js

@@ -1,6 +1,6 @@
 const logging = require('../util/logging.js');
 const logging = require('../util/logging.js');
 const Wiki = require('../util/wiki.js');
 const Wiki = require('../util/wiki.js');
-const {limitLength, partialURIdecode, allowDelete} = require('../util/functions.js');
+const {limitLength, partialURIdecode, sendMessage} = require('../util/functions.js');
 
 
 /**
 /**
  * Post a message with inline wiki links.
  * Post a message with inline wiki links.
@@ -284,22 +284,6 @@ function slash_inline(interaction, lang, wiki, channel) {
 	}, log_error );
 	}, log_error );
 }
 }
 
 
-/**
- * Sends an interaction response.
- * @param {Object} interaction - The interaction.
- * @param {Object} message - The message.
- * @param {String} message.content - The message content.
- * @param {{parse: String[], roles?: String[]}} message.allowed_mentions - The allowed mentions.
- * @param {import('discord.js').TextChannel} [channel] - The channel for the interaction.
- */
-function sendMessage(interaction, message, channel) {
-	return interaction.client.api.webhooks(interaction.application_id, interaction.token).messages('@original').patch( {
-		data: message
-	} ).then( msg => {
-		if ( channel ) allowDelete(channel.messages.add(msg), ( interaction.member?.user.id || interaction.user.id ));
-	}, log_error );
-}
-
 module.exports = {
 module.exports = {
 	name: 'inline',
 	name: 'inline',
 	run: slash_inline
 	run: slash_inline

+ 118 - 0
interactions/verify.js

@@ -0,0 +1,118 @@
+var db = require('../util/database.js');
+var verify = require('../functions/verify.js');
+const {sendMessage} = require('../util/functions.js');
+
+/**
+ * Post a message with inline wiki links.
+ * @param {Object} interaction - The interaction.
+ * @param {import('discord.js').Client} interaction.client - The client of the interaction.
+ * @param {import('../util/i18n.js')} lang - The user language.
+ * @param {import('../util/wiki.js')} wiki - The wiki for the interaction.
+ * @param {import('discord.js').TextChannel} [channel] - The channel for the interaction.
+ */
+function slash_verify(interaction, lang, wiki, channel) {
+	var reply = '<@' + ( interaction.member?.nick ? '!' : '' ) + interaction.user.id + '>, ';
+	var allowed_mentions = {
+		users: [interaction.user.id]
+	};
+	if ( !channel?.guild ) return interaction.client.api.interactions(interaction.id, interaction.token).callback.post( {
+		data: {
+			type: 4,
+			data: {
+				content: reply + lang.get('verify.missing'),
+				allowed_mentions,
+				flags: 64
+			}
+		}
+	} ).catch(log_error);
+	if ( !channel.guild.me.permissions.has('MANAGE_ROLES') ) {
+		console.log( channel.guild.id + ': Missing permissions - MANAGE_ROLES' );
+		return interaction.client.api.interactions(interaction.id, interaction.token).callback.post( {
+			data: {
+				type: 4,
+				data: {
+					content: reply + lang.get('general.missingperm') + ' `MANAGE_ROLES`',
+					allowed_mentions,
+					flags: 64
+				}
+			}
+		} ).catch(log_error);
+	}
+	
+	return interaction.client.api.interactions(interaction.id, interaction.token).callback.post( {
+		data: {
+			type: 5,
+			data: {
+				allowed_mentions,
+				flags: 0
+			}
+		}
+	} ).then( () => {
+		return db.query( 'SELECT role, editcount, postcount, usergroup, accountage, rename FROM verification WHERE guild = $1 AND channel LIKE $2 ORDER BY configid ASC', [interaction.guild_id, '%|' + interaction.channel_id + '|%'] ).then( ({rows}) => {
+			if ( !rows.length ) return sendMessage(interaction, {
+				content: reply + lang.get('verify.missing') + ( (interaction.member.permissions & 1 << 5) === 1 << 5 ? '\n' + new URL(`/guild/${interaction.guild_id}/verification`, process.env.dashboard).href : '' ), // MANAGE_GUILD
+				allowed_mentions
+			}, channel);
+			
+			return channel.guild.members.fetch(interaction.user.id).then( member => {
+				var username = ( interaction.data.options?.[0]?.value || '' ).replace( /^\s*<@!?(\d+)>\s*$/, (mention, id) => {
+					if ( id === interaction.user.id ) {
+						return ( interaction.member?.nick || interaction.user.username );
+					}
+					let user = channel.guild.members.cache.get(id);
+					if ( user ) return user.displayName;
+					else {
+						user = interaction.client.users.cache.get(user);
+						if ( user ) return user.username;
+					}
+				} ).replace( /_/g, ' ' ).trim().replace( /^<\s*(.*)\s*>$/, '$1' ).split('#')[0].substring(0, 250).trim();
+				if ( /^(?:https?:)?\/\/([a-z\d-]{1,50})\.(?:gamepedia\.com\/|(?:fandom\.com|wikia\.org)\/(?:[a-z-]{1,8}\/)?(?:wiki\/)?)/.test(username) ) {
+					username = decodeURIComponent( username.replace( /^(?:https?:)?\/\/([a-z\d-]{1,50})\.(?:gamepedia\.com\/|(?:fandom\.com|wikia\.org)\/(?:[a-z-]{1,8}\/)?(?:wiki\/)?)/, '' ) );
+				}
+				if ( wiki.isGamepedia() ) username = username.replace( /^userprofile\s*:\s*/i, '' );
+				
+				if ( !username.trim() ) return sendMessage(interaction, {
+					content: lang.get('interaction.verify'),
+					allowed_mentions
+				}, channel);
+
+				return verify(lang, channel, member, username, wiki, rows).then( result => {
+					var message = {
+						content: reply + result.content,
+						embeds: [result.embed],
+						allowed_mentions
+					};
+					if ( result.reaction ) {
+						if ( result.reaction === 'nowiki' ) message.content = lang.get('interaction.nowiki');
+						else message.content = reply + lang.get('verify.error_reply');
+						message.embeds = [];
+					}
+					return sendMessage(interaction, message, channel);
+				}, error => {
+					console.log( '- Error during the verifications: ' + error );
+					return sendMessage(interaction, {
+						content: reply + lang.get('verify.error_reply'),
+						allowed_mentions
+					}, channel);
+				} );
+			}, error => {
+				console.log( '- Error while getting the member: ' + error );
+				return sendMessage(interaction, {
+					content: reply + lang.get('verify.error_reply'),
+					allowed_mentions
+				}, channel);
+			} );
+		}, dberror => {
+			console.log( '- Error while getting the verifications: ' + dberror );
+			return sendMessage(interaction, {
+				content: reply + lang.get('verify.error_reply'),
+				allowed_mentions
+			}, channel);
+		} );
+	}, log_error );
+}
+
+module.exports = {
+	name: 'verify',
+	run: slash_verify
+};

+ 22 - 3
util/functions.js

@@ -165,7 +165,7 @@ function htmlToPlain(html) {
 		ontext: (htmltext) => {
 		ontext: (htmltext) => {
 			if ( !ignoredTag ) {
 			if ( !ignoredTag ) {
 				htmltext = htmltext.replace( /[\r\n\t ]+/g, ' ' );
 				htmltext = htmltext.replace( /[\r\n\t ]+/g, ' ' );
-				if ( text.endsWith( ' ' ) && htmltext.startsWith( ' ' ) ) htmltext = htmltext.replace( /^ +/, '' );
+				if ( /[\n ]$/.test(text) && htmltext.startsWith( ' ' ) ) htmltext = htmltext.replace( /^ +/, '' );
 				text += escapeFormatting(htmltext);
 				text += escapeFormatting(htmltext);
 			}
 			}
 		},
 		},
@@ -309,7 +309,9 @@ function htmlToDiscord(html, pagelink = '', ...escapeArgs) {
 				if ( code ) text += htmltext.replace( /`/g, 'ˋ' );
 				if ( code ) text += htmltext.replace( /`/g, 'ˋ' );
 				else {
 				else {
 					htmltext = htmltext.replace( /[\r\n\t ]+/g, ' ' );
 					htmltext = htmltext.replace( /[\r\n\t ]+/g, ' ' );
-					if ( text.endsWith( ' ' ) && htmltext.startsWith( ' ' ) ) htmltext = htmltext.replace( /^ +/, '' );
+					if ( /[\n ]$/.test(text) && htmltext.startsWith( ' ' ) ) {
+						htmltext = htmltext.replace( /^ +/, '' );
+					}
 					text += escapeFormatting(htmltext, ...escapeArgs);
 					text += escapeFormatting(htmltext, ...escapeArgs);
 				}
 				}
 			}
 			}
@@ -429,6 +431,22 @@ function allowDelete(msg, author) {
 	} );
 	} );
 };
 };
 
 
+/**
+ * Sends an interaction response.
+ * @param {Object} interaction - The interaction.
+ * @param {Object} message - The message.
+ * @param {String} message.content - The message content.
+ * @param {{parse: String[], roles?: String[]}} message.allowed_mentions - The allowed mentions.
+ * @param {import('discord.js').TextChannel} [channel] - The channel for the interaction.
+ */
+function sendMessage(interaction, message, channel) {
+	return interaction.client.api.webhooks(interaction.application_id, interaction.token).messages('@original').patch( {
+		data: message
+	} ).then( msg => {
+		if ( channel ) allowDelete(channel.messages.add(msg), ( interaction.member?.user.id || interaction.user.id ));
+	}, log_error );
+};
+
 module.exports = {
 module.exports = {
 	got,
 	got,
 	parse_infobox,
 	parse_infobox,
@@ -440,5 +458,6 @@ module.exports = {
 	escapeFormatting,
 	escapeFormatting,
 	limitLength,
 	limitLength,
 	partialURIdecode,
 	partialURIdecode,
-	allowDelete
+	allowDelete,
+	sendMessage
 };
 };