Mapping IDs for Discord OAuth
Hi, I am trying to map the user id to the profile id when returned from discord sign in. I want the discord ID to be the primary key and id for the user table. I have tried mapProfileToUser and it still generates a UUID. Any help would be appreciated. Here is my Auth.ts.
1 Reply
import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { nextCookies } from "better-auth/next-js";
import { prisma } from "@/utils/prisma";
interface Account {
    id: string;
    providerId: string;
    accountId: string;
    userId: string;
    createdAt: Date;
    updatedAt: Date;
    accessToken?: string | null;
    refreshToken?: string | null;
    scope?: string | null;
    idToken?: string | null;
    accessTokenExpiresAt?: Date | null;
    refreshTokenExpiresAt?: Date | null;
    password?: string | null;
}
export const auth = betterAuth({
    database: prismaAdapter(prisma, {
        provider: "postgresql",
    }),
    emailAndPassword: {
        enabled: false,
    },
    user: {
        additionalFields: {
            username: {
                type: "string",
                required: false,
            },
            nickname: {
                type: "string",
                required: false,
            }
        }
    },
    socialProviders: {
        discord: {
            clientId: process.env.AUTH_DISCORD_ID as string,
            clientSecret: process.env.AUTH_DISCORD_SECRET as string,
            scope: ["identify", "email", "guilds", "guilds.members.read"],
            prompt: "consent",
            mapProfileToUser: (profile) => {
                console.log(profile);
                return {
                    discordId: profile.id,
                    username: profile.username
                }
            }
        },
    },
    databaseHooks: {
        account: {
            create: {
                after: async (account) => {
                    await updateUserData(account);
                }
            },
            update: {
                after: async (account) => {
                    await updateUserData(account);
                }
            }
        }
    },
    plugins: [nextCookies()],
});
async function updateUserData(account:Account) {
    if (account.providerId === 'discord' && account.accessToken) {
        try {
            const guildId = process.env.GUILD_ID;
            const response = await fetch(`https://discord.com/api/users/@me/guilds/${guildId}/member`, {
                headers: {
                    'Authorization': `Bearer ${account.accessToken}`,
                    'Content-Type': 'application/json',
                }
            });
            const memberData = await response.json();
            console.log('Member data:', memberData);
            await prisma.user.update({
                where: {
                    id: account.userId,
                },
                data: {
                    nickname: memberData.nick,
                    username: memberData.username,
                    email: memberData.email,
                }
            });
        } catch (error) {
            console.error('Error fetching guild:', error);
        }
    } else {
        console.log('No guild ID or access token found for Discord provider.');
    }
}
import { betterAuth } from "better-auth";
import { prismaAdapter } from "better-auth/adapters/prisma";
import { nextCookies } from "better-auth/next-js";
import { prisma } from "@/utils/prisma";
interface Account {
    id: string;
    providerId: string;
    accountId: string;
    userId: string;
    createdAt: Date;
    updatedAt: Date;
    accessToken?: string | null;
    refreshToken?: string | null;
    scope?: string | null;
    idToken?: string | null;
    accessTokenExpiresAt?: Date | null;
    refreshTokenExpiresAt?: Date | null;
    password?: string | null;
}
export const auth = betterAuth({
    database: prismaAdapter(prisma, {
        provider: "postgresql",
    }),
    emailAndPassword: {
        enabled: false,
    },
    user: {
        additionalFields: {
            username: {
                type: "string",
                required: false,
            },
            nickname: {
                type: "string",
                required: false,
            }
        }
    },
    socialProviders: {
        discord: {
            clientId: process.env.AUTH_DISCORD_ID as string,
            clientSecret: process.env.AUTH_DISCORD_SECRET as string,
            scope: ["identify", "email", "guilds", "guilds.members.read"],
            prompt: "consent",
            mapProfileToUser: (profile) => {
                console.log(profile);
                return {
                    discordId: profile.id,
                    username: profile.username
                }
            }
        },
    },
    databaseHooks: {
        account: {
            create: {
                after: async (account) => {
                    await updateUserData(account);
                }
            },
            update: {
                after: async (account) => {
                    await updateUserData(account);
                }
            }
        }
    },
    plugins: [nextCookies()],
});
async function updateUserData(account:Account) {
    if (account.providerId === 'discord' && account.accessToken) {
        try {
            const guildId = process.env.GUILD_ID;
            const response = await fetch(`https://discord.com/api/users/@me/guilds/${guildId}/member`, {
                headers: {
                    'Authorization': `Bearer ${account.accessToken}`,
                    'Content-Type': 'application/json',
                }
            });
            const memberData = await response.json();
            console.log('Member data:', memberData);
            await prisma.user.update({
                where: {
                    id: account.userId,
                },
                data: {
                    nickname: memberData.nick,
                    username: memberData.username,
                    email: memberData.email,
                }
            });
        } catch (error) {
            console.error('Error fetching guild:', error);
        }
    } else {
        console.log('No guild ID or access token found for Discord provider.');
    }
}