Building a Strapi Custom Field for Text Generation with Open AI

This page summarizes the projects mentioned and recommended in the original post on dev.to

SurveyJS - Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App
With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.
surveyjs.io
featured
InfluxDB - Power Real-Time Data Analytics at Scale
Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.
www.influxdata.com
featured
  • strapi-open-ai-text-generation

    A Strapi Custom Field to generate text content with Open AI Text generation API

  • : acts as our input for prompts; we use onChange() ‘watcher’ to update the value of our prompt state as we type data. We then store the prompt in a variable called prompt. TextArea />: is what we use to store the value of our generated text. We use a to edit the generated text. We use a special implementation of our onChange() watcher, which allows us to pass an object of multiple values to update when a change occurs in that component.

    We also have two buttons where all the magic happens. One button calls generateText() - this function uses fetch to call our backend service, /ai-text-generation/generate-text that makes authenticated calls to the Open AI API (we’ll create this next). To authenticate this, we use auth from @strapi/helper-plugin which helps us make a secure request to the Strapi service we’ll create using the Admins token.

    We then parse our result and use the special implementation of onChange() to pass the parsed response as the content that will get added to our database with onChange({ target: { name, value: parsedResult, type: attribute.type } }).

    The other button calls clearGeneratedText() - this function clears all the text the AI generated in case we want to start over. At this point, our application should look something like this.

    Image of custom field in content manager

    Building a Custom Open AI Route in Strapi

    To access Open AI, we need to provide an API KEY; having this key in the admin poses a security risk, and to combat that, we’ll create a custom route that, when called, makes an API call to Open AIs API and returns the generated text that we can then send to the admin.

    So start, in our ./config/plugins.js file add a config object below enabled: true, your config file after should look like this:

    // …
    'ai-text-generation': {
          enabled: true,
          config: {
            apiToken: process.env.OPEN_AI_API_TOKEN,
          },
          resolve: './src/plugins/ai-text-generation'
        },
    
    
    Enter fullscreen mode Exit fullscreen mode

    Now, create a file called open-ai.js in ./src/plugins/ai-text-generation/server/services and paste the following code in it.

    For the code to work, you will also have to install axios, for that navigate to your plugin root and type yarn add axios

    'use strict';
    
    const axios = require('axios');
    
    module.exports = ({ strapi }) => ({
    
      async generateText(prompt) {
        try {
          const response = await axios(
            {
              url: 'https://api.openai.com/v1/completions',
              method: 'POST',
              headers: {
                'Content-Type': 'application/json',
                'Authorization': `Bearer ${strapi.plugin('ai-text-generation').config('apiToken')}`
              },
              data: JSON.stringify({
                'model': 'text-davinci-001',
                'prompt': `${prompt}`,
                'temperature': 0.4,
                'max_tokens': 64,
                'top_p': 1,
                'frequency_penalty': 0,
                'presence_penalty': 0
              })
            })
    
          return response.data;
        }
        catch (err) {
          console.log(err.response)
        }
    
      }
    
    });
    
    
    Enter fullscreen mode Exit fullscreen mode

    Here we define a function generateText() that takes a prompt as an argument. We then use prompt as a parameter in our request to Open AI.

    Next up, in the same services folder, paste the following code in your index.js file.

    'use strict';
    
    const openAi = require('./open-ai');
    
    module.exports = {
      openAi,
    };
    
    
    Enter fullscreen mode Exit fullscreen mode

    This code registers a service in Strapi that we call from a controller, before we do that. We need to create a controller. In ./src/plugins/ai-text-generation/server/controllers, create a file called ai-controller.js and paste the following code in it:

    'use strict';
    
    module.exports = ({ strapi }) => ({
      async generate(ctx) {
        ctx.body = await strapi
          .plugin('ai-text-generation')
          .service('openAi')
          .generateText(ctx.request.body.prompt);
      },
    });
    
    
    Enter fullscreen mode Exit fullscreen mode

    In this file, we call the generateText() function that we defined in the service we just made and pass ctx.request.body.prompt (from our POST request).

    In the same folder, we need to paste the following code in our index.js file:

    'use strict';
    
    const aiController = require('./ai-controller');
    
    module.exports = {
      aiController,
    };
    
    
    Enter fullscreen mode Exit fullscreen mode

    Lastly, we must create a route to access the controller we just created. In ./src/plugins/ai-text-generation/server/routes we need to paste the following code:

    module.exports = [
      {
        method: 'POST',
        path: '/generate-text',
        handler: 'aiController.generate',
        config: {
          policies: [],
        },
      },
    ];
    
    
    Enter fullscreen mode Exit fullscreen mode

    In this file, we define how our endpoint should behave. With this code, we create a POST method on the /generate-text URI and pass the aiController controller we created to define its behavior.

    In your preferred API client, you can now make a request to localhost:1337/ai-text-generation/generate-text and you should get AI-generated text as a response. Be sure to add your prompt as a parameter and pass your admin JWT for authentication.

    We should also get a response when we enter a prompt and click “generate” in our Custom Field.

    Gif of working Custom Field

    Publishing to npm

    Maxime from the Strapi team wrote an amazing article on how to publish your plugin to npm, and if you have any trouble you can refer to my package.json file for how to structure yours.

    You can also take your Custom field to the next level and submit it to the official Strapi marketplace.

    Hopefully, you have a better idea of how to build Custom fields now, and even better, you have a custom field that generates content for you with Open AI.

    Let us know if you build something, the Strapi community will be excited to try it out. Take care.

  • SurveyJS

    Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.

    SurveyJS logo
NOTE: The number of mentions on this list indicates mentions on common posts plus user suggested alternatives. Hence, a higher number means a more popular project.

Suggest a related project

Related posts

  • I'm puzzled how anyone trusts ChatGPT for code

    2 projects | news.ycombinator.com | 8 May 2024
  • Psql-describe: \d ported to JavaScript

    2 projects | news.ycombinator.com | 8 May 2024
  • Weather Application using ReactJS | react mini project

    1 project | dev.to | 8 May 2024
  • Show HN: I Created 3,800 Open Source React Icons (Beautiful, Rounded Style)

    1 project | news.ycombinator.com | 8 May 2024
  • How to implement a Multi-Select Dropdown component with React and Tailwind CSS

    1 project | dev.to | 8 May 2024