How to use hooks to upload file to an ftp server

default discord avatar
aljubaer2 years ago
1 1

I want to send the uploaded files to an ftp server (using basic-ftp) and receive them from there also. The process has been already mentioned in the doc here: https://payloadcms.com/docs/production/deployment#file-storage But I am a bit confused about how I can use hooks there?
For example here is a collection with upload I put a hook a beforeChange here but it seems like not triggering the hook when hook at time of uploading file:

import { CollectionConfig } from 'payload/types';
const Media: CollectionConfig = {
    slug: 'media',
    access: {
        read: () => true,
    },
    hooks: {
        beforeChange: [
            (operation) => {
                if (operation.req.headers.hook === 'beforeChange') {
                    operation.data.description += '-beforeChangeSuffix';
                    // Todo: send to ftp
                }
                return operation.data;
            },
        ],
    },
    upload: {
        staticURL: '/media',
        staticDir: 'media',
        imageSizes: [
            {
                name: 'thumbnail',
                width: 400,
                height: 300,
                crop: 'centre',
            },
            {
                name: 'card',
                width: 768,
                height: 1024,
                crop: 'centre',
            },
        ],
        adminThumbnail: 'thumbnail'
    },
    fields: [],
};
  • Selected Answer
    discord user avatar
    jmikrut
    2 years ago

    Hey @aljubaer

    You're almost there! You have a bug in your hook, though.

    Your if statement that is checking if the operation.req.headers.hook is equal to beforeChange is incorrect and unnecessary. Because you are adding a function to the beforeChange hooks array itself, you know that the code will only be running in a beforeChange context.

    So basically, right now, code within your if will never fire. Just remove it!

    Pro tip:

    You might want to do different actions based on if your beforeChange hook is either running in response to a create or an update operation. You can gain access to which operation is active by destructuring operation out of the hook arguments, like so:

    {
      beforeChange: [
        ({
          data, // incoming data to update or create with
          req, // full express request
          operation, // name of the operation ie. 'create', 'update'
          originalDoc, // original document
        }) => {
          console.log(operation) // will be either 'update' or 'create'
          return data;
        } 
      ]
    }

    For example, a create operation will always have a file that needs to be uploaded to FTP. But, update might only need to upload a file if the file is being replaced. So you could extend your hook to do different things based on the operation, and based on if there is a new file present or not.

    Take a look at the Hooks documentation for more!

    https://payloadcms.com/docs/hooks/collections#beforechange

    Does this answer your question?

Star on GitHub

Star

Chat on Discord

Discord

online

Can't find what you're looking for?

Get help straight from the Payload team with an Enterprise License.