Ao longo dos anos, nossos serviços na Kinsta sempre foram gerenciados manualmente através do painel MyKinsta. No entanto, com a introdução da API da Kinsta e o lançamento contínuo de novos endpoints de API, você pode aprimorar sua estratégia desenvolvendo um método personalizado para interagir com os serviços da Kinsta. Um desses meios é desenvolver um Slackbot para monitorar e gerenciar atividades como a criação de sites.

O que você está construindo

Este tutorial explica como você pode criar um Slackbot (ou aplicativo Slack) que interage com a API da Kinsta para recuperar informações e entregá-las como mensagens em tempo real para um canal designado do Slack usando os Webhooks de entrada da API do Slack.

Para conseguir isso, você criará um aplicativo Node.js com a framework Express para criar uma interface de usuário para a criação de sites WordPress e integrá-la à API da Kinsta. O aplicativo usa um formulário para coletar detalhes de configuração para o seu site WordPress e, em seguida, envia uma atualização em tempo real sobre as informações do site e detalhes sobre como verificar seu status de operação para o canal Slack especificado.

Gif mostrando o aplicativo que seria criado e como ele envia informações em tempo real para o Slack.
Gif mostrando o aplicativo que seria criado e como ele envia informações em tempo real para o Slack.

Pré-requisitos

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

Configuração do ambiente de desenvolvimento

Para começar, crie um novo diretório para o seu aplicativo e inicialize com o npm:

mkdir my-express-app 
cd my-express-app 
npm init -y

Após executar o comando npm init -y, um novo arquivo package.json será criado no diretório do seu projeto com valores padrão. Esse arquivo contém informações importantes sobre seu projeto e suas dependências.

Em seguida, instale as dependências necessárias para seu projeto. As seguintes dependências são essenciais:

  • ejs: o EJS (Embedded JavaScript) é um mecanismo de modelos que permite a você gerar conteúdo HTML dinâmico com JavaScript.
  • express: O Express é uma estrutura de aplicativos da web rápida e minimalista para o Node.js. Ele simplifica a criação de aplicativos da Web e APIs fornecendo recursos essenciais como roteamento, suporte a middleware e manipulação de solicitações e respostas HTTP.
  • express-ejs-layouts: Os layouts do Express EJS são uma extensão do Express que permite o uso de layouts ou modelos para manter uma estrutura consistente em várias exibições.

Para instalar essas dependências, execute o comando abaixo:

npm install ejs express express-ejs-layouts

Além disso, você precisará instalar as seguintes dependências de desenvolvimento para facilitar a criação e o teste do seu projeto Node.js:

  • nodemon: Uma ferramenta valiosa que reinicia automaticamente seu aplicativo Node.js sempre que são detectadas alterações de arquivo no diretório, garantindo um fluxo de trabalho de desenvolvimento simplificado.
  • dotenv: esse módulo de dependência zero desempenha uma função crucial no carregamento de variáveis de ambiente de um arquivo .env.

Para instalar essas dependências de desenvolvimento, execute o comando abaixo:

npm install -D nodemon dotenv

Depois que o package.json for inicializado e todas as dependências estiverem instaladas, crie um novo arquivo, por exemplo, app.js.

touch app.js

Aqui está uma configuração padrão para o seu arquivo app.js, em que você importa os módulos necessários e o define para ser executado em uma porta específica:

// Import required modules
const express = require('express');
const app = express();

// Set up your routes and middleware here
// ...

// Start the server to listen on the specified port
app.listen(process.env.PORT || 3000, () => {
  console.log(`Server is running on port ${process.env.PORT || 3000}`);
});

Para executar seu aplicativo Node.js, execute o comando:

node app.js

No entanto, executar um aplicativo como esse significa reiniciá-lo manualmente toda vez que você fizer alterações no projeto. Para superar esse inconveniente, use nodemon, que você já instalou. Configure em seu arquivo package.json criando um comando de script:

  "scripts": {
    "dev": "nodemon app.js"
  },

Agora, execute seu aplicativo Node.js com reinicializações automáticas usando o seguinte comando:

npm run dev

Começando com o Express e o Templating EJS

Neste tutorial, você está construindo um aplicativo Node.js que exibirá conteúdo no navegador. Para conseguir isso, express.js é utilizado como seu framework web e EJS (Embedded JavaScript) como seu mecanismo de template.

Para definir o EJS como mecanismo de exibição, adicione a seguinte linha ao arquivo app.js. Isso permitirá que você execute os arquivos .ejs:

// Use EJS as the view engine 
app.set('view engine', 'ejs');

Agora que o Express está configurado com o EJS, defina suas rotas. Em aplicativos web, as rotas determinam como o aplicativo responde a diferentes solicitações HTTP (como GET ou POST) e especificam as ações a serem executadas quando uma URL específica é acessada.

Por exemplo, crie uma rota que carregue uma página específica quando um usuário navegar até a página de índice (/). Para fazer isso, use o método de solicitação GET.

// Define a route for the homepage
app.get('/', (req, res) => {
  // Here, you can specify what to do when someone accesses the homepage
  // For example, render an EJS template or send some HTML content
});

No código acima, quando um usuário acessar o índice do seu aplicativo, o servidor executará a função de callback especificada como o segundo parâmetro. Dentro dessa função de callback, você pode manipular a lógica para renderizar um Templating EJS ou enviar algum conteúdo HTML para ser exibido na página inicial.

Você pode usar o método res.render() para renderizar um Templating EJS ou usar res.send() para enviar conteúdo HTML simples.

app.get('/', (req, res) => {
    res.send('Hello World');
});

Quando você executar o aplicativo, a mensagem “Hello World” será exibida na página de índice.

Templating EJS

Este tutorial se concentra na lógica e inclui arquivos iniciais, de modo que você não precisa se preocupar em criar templates do zero. Siga estas etapas para que você possa começar:

  1. Acesse o template no GitHub para criar um novo repositório.
  2. Marque a opção Include all branches durante a criação do repositório.
  3. Depois que o repositório for criado, clone o projeto em seu computador usando o Git.
  4. Para acessar o código inicial, mude para a branch starter-files em seu repositório local.

No código inicial, temos duas pastas principais: public e views. A pasta public contém todos os ativos estáticos (arquivos CSS e imagens). Eles são adicionados ao template como arquivos estáticos:

// Static files
app.use(express.static('/public'));
app.use('/css', express.static(__dirname + '/public/css'));
app.use('/images', express.static(__dirname + '/public/images'));

Na pasta views, você tem o arquivo layout.ejs e duas pastas: pages e partials. O arquivo layout. ejs contém o layout geral deste projeto, de modo que você não precisa repetir alguns códigos recorrentes para todas as páginas. Você deve importar a biblioteca express-ejs-layouts para o arquivo app.js e configurá-la:

// Import
const expressEjsLayouts = require('express-ejs-layouts');

// Configure
app.use(expressEjsLayouts);

A pasta pages contém os arquivos de rota (index.ejs e operation.ejs), enquanto a pasta partials contém componentes (header.ejs e footer.ejs). Adicione ao layout desta forma:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <link rel="icon" href="/images/favicon.ico" />
        <link rel="stylesheet" href="/css/index.css" />
        <title>Site Builder</title>
    </head>
    <body>
        <div class="app-container">
            <%- include('partials/header') %>
            <div class="container"><%- body %></div>
            <%- include('partials/footer') %>
        </div>
    </body>
</html>

Quando você executar seu aplicativo Node.js, a interface do usuário será carregada, mas você precisará adicionar lógica a esse aplicativo para enviar os dados do formulário para a API da Kinsta e enviar informações sobre o site para o Slack quando a operação for iniciada.

Começando com o Slack Incoming Webhooks

Os Incoming Webhooks do Slack fornecem uma maneira simples de enviar mensagens de aplicativos externos para o Slack. Para usar os Incoming Webhooks do Slack, crie e configure um aplicativo Slack, depois copie a URL do Webhook para enviar mensagens ao Slack programaticamente.

Como configurar um aplicativo do Slack e obter a URL do webhook

Crie um novo aplicativo do Slack seguindo estas etapas:

  1. Navegue até o painel de controle da API do Slack.
  2. Clique no botão Criar novo aplicativo, que abrirá um modal.
  3. Selecione a opção From Scratch para começar a criar seu aplicativo do zero.
  4. Forneça um nome para o seu aplicativo Slack, por exemplo, Kinsta Bot.
  5. Em seguida, escolha o espaço de trabalho onde você deseja instalar o aplicativo e clique no botão Create App.

Depois que o aplicativo Slack for criado, você poderá ativar os Webhooks de entrada navegando até Features e selecionando Incoming Webhooks. Alterne a chave para ativar os Webhooks de entrada para seu aplicativo.

Role para baixo até a seção Webhook URLs for Your Workspaceg e clique em Add New Webhook to Workspace. Você será solicitado a escolher um canal para o qual as mensagens serão enviadas. Selecione o canal desejado e clique em Authorize.

Após a autorização, será fornecida uma URL de Webhook para o canal selecionado. Essa URL é o que você usará para enviar mensagens ao Slack programaticamente. É assim que uma URL de Webhook se parece:

https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX

Esse Webhook é específico para um único usuário e um único canal. Mantenha seguro, pois ele funciona como um token de autenticação para o seu aplicativo. Você pode armazenar os códigos exclusivos após /services/ em seu arquivo .env. Você também será solicitado a reinstalar o aplicativo no seu espaço de trabalho para que as alterações tenham efeito.

Como enviar mensagens para o Slack com o Node.js e a API da Kinsta

Agora que a interface do seu aplicativo Node.js está configurada e o Slackbot foi criado com sucesso (juntamente com a URL do WebHook), é hora de lidar com a lógica.

Obtendo dados de formulário no Node.js

Na página de índice, você tem um formulário que enviará dados para a API da Kinsta para criar um novo site WordPress. Para que isso funcione, você precisa criar uma solicitação POST a partir da página de índice. Certifique-se de que seu formulário tenha um método POST e que os campos de entrada tenham um atributo name, que será usado no arquivo app.js.

app.post('/', (req, res) => {
    // Perform the desired operation with the form data
});

Para recuperar dados de um formulário no Node.js, você precisará usar o seguinte middleware:

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

Agora, você pode acessar os valores do formulário usando req.body.[form field name]. Por exemplo, req.body.displayName fornecerá a você o nome de exibição enviado por meio do formulário. Vamos registrar os dados gerais do formulário:

app.post('/', (req, res) => {
    console.log(req.body);
});

Quando você executar o seu código, os dados do formulário serão exibidos depois que você preencher o formulário e clicar no botão Submit.

Detalhes do formulário recuperados do parâmetro req no Node.js.
Detalhes do formulário recuperados do parâmetro req no Node.js.

Criando um site com a API da Kinsta no Node.js

Para criar um site WordPress com a API da Kinsta no Node.js, você pode usar o método fetch(), que agora é suportado e tem um desempenho eficiente nas versões mais recentes do Node.js.

Para realizar qualquer operação com a API da Kinsta, você precisa criar uma chave de API. Para gerar uma chave de API:

  1. Vá para o seu 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 data de 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.

Certifique-se de copiar a chave API gerada e armazená-la com segurança, pois ela só estará visível neste momento. Para este projeto, crie um arquivo .env em seu diretório raiz e salve a chave API como KINSTA_API_KEY.

Além disso, para criar um site WordPress usando a API da Kinsta, você precisará do ID da empresa (que pode ser encontrado no MyKinsta em Empresa > Detalhes da fatura > Identificação da empresa. Armazene esse ID no arquivo .env também, para que você possa acessar essas variáveis de ambiente por meio de process.env. Para habilitar essa funcionalidade, certifique-se de que você configure a dependência dotenv na parte superior do seu arquivo app.js da seguinte forma:

require('dotenv').config();

Para prosseguir com a criação de um site WordPress por meio da API da Kinsta, envie uma solicitação POST para o endpoint /sites com os dados necessários fornecidos no objeto req.body:

const KinstaAPIUrl = 'https://api.kinsta.com/v2';

app.post('/', (req, res) => {
    const createSite = async () => {
        const resp = await fetch(`${KinstaAPIUrl}/sites`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                Authorization: `Bearer ${process.env.REACT_APP_KINSTA_API_KEY}`,
            },
            body: JSON.stringify({
                company: process.env.REACT_APP_KINSTA_COMPANY_ID,
                display_name: req.body.displayName,
                region: req.body.location,
                install_mode: 'new',
                is_subdomain_multisite: false,
                admin_email: req.body.email,
                admin_password: req.body.password,
                admin_user: req.body.username,
                is_multisite: false,
                site_title: req.body.siteTitle,
                woocommerce: false,
                wordpressseo: false,
                wp_language: 'en_US',
            }),
        });
        const data = await resp.json();
        console.log(data);
    };
    createSite();
});

Ao executar o código acima, você criará um novo site WordPress com a API da Kinsta. Mas esse não é o objetivo principal. O objetivo é enviar uma mensagem para o Slack contendo informações sobre o site quando a operação de criação do site for bem-sucedida.

Enviando uma mensagem para o Slack com a URL do Incoming Webhook

Para fazer isso, crie uma instrução If para verificar o status da resposta da solicitação de API. Se for 202, isso significa que “a criação do site foi iniciada” e você pode enviar uma mensagem para o Slack usando a URL do Incoming Webhook. Para conseguir isso, você pode usar sua biblioteca de solicitação HTTP preferida (por exemplo, Axios) ou método para enviar uma solicitação POST ao Slack. Vamos usar o método fetch():

if (data.status === 202) {
    fetch(
        `https://hooks.slack.com/services/${process.env.SLACK_WEBHOOK_ID}`,
        {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                text: 'Hello, world.',
            }),
        }
    );
}

Execute o código acima e preencha o formulário de criação do site. Se o processo for bem-sucedido, uma mensagem será enviada ao Slack imediatamente.

Hello World enviado do Node.js para o Slack com o Incoming Webhook.
Hello World enviado do Node.js para o Slack com o Incoming Webhook.

Personalizando as mensagens do Slack

O exemplo acima envia uma mensagem de texto básico, mas os webhooks de entrada do Slack suportam muito mais do que um simples texto. Você pode personalizar suas mensagens para incluir anexos, links, imagens, botões e muito mais.

Uma maneira de você personalizar as mensagens do Slack é usando o Slack Block Kit Builder. O Block Kit é uma estrutura de interface de usuário fornecida pelo Slack que permite que você crie mensagens ricas e interativas com vários elementos de conteúdo.

Para este tutorial, você verá um bloco criado com o Block Kit Builder para formatar a mensagem adequadamente e adicionar alguns valores do formulário e da resposta de criação do site:

const message = {
    blocks: [
        {
            type: 'section',
            text: {
                type: 'mrkdwn',
                text: `Hello, your new site (${req.body.displayName}) has started building. It takes minutes to build. You can check the operation status intermittently via https://site-builder-nodejs-xvsph.kinsta.app/operation/${req.body.displayName}/${data.operation_id}.`,
            },
        },
        {
            type: 'divider',
        },
        {
            type: 'section',
            text: {
                type: 'mrkdwn',
                text: "_Here are your site's details:_",
            },
        },
        {
            type: 'section',
            text: {
                type: 'mrkdwn',
                text: `1. *Site URL:* http://${req.body.displayName}.kinsta.cloud/n2. *WP Admin URL:* http://${req.body.displayName}.kinsta.cloud/wp-admin/`,
            },
        },
    ],
};

Nesse código, você cria um objeto de mensagem que contém uma array de blocos. Cada bloco representa uma seção específica da mensagem do Slack e pode ter diferentes tipos de conteúdo.

  1. Bloco de seção: Esse tipo de bloco é usado para exibir uma seção de texto. Você usa o type: 'section' para indicar que se trata de um bloco de seção. Dentro do bloco de seção, a propriedade text é usada com type: 'mrkdwn' para especificar que o conteúdo do texto deve ser interpretado como formato Markdown. O conteúdo real do texto é fornecido na propriedade text, e usamos literais de modelo para incluir valores dinâmicos do formulário e da resposta de criação do site, como req.body.displayName e data.operation_id.
  2. Bloco divisor: Esse tipo de bloco é usado para adicionar uma linha horizontal para separar as seções da mensagem. Usamos type: 'divider' para criar o bloco divisor.

Quando essa mensagem for enviada ao Slack usando o Incoming Webhook, ela gerará uma mensagem visualmente atraente e informativa em seu canal do Slack. A mensagem incluirá valores dinâmicos do formulário (como o nome do site) e informações da resposta de criação do site, tornando uma mensagem altamente personalizada e customizada.

Para enviar essa mensagem personalizada, substitua o objeto no corpo do fetch() pelo conteúdo da variável de mensagem:

if (data.status === 202) {
    fetch(
        `https://hooks.slack.com/services/${process.env.SLACK_WEBHOOK_ID}`,
        {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(message),
        }
    );
}
Mensagem do Slack personalizada com o Slack Block Kit Builder.
Mensagem do Slack personalizada com o Slack Block Kit Builder.

Lidando com a operação de criação do site com a API da Kinsta

Na mensagem enviada ao Slack, é criado um link que tem o ID da operação e o nome de exibição. Você pode criar uma nova rota para a página Operations para usar esses dados para verificar o status da operação.

No Express, você pode acessar parâmetros de URL com o parâmetro req. Por exemplo, para obter o ID da operação, você usa req.params.operationId.

const KinstaAPIUrl = 'https://api.kinsta.com/v2';

app.get('/operation/:displayName/:operationId', (req, res) => {
    const checkOperation = async () => {
        const operationId = req.params.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();
        res.render('pages/operation', {
            operationID: req.params.operationId,
            displayName: req.params.displayName,
            operationMessage: data.message,
        });
    };
    checkOperation();
});

Com o código acima, ao clicar no link no Slack, você fará uma solicitação à API da Kinsta para verificar o status da operação do seu site. Atualize o arquivo operation.ejs para adicionar dados dinâmicos:

<div class="container-title">
    <h1 class="title">Check Site Operation Status</h1>
    <p>
        Check the status of your site tools operation via the id. Feel free to copy
        the ID and check in few seconds.
    </p>
</div>
<div class="form-container">
    <div class="input-div">
        <input class="form-control" value="<%= operationID %>" readOnly />
    </div>
    <button class="btn" type="submit" onclick="window.location.reload()">
        Refresh Operation Status
    </button>
</div>
<div class="services">
    <div class="details">
        <p><%= operationMessage %>..</p>
    </div>
</div>
<div class="services">
    <p class="description">
        If message above indicates that "Operation has successfully finished", use
        the links below to access your WP admin and the site itself.
    </p>
    <div class="details">
        <a
            href="http://<%= displayName %>.kinsta.cloud/wp-admin/"
            target="_blank"
            rel="noreferrer"
            class="detail-link"
        >
            <p>Open WordPress admin</p>
            <FiExternalLink />
        </a>
        <a
            href="http://<%= displayName %>.kinsta.cloud/"
            target="_blank"
            rel="noreferrer"
            class="detail-link"
        >
            <p>Open URL</p>
            <FiExternalLink />
        </a>
    </div>
</div>
Página de operações mostrando o ID da operação e os detalhes do site.
Página de operações mostrando o ID da operação e os detalhes do site.

Por fim, você pode usar o método de redirecionamento para navegar até a página de operações quando o processo de criação de um site for iniciado:

if (data.status === 202) {
    fetch(
        `https://hooks.slack.com/services/${process.env.SLACK_WEBHOOK_ID}`,
        {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify(message),
        }
    );
    res.redirect(`/operation/${req.body.displayName}/${data.operation_id}`);
}

O código-fonte completo para este projeto está disponível na branch principal deste repositório no GitHub.

Implantando seu aplicativo Node.js na Kinsta

Você pode implantar facilmente este aplicativo Node.js na plataforma de hospedagem de aplicativos da Kinsta. Tudo o que você precisa fazer é enviar seu código para o seu provedor Git preferido (Bitbucket, GitHub ou GitLab). Em seguida, você deve seguir estas etapas:

  1. Faça login em sua conta Kinsta no painel MyKinsta.
  2. Clique em Adicionar serviço.
  3. Selecione Aplicativo no menu suspenso.
  4. No modal que aparece, escolha o repositório que você deseja implantar. Se você tiver várias branches, poderá selecionar a branch desejada e dar um nome ao seu aplicativo.
  5. Selecione um dos locais de centros de dados disponíveis. A Kinsta detectará e instalará as dependências do seu aplicativo a partir do package.json e, em seguida, criará e implantará.

Por fim, não é seguro enviar chaves de API para hosts públicos, como seu provedor Git. Ao hospedar, você pode adicioná-las como variáveis de ambiente usando o mesmo nome e valor de variável especificados no arquivo .env.

Defina as variáveis de ambiente no DevKinsta ao fazer a implantação.
Defina as variáveis de ambiente no DevKinsta ao fazer a implantação.

Depois que você iniciar a implantação do seu aplicativo, ele será normalmente criado e implantado em alguns minutos. Você receberá um link para o seu novo aplicativo, que terá a seguinte aparência: https://site-builder-nodejs-xvsph.kinsta.app.

Resumo

Neste tutorial, você aprendeu como enviar mensagens para o Slack a partir de um aplicativo Node.js usando Incoming Webhooks e como personalizar as mensagens do Slack com o Block Kit Builder.

As possibilidades com o Slack e a API Kinsta são vastas, e este tutorial é apenas o começo. Ao integrar essas ferramentas, você pode criar um fluxo de trabalho contínuo que mantém sua equipe bem informada e aumenta a produtividade.

Como você está usando a API Kinsta? Quais recursos você gostaria de ver adicionados em seguida?

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.