I have a function with the following code. Its purpose is to delete old deployments and win back storage capacity (since there's no option in the Console that I know of... please point me towards it if there is one <3)
import {serverFunctions} from '#/functions/appwriteClient.ts';
import type {IFunctionContext} from '#/functions/models.ts';
import {Query} from 'node-appwrite';
export default async ({res}: IFunctionContext) => {
const functions = await serverFunctions.list();
const deletionPromises: Promise<object>[] = [];
console.log(`Found ${functions.total} functions. Deleting old deployments...`);
for (const function_ of functions.functions) {
const deploymentList = await serverFunctions.listDeployments(function_.$id, [Query.equal('activate', false)]);
const deletableDeployments = deploymentList.deployments
.map((deployment) => ({...deployment, $createdAt: new Date(deployment.$createdAt)}))
.sort((a, b) => {
const aSuccessful = a.status !== 'failed' ? 1 : 0;
const bSuccessful = b.status !== 'failed' ? 1 : 0;
if (!aSuccessful || !bSuccessful) {
return bSuccessful - aSuccessful;
}
return b.$createdAt.getTime() - a.$createdAt.getTime();
});
for (const deployment of deletableDeployments.slice(3)) {
console.log(`Deleting deployment ${deployment.$id} for function ${function_.$id}`);
deletionPromises.push(serverFunctions.deleteDeployment(function_.$id, deployment.$id));
}
}
await Promise.all(deletionPromises);
return res.empty();
};
However, when I try to execute the function, I always get this error:
AppwriteException: app.xxx@service.cloud.appwrite.io (role: applications) missing scope (functions.read)
at new AppwriteException (/usr/local/server/src/function/functions/node_modules/node-appwrite/dist/client.mjs:8:5)
at <anonymous> (/usr/local/server/src/function/functions/node_modules/node-appwrite/dist/client.mjs:294:17)
at processTicksAndRejections (:12:39)
The thing is... the function has that scope. In fact, I gave it all scopes just to test if something's missing...
It seems to already fail at serverFunctions.list() , since there are no other logs
can anyone help me? Is this a bug, or error on my side?
what region is the project in?
it's in FRA
hmm very odd...
can you log the api key and DM it to me?
it's dynamic, right?
so, unfortunately, after sending the key and everything, I never heard back from @Steven . Can anyone help me or will I need email support?
sorry i lost track of the issue. so the key has these scopes:
"sessions.write",
"users.read",
"users.write",
"teams.read",
"teams.write",
"databases.read",
"databases.write",
"collections.read",
"collections.write",
"attributes.read",
"attributes.write",
"indexes.read",
"indexes.write",
"documents.read",
"documents.write",
"files.read",
"files.write",
"buckets.read",
"buckets.write",
"functions.read",
"functions.write",
"execution.read",
"execution.write",
"targets.read",
"targets.write",
"providers.read",
"providers.write",
"messages.read",
"messages.write",
"topics.read",
"topics.write",
"subscribers.read",
"subscribers.write",
"locale.read",
"avatars.read",
"health.read",
"migrations.read",
"migrations.write",
"tokens.read",
"tokens.write",
"sites.read",
"sites.write",
"log.read",
"log.write"
which looks fine..
can you share your code in '#/functions/appwriteClient.ts'?
Thank you for taking a look at it β€οΈ
#/functions/appwriteClient.ts is used by all my functions, and they all work great, however, here's the code for reference:
import { Account, Client, Databases, Functions, Storage, TablesDB, Teams, Users } from 'node-appwrite';
export const serverClient = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
// @ts-expect-error
.setProject(Bun.env.APPWRITE_FUNCTION_PROJECT_ID)
// @ts-expect-error
.setKey(Bun.env.APPWRITE_API_KEY);
// assign session before use
export const sessionClient = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
// @ts-expect-error
.setProject(Bun.env.APPWRITE_FUNCTION_PROJECT_ID);
export const serverAccount = new Account(serverClient);
export const serverDatabases = new Databases(serverClient);
export const serverFunctions = new Functions(serverClient);
export const serverStorage = new Storage(serverClient);
export const serverTables = new TablesDB(serverClient);
export const serverTeams = new Teams(serverClient);
export const serverUsers = new Users(serverClient);
export const sessionAccount = new Account(sessionClient);
export const sessionStorage = new Storage(sessionClient);
If it's FRA region, does the endpoint need to be https://fra.cloud.appwrite.io/v1 instead of https://cloud.appwrite.io/v1
if I'm not mistaken, you could use
.setEndpoint(Bun.env.APPWRITE_FUNCTION_API_ENDPOINT)
Wait it's using an API key, not the dynamic key π§
oh, you're right! Just to check: In order to use the dynamic key, all I have to do is use the header x-appwrite-key instead, right?
Do you have a best practice for providing the client globally (e.g. can I update the client from a different place when I handle the request) or is it better to use a state object which I pass around (I already have that, it's just not providing the client right now)?
Yes, correct
You should definitely scope it to the current request
Recommended threads
- Relation Question
How do I create a relation from table y to an others x.$id. in my example I have a users table where I use Appwrites unique User IDs and I want other tables fo...
- Unknown attribute type: varchar / text
Since the `string` type is deprecated I tried using `varchar` and `text` in some newer tables, but when running `appwrite pull tables && appwrite types ./src/li...
- I'm experiencing a critical bug on Appwr...
Hey <@870607367597850624> team / support π I'm experiencing a critical bug on Appwrite Cloud that's blocking my production Flutter app. I've already filed GitH...