> ## Documentation Index
> Fetch the complete documentation index at: https://docs.devinenterprise.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Correção automática de tickets via webhooks

export const UseCaseHero = ({title, description, prompt, category, features, devinUrl, agent, intent, playbookId, type}) => {
  const encodedPrompt = encodeURIComponent(prompt || '');
  const tag = 'docs-use-case-gallery';
  const utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=hero-cta';
  const agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  const devinHref = type === 'schedule' ? 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + (prompt ? '&prompt=' + encodedPrompt : '') : type === 'review' ? 'https://app.devin.ai/review?' + utm : agent === 'ada' ? 'https://app.devin.ai/search?' + utm + '&noSubmit=true' + (prompt ? '&prompt=' + encodedPrompt : '') : devinUrl ? devinUrl.includes('?') ? devinUrl + '&' + utm + agentParams : devinUrl + '?' + utm + agentParams : prompt ? 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encodedPrompt : 'https://app.devin.ai/?' + utm + agentParams;
  const buttonLabel = type === 'schedule' ? 'Schedule in Devin ↗' : type === 'review' ? 'Set Up Devin Review ↗' : agent === 'advanced' ? 'Try in Devin ↗' : agent === 'dana' ? 'Try in Dana ↗' : agent === 'ada' ? 'Try in Ask Devin ↗' : 'Try in Devin ↗';
  const featureList = features ? features.split(',').map(f => f.trim()) : [];
  return <div className="uc-hero">
      <div className="uc-hero-inner">
        <div className="uc-hero-left">
          <h1 className="uc-hero-title">{title}</h1>
          <p className="uc-hero-desc">{description}</p>
          <div>
            <a href={devinHref} target="_blank" rel="noopener noreferrer" className="try-in-devin-btn">
              {buttonLabel}
            </a>
          </div>
        </div>
        <div className="uc-hero-meta">
          <div className="uc-meta-item">
            <span className="uc-meta-label">Author</span>
            <span className="uc-meta-value">Cognition</span>
          </div>
          <div className="uc-meta-item">
            <span className="uc-meta-label">Category</span>
            <span className="uc-meta-value">{category}</span>
          </div>
          {featureList.length > 0 && <div className="uc-meta-item">
              <span className="uc-meta-label">Features</span>
              <span className="uc-meta-value">{featureList.join(', ')}</span>
            </div>}
        </div>
      </div>
    </div>;
};

export const PromptBlock = ({children, type, agent, intent, playbookId}) => {
  var utm = 'utm_source=docs&utm_medium=use-case-gallery&utm_campaign=prompt-block';
  var tag = 'docs-use-case-gallery';
  var agentParams = (agent ? '&agent=' + agent : '') + (intent ? '&intent=' + intent : '') + (playbookId ? '&playbookId=' + playbookId : '');
  var label = type === 'schedule' ? 'Schedule in Devin' : type === 'playbook' ? 'Create Playbook' : type === 'knowledge' ? 'Add to Knowledge' : agent === 'advanced' ? 'Try in Devin' : agent === 'dana' ? 'Try in Dana' : agent === 'ada' ? 'Try in Ask Devin' : 'Try in Devin';
  var buildUrl = function (text) {
    var encoded = encodeURIComponent(text);
    if (type === 'schedule') return 'https://app.devin.ai/settings/schedules/create?' + utm + agentParams + '&prompt=' + encoded;
    if (type === 'playbook') return 'https://app.devin.ai/settings/playbooks/create?' + utm + '&body=' + encoded;
    if (type === 'knowledge') return 'https://app.devin.ai/knowledge?' + utm + '&body=' + encoded;
    if (agent === 'ada') return 'https://app.devin.ai/search?' + utm + '&noSubmit=true&prompt=' + encoded;
    return 'https://app.devin.ai/?tags=' + tag + '&' + utm + agentParams + '&prompt=' + encoded;
  };
  const ref = React.useRef(null);
  const [href, setHref] = React.useState('#');
  React.useEffect(() => {
    if (!ref.current) return;
    var codeEl = ref.current.querySelector('pre code');
    if (codeEl) {
      var text = codeEl.textContent.trim();
      if (text) setHref(buildUrl(text));
    }
    var header = ref.current.querySelector('[data-component-part="code-block-header"]');
    if (header && !header.querySelector('.prompt-block-devin-link')) {
      var link = document.createElement('a');
      link.href = href;
      link.target = '_blank';
      link.rel = 'noopener noreferrer';
      link.className = 'prompt-block-devin-link';
      link.style.cssText = 'display:inline-flex;align-items:center;gap:6px;text-decoration:none;color:#fff;font-size:11px;font-weight:500;padding:4px 10px;border-radius:6px;white-space:nowrap;background:#317CFF;transition:background 0.2s;margin-left:8px;';
      link.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg> ' + label;
      link.onmouseenter = function () {
        link.style.background = '#2968D9';
      };
      link.onmouseleave = function () {
        link.style.background = '#317CFF';
      };
      header.appendChild(link);
    }
    var existingLink = ref.current.querySelector('.prompt-block-devin-link');
    if (existingLink && href !== '#') existingLink.href = href;
  });
  return <div className="prompt-block" ref={ref}>{children}</div>;
};

<UseCaseHero title="Correção Automática de Tíquetes via Webhooks" description="Conecte sistemas de tíquetes locais (on-prem) ou não compatíveis ao Devin com uma ponte de webhook-para-sessão." prompt="Ajude-me a configurar um pipeline de webhook-para-Devin para meu sistema de tíquetes. Siga o guia em https://docs.devin.ai/use-cases/gallery/api-webhook-custom-ticketing e me explique cada etapa: criar um usuário de serviço, criar o manipulador de webhook e configurar meu sistema de tíquetes para enviar eventos para ele." category="Automação" features="API, Playbooks" />

<div className="uc-detail-wrapper">
  <Tip>Não quer configurar isso manualmente? Cole um link para esta página em uma sessão do Devin e peça para ele configurar tudo para você.</Tip>

  <Steps>
    <Step title="Criar um usuário de serviço">
      Devin usa [tokens de usuário de serviço](/pt-BR/api-reference/v3/overview) para autenticar requisições à API. Esta é a abordagem recomendada para automação em produção.

      1. Vá para [app.devin.ai](https://app.devin.ai/?utm_source=docs\&utm_medium=use-case-gallery) > **Settings** > **Service Users** e crie um novo usuário de serviço com a permissão `ManageOrgSessions`
      2. Copie o token de API exibido após a criação e armazene-o com segurança — ele é exibido apenas uma vez e você o usará como `DEVIN_API_KEY` no seu manipulador de webhook

      Para encontrar o ID da sua organização, faça uma chamada `GET https://api.devin.ai/v3/enterprise/organizations` com o seu token — a URL mostra apenas o slug da organização, não o ID.

      Teste com um comando curl rápido:

      ```bash theme={null}
      curl -X POST https://api.devin.ai/v3/organizations/YOUR_ORG_ID/sessions \
        -H "Authorization: Bearer YOUR_API_TOKEN" \
        -H "Content-Type: application/json" \
        -d '{"prompt": "Say hello — this is a test session."}'
      ```

      Você deve receber um `session_id` e uma `url`. Exclua a sessão de teste no aplicativo web do Devin e prossiga.
    </Step>

    <Step title="Crie o manipulador de webhook">
      Esse padrão é ideal para **sistemas de tickets on‑premises** (como Jira, Redmine ou Bugzilla em hospedagem própria) ou **ferramentas de tickets que não têm integração nativa com o Devin** (diferente do [Linear](/pt-BR/integrations/linear) e do [Jira Cloud](/pt-BR/integrations/jira), que têm suporte integrado). Se o seu sistema de tickets oferece suporte a webhooks, você pode conectá‑lo ao Devin com um pequeno serviço.

      Inclua um link para a documentação da API do seu sistema de tickets no prompt para que o Devin consiga entender como enviar comentários de volta para os tickets. Passe o token da API de tickets como um [session secret](/pt-BR/api-reference/common-flows) para que o Devin possa se autenticar diretamente.

      Peça ao Devin para criar a estrutura inicial:

      <PromptBlock>
        ```txt Manipulador de webhook para sistema de tickets personalizado theme={null}
        Crie um serviço em Express.js que:
        1. Aceite POST /webhooks/tickets com um corpo JSON contendo id, title,
           description e labels
        2. Verifique a assinatura do webhook usando HMAC-SHA256
        3. Ignore tickets sem o rótulo "devin-autofix" ou "devin-feature"
        4. Chame POST https://api.devin.ai/v3/organizations/{org_id}/sessions
           com um prompt construído a partir dos campos do ticket, um playbook_id
           baseado no rótulo e o token da API de tickets como um session secret

        Leia DEVIN_API_KEY, DEVIN_ORG_ID, TICKET_API_TOKEN e WEBHOOK_SECRET
        de variáveis de ambiente.
        ```
      </PromptBlock>

      Veja como fica o handler principal:

      ```javascript theme={null}
      const PLAYBOOKS = {
        'devin-autofix': 'playbook-a1b2c3d4e5f6',
        'devin-feature': 'playbook-f6e5d4c3b2a1',
      };

      app.post('/webhooks/tickets', async (req, res) => {
        if (!verifySignature(req)) return res.status(401).send('Bad signature');

        const { id, title, description, labels } = req.body;
        const label = labels.find(l => PLAYBOOKS[l]);
        if (!label) return res.status(200).send('No Devin label — skipped');

        const orgId = process.env.DEVIN_ORG_ID;
        const { session_id } = await fetch(
          `https://api.devin.ai/v3/organizations/${orgId}/sessions`, {
          method: 'POST',
          headers: {
            'Authorization': `Bearer ${process.env.DEVIN_API_KEY}`,
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            prompt: [
              `Ticket ${id}: ${title}`,
              description,
              `Reference ticket ${id} in your commit message.`,
              `When done, post a comment on ticket ${id} with a summary of your`,
              `changes and a link to the PR. Use the ticketing API at`,
              `https://your-ticketing-system.com/api/docs to post the comment.`,
              `Authenticate with the $TICKET_API_TOKEN environment variable.`,
            ].join('\n\n'),
            playbook_id: PLAYBOOKS[label],
            session_secrets: [
              { key: 'TICKET_API_TOKEN', value: process.env.TICKET_API_TOKEN },
            ],
          }),
        }).then(r => r.json());

        res.json({ session_id });
      });
      ```

      O mapa `PLAYBOOKS` direciona rótulos de tickets para os [playbooks](/pt-BR/product-guides/creating-playbooks) que você cria em **Settings > Playbooks**. Um playbook de correção de bug pode dizer *"Sempre adicione um teste de regressão"*; um playbook de feature pode dizer *"Crie um PR em rascunho e solicite revisão."*

      O prompt inclui um link para a documentação da API do seu sistema de tickets, para que o Devin saiba como enviar comentários de volta. O `TICKET_API_TOKEN` é passado como um [session secret](/pt-BR/api-reference/common-flows) — ele é injetado como uma variável de ambiente apenas para aquela sessão e nunca é armazenado. Substitua a URL da documentação da API pela documentação real do seu sistema de tickets.

      Implante o handler em qualquer lugar que possa receber solicitações POST HTTPS — uma função em nuvem (AWS Lambda, Google Cloud Functions), um contêiner ou um VPS. Registre sua URL como um webhook nas configurações de notificação ou integração do seu sistema de tickets e filtre por eventos de **ticket created**.

      Crie um ticket de teste com o rótulo `devin-autofix` para verificar o ciclo completo: ticket created → webhook é disparado → sessão do Devin é iniciada → PR é aberto → Devin publica um comentário no ticket.
    </Step>
  </Steps>
</div>
