#[SOLVED] Add a default team for new User and adding verified role for verified email account
148 messages · Page 1 of 1 (latest)
You'll need to create two functions.
- On user create
- On user verified
If you look here
https://appwrite.io/docs/functions#functionVariables
You can see the list of all the variables that can be sent to your function.
Additionally, you can add custom variables like APPWRITE_FUNCTION_PROJECT_ID for example in your function Settings page.
What is the function api key ?
When accessing Appwrite
You can do it in one of two ways:
- Server side
- Client side
https://appwrite.io/docs/sdks
In function you'll usaully use the Server side.
The server side has much more capabilities and no rate-limit on number of requests.
But, for that you'll need to create an Api key in the project overview page.
https://appwrite.io/docs/keys
Okay I understand the benefit of using server side against client side. So I have to create an API KEY with Function permissions right ? Like this ?
In your case you'll need the Auth one.
As you want the function to have access to some Auth functions.
Okay well only Auth ?
Seems like it, yes.
Probably a stupid question but there is a way to try locally the function ? I guess I dont have to deploy the function each time right ?
For now, there's no direct way.
You can upvote this one
https://github.com/appwrite/appwrite/issues/5425
What I'm doing is creating a file named local-server and run it each time with mocked variables, etc.
Okay np but I guess my function will be very simple so
Well something like that should work (for the function who add the default Team for new user) ?
module.exports = async function (req, res) {
const client = new sdk.Client();
const teams = new sdk.Teams(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 teamId = 'APPWRITE_FUNCTION_TEAM_ID';
const user = JSON.parse(req.variables["APPWRITE_FUNCTION_EVENT_DATA"]);
try {
await teams.createTeamMember(teamId, user.$id, ['MEMBER']);
res.json({ success: `User ${userId} added to the team successfully` });
} catch (error) {
console.error('Error adding user to the team:', error);
res.json({ error: 'Error adding user to the team' });
}
};
But do I have to add the MEMBER rôle ? Or I can leave blank ?
I think the function name is createMembership instead of createTeamMember, like so:
const r = await teams.createMembership(teamID, email, [], 'url');
You can leave it empty
If I got that :
await teams.createMembership(teamId, user.$id, [], 'url');
How Appwrite gonna know if user.$id its an email or an id ? How can I gave him the two like that :
await teams.createMembership(teamId, user.email, user.$id, [], 'url');
Oh, you're right
You'll need to use the email
But you have it
So just like this
await teams.createMembership(teamId, user.email, [], 'url');
but I have to add the id no ?
Appwrite gonna make the link between email and the corresponding user id ?
Yes
But I can add the user id anyway no (to be sure ahah) ?
The order is a bit different
Check here
https://github.com/appwrite/appwrite/issues/5676
This is the function declaration.
createMembership(teamId: string, email: string, roles: string[], url: string, name?: string):
You don't even have the userId field over there.
okay strange. So Im gonna try without
There is a way to delete a function with APpwrite CLI ?
delete from the console?
I delete a function directly from the web ui of Appwrite but still on my console (on my laptop)
Yes,
But you mean that is still in your console
After you have deleted it?
I delete on the APpwrite Web UI. So the solution its go to appwrite.json and delete manually the section of the function
Okay
In the folder of your appwrite.json run
appwrite functions delete --functionId FUNCTION_ID
ohh that what I was looking for
Now I add the user verified function so I just have to add the 'verified' role right ? Like this
module.exports = async function (req, res) {
const client = new sdk.Client();
const teams = new sdk.Teams(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 teamId = req.variables["APPWRITE_FUNCTION_TEAM_ID"];
const user = JSON.parse(req.variables["APPWRITE_FUNCTION_EVENT_DATA"]);
if (!user.emailVerification) {
try {
await teams.createMembership(teamId, user.email, ['verified'], 'url');
res.json({ success: `User ${user.name} added to the Verified Role successfully` });
} catch (error) {
console.error('Error adding user to the role:', error);
res.json({ error: 'Error adding user to the role' });
}
}
};
Something wrong. When I add this update event :
users.*.verifications.*.update
I got that :
Set events like so
"events" : [
"users.*.verifications.*.update"
]
The users.*.verification.*.update returns a Token Object https://appwrite.io/docs/models/token so you need to get the user other way.
Also, you'll need to get the current user membershipId.
And you'll need to use the updateMembershipRoles function.
So in this function you'll need to something like this.
module.exports = async function(req, res) {
const client = new sdk.Client();
const teams = new sdk.Teams(client);
const users = new sdk.Users(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 teamId = req.variables['APPWRITE_FUNCTION_TEAM_ID'];
// Getting Token
const token = JSON.parse(req.variables['APPWRITE_FUNCTION_EVENT_DATA']);
// Getting user
const user = await users.get(token.userId);
if (user.emailVerification) {
try {
// Getting membership
const members = teams.listMemberships(teamId, [
Query.equal('userId', user.$id)
]);
// We have members? we can have only one as we are searching by user ID.
if (members.total === 1) {
await teams.updateMembershipRoles(teamId, members.memberships[0].$id, ['verified'], 'url');
res.json({ success: `User ${user.name} added to the Verified Role successfully` });
} else {
throw 'Error looking for a membership user.';
}
} catch (error) {
console.error('Error adding user to the role:', error);
res.json({ error: 'Error adding user to the role' });
}
}
};
Also make sure to check this #1109179801572483214 message
but when i try this i got an error :
Try to set it in the appwrite.json file, inside the events property, and depoly it
I got same error in console when appwrite deploy function :
Invalid events: Value must a valid array and Event is not valid.
Can you share the function events part?
{
"runtime": "node-16.0",
"path": "functions/sendWelcomeEmail",
"entrypoint": "src/index.js",
"ignore": [
"node_modules",
".npm"
],
"execute": [],
"events": [
],
"schedule": "",
"timeout": 15
},
{
"$id": "648c8c94bb9519a5a931",
"name": "user_verified",
"runtime": "node-16.0",
"path": "functions/user_verified",
"entrypoint": "src/index.js",
"ignore": [
"node_modules",
".npm"
],
"execute": [],
"events": [
"users.*.verifications.*.update"
],
"schedule": "",
"timeout": 15
},
{
"$id": "648c8cc7c167b6743da6",
"name": "user_created",
"runtime": "node-16.0",
"path": "functions/user_created",
"entrypoint": "src/index.js",
"ignore": [
"node_modules",
".npm"
],
"execute": [],
"events": [
"users.*.create"
],
"schedule": "",
"timeout": 15
}
But its working for user_created
I think maybe because it should be users.*.verification.*.update in single
What do u mean ? like not an array ?
without the s
DAMN ahah sryy
If I try to manually verify an account (with Web UI) like that. Do the function gonna be launched ?
BEcause there is no execution
I'm not sure
But looks like it should
Have you gave it a try?
Sorry,
I see that it won't propagate any events, as this will use the Users SDK.
When using the client Account SDK then you can see the events being sent
https://github.com/appwrite/appwrite/blob/master/app/controllers/api/account.php#L2382
The Users one on the other side just change the value in the DB
https://github.com/appwrite/appwrite/blob/master/app/controllers/api/users.php#L959
Okay Im gonna chck that. For the function 'user_created', she's executed but there is a problem with this line :
await teams.createMembership(teamId, user.email, [], 'url');
Because ive got this error :
Error adding user to the team
Change to this, so we can get the full error
} catch (error) {
console.error(error);
console.error('Error adding user to the team:');
res.json({ error: 'Error adding user to the team' });
}
Maybe the user is already in the team.
well my appwrite instance crash ahah idk why
Oh, is not accessible?
Even after rebooting my VPS, is completely down
Mmmm
Maybe your Docker doesn't start automatically
Run
docker compose ls
And share the results
ive run docker container ls -a
Now i try to restart all container
During restarting ive got this error :
Error response from daemon: Cannot restart container eebd9cccf2b8: driver failed programming external connectivity on endpoint appwrite-traefik (9e3dfc5d02a57100f1cbc18dc26012d2dc17b097aa993a6fe69678a91eea8317): Bind for 0.0.0.0:443 failed: port is already allocated
And the docker compose ls command :
root@localhost:~# docker compose ls
NAME STATUS CONFIG FILES
appwrite running(18) /usr/src/code/appwrite/docker-compose.yml
Maybe you have Nginx/Apache on the server the uses port 443?
Because port 443 is in-use then traefik cannot start.
Mhh Nginx dont seems to be installed
Run this, what you get?
ss -tulpn | grep :443
Yeah I try this to see what use the 443 port but its seems to be docker
But no container use thze 443 port
Can you try to restart docker?
service docker restart
Ohh its fix !
really thx for ur help !
Happily
btw when Appwrite crash, my function crash too
I just wanted some advice. I saw that APpwrite offered a Cloud option in Beta, which may be easier. For now I have a VPS with these specs (Ive take the minimum for the development):
CPU :1 vCore
RAM :0.5 Go
SSD :10 Go
Idk what do I need for my app
I'm afraid that the 512mb of RAM will hold your Appwrite back, specially when running functions.
Appwrite itself recommend having at least 2GB or RAM, https://appwrite.io/docs/self-hosting
I my self, got really good results with a 1 vcpu 1 gm ram 25 ssd, so maybe this could be a good start for your project.
P.s. at https://www.hetzner.com/cloud you can get really good servers for less the most providers.
And, in many use-cases Appwrite cloud will be the best solution.
We cant know the power of APpwrite cloud right ?
I mean specs for each isntance
Like that ?
Appwrite cloud uses Docker Swarm (on DigitalOcean) for their stack deployment,
This means that there's no way to know, and even more it's irrelevant, as in Docker Swarm the power is shared among the server in the load balancers.
Okay I just ask because I dont know the good way to launch an app ahah (im student) so if paying a VPS is the best option, Im gonna take a vps
Do you have estimation of your monthly user and usages?
Gotcha
I would recommend you start with CX11 - intel
No idea ahah its a simple movie app and i dont really know if people would be interested
what the difference with Arm64 ?
If you're using only docker compose then you can go with arm64
Sometime when wanting to expand it can get difficult.
Like expand in which way ?
I don't anything on mind right now,
For example
If you want to integrate some software on the server that has only x64
Well this is the first time I've developed an app, I don't necessarily know the possible improvements. But I would tend to say to have only one server for appwrite. And if I need other software or application, I would rent another server, right?
Right now the arm server are way more cheaper than the x86
Yes, that sounds right.
Yes, you can try and go ahead with it.
Finally I have just inquired and the x86 cores are more efficient and powerful than the arm so the number of cores does not mean much I believe
There is estimation price of Appwrite Cloud ? Because if is cheaper or evne little expensive, maybe is the best because power adapts to consumption, right?
Check this: #🌩│cloud message
Im gonna check that ty
Well about my user_created function, ive made a stupid error :
{"error":{"code":400,"type":"general_argument_invalid","response":{"message":"Invalid url: URL host must be one of: localhost, appwrite.nvlab.fr, *.vercel.app","code":400,"type":"general_argument_invalid","version":"1.2.0"}}}
Which url do I have to add :
await teams.createMembership(teamId, user.email, [], 'url');
I dont really understand why an url is needed
I agree - https://github.com/appwrite/appwrite/issues/5675
For now just put your server URL appwrite.nvlab.fr
await teams.createMembership(teamId, user.email, [], 'appwrite.nvlab.fr');
ahah my vps is too slow. Each time function is launched almost crash
Weird, ive got the same error :
{"error":{"code":400,"type":"general_argument_invalid","response":{"message":"Invalid url: URL host must be one of: localhost, appwrite.nvlab.fr, *.vercel.app","code":400,"type":"general_argument_invalid","version":"1.2.0"}}}
BUt i have this code
try {
await teams.createMembership(teamId, user.email, [], 'appwrite.nvlab.fr');
res.json({ success: `User ${user.name} added to the team successfully` });
} catch (error) {
console.error('Error adding user to the team:', error);
res.json({ error: 'Error adding user to the team', error: error});
}
Yes, you'll need to upgrade your server.
Where do you run this code? In a function?
Its in the log of the function
ohh i find !
we have to add 'https://'
like that
try {
await teams.createMembership(teamId, user.email, [], 'https://appwrite.nvlab.fr');
res.json({ success: `User ${user.name} added to the team successfully` });
} catch (error) {
console.error('Error adding user to the team:', error);
res.json({ error: 'Error adding user to the team', error: error});
}
nonoooo
well the function user_created work !
now i have to see if the verified one work too
Cool
I have to find a way to launch the users..verification..update event
Mmm, meaning to do trigger it manually?
yeah
Because idk yet how add an email verification with smtp provider etc...
And I assume you didn't set SMTP, so you can fully test it?
Besides, what the best option for email sending ? Sendgrid ?
SendGrid or https://www.brevo.com/pricing/
Bravo gives 300/Free/Daily
So either you can configure one of those options.
Or
You'll need to do it manually like so:
Create Another function, make it trigger on users.*.verification.*.create, this will run when a verification token is created. log the token.
Using this method https://appwrite.io/docs/client/account?sdk=web-default#accountCreateVerification
Create the verification token.
Now, use the token you have logged and use the 2-step of the verification process https://appwrite.io/docs/client/account?sdk=web-default#accountUpdateVerification
Like so
await account.updateVerification('[USER_ID]', '[SECRET]');
Remember that you'll need to login the user before running any one of those two function.
Now you will trigger the users.*.verification.*.update