memberConverter top-level property

Converter<Member> memberConverter
final

Converter to convert input to Members.

This uses multiple strategies to look up members, in the order below:

  • ID lookup (parse input as snowflake or mention)
  • Exact username match
  • Exact nickname match
  • Full case insensitive username match
  • Full case insensitive nickname match
  • Partial case insensitive username match (username starts with input)
  • Partial case insensitive nickname match (nickname starts with input)

Note that for all of these strategies, if multiple members match any condition then no results will be given based off of that condition.

Implementation

final Converter<Member> memberConverter = FallbackConverter<Member>([
  // Get member from mention or snowflake.
  CombineConverter<Snowflake, Member>(snowflakeConverter, (snowflake, context) async {
    if (context.guild != null) {
      Member? cached = context.guild!.members.asMap[snowflake];
      if (cached != null) {
        return cached;
      }

      try {
        return await context.guild!.fetchMember(snowflake);
      } on HttpResponseError {
        return null;
      }
    }
    return null;
  }),
  // Get member by name or nickname
  Converter<Member>((view, context) async {
    String word = view.getQuotedWord();

    if (context.guild != null) {
      Stream<Member> named = context.guild!.searchMembersGateway(word, limit: 800000);

      List<Member> usernameExact = [];
      List<Member> nickExact = [];

      List<Member> usernameCaseInsensitive = [];
      List<Member> nickCaseInsensitive = [];

      List<Member> usernameStart = [];
      List<Member> nickStart = [];

      await for (final member in named) {
        User user = await member.user.getOrDownload();

        if (user.username == word) {
          usernameExact.add(member);
        }
        if (user.username.toLowerCase() == word.toLowerCase()) {
          usernameCaseInsensitive.add(member);
        }
        if (user.username.toLowerCase().startsWith(word.toLowerCase())) {
          usernameStart.add(member);
        }

        if (member.nickname != null) {
          if (member.nickname! == word) {
            nickExact.add(member);
          }
          if (member.nickname!.toLowerCase() == word.toLowerCase()) {
            nickCaseInsensitive.add(member);
          }
          if (member.nickname!.toLowerCase().startsWith(word.toLowerCase())) {
            nickStart.add(member);
          }
        }
      }

      for (final list in [
        usernameExact,
        nickExact,
        usernameCaseInsensitive,
        nickCaseInsensitive,
        usernameStart,
        nickStart
      ]) {
        if (list.length == 1) {
          return list.first;
        }
      }
    }
    return null;
  }),
]);