Manual do usuárioFluxos de trabalhoGerar um PDF

Gerar um PDF a partir do Vecta Desk

Crie um fluxo de trabalho para gerar e anexar um PDF (como um orçamento) a um registro.

Gere automaticamente ou obtenha um PDF e anexe-o a um registro no Vecta Desk. Isso é normalmente utilizado para criar orçamentos, faturas ou relatórios associados a Empresas, Oportunidades ou outros objetos.

Visão geral

Este fluxo de trabalho utiliza um gatilho manual para que os usuários possam gerar um PDF sob demanda para qualquer registro selecionado. Uma ação de Código trata de:

  1. Baixar o PDF a partir de uma URL (de um serviço de geração de PDF).
  2. Carregar o arquivo para o Vecta Desk.
  3. Criar um anexo ligado ao registro.

Pré-requisitos

Antes de configurar o fluxo de trabalho:

  1. Crie uma chave de API: vá a Configurações → APIs e crie uma nova chave de API. Você vai precisar desse token na ação de código.
  2. Configure um serviço de geração de PDF (opcional): se quiser gerar PDFs dinamicamente (por exemplo, orçamentos), utilize um serviço como Carbone, PDFMonkey ou DocuSeal para criar o PDF e obter uma URL de download.

Configuração passo a passo

Etapa 1: configurar o gatilho

  1. Vá a Fluxos de trabalho e crie um novo fluxo de trabalho.
  2. Selecione Gatilho manual.
  3. Escolha o objeto ao qual pretende anexar PDFs (por exemplo, Empresa ou Oportunidade).

Com um gatilho manual, os usuários podem executar este fluxo de trabalho utilizando um botão que aparece no canto superior direito quando um registro é selecionado, para gerar e anexar um PDF.

Etapa 2: adicionar uma ação de Código

  1. Adicione uma ação Código.
  2. Crie uma nova função com o código abaixo.
  3. Configure os parâmetros de entrada.

Parâmetros de entrada

ParâmetroValor
companyId{{trigger.object.id}}

Se estiver anexando a um objeto diferente (Pessoa, Oportunidade, etc.), renomeie o parâmetro em conformidade (por exemplo, personId, opportunityId) e atualize a função.

Código da função

export const main = async (
  params: { companyId: string },
) => {
  const { companyId } = params;
  // Substitua pelos endpoints GraphQL do seu Vecta Desk
  // (/metadata para metadados e arquivos, /graphql para seus registros)
 
  const metadataGraphqlEndpoint = 'https://sua-instancia/metadata';
  const dataGraphqlEndpoint = 'https://sua-instancia/graphql';
 
  // Substitua pela sua chave de API de Configurações → APIs
  const authToken = 'SUA_API_KEY';
 
  // Substitua pela URL do seu PDF
  // Pode vir de um serviço de geração de PDF ou de uma URL estática
  const pdfUrl = 'https://seu-servico-pdf.com/orcamento-gerado.pdf';
  const filename = 'orcamento.pdf';
 
  // Passo 1: baixar o arquivo PDF
  const pdfResponse = await fetch(pdfUrl);
 
  if (!pdfResponse.ok) {
    throw new Error(`Falha ao baixar PDF: ${pdfResponse.status}`);
  }
 
  const pdfBlob = await pdfResponse.blob();
  const pdfFile = new File([pdfBlob], filename, { type: 'application/pdf' });
 
  const fieldMetadataIdQuery = `
    query FindUploadFileFieldMetadataId {
      objects {
        edges {
          node {
            nameSingular
            fieldsList {
              id
              name
            }
          }
        }
      }
    }
  `;
 
  // Passo 2: encontrar o fieldMetadataId do campo "arquivo" no objeto Anexos
  const response = await fetch(metadataGraphqlEndpoint, {
      method: 'POST',
      headers: {
        Authorization: `Bearer ${authToken}`
      },
      body: {
        query: fieldMetadataIdQuery,
      }
    });
  const result = await response.json();
  const uploadFileFieldMetadataId = result.data.objects.edges.find(object => object.node.nameSingular === 'attachment').node.fieldsList.find(field => field.name === 'file').id;
 
  // Passo 3: enviar o arquivo via upload multipart GraphQL
  const uploadMutation = `
    mutation UploadFilesFieldFile($file: Upload!, $fieldMetadataId: String!) {
      uploadFilesFieldFile(file: $file, fieldMetadataId: $fieldMetadataId) {
        id
      }
    }
  `;
 
  const uploadForm = new FormData();
  uploadForm.append('operations', JSON.stringify({
    query: uploadMutation,
    variables: { file: null, fieldMetadataId: uploadFileFieldMetadataId },
  }));
  uploadForm.append('map', JSON.stringify({ '0': ['variables.file'] }));
  uploadForm.append('0', pdfFile);
 
  const uploadResponse = await fetch(metadataGraphqlEndpoint, {
    method: 'POST',
    headers: { Authorization: `Bearer ${authToken}` },
    body: uploadForm,
  });
 
  const uploadResult = await uploadResponse.json();
 
  if (uploadResult.errors?.length) {
    throw new Error(`Falha no upload: ${uploadResult.errors[0].message}`);
  }
 
  const fileId = uploadResult.data?.uploadFilesFieldFile?.id;
 
  if (!fileId) {
    throw new Error('Nenhum file id retornado do upload');
  }
 
  // Passo 4: criar o anexo ligado à empresa
  const attachmentMutation = `
    mutation CreateOneAttachment($data: AttachmentCreateInput!) {
      createAttachment(data: $data) {
        id
        name
      }
    }
  `;
 
  const attachmentResponse = await fetch(dataGraphqlEndpoint, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${authToken}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      query: attachmentMutation,
      variables: {
        data: {
          name: filename,
          targetCompanyId: companyId,
          file: [
            {
              fileId: fileId,
              label: filename
            }
          ]
        },
      },
    }),
  });
 
  const attachmentResult = await attachmentResponse.json();
 
  if (attachmentResult.errors?.length) {
    throw new Error(`Falha ao criar anexo: ${attachmentResult.errors[0].message}`);
  }
 
  return attachmentResult.data?.createAttachment;
};

Etapa 3: personalizar para o seu caso de uso

Para anexar a um objeto diferente

Substitua targetCompanyId pelo campo apropriado:

ObjetoNome do campo
EmpresatargetCompanyId
PessoatargetPersonId
OportunidadetargetOpportunityId
Objeto personalizadotargetYourCustomObjectId

Atualize tanto o parâmetro da função quanto o objeto variables.data na mutação de anexo.

Para utilizar uma URL de PDF dinâmica

Se utilizar um serviço de geração de PDF, você pode:

  1. Primeiro, fazer uma ação de Requisição HTTP para gerar o PDF.
  2. Passar a URL do PDF retornada para a função como parâmetro.
export const main = async (
  params: { companyId: string; pdfUrl: string; filename: string },
) => {
  const { companyId, pdfUrl, filename } = params;
  // ... restante da função
};

Etapa 4: testar e ativar

  1. Salve o fluxo de trabalho.
  2. Acesse um registro de Empresa.
  3. Clique no menu e selecione o seu fluxo de trabalho.
  4. Verifique a seção Anexos no registro para confirmar que o PDF foi anexado.
  5. Ative o fluxo de trabalho.

Combinar com serviços de geração de PDF

Para criar orçamentos ou faturas dinâmicos:

Exemplo: gerar orçamento → anexar PDF

EtapaAçãoFinalidade
1Gatilho manual (Empresa)O usuário inicia num registro
2Pesquisar registroObter detalhes da Oportunidade ou dos itens de linha
3Requisição HTTPChamar a API de geração de PDF com os dados do registro
4CódigoBaixar e anexar o PDF gerado

Serviços populares de geração de PDF

  • Carbone — geração de documentos baseada em modelos.
  • PDFMonkey — criação dinâmica de PDF a partir de modelos.
  • DocuSeal — plataforma de automação de documentos.
  • Documint — geração de documentos orientada a API.

Cada serviço fornece uma API que devolve uma URL de PDF, que você pode então passar para a função.

Resolução de problemas

ProblemaSolução
”Falha ao baixar PDF”Verifique se a URL do PDF é acessível e devolve um PDF válido
”Falha no upload”Verifique se a sua chave de API é válida e tem permissões de escrita
”Falha ao criar anexo”Garanta que o nome do campo de ID do objeto corresponde ao objeto de destino

Relacionados