Desenvolvimento e bases de dados

Gerar relatórios CSV de correio e cron a partir do cPanel

Revisto a 8 min de leitura API do cPanel relatórios

Pode utilizar a UAPI para inventariar as caixas de correio, os reencaminhamentos e as respostas automáticas da sua conta. Os exemplos seguintes são executados com PHP 8 por SSH; não são páginas para publicar na web. Consulte antes a introdução à UAPI.

Preparar uma pasta privada

Guarde os scripts e os resultados fora de public_html e das raízes dos seus outros domínios, por exemplo em /home/usuario_cpanel/reportes. Restrinja o acesso ao seu utilizador: os relatórios contêm endereços e podem incluir comandos com informação privada.

Antes de automatizar, execute cada chamada de consulta na sua conta e confirme que campos devolve a versão instalada. As funções dependem dos serviços e das permissões disponíveis. Um relatório vazio não demonstra que não existam contas, se a chamada tiver falhado.

Funções comuns

Guarde este ficheiro como funciones.php na pasta privada. Verifique se exec está disponível no PHP do terminal. A função só permite as consultas fixas utilizadas nestes exemplos e verifica tanto o processo como o estado da UAPI.

<?php

function ejecutar(string $comando): string
{
    $lineas = [];
    $codigo = 0;
    exec($comando, $lineas, $codigo);
    if ($codigo !== 0) {
        throw new RuntimeException('A consulta não terminou corretamente.');
    }
    return implode("\n", $lineas);
}

function uapi(string $funcion, array $parametros = []): array
{
    $permitidas = [
        'list_pops_with_disk', 'list_forwarders',
        'list_auto_responders', 'get_auto_responder',
    ];
    if (!in_array($funcion, $permitidas, true)) {
        throw new InvalidArgumentException('Função não permitida.');
    }
    $comando = '/usr/local/cpanel/bin/uapi --output=json Email '
        . escapeshellarg($funcion);
    foreach ($parametros as $clave => $valor) {
        if (!in_array($clave, ['domain', 'email'], true)) {
            throw new InvalidArgumentException('Parâmetro não permitido.');
        }
        $comando .= ' ' . escapeshellarg($clave . '=' . $valor);
    }
    $respuesta = json_decode(ejecutar($comando), true, 512, JSON_THROW_ON_ERROR);
    $resultado = $respuesta['result'] ?? [];
    if ((int) ($resultado['status'] ?? 0) !== 1) {
        throw new RuntimeException('A UAPI rejeitou a consulta; verifique as permissões e os parâmetros.');
    }
    if (!is_array($resultado['data'] ?? null)) {
        throw new RuntimeException('A UAPI devolveu um formato de dados inesperado.');
    }
    return $resultado['data'];
}

function escribirCsv(array $filas): void
{
    foreach ($filas as $fila) {
        $valores = array_map(static function ($valor): string {
            $texto = (string) ($valor ?? '');
            // Evita que textos do relatório sejam interpretados como fórmulas.
            if (preg_match('/^[\s]*[=+@-]/u', $texto)) {
                $texto = "'" . $texto;
            }
            return $texto;
        }, $fila);
        if (fputcsv(STDOUT, $valores, ';', '"', '') === false) {
            throw new RuntimeException('Não foi possível escrever o CSV.');
        }
    }
}

fputcsv trata corretamente os delimitadores, as aspas e as quebras de linha. Importe também as colunas como texto na folha de cálculo quando for o caso; evite abrir relatórios de origem desconhecida com fórmulas ativadas.

Caixas de correio e utilização de espaço

Guarde como buzones.php:

<?php
require __DIR__ . '/funciones.php';

$filas = [['Email', 'Espaço usado', 'Quota']];
foreach (uapi('list_pops_with_disk') as $cuenta) {
    $filas[] = [
        $cuenta['email'] ?? '',
        $cuenta['humandiskused'] ?? '',
        $cuenta['humandiskquota'] ?? '',
    ];
}
escribirCsv($filas);

Os campos de espaço estão preparados para leitura humana e podem incluir unidades ou um valor de quota ilimitada. Não os some como se fossem números de bytes. Consulte os campos disponíveis em list_pops_with_disk se precisar de outro formato.

Reencaminhamentos de um domínio

Guarde como reenviadores.php e altere o domínio:

<?php
require __DIR__ . '/funciones.php';

$filas = [['Origem', 'Destino']];
foreach (uapi('list_forwarders', ['domain' => 'example.com']) as $regla) {
    $filas[] = [$regla['dest'] ?? '', $regla['forward'] ?? ''];
}
escribirCsv($filas);

O exemplo filtra expressamente um domínio. Repita a consulta para os domínios que quiser incluir e confirme que não duplica resultados. Um endereço de destino pode ser externo; a lista não comprova que esteja a entregar correio. Referência: list_forwarders.

Respostas automáticas

A lista por domínio identifica as respostas configuradas. Guarde-a como respuestas.php:

<?php
require __DIR__ . '/funciones.php';

$filas = [['Conta', 'Assunto']];
foreach (uapi('list_auto_responders', ['domain' => 'example.com']) as $respuesta) {
    $filas[] = [$respuesta['email'] ?? '', $respuesta['subject'] ?? ''];
}
escribirCsv($filas);

Consulte list_auto_responders para o formato do seu servidor. Se precisar de datas, reveja também get_auto_responder: verifique o identificador admitido e valide uma resposta conhecida antes de repetir essa consulta para todas as contas. Não corte automaticamente o domínio de um email; poderia consultar outra identidade ou não obter o resultado previsto.

Os campos de início e fim podem ser nulos. Se exportar marcas temporais Unix, converta-as com um fuso horário explícito e indique esse fuso no cabeçalho. Uma resposta configurada não significa que esteja ativa no momento do relatório.

Tarefas cron

Pode consultar as tarefas do utilizador com crontab -l. Guarde primeiro a saída original como referência privada. Para gerar um CSV das linhas de programação habituais, guarde cron.php:

<?php
require __DIR__ . '/funciones.php';

$filas = [['Agendamento', 'Comando']];
foreach (explode("\n", ejecutar('crontab -l')) as $linea) {
    $linea = trim($linea);
    if ($linea === '' || str_starts_with($linea, '#')
        || preg_match('/^[A-Za-z_][A-Za-z0-9_]*\s*=/', $linea)) {
        continue;
    }
    if (preg_match('/^(@\S+)\s+(.+)$/', $linea, $partes)) {
        $filas[] = [$partes[1], $partes[2]];
    } else {
        $partes = preg_split('/\s+/', $linea, 6);
        if (count($partes) !== 6) {
            throw new RuntimeException('Há uma linha cron não reconhecida.');
        }
        $filas[] = [implode(' ', array_slice($partes, 0, 5)), $partes[5]];
    }
}
escribirCsv($filas);

Se o utilizador não tiver crontab, o comando pode terminar com erro: verifique a mensagem no terminal antes de interpretar o resultado. Este CSV omite variáveis de ambiente e comentários; serve para inventário, não para restaurar uma programação completa. Não representa as tarefas de outros utilizadores nem do sistema.

Gerar e verificar cada relatório

Por exemplo:

umask 077
php /home/usuario_cpanel/reportes/buzones.php > /home/usuario_cpanel/reportes/buzones.csv

Utilize um nome de saída novo e verifique que o comando termina sem erros. Não utilize o ficheiro se tiver falhado: o redirecionamento pode deixar um CSV vazio ou parcial. Reveja o cabeçalho, uma linha conhecida e a contagem antes de o descarregar. Apague as cópias temporárias quando já não forem necessárias.

Também lhe pode ser útil

Algo não bate certo ou mudou? Diga-nos e revemos.