public async Task CreateInviteAsync(string?shortcutName = null, int purpose = 1, DateTime?startDate = null,
                                            DateTime?endDate    = null)
        {
            await using var transaction = await _db.Database.BeginTransactionAsync();

            var template = _db.ContentTemplates.FirstOrDefault(x => x.ShortcutName == shortcutName);

            if (template == null)
            {
                return;
            }

            var user = await _db.Users.FirstOrDefaultAsync(x => x.DiscordId == Context.User.Id);

            if (user == null)
            {
                await ReplyAsync("You are not registered.");

                return;
            }

            var invite = new PartyInvite
            {
                UserId            = user.UserId,
                ContentTemplateId = template.ContentTemplateId,
                Purpose           = (Purpose)purpose,
                StartDate         = startDate ?? DateTime.Now,
                EndDate           = endDate
            };

            await _db.PartyInvites.AddAsync(invite);

            await _db.SaveChangesAsync();

            var inviteEmbed = new InviteEmbedWrapper
            {
                InviteId    = invite.PartyInviteId,
                ContentType = invite.ContentTemplate.ContentType.TypeName,
                ContentName = invite.ContentTemplate.GetQuestName(),
                Purpose     = invite.Purpose.DisplayName(),
                MaxPlayer   = invite.ContentTemplate.MaxPlayer,
                StartDate   = startDate,
                EndDate     = endDate,
                Inviter     = Context.User,
            };

            var inviteMessage = await ReplyAsync(embed : inviteEmbed.ToEmbed());

            var memberMessage = await ReplyAsync("参加者 \uD83D\uDCCC");

            invite.MessageId           = inviteMessage.Id;
            invite.MemberListMessageId = memberMessage.Id;
            _db.PartyInvites.Update(invite);
            await _db.SaveChangesAsync();

            await Context.Message.DeleteAsync();

            await transaction.CommitAsync();
        }
        public async Task FinishInviteAsync(int id)
        {
            await using var transaction = await _db.Database.BeginTransactionAsync();

            var invite = await _db.PartyInvites.FindAsync(id);

            if (invite == null)
            {
                return;
            }

            var message = await Context.Channel.GetMessageAsync(invite.MessageId) as IUserMessage;

            if (message?.Embeds.Any() != true)
            {
                return;
            }

            var inviter = await Context.Channel.GetUserAsync(invite.User.DiscordId);

            if (inviter == null)
            {
                return;
            }

            var embed       = message.Embeds.ToList()[0];
            var inviteEmbed = new InviteEmbedWrapper(embed.ToEmbedBuilder());

            invite.IsFinished = true;
            _db.PartyInvites.Update(invite);
            await _db.SaveChangesAsync();

            inviteEmbed.Title += "(終了)";

            await message.ModifyAsync(properties =>
            {
                properties.Embed = inviteEmbed.ToEmbed();
            });

            await transaction.CommitAsync();
        }