How to integrate Google login with your Discord.js bots
My open-source solution makes it easier than ever to allow your Discord bot’s users to sign in to Google, Spotify, and other platforms.
What if your Discord bot could add songs to Spotify playlists? Or access a user’s Google Calendar to schedule events?
While services like Google and Spotify give developers access to this kind of data, developers generally have to set up entire OAuth2 flows, which can be confusing and result in a bad experience for the end user.
Enter AuthConnect, a library designed specifically for Discord.js bots that makes OAuth2 integration super simple.
📝 Simplifies OAuth2: The entire flow, from getting permission from your users to getting a token to use for your requests, is handled for you.
💾 Built-in data storage solutions: AuthConnect provides built-in ways to store users’ authentication data, such as on-disk or in Firebase.
🌐 Fantastic user experience: All users have to do is click a link and accept the prompt. Everything else is handled between you and AuthConnect.
🔒Your data is safe: AuthConnect cannot make API requests on your behalf and cannot access your users’ data.
🔢 Multiple server support: Each server your bot’s in can have its set of accounts associated with it.
The Authentication Flow, Simplified
You call generateAuthURL() and show your users the link.
The user authorizes your app and is redirected to our landing page, which sends the result data to your server.
You call getAccessToken(); we refresh the token if it's expired then give it to your app.
You call an API with your access token!
Demo: Setting up Google login with AuthConnect
What better way to learn than by example? Here’s step-by-step instructions to use AuthConnect to get authorization from a user to access their Google data.
Set up a Google Cloud project
From the Google Cloud Console, create a new project.
Head to APIs & Services and click on the Credentials page. A credential is a set of keys that allows your program/server to interface with Google APIs.
Click on Create credentials, and select type OAuth Client ID. When prompted for an application type, choose Web application. Give your credential a friendly name.
Now, add the following as an authorized redirect URI, which will allow users to be redirected to the AuthConnect website that beams data back to your bot:
https://authconnect-djs.web.app/redir.htmlAll in all, your credential should look like this:
Once your credential is created, copy down the Client ID and Client Secret that you’re given. These values identify your app to Google so that no one else can impersonate you.
Finally, head to the Library tab of the Cloud Console, and enable whichever service you plan to call.
Adding the code
Now, all we need to do is add AuthConnect to our Discord project! Once you’ve gotten a Node project created and Discord.js installed, install AuthConnect:
npm install authconnect-djsNow, let’s start writing the code. First, let’s import our libraries:
import AuthConnect from "authconnect-djs";
import {Client, GatewayIntentBits} from "discord.js";Let’s define some constants. This is where you’ll paste your bot’s token and the values you got when you set up your Google Cloud credential.
Scopes define what your app is allowed to request; for example, a user might only authorize your bot to access their Youtube data and nothing else. Check out this page to see what scopes you’ll need, and paste them in the code, separating each scope with a space.
const DISCORD_TOKEN = "123_your_discord_token_456";
const GOOGLE_CLIENT_ID = "123_your_google_client_id_456";
const GOOGLE_CLIENT_SECRET = "123_your_google_client_secret_456";
const SCOPES_TO_REQUEST = "https://www.googleapis.com/auth/youtube";Now, let’s initialize our bot.
const bot = new Client({
intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.DirectMessages ],
partials: [ "CHANNEL" ]
});
let auth;
bot.login(DISCORD_TOKEN);Let’s give our bot an “on ready” callback, in which we will initialize our AuthConnect object. We’ll tell AuthConnect to store authentication data in a file, but you can also have it store data in Firebase or in your own server.
bot.on("ready", () => {
auth = new AuthConnect({
google: {
clientId: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET
}
});
auth.useDefaultDataHandlers("./auth-data.json");
console.log("Bot ready and AuthConnect initialized.")
});Now, let’s allow users to log in when they send a “login” command, only if they’re an admin. We’ll generate an auth URL and DM it to the admin.
bot.on("messageCreate", async message => {
if(message.guild !== null && message.content === "login" && message.member.permissions.has("ADMINISTRATOR")) {
const url = auth.generateAuthURL("google", message.guild.id, SCOPES_TO_REQUEST);
message.channel.send("Please check your DMs for a link to log in.");
message.member.send(`Please visit this URL to log in: ${url}`);
}
});Now that we have the user’s permission, AuthConnect will give us a token with which to send API requests. let’s make a request when the user tells us to, for example using the fetch function.
// this snippet goes inside the messageCreate callback:
// bot.on("messageCreate", async message => {
// code from previous snippet here
if(message.guild !== null && message.content === "call an API") {
if(await auth.isGuildLoggedIn("google", message.guild.id)) {
const token = await auth.getAccessToken("google", message.guild.id);
// You can use this token to call a Google API, such as this Youtube search endpoint:
/*
await fetch("https://www.googleapis.com/youtube/v3/search", {
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
}
});
*/
} else {
message.channel.send("This server is not logged in to Google. Have an administrator type `login`.");
}
}
// });Putting it all together
Your entire file should look like this:
import AuthConnect from "authconnect-djs";
import {Client, GatewayIntentBits} from "discord.js";
const DISCORD_TOKEN = "123_your_discord_token_456";
const GOOGLE_CLIENT_ID = "123_your_google_client_id_456";
const GOOGLE_CLIENT_SECRET = "123_your_google_client_secret_456";
// Replace this with the scopes you want to request: https://developers.google.com/identity/protocols/oauth2/scopes
const SCOPES_TO_REQUEST = "https://www.googleapis.com/auth/youtube";
const bot = new Client({
intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.DirectMessages ],
partials: [ "CHANNEL" ]
});
let auth;
bot.login(DISCORD_TOKEN);
bot.on("ready", () => {
auth = new AuthConnect({
google: {
clientId: GOOGLE_CLIENT_ID,
clientSecret: GOOGLE_CLIENT_SECRET
}
});
// This is where your auth data will be stored on disk.
auth.useDefaultDataHandlers("./auth-data.json");
console.log("Bot ready and AuthConnect initialized.")
});
bot.on("messageCreate", async message => {
if(message.guild !== null && message.content === "login" && message.member.permissions.has("ADMINISTRATOR")) {
const url = auth.generateAuthURL("google", message.guild.id, SCOPES_TO_REQUEST);
message.channel.send("Please check your DMs for a link to log in.");
message.member.send(`Please visit this URL to log in: ${url}`);
}
if(message.guild !== null && message.content === "call an API") {
if(await auth.isGuildLoggedIn("google", message.guild.id)) {
const token = await auth.getAccessToken("google", message.guild.id);
// You can use this token to call a Google API, such as this Youtube search endpoint:
/*
await fetch("https://www.googleapis.com/youtube/v3/search", {
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json",
}
});
*/
} else {
message.channel.send("This server is not logged in to Google. Have an administrator type `login`.");
}
}
});More about AuthConnect
You can view AuthConnect on Github! The library can do much more than what we’ve covered in our example. Check out the README for more detailed instructions.



