Os plugins desempenham um papel fundamental na personalização e no aprimoramento dos sites WordPress. Eles são usados para adicionar funcionalidades como formulários de contato, eCommerce e análises aos seus sites sem a necessidade de codificação.

Assim como o WordPress, que recebe atualizações regulares, os plugins também recebem atualizações regulares para adicionar novos recursos, corrigir uma falha de segurança, aumentar a compatibilidade e muito mais. É por isso que a Kinsta incluiu o gerenciamento de plugins e temas entre as ferramentas disponíveis no MyKinsta para cada um de seus sites.

No entanto, atualizar plugins em diversos sites ainda pode ser uma tarefa desafiadora para clientes ocupados, como agências. Este artigo apresenta uma solução que utiliza a API da Kinsta para gerenciar plugins simultaneamente em vários sites.

O que você está construindo

Este guia se concentra na criação de uma solução avançada usando a API da Kinsta, que agora oferece endpoints para recuperar e atualizar plugins.

Nele, criamos um aplicativo React personalizado que busca todos os plugins da conta da sua empresa na Kinsta. Essa ferramenta permite que você identifique e atualize um plugin específico em vários sites, simplificando significativamente o processo.

Ferramenta desenvolvida com React e a API da Kinsta para atualizar em massa plugins de WordPress em vários sites.
Ferramenta desenvolvida com React e a API da Kinsta para atualizar em massa plugins de WordPress em vários sites.

Pré-requisitos do aplicativo

Para acompanhar este projeto, você deve ter o seguinte:

Entendendo a API da Kinsta

A API da Kinsta é uma ferramenta poderosa que permite que você interaja programaticamente com os serviços Kinsta, como sites WordPress hospedados. Ela pode ajudar a automatizar várias tarefas relacionadas ao gerenciamento do WordPress, incluindo criação de sites, recuperação de informações de sites, obtenção do status de um site, navegação e restauração de backups, e muito mais.

Para usar a API da Kinsta, você deve ter uma conta com pelo menos um site, aplicativo ou banco de dados de WordPress no MyKinsta. Você também deve gerar uma chave API para autenticar e acessar sua conta.

Para gerar uma chave API:

  1. Vá para o painel MyKinsta.
  2. Navegue até a página Chaves API (Seu nome > Configurações da empresa > Chaves API).
  3. Clique em Criar chave API.
  4. Escolha uma expiração ou defina uma data de início personalizada e o número de horas para a chave expirar.
  5. Dê à chave um nome exclusivo.
  6. Clique em Gerar.

Depois de criar uma chave API, copie e armazene em um local seguro (recomenda-se o uso de um gerenciador de senhas). Você pode gerar várias chaves API, que serão listadas na página Chaves API. Se você precisar revogar uma chave API, clique no botão Revogar.

Configure seu ambiente de desenvolvimento do React

O React é uma biblioteca JavaScript popular para criar interfaces de usuário. Ela permite que os desenvolvedores criem componentes declarativos que representam diferentes partes da interface do usuário. Esses componentes são definidos usando a sintaxe JSX, uma combinação de JavaScript e HTML.

Para começar, siga estas etapas:

  1. Navegue até a pasta em que você deseja criar seu projeto e use create-react-app para criar um projeto React:
    npx create-react-app <project-name>

    Altere <project-name> acima para o nome que você preferir para seu projeto.

  2. Quando a operação for concluída com sucesso, acesse o diretório do projeto e inicie o servidor de desenvolvimento:
    cd <project-name>
    npm run start

    Seu aplicativo React será aberto no navegador web padrão em http://localhost:3000.

Ao criar um projeto React usando create-react-app, você configura uma estrutura de pastas. A pasta crucial é src, onde o desenvolvimento acontece. Os principais arquivos dessa pasta são:

  • App.js: Esse é o componente principal, que renderiza todos os outros em seu aplicativo React. É aqui que você adicionará todo o código para essa ferramenta.
  • index.js: É o ponto de entrada, carregado primeiro e responsável por renderizar o App.js.
  • index.css: Esse arquivo define o estilo e o layout gerais do aplicativo. Todos os estilos serão adicionados aqui.

Construindo e estilizando a Interface de Usuário

Vamos nos concentrar na criação e no estilo da interface de um aplicativo básico hospedado no arquivo App.js sem envolver roteamento. Nossa interface de usuário principal é um formulário com um campo select para listar plugins exclusivos em seus sites da Kinsta, juntamente com um botão submit para buscar sites com o plugin selecionado.

Interface de usuário para a ferramenta de gerenciamento de plugins para acessar uma lista de plugins e carregar sites.
Interface de usuário para a ferramenta de gerenciamento de plugins para acessar uma lista de plugins e carregar sites.

Além disso, uma seção de exibição mostra detalhes do site, como nome, status do plugin e versão. Ela inclui um botão para atualizar cada site, se necessário, e um botão geral para atualizar em massa todos os sites que exigem a atualização do plugin.

Em seu arquivo App.js, adicione o seguinte código:

import KinstaLogo from './images/kinsta_logo.png';

const App = () => {
    return (
        <div className="container">
            <div className="title-section">
                <img src={KinstaLogo} className="logo" alt="" />
                <h2>Manage your site's plugins</h2>
                <p>
                    Easily update plugins across all sites hosted with Kinsta using the
                    Kinsta API.
                </p>
            </div>
            <div> className="info-section">
                <p>
                    This application allows you to retrieve a list of all sites within
                    your company that uses a specific plugin. You can then choose to update
                    the plugin across all these sites simultaneously or individually.
                </p>
            </div>
            <div className="form-section">
                <form>
                    <div className="form-control">
                        <label> htmlFor="plugin-name">Plugin name</label>
                        <select name="plugin-name" id="plugin-name">
                            <option> value="">Select a plugin</option>
                        </select>
                    </div>
                    <button> className="btn">Fetch sites with this plugin</button>
                </form>
            </div>
            <div className="display_container">
                <div className="site-list">
                    <div className="list-title">
                        <h3>Sites with WooCommerce plugin</h3>

                        <button> className="sm-btn">Update all sites to v.3.6</button>
                    </div>
                    <ul>
                        <li>
                            <div className="info">
                                <p>
                                    <b>Site Name:</b> WooCommerce
                                </p>
                                <p>
                                    <b>Plugin Status:</b> active
                                </p>
                                <p>
                                    <b>Plugin Version:</b> 3.5.1
                                </p>
                            </div>
                            <button> className="sm-btn">Update to v.5.6</button>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    );
};

export default App;

Para estilizar este projeto, visite o arquivo CSS em nosso repositório completo do GitHub e copie o código dele em seu arquivo index.css.

Interagindo com a API da Kinsta

A API da Kinsta oferece uma série de endpoints essenciais para você acessar vários parâmetros necessários para interagir com o plugin de um site. Por exemplo, se você deseja recuperar ou atualizar um plugin, primeiro deve adquirir o ID do ambiente do site.

Para obter o ID de ambiente, siga um processo passo a passo. Primeiramente, identifique o ID do site, que depende diretamente do ID da empresa Kinsta. Esse ID da empresa está disponível no painel MyKinsta, acessando Configurações da empresa e depois Detalhes de cobrança. É importante tratar esse ID como uma informação sensível, semelhante à sua chave API, e não compartilhá-lo.

Você pode armazená-las com segurança como variáveis de ambiente em seu aplicativo React, criando um arquivo .env na pasta raiz do seu projeto. Nesse arquivo, adicione o seguinte com o valor correto:

REACT_APP_KINSTA_COMPANY_ID = 'YOUR_COMPANY_ID' 
REACT_APP_KINSTA_API_KEY = 'YOUR_API_KEY'

Para acessar essas variáveis de ambiente em seu projeto, você pode usar a sintaxe process.env.THE_VARIABLE. Por exemplo, para acessar REACT_APP_KINSTA_COMPANY_ID, você usaria process.env.REACT_APP_KINSTA_COMPANY_ID.

Ao adicionar o arquivo .env ao seu arquivo .gitignore é importante para evitar que você o envie para o GitHub. Isso garante que suas informações confidenciais permaneçam privadas e seguras.

Recupere todos os sites e plugins usando a API da Kinsta

Para recuperar dados de plugin para todos os sites gerenciados pela sua conta da empresa Kinsta, você pode utilizar a API da Kinsta executando três solicitações de API. Aqui está uma explicação simplificada:

Comece armazenando a URL da API da Kinsta em uma variável para facilitar a referência.

const KinstaAPIUrl = 'https://api.kinsta.com/v2';
  1. Obtenha a lista de sites da empresa: Você precisa obter uma lista de todos os sites WordPress associados à sua empresa. Para isso, crie uma consulta usando o ID da empresa, faça uma solicitação GET com a autorização apropriada, processe a resposta no formato JSON e extraia os detalhes do site da resposta.
    const query = new URLSearchParams({
        company: process.env.REACT_APP_KINSTA_COMPANY_ID,
    }).toString();
    const response = await fetch(`${KinstaAPIUrl}/sites?${query}`, {
        method: 'GET',
        headers: { Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}` },
    });
    
    const data = await response.json();
    const companySites = data.company.sites;
  2. Recupere o ID do ambiente do site: A etapa anterior retorna uma array de sites WordPress. Para cada site, faça um loop e outra solicitação GET para obter os ambientes associados.
    const sitesEnvironmentData = companySites.map(async (site) => {
        const siteId = site.id;
        const resp = await fetch(`${KinstaAPIUrl}/sites/${siteId}/environments`, {
            method: 'GET',
            headers: {
                Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
            },
        });
        const data = await resp.json();
        const environments = data.site.environments;
        return {
            id: siteId,
            name: site.display_name,
            environments: environments,
        };
    });
  3. Obtenha a lista de plugins de sites WordPress: Depois de obter o ID do site, o nome e o ambiente, você pode usar o ID do ambiente para recuperar uma lista de todos os plugins em cada site. Primeiro, você precisa resolver as promessas da etapa anterior e, em seguida, fazer as solicitações GET para os plugins:
    // Wait for all the promises to resolve
    const sitesData = await Promise.all(sitesEnvironmentData);
    
    // Get all plugins for each environment
    const sitesWithPlugin = sitesData.map(async (site) => {
        const environmentId = site.environments[0].id;
        const resp = await fetch(
            `${KinstaAPIUrl}/sites/environments/${environmentId}/plugins`,
            {
                method: 'GET',
                headers: {
                    Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
                },
            }
        );
        const data = await resp.json();
        const plugins = data.environment.container_info;
        return {
            env_id: environmentId,
            name: site.name,
            plugins: plugins,
        };
    });
    
    const sitesWithPluginData = await Promise.all(sitesWithPlugin);
    return sitesWithPluginData;
  4. Consolidando o processo: Para simplificar o processo, você pode encapsular essas solicitações de API em uma única função assíncrona getSitesWithPluginData, que pode ser reutilizada. Essa função executará as etapas descritas acima e retornará uma array que contém as informações essenciais sobre cada site, incluindo o ID do ambiente, o nome do site e uma array de plugins.
    const getSitesWithPluginData = async () => {
        const query = new URLSearchParams({
            company: process.env.REACT_APP_KINSTA_COMPANY_ID,
        }).toString();
        const resp = await fetch(`${KinstaAPIUrl}/sites?${query}`, {
            method: 'GET',
            headers: {
                Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
            },
        });
    
        const data = await resp.json();
        const companySites = data.company.sites;
    
        // Get all environments for each site
        const sitesEnvironmentData = companySites.map(async (site) => {
            const siteId = site.id;
            const resp = await fetch(`${KinstaAPIUrl}/sites/${siteId}/environments`, {
                method: 'GET',
                headers: {
                    Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
                },
            });
            const data = await resp.json();
            const environments = data.site.environments;
            return {
                id: siteId,
                name: site.display_name,
                environments: environments,
            };
        });
    
        // Wait for all the promises to resolve
        const sitesData = await Promise.all(sitesEnvironmentData);
    
        // Get all plugins for each environment
        const sitesWithPlugin = sitesData.map(async (site) => {
            const environmentId = site.environments[0].id;
            const resp = await fetch(
                `${KinstaAPIUrl}/sites/environments/${environmentId}/plugins`,
                {
                    method: 'GET',
                    headers: {
                        Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
                    },
                }
            );
            const data = await resp.json();
            const plugins = data.environment.container_info;
            return {
                env_id: environmentId,
                name: site.name,
                plugins: plugins,
            };
        });
    
        // Wait for all the promises to resolve
        const sitesWithPluginData = await Promise.all(sitesWithPlugin);
        return sitesWithPluginData;
    };

Recupere plugins exclusivos de todos os sites

No seu aplicativo, a intenção é apresentar a lista de plugins disponíveis em todos os sites através de um menu suspenso select. Para isso, utilizaremos a função getSitesWithPluginData que coleta o ID do ambiente, o nome e os plugins de cada site. Com essas informações em mãos, é possível montar uma lista completa de plugins.

Defina uma nova função, fetchAllSitesPlugins, que chama getSitesWithPluginData e processa sua saída para obter uma lista de todos os plugins:

const fetchAllSitesPlugins = async () => {
    const sitesWithPluginData = await getSitesWithPluginData();

    // get all plugins
    const allPlugins = sitesWithPluginData.map((site) => {
        const { plugins } = site;
        return plugins.wp_plugins.data;
    });

   // …
};

Este código percorre os dados de cada site e compila uma lista de plugins. Para garantir que cada plugin seja listado apenas uma vez, utilize o objeto Set do JavaScript, que armazena valores únicos:

// get unique plugins
    const uniquePlugins = [
        ...new Set(allPlugins.flat().map((plugin) => plugin.name)),
    ];

O método .flat() simplifica a estrutura do array e .map() faz um loop para extrair apenas os nomes dos plugins. O objeto Set filtra as duplicatas.

Para carregar e exibir esses dados em seu aplicativo React, utilize os hooks useState() e useEffect():

import { useState, useEffect } from 'react';

const App = () => {
    const [pluginName, setPluginName] = useState('');
    const [plugins, setPlugins] = useState([]);

    //Get sites with plugin data
    const getSitesWithPluginData = async () => {
        // perform requests
    };

    useEffect(() => {
        const fetchAllSitesPlugins = async () => {
            const sitesWithPluginData = await getSitesWithPluginData();
            // get all plugins
            const allPlugins = sitesWithPluginData.map((site) => {
                const { plugins } = site;
                return plugins.wp_plugins.data;
            });
            // get unique plugins
            const uniquePlugins = [
                ...new Set(allPlugins.flat().map((plugin) => plugin.name)),
            ];
            setPlugins(uniquePlugins);
        };

        fetchAllSitesPlugins();
    }, []);

     // JSX render code follows
    //...
};

O hook useEffect() garante que os dados sejam obtidos e definidos quando o componente for montado. O hook useState() mantém a lista de plugins exclusivos.

Por fim, exiba esses plugins em um campo select. Se os plugins ainda estiverem sendo carregados, mostre uma mensagem de espaço reservado:

<select>
    name="plugin-name"
    id="plugin-name"
    value={pluginName}
    onChange={(e) => setPluginName(e.target.value)}
>
    {plugins.length > 0 ? (
        <>
            <option value="">Select a plugin</option>
            {plugins.map((plugin) => (
                <option key={plugin} value={plugin.toLowerCase()}>
                    {plugin}
                </option>
            ))}
        </>
    ) : (
        <option> value="">Loading plugins...</option>
    )}
</select>

Neste código:

  • O elemento select está vinculado a uma variável de estado pluginName para armazenar o valor selecionado.
  • O manipulador onChange atualiza esse estado sempre que um novo plugin é selecionado.
  • A função plugins.map() cria dinamicamente elementos de opção para cada plugin.

Seguindo essas etapas, seu aplicativo exibirá efetivamente uma lista exclusiva de plugins obtidos de todos os sites, fornecendo uma interface limpa e fácil de usar para a seleção.

Selecione o campo que mostra a lista de plugins exclusivos de todos os sites na conta da empresa Kinsta.
Selecione o campo que mostra a lista de plugins exclusivos de todos os sites na conta da empresa Kinsta.

Busque sites com um plugin específico

Até agora, você conseguiu recuperar plugins da conta da empresa Kinsta, mas deseja percorrer todos os sites para buscar sites com um plugin específico, armazená-los em um estado e depois exibi-los.

Para fazer isso, crie dois estados: Um para armazenar os sites (sites) e outro para indicar o status de carregamento (isLoading).

const [sites, setSites] = useState([]);
const [isLoading, setIsLoading] = useState(false);

Em seguida, crie uma função fetchSites para filtrar cada site e verificar se ele contém o plugin selecionado. Se isso acontecer, os detalhes relevantes do site serão armazenados.

Essa função começa definindo isLoading como true e limpando a array sites. Em seguida, ela chama getSitesWithPluginData para buscar todos os dados do site.

const fetchSites = async () => {
    setIsLoading(true);
    setSites([]);
    const sitesWithPluginData = await getSitesWithPluginData();

    // Filter out sites that don't have the plugin
    const sitesWithPluginDataFiltered = sitesWithPluginData
        .filter((site) => {
            const sitePlugins = site.plugins.wp_plugins.data;
            return sitePlugins.some((plugin) => {
                return plugin.name === pluginName;
            });
        })
        .map((site) => {
            const { env_id, name } = site;
            const { version, status, update, update_version } =
                site.plugins.wp_plugins.data.find(
                    (plugin) => plugin.name === pluginName
                );
            return {
                env_id,
                name,
                version,
                status,
                updateAvailable: update,
                updateVersion: update_version,
            };
        });
    setSites(sitesWithPluginDataFiltered);
    setIsLoading(false);
};

Na função sitesWithPluginDataFiltered:

  • O método .filter() isola os sites que contêm o plugin selecionado.
  • Em seguida, o método .map() extrai os detalhes necessários de cada site.
  • Por fim, os hooks setSites e setIsLoading atualizam o estado com os novos dados e o status de carregamento.

Em seguida, crie uma função handleSubmit e adicione ao botão Fetch sites with this plugin no formulário para invocar a função quando um usuário selecionar um plugin e enviar o formulário. Essa função impede a ação padrão do formulário e chama fetchSites:

const handleSubmit = (e) => {
    e.preventDefault();
    fetchSites();
};

Dessa forma, ao selecionar um plugin específico e clicar no botão de envio, o sistema realiza a busca por todos os sites que utilizam esse plugin, armazenando no estado de sites.

Exiba sites com o plugin selecionado

Depois de armazenar com êxito os sites relevantes no estado sites, a próxima etapa é exibir esses dados na interface de usuário do seu projeto. O objetivo é apresentar cada site como um item de lista com detalhes importantes e um botão condicional para atualizações de plugins.

<ul>
    {sites.map((site) => (
        <li key={site.env_id}>
            <div className="info">
                <p>
                    <b>Site Name:</b> {site.name}
                </p>
                <p>
                    <b>Plugin Status:</b> {site.status}
                </p>
                <p>
                    <b>Plugin Version:</b> {site.version}
                </p>
            </div>
            <button>
                className={`sm-btn ${
                    site.updateAvailable !== 'available' ? 'disabled-btn' : ''
                }`}
                disabled={site.updateAvailable !== 'available'}
            >
                {site.updateAvailable === 'available'
                    ? `Update to v.${site.updateVersion}`
                    : 'Up to date'}
            </button>
        </li>
    ))}
</ul>

No código acima, o array sites é iterado usando o método .map(), criando uma lista (<ul>) de sites (elementos<li>). Cada item da lista contém detalhes sobre o site e um botão para atualizações do plugin.

O botão na interface do usuário altera o estilo e a função com base no status de atualização do plugin: Ele fica ativo para atualizações disponíveis, caso contrário, é desativado e rotulado como “Up to date”, controlado por CSS condicional e pelo atributo disabled.

Além disso, para melhorar a experiência do usuário, vamos adicionar condicionalmente um texto de carregamento usando o estado isLoading quando os sites estiverem sendo buscados.

{isLoading && (
    <div className="loading">
        <p>Loading...</p>
    </div>
)}
Uma lista de sites que usam um determinado plugin da conta da empresa Kinsta com botões para atualizá-los individualmente ou de uma só vez.
Uma lista de sites que usam um determinado plugin da conta da empresa Kinsta com botões para atualizá-los individualmente ou de uma só vez.

Atualize plugins com a API da Kinsta

Até agora, conseguimos buscar sites com detalhes importantes e acessar seus plugins. O objetivo dessa ferramenta é facilitar a atualização de plugins em vários sites usando a API da Kinsta. O processo envolve iniciar atualizações e acompanhar seu progresso.

Acionando as atualizações de plugins

Para cada site listado, disponibilizamos um botão, cujo estilo indica se existe uma atualização disponível, ao clicar no botão você aciona a função updatePlugin.

<button>
    className={`sm-btn ${
        site.updateAvailable !== 'available' ? 'disabled-btn' : ''
    }`}
    disabled={site.updateAvailable !== 'available'}
    onClick={() =>
        updatePlugin(site.env_id, site.updateVersion)
    }
>
    {site.updateAvailable === 'available'
        ? `Update to v.${site.updateVersion}`
        : 'Up to date'}
</button>

O manipulador onClick chama updatePlugin com o ID do ambiente do site e a versão mais recente do plugin (updateVersion). Essa função envia uma solicitação PUT para a API da Kinsta para atualizar o plugin.

const updatePlugin = async (envId, pluginVersion) => {
    const resp = await fetch(`${KinstaAPIUrl}/sites/environments/${envId}/plugins`, {
        method: 'PUT',
        headers: {
            'Content-Type': 'application/json',
            Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
        },
        body: JSON.stringify({
            name: pluginName,
            update_version: pluginVersion,
        }),
    });

    const data = await resp.json();
    // Further processing
};

Acompanhe o progresso da atualização

Após iniciar a atualização, é importante acompanhar o seu progresso. A API da Kinsta retorna uma resposta como a seguinte ao iniciar uma atualização:

{
  "operation_id": "wp-plugin:update-54fb80af-576c-4fdc-ba4f-b596c83f15a1",
  "message": "Updating WordPress plugin in progress",
  "status": 202
}

O operation_id rastreia o status da atualização por meio do endpoint de operações. Crie uma função para fazer essa solicitação de API, esperando o operation_id como um argumento:

// Check plugin update status
const checkPluginUpdateStatus = async (operationId) => {
    const resp = await fetch(`${KinstaAPIUrl}/operations/${operationId}`, {
        method: 'GET',
        headers: {
            Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
        },
    });
    const data = await resp.json();
    return data.status;
};

Dentro de updatePlugin, use uma instrução if para verificar se as solicitações de atualização inicial status é 202. Em caso afirmativo, você define um intervalo para chamar checkPluginUpdateStatus a cada cinco segundos (5000 milissegundos).

O intervalo realiza verificações contínuas do status da atualização e, em caso de sucesso, encerra o intervalo e aciona fetchSites para renovar a lista de sites. Se algum erro surgir durante essas verificações, este será registrado no console.

if (data.status === 202) {
    const interval = setInterval(() => {
        checkPluginUpdateStatus(data.operation_id)
            .then((status) => {
                console.log(status);
                if (status === 200) {
                    clearInterval(interval);
                    fetchSites();
                }
            })
            .catch((error) => {
                // Handle any errors that occur during the promise resolution
                console.error('Error:', error);
            });
    }, 5000);
}

Feedback do usuário durante a operação

Tudo funciona bem neste ponto, mas é bom que você informe o usuário sobre o andamento da operação em vez de deixá-lo na dúvida. Você pode fazer isso exibindo uma notificação que aparece quando a operação está em andamento e é apagada quando a operação é concluída. Crie um estado showStatusBar para controlar isso:

const [showStatusBar, setShowStatusBar] = useState(false);

Quando showStatusBar é true, uma barra de status aparece na parte superior da tela, sinalizando que uma atualização está em andamento. Esta barra é estilizada para permanecer fixa no topo da tela.

{showStatusBar && (
    <div className="status-bar">
        <p>Updating WordPress plugin in progress...</p>
    </div>
)}

Agora você pode ajustar a instrução if na função updatePlugin para definir showStatusBar para true ou false com base no status da atualização:

if (data.status === 202) {
    setShowStatusBar(true);
    const interval = setInterval(() => {
        checkPluginUpdateStatus(data.operation_id)
            .then((status) => {
                console.log(status);
                if (status === 200) {
                    setShowStatusBar(false);
                    clearInterval(interval);
                    fetchSites();
                }
            })
            .catch((error) => {
                // Handle any errors that occur during the promise resolution
                console.error('Error:', error);
            });
    }, 5000);
}

Esta estratégia assegura que os usuários sejam constantemente atualizados sobre o estado das atualizações do plugin, melhorando significativamente a usabilidade da ferramenta.

Atualize os plugins em vários sites com a API da Kinsta

O principal recurso dessa ferramenta é a capacidade de atualizar um determinado plugin com um clique em vários sites da sua conta Kinsta. Isso é semelhante à funcionalidade implementada para atualizar plugins em um único site.

O processo envolve percorrer o estado sites, que contém os sites com o plugin específico que precisa de uma atualização. Para cada site que requer uma atualização, é feita uma solicitação de API para atualizar o plugin e, posteriormente, rastrear o status da operação:

// Update all plugins
const updateAllPlugins = async () => {
    sites.map(async (site) => {
        if (site.updateAvailable === 'available') {
            const environmentId = site.env_id;
            const resp = await fetch(
                `${KinstaAPIUrl}/sites/environments/${environmentId}/plugins`,
                {
                    method: 'PUT',
                    headers: {
                        'Content-Type': 'application/json',
                        Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
                    },
                    body: JSON.stringify({
                        name: pluginName,
                        update_version: site.updateVersion,
                    }),
                }
            );
            const data = await resp.json();
            if (data.status === 202) {
                setShowStatusBar(true);
                const interval = setInterval(() => {
                    checkPluginUpdateStatus(data.operation_id)
                        .then((status) => {
                            console.log(status);
                            if (status === 200) {
                                setShowStatusBar(false);
                                clearInterval(interval);
                                fetchSites();
                            }
                        })
                        .catch((error) => {
                            // Handle any errors that occur during the promise resolution
                            console.error('Error:', error);
                        });
                }, 5000);
            }
        }
    });
};

Essa função está conectada a um botão Update All. Para aprimorar a experiência do usuário, o botão exibe o número da versão para a qual os plugins estão sendo atualizados:

<button> className="sm-btn" onClick={updateAllPlugins}>
    Update all sites to v.
    {
        sites.find((site) => site.updateVersion !== null)
            ?.updateVersion
    }
</button>

Além disso, renderizamos condicionalmente esse botão para ser exibido somente quando mais de um site necessita de uma atualização para o plugin. Se todos os sites estiverem atualizados, uma mensagem será exibida em seu lugar:

<div className="list-title">
    <h3>Sites with {pluginName} plugin</h3>
    {sites.filter((site) => site.updateAvailable === 'available')
        .length > 1 && (
        <button className="sm-btn" onClick={updateAllPlugins}>
            Update all sites to v.
            {
                sites.find((site) => site.updateVersion !== null)
                    ?.updateVersion
            }
        </button>
    )}
    {sites.every((site) => site.updateAvailable !== 'available') && (
        <p>All sites are up to date</p>
    )}
</div>

Com essas implementações, agora você pode atualizar sem esforço os plugins em vários sites da sua conta Kinsta, aumentando a eficiência e garantindo que todos os seus sites estejam atualizados com as versões mais recentes do plugin.

Implante seu site estático React na Kinsta gratuitamente

Estamos usando a hospedagem de site estático da Kinsta para demonstrar o aplicativo. Na prática, você pode executar esse aplicativo React a partir de sua própria rede ou implantá-lo somente depois de adicionar um meio de autenticação a essa ferramenta para segurança.

Você pode hospedar seus aplicativos React criados com o create-react-app como um site estático usando nossa hospedagem de site estático gratuitamente, enviando seu código para um provedor Git preferido (Bitbucket, GitHub ou GitLab).

Quando seu repositório estiver pronto, siga estas etapas para implantar seu site estático na Kinsta:

  1. Faça login ou crie uma conta para visualizar seu painel MyKinsta.
  2. Autorize a Kinsta com seu provedor Git.
  3. Clique em Sites estáticos na barra lateral esquerda e, em seguida, clique em Adicionar site.
  4. Selecione o repositório e a branch a partir da qual você deseja implantar.
  5. Atribua um nome exclusivo ao seu site.
  6. Adicione as configurações de build no seguinte formato:
    • Comando build: npm run build
    • Versão do node: 18.16.0
    • Diretório de publicação: build
  7. Por fim, clique em Criar site.

E é isso! Agora você tem um site implantado em poucos segundos. Você receberá um link para acessar a versão implantada do seu site. Posteriormente, você poderá adicionar seu domínio personalizado e o certificado SSL, se desejar.

Como alternativa à hospedagem de sites estáticos, você pode implantar seu site estático com a hospedagem de aplicativos da Kinsta, que oferece maior flexibilidade de hospedagem, uma gama mais ampla de benefícios e acesso a recursos mais robustos. Por exemplo, escalabilidade, implantação personalizada usando um Dockerfile e análises abrangentes que englobam dados históricos e em tempo real.

Resumo

A API da Kinsta oferece possibilidades que ultrapassam o que mencionamos aqui. Por exemplo, você poderia criar um Slackbot que o notifique no Slack sempre que detectar um plugin desatualizado em seu site. Essa integração tem o potencial de aprimorar consideravelmente seu fluxo de trabalho, mantendo-o sempre informado e à frente das necessidades de atualização.

Além disso, seguindo as orientações deste guia, é possível desenvolver uma ferramenta para atualizar automaticamente seus temas, aproveitando os endpoints já disponíveis na API da Kinsta.

Kristof Siket, líder da equipe de desenvolvimento da API na Kinsta, destaca que a equipe está em constante esforço para expandir os recursos disponíveis, sempre atenta e receptiva ao feedback dos usuários.

O feedback dos usuários é fundamental para definir a priorização e a exposição de novas funcionalidades. O plano atual não abrange completamente a página de Ferramentas; ao invés disso, as funcionalidades são desenvolvidas com base nos pedidos e no feedback dos usuários. Caso considere que uma ferramenta específica ou um endpoint deveria ser incluído na API da Kinsta, fique à vontade para enviar seu feedback.

Como você está utilizando a API da Kinsta atualmente? Quais funcionalidades ou melhorias você gostaria de ver nas próximas atualizações?

Joel Olawanle Kinsta

Joel is a Frontend developer working at Kinsta as a Technical Editor. He is a passionate teacher with love for open source and has written over 200 technical articles majorly around JavaScript and it's frameworks.