# PATCH /regras-comentario/{id} — Editar regra de comentário

- URL: `PATCH https://chat.forsi.com.br/api/v1/regras-comentario/{id}`
- Acesso: escopo `automacoes:escrever` · módulos do plano: API + Automações · aceita `Idempotency-Key`
- Sucesso: `200`, `{"dados": ...}` com `RegraComentario`
- Página: https://docs.forsi.com.br/api/automacoes/editar-regra-comentario (Markdown: https://docs.forsi.com.br/api/automacoes/editar-regra-comentario.md)

Só os campos enviados mudam. `ativo` liga ou desliga. Mudar `tipo` para `comum` apaga o bloco `seguir`. Em `seguir`, só os campos enviados mudam e os omitidos mantêm o valor atual (dentro de `conteudo` também; `conteudo.botao: null` tira o botão). O resultado final tem de continuar válido (por exemplo, não dá para ficar sem resposta nenhuma).

**Parâmetros no caminho**

| Campo | Tipo | Obrigatório | Notas |
| --- | --- | --- | --- |
| `id` | uuid | sim | No caminho da URL. |

**Corpo (JSON)**

| Campo | Tipo | Obrigatório | Notas |
| --- | --- | --- | --- |
| `nome` | string | não | Nome da regra, só para você identificar. até 80 caracteres |
| `conexao_id` | uuid | não | Conta do Instagram (GET /instagram/contas). |
| `post_id` | string ou null | não | Id da publicação. null = vale para qualquer publicação (não recomendado: responde em todos os posts). |
| `palavras` | lista de string | não | Até 30 palavras. Vazio só com `qualquer_comentario: true`. |
| `modo` | "contem" \| "igual" | não | `contem`: o comentário tem a palavra. `igual`: o comentário é só a palavra. |
| `qualquer_comentario` | boolean | não | true = dispara em qualquer comentário, sem palavras. Precisa estar liberado na organização. |
| `responder_publico` | string ou null | não | Resposta pública ao comentário (até 2200 caracteres). |
| `respostas_publicas` | lista de string | não | Variações da resposta pública (até 5), sorteadas a cada comentário. Precisa de `responder_publico`. |
| `ocultar_apos` | boolean | não | Oculta o comentário depois de responder. Precisa de `responder_publico`. |
| `resposta_privada` | string ou null | não | Mensagem direta enviada a quem comentou (até 1000 caracteres). |
| `automacao_id` | uuid ou null | não | Automação a iniciar com a resposta privada (GET /automacoes?gatilho=comentario). Precisa de `resposta_privada`. |
| `botoes` | lista de string ou object | não | Até 3 botões na mensagem direta. Cada botão é um texto (devolve o toque) ou `{ titulo, url? }`; com `url` (https) abre o link. Se a Meta recusar os botões nessa resposta, a mensagem sai só com texto e os links entram no fim do texto. Precisa de `resposta_privada` e de estar liberado na organização. |
| `ativo` | boolean | não | Liga ou desliga a regra. Ao criar, o padrão é false. |
| `tipo` | "comum" \| "seguir" | não | `comum` (padrão): responde e manda a mensagem. `seguir`: o conteúdo só é entregue a quem segue a conta; veja `seguir`. No tipo `seguir` não use `automacao_id` nem `botoes`. |
| `seguir` | object | não | Mesmo formato de `seguir`, com todos os campos opcionais (inclusive dentro de `conteudo`). Só os campos enviados mudam; os omitidos mantêm o valor atual. `max_tentativas: null` e `texto_limite: null` voltam ao padrão (sem limite). Se a regra era `comum`, o que faltar vem dos padrões e `conteudo.texto` é obrigatório. |
| `seguir.botao_receber` | string | não | Texto do botão que vai junto da mensagem do comentário. 1 a 20 caracteres, sem variáveis (o banco recusa "{"). Padrão: "Quero receber". |
| `seguir.texto_nao_segue` | string | não | Mensagem para quem pediu e ainda não segue a conta. 1 a 640 caracteres. Padrão: "Para receber, é só seguir o perfil @{conta} e depois tocar em "Estou seguindo".". Aceita {nome}, {usuario} e {conta}. |
| `seguir.botao_estou_seguindo` | string | não | Texto do botão para avisar que passou a seguir. 1 a 20 caracteres, sem variáveis (o banco recusa "{"). Padrão: "Estou seguindo". |
| `seguir.texto_ainda_nao_segue` | string | não | Mensagem quando a pessoa toca em "Estou seguindo" e ainda não segue. 1 a 640 caracteres. Padrão: "Ainda não apareceu que você segue @{conta}. Siga o perfil e toque de novo em "Estou seguindo".". Aceita {nome}, {usuario} e {conta}. |
| `seguir.texto_ja_segue` | string | não | Mensagem antes do conteúdo para quem já seguia. 0 a 640 caracteres. Padrão: "Que bom ter você por aqui! Aqui está o que você pediu:". Vazio ("") = não envia este texto, só o conteúdo. Aceita {nome}, {usuario} e {conta}. |
| `seguir.texto_seguiu_depois` | string | não | Mensagem antes do conteúdo para quem acabou de seguir. 0 a 640 caracteres. Padrão: "Obrigado por seguir! Aqui está o que você pediu:". Vazio ("") = não envia este texto, só o conteúdo. Aceita {nome}, {usuario} e {conta}. |
| `seguir.conteudo` | object | não | Só o que mudar: `texto`, `botao` ou os dois. `botao: null` tira o botão. |
| `seguir.max_tentativas` | integer ou null | não | Quantas vezes conferir se a pessoa passou a seguir (1 a 50). Padrão: null = confere até seguir, no máximo 50 vezes. |
| `seguir.texto_limite` | string ou null | não |  |
| `seguir.se_nao_verificar` | "enviar" \| "pedir_de_novo" | não | Se a Meta não deixar conferir: `enviar` (padrão) entrega o conteúdo assim mesmo; `pedir_de_novo` pede para seguir outra vez. |

**Exemplo (curl)**

```bash
curl -X PATCH "https://chat.forsi.com.br/api/v1/regras-comentario/7f0a344c-4fb9-4180-8d9b-46d51ab38635" \
  -H "Authorization: Bearer $FORSI_CHAVE" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: pedido-4821" \
  -d '{"palavras":["preço","valor","quanto custa"],"ativo":false}'
```

**JavaScript (fetch)**

```js
const resposta = await fetch('https://chat.forsi.com.br/api/v1/regras-comentario/7f0a344c-4fb9-4180-8d9b-46d51ab38635', {
  method: 'PATCH',
  headers: {
    Authorization: `Bearer ${process.env.FORSI_CHAVE}`,
    'Content-Type': 'application/json',
    'Idempotency-Key': 'pedido-4821',
  },
  body: JSON.stringify({"palavras":["preço","valor","quanto custa"],"ativo":false}),
});
const json = await resposta.json();
if (!resposta.ok) throw new Error(`${resposta.status} ${json.erro.codigo}: ${json.erro.mensagem}`);
console.log(json.dados);
```

**Python (requests)**

```python
import os
import requests

resposta = requests.patch(
    "https://chat.forsi.com.br/api/v1/regras-comentario/7f0a344c-4fb9-4180-8d9b-46d51ab38635",
    headers={
        "Authorization": f"Bearer {os.environ['FORSI_CHAVE']}",
        "Idempotency-Key": "pedido-4821",
    },
    json={
        "palavras": ["preço", "valor", "quanto custa"],
        "ativo": False,
    },
    timeout=30,
)
corpo = resposta.json()
if not resposta.ok:
    raise RuntimeError(f"{resposta.status_code} {corpo['erro']['codigo']}: {corpo['erro']['mensagem']}")
print(corpo["dados"])
```

**Resposta `200` (exemplo)**

```json
{
  "dados": {
    "id": "cc23f373-2c83-42d6-83a7-c4e00ac10c39",
    "nome": "Maria Souza",
    "ativo": true,
    "conexao_id": "11908b04-f817-4068-afa6-896d3e1b7265",
    "post_id": "texto",
    "palavras": ["texto"],
    "modo": "contem",
    "qualquer_comentario": false,
    "automacao_id": "b6b1fba7-e2a3-4922-a365-70584a78e091",
    "automacao": "texto",
    "responder_publico": "texto",
    "resposta_privada": "texto",
    "respostas_publicas": ["texto"],
    "ocultar_apos": false,
    "botoes": ["texto"],
    "botoes_detalhe": [{"titulo":"Consulta de retorno","url":"https://seu-sistema.com.br/webhooks/forsi"}],
    "tipo": "comum",
    "seguir": {
      "botao_receber": "texto",
      "texto_nao_segue": "texto",
      "botao_estou_seguindo": "texto",
      "texto_ainda_nao_segue": "texto",
      "texto_ja_segue": "texto",
      "texto_seguiu_depois": "texto",
      "conteudo": {
        "texto": "Oi, queria remarcar minha consulta",
        "botao": {"titulo":"Consulta de retorno","url":"https://seu-sistema.com.br/webhooks/forsi"}
      },
      "max_tentativas": 12,
      "texto_limite": "texto",
      "se_nao_verificar": "enviar"
    },
    "estatisticas": {"pediram":12,"entregues":42,"ja_seguiam":12,"seguiram_depois":12,"aguardando":12},
    "atualizado_em": "2026-10-04T13:05:12.481Z",
    "execucoes_7d": 12,
    "ultima_em": "2026-10-04T13:05:12.481Z"
  }
}
```

**Campos de `RegraComentario`**

| Campo | Tipo | Obrigatório | Notas |
| --- | --- | --- | --- |
| `id` | uuid | não |  |
| `nome` | string | não |  |
| `ativo` | boolean | não |  |
| `conexao_id` | uuid | não |  |
| `post_id` | string ou null | não |  |
| `palavras` | lista de string | não |  |
| `modo` | "contem" \| "igual" | não |  |
| `qualquer_comentario` | boolean | não |  |
| `automacao_id` | uuid ou null | não |  |
| `automacao` | string ou null | não | Nome da automação. |
| `responder_publico` | string ou null | não |  |
| `resposta_privada` | string ou null | não |  |
| `respostas_publicas` | lista de string | não |  |
| `ocultar_apos` | boolean | não |  |
| `botoes` | lista de string | não |  |
| `botoes_detalhe` | lista de object | não | Os mesmos botões com o link: `url` não aparece no botão que só devolve o toque. |
| `botoes_detalhe[].titulo` | string | não |  |
| `botoes_detalhe[].url` | string | não |  |
| `tipo` | "comum" \| "seguir" | não | `comum` ou `seguir` ("Seguir para receber"). Regras antigas são `comum`. |
| `seguir` | object ou null | não | Só no tipo `seguir`: completo, com os padrões aplicados. Não aparece no tipo `comum`; dentro dele, `conteudo.botao`, `max_tentativas` e `texto_limite` também não aparecem enquanto forem null. |
| `seguir.botao_receber` | string | não | Botão da mensagem do comentário (1 a 20). Padrão: "Quero receber". |
| `seguir.texto_nao_segue` | string | não | Para quem ainda não segue (1 a 640). |
| `seguir.botao_estou_seguindo` | string | não | Botão para avisar que passou a seguir (1 a 20). Padrão: "Estou seguindo". |
| `seguir.texto_ainda_nao_segue` | string | não | Quando toca em "Estou seguindo" e ainda não segue (1 a 640). |
| `seguir.texto_ja_segue` | string | não | Antes do conteúdo, para quem já seguia (0 a 640; "" = não envia). |
| `seguir.texto_seguiu_depois` | string | não | Antes do conteúdo, para quem acabou de seguir (0 a 640; "" = não envia). |
| `seguir.conteudo` | object | não | O que é entregue. |
| `seguir.max_tentativas` | integer ou null | não | null = confere até seguir (no máximo 50 vezes). mín. 1 |
| `seguir.texto_limite` | string ou null | não | Enviada uma vez quando as tentativas acabam (1 a 640). |
| `seguir.se_nao_verificar` | "enviar" \| "pedir_de_novo" | não | Quando a Meta não deixa conferir. Padrão: `enviar`. |
| `estatisticas` | object ou null | não | Só no tipo `seguir`. Contagem desde que a regra existe. |
| `estatisticas.pediram` | integer | não | Pessoas que receberam o botão. |
| `estatisticas.entregues` | integer | não | Pessoas que receberam o conteúdo. |
| `estatisticas.ja_seguiam` | integer | não | Já seguiam ao pedir. |
| `estatisticas.seguiram_depois` | integer | não | Passaram a seguir depois de pedir. |
| `estatisticas.aguardando` | integer | não | Ainda esperando tocar ou seguir. |
| `atualizado_em` | data e hora ISO 8601 | não |  |
| `execucoes_7d` | integer | não | Disparos nos últimos 7 dias. |
| `ultima_em` | data e hora ISO 8601 ou null | não |  |

**Erros**

- `401`: Chave ausente ou inválida (resposta igual para qualquer motivo).
- `403`: Plano sem API, escopo insuficiente ou https/origem recusados.
- `404`: Não existe nesta organização.
- `409`: Conflito (repetido, Idempotency-Key com outro corpo).
- `422`: Dados inválidos ou regra de negócio (ex.: janela_fechada; conta_restrita = a Meta restringiu a conta por spam: erro traz os campos de RestricaoMeta, como ate, escopo, motivo e retry_after_s).
- `429`: Limite de requisições. Veja Retry-After.
- Códigos comuns aqui: `regra_inexistente`, `regra_conexao_invalida`, `regra_sem_palavras`, `regra_modo_invalido`, `regra_sem_acao`, `regra_texto_longo`, `regra_variantes_demais`, `regra_extra_sem_publico`, `regra_automacao_invalida`, `regra_automacao_sem_privada`, `regra_botao_longo`, `regra_botao_repetido`, `regra_botao_url_invalida`, `regra_botoes_demais`, `regra_botoes_invalidos`, `regra_botoes_sem_privada`, `recurso_desligado`, `seguir_invalido`, `limite_de_regras`.

---

Página: https://docs.forsi.com.br/api/automacoes/editar-regra-comentario · Índice: https://docs.forsi.com.br/llms.txt · Tudo num arquivo: https://docs.forsi.com.br/llms-full.txt
