Lifecycle hook and field population

System Information
  • Strapi Version: 4.1.5
  • Operating System: MacOS
  • Database:
  • Node Version: v16.13.2
  • NPM Version: 8.5.1
  • Yarn Version:

Hi,

I have a small model which expects a link and I want to fetch the favicon for that link and store it in the Media Library. My original intention is to have a button in the Content Manger like Fetch Favicon but I didn’t know how to realize that. I am quite new to Strapi. I did choose now lifecycle hooks but later realized that afterUpdate might help in backfilling my data but afterCreate is what I actually need.

(If somebody can point in to a better concept into realizing that, please let me know.)

Besides that I have the following questions:

  1. I use populate: "*" (because this model stands in relation to another model). Besides the favicon field I have some other Boolean fields in the same model. They all do get fetched/populated correctly but the favicon is not visible. Why could that be?

  2. I do need to reload the Content Manager in order to see the uploaded favicon in the Content Manager view where I enter also the link - in order to see the uploaded favicon being displayed in the model component. Is there some way to automatically update that view without a reload?

  3. What better approach could I have taken to realize the below functionality in the Strapi system? I saw services but am not sure.

    "favicon": {
      "type": "media",
      "multiple": false,
      "required": false,
      "allowedTypes": [
        "images"
      ]
    }
    "link": {
      "type": "string",
      "unique": true,
      "required": true
    },
const axios = require("axios");
const mime = require("mime-types");
const fs = require("fs");
const tmp = require("tmp");

module.exports = {
  // Needs to be afterCreate() otherwise new entries won't get icons.
  async afterUpdate(event) {
    const { params, result } = event;

    console.log(result);
    // How to overwrite a file when uploading insteading creating duplicates?
    if (params.data.favicon) {
      console.log("Icon already exists.");
      return;
    }
    console.log(`Icon: ${params.data.favicon}`);

    let link = params.data.link;
    if (!link) {
      return;
    }
    const faviconLink = `http://www.google.com/s2/favicons?domain=${link}`;
    console.log(faviconLink);

    const response = await axios(faviconLink, { responseType: "arraybuffer" });
    if (!response) {
      console.log(`fetch(): ${response.status}`);
      return;
    }
    const mimeType = response.headers["content-type"];
    const fileName = new URL(link).hostname;
    console.log(mimeType);
    console.log(fileName);

    const tempFileName = tmp.fileSync();
    fs.writeFileSync(tempFileName.name, response.data);

    const stats = fs.statSync(tempFileName.name);
    console.log(result);
    try {
      await strapi.plugins.upload.services.upload.upload({
        data: {
          refId: result.id,
          ref: "api::link.link",
          field: "favicon",
        },
        files: {
          path: tempFileName.name,
          name: fileName,
          type: mimeType,
          size: stats.size,
        },
      });
    } catch (error) {
      console.error(`Error: ${error}`);
    }
  },
};