Mhh for example soundcloud, when u signup with Google, soundcloud choose a username considering ur name
I guess there is no function trigger event when someone logs with OAuth?
Twitter too do that like create a default username
It depends on the app/system. Some apps have usernames, while others rely on email. Appwrite mostly uses emails, especially for oauth
If I make a function triggered by user.*.create
Inside I check if a document in the user
collection (where extra user data are) exist with the userId just created. If yes (signup with email), return. If not (signup with OAuth), create a default username based on the Name
Well I try to create a function which for the moment only check if a document with the userId of the user just created exist :
const sdk = require("node-appwrite");
module.exports = async function (req, res) {
const client = new sdk.Client();
const account = new sdk.Account(client);
const avatars = new sdk.Avatars(client);
const database = new sdk.Databases(client);
const functions = new sdk.Functions(client);
const health = new sdk.Health(client);
const locale = new sdk.Locale(client);
const storage = new sdk.Storage(client);
const teams = new sdk.Teams(client);
const users = new sdk.Users(client);
const query = new sdk.Query();
if (
!req.variables['APPWRITE_FUNCTION_ENDPOINT'] ||
!req.variables['APPWRITE_FUNCTION_API_KEY']
) {
console.warn("Environment variables are not set. Function cannot use Appwrite SDK.");
} else {
client
.setEndpoint(req.variables['APPWRITE_FUNCTION_ENDPOINT'])
.setProject(req.variables['APPWRITE_FUNCTION_PROJECT_ID'])
.setKey(req.variables['APPWRITE_FUNCTION_API_KEY'])
.setSelfSigned(true);
}
const user = JSON.parse(req.variables['APPWRITE_FUNCTION_DATA'])
async function checkSignupType(id, databaseId, collectionId) {
try {
await database.getDocument(req.variables["APPWRITE_FUNCTION_DATABASE_ID"], req.variables["APPWRITE_FUNCTION_COLLECTION_ID"], id);
return true
} catch (error) {
console.error("Error checking signup type:", error);
return false;
}
}
// const userDocuments = await database.getDocument(req.variables["APPWRITE_FUNCTION_DATABASE_ID"], req.variables["APPWRITE_FUNCTION_COLLECTION_ID"], user.$id);
const userDocuments = await checkSignupType(user.$id);
console.log("userDocuments", userDocuments)
};
But Ive got a function error : An internal curl error has occurred within the executor! Error Msg: Operation timed out
But if I replace this line:
const userDocuments = await checkSignupType(user.$id);
By :
const userDocuments = await database.getDocument(req.variables["APPWRITE_FUNCTION_DATABASE_ID"]
Ive this output :
Error: Document with the requested ID could not be found.
But without the console.log
You must call res.json() or res.send() once before returning
Ohh yes mb that work. In Appwrite Function when we made a return even if its true or false, the function stop ? Because the console.log never read so these returns in the checkSignupType
function stop the Appwrite function
No. The function needs to complete successfully for you to see the logs
That weird because Ive this :
async function checkSignupType(id) {
try {
await database.getDocument(req.variables["APPWRITE_FUNCTION_DATABASE_ID"], req.variables["APPWRITE_FUNCTION_COLLECTION_ID"], id);
console.log('Email')
res.json()
return false
} catch (error) {
console.log('OAuth')
res.json()
return true;
}
}
const isOAuth = await checkSignupType(user.$id);
console.log("isOAuth", isOAuth)
And in the function logs I can see the console.log('OAuth')
and the console.log('Email')
but not the last one
Create Appwrite function to add username when OAuth signup
wait when signup with OAuth the user.*.create isnt triggered ?
Known issue: https://github.com/appwrite/appwrite/issues/2406
You should probably call res.json last. You should also be passing an object to it
ohh okay sry
Okay I didn't understand that the function stops when res.json is called. Its working !
Well I success to make username generator function for OAuth signups, based on username; there is the code <:appwriterocket:823996226894692403> :
const sdk = require("node-appwrite");
module.exports = async function (req, res) {
const client = new sdk.Client();
const database = new sdk.Databases(client);
if (
!req.variables['APPWRITE_FUNCTION_ENDPOINT'] ||
!req.variables['APPWRITE_FUNCTION_API_KEY']
) {
console.warn("Environment variables are not set. Function cannot use Appwrite SDK.");
} else {
client
.setEndpoint(req.variables['APPWRITE_FUNCTION_ENDPOINT'])
.setProject(req.variables['APPWRITE_FUNCTION_PROJECT_ID'])
.setKey(req.variables['APPWRITE_FUNCTION_API_KEY'])
.setSelfSigned(true);
}
const user = JSON.parse(req.variables['APPWRITE_FUNCTION_EVENT_DATA'])
async function handleIsOAuth(id) {
try {
await database.getDocument(req.variables["APPWRITE_FUNCTION_DATABASE_ID"], req.variables["APPWRITE_FUNCTION_COLLECTION_ID"], id);
console.log('User already has a username')
res.json({ message: 'User already has a username' })
return false
} catch (error) {
console.log('User has no username')
return true
}
}
async function generateUniqueUsername(name, id, attempt = 1) {
if (attempt > 5) {
console.log('Unable to generate a unique username.')
return id
}
let username = name.toLowerCase().replace(/[^A-Za-z0-9_]/g, "");
username = username.slice(0, 11)
username += Math.floor(Math.random() * Math.pow(10, (15 - username.length)));
const checkUsernameAvailability = await database.listDocuments(req.variables["APPWRITE_FUNCTION_DATABASE_ID"], req.variables["APPWRITE_FUNCTION_COLLECTION_ID"], [
sdk.Query.equal('username', username)
]);
if (checkUsernameAvailability.documents.length > 0) {
console.log('Username is already in use, generating a new one.')
return generateUniqueUsername(name, id, attempt + 1);
}
return username;
}
await handleIsOAuth(user.$id);
const username = await generateUniqueUsername(user.name, user.$id)
try {
await database.createDocument(req.variables["APPWRITE_FUNCTION_DATABASE_ID"], req.variables["APPWRITE_FUNCTION_COLLECTION_ID"], user.$id, {
"userId": user.$id,
"username": username
})
res.json({ message: 'Username @' + username +' has been created successfully.'})
return
} catch (error) {
res.json({ error: 'Error creating user', error: error })
return
}
};
But for now I can't use it until the user.*.create event is triggered when creating a user via OAuth
You can trigger on create session and check if it's an oauth session and there's no document in your collection
I was thinking of doing this but I don't realize if it will require a lot of server power to check each session. I want to do some less energy intensive things at the server level so ... But if you think it's not a problem I would do that!
Well with the event user.*.sessions.*.create
we dont have a the user Name
You can make an API call for the user
Yeah I get all info with sdk.Users
[SOLVED] Create Appwrite function to add username when OAuth signup
Recommended threads
- Invalid document structure: missing requ...
I just pick up my code that's working a week ago, and now I got this error: ``` code: 400, type: 'document_invalid_structure', response: { message: 'Inv...
- custom domain with CloudFlare
Hi all, it seems that CloudFlare has blocked cross-domain CNAME link which made my app hostname which is in CloudFlare, unable to create a CNAME pointing to clo...
- Type Mismatch in AppwriteException
There is a discrepancy in the TypeScript type definitions for AppwriteException. The response property is defined as a string in the type definitions, but in pr...