#[SOLVED] Listing all function deployments from a function always causes an error

22 messages · Page 1 of 1 (latest)

cursive girder
#

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: [email protected] (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...

cursive girder
#

It seems to already fail at serverFunctions.list() , since there are no other logs

cursive girder
#

can anyone help me? Is this a bug, or error on my side?

deep apex
cursive girder
#

it's in FRA

deep apex
deep apex
#

it's dynamic, right?

cursive girder
#

so, unfortunately, after sending the key and everything, I never heard back from @deep apex . Can anyone help me or will I need email support?

deep apex
# cursive girder so, unfortunately, after sending the key and everything, I never heard back from...

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..

deep apex
cursive girder
#

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);
crimson olive
#

if I'm not mistaken, you could use

 .setEndpoint(Bun.env.APPWRITE_FUNCTION_API_ENDPOINT)
deep apex
cursive girder
#

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)?

deep apex
cursive girder
#

Thank you, I did and it's working now