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

# Comentários

> Adicione e exclua comentários, com anexos, em um card

## Objeto Comentário

| Campo | Tipo | Descrição |
| - | - | - |
| `id` | `integer` | Identificador. |
| `text` | `string` | Texto. |
| `date` | `string` | Data de criação. |
| `user` | `object` | Autor. |
| `medias` | `array` | Anexos: `{ id, uuid, file_name, is_image, date }`. |

## Adicionar comentário

```http theme={null}
POST /task/{id}/comment
```

| Campo | Tipo | Obrigatório | Descrição |
| - | - | - | - |
| `text` | `string` | Sim | Texto. Pode ser vazio quando houver anexo. |
| `media` | `array` | Não | Anexos já enviados ao storage: `{ uuid, filePath }`. |

O responsável pelo card é avisado no WhatsApp, exceto quando ele mesmo é o autor.

Retorna `200` com o comentário criado.

### Anexos

O upload segue o mesmo fluxo de [Enviar mídia](/chat/enviar-midia.md): peça a URL assinada, envie o arquivo e informe o `uuid` e o `filePath` no comentário. Limite de **5 MB** por arquivo.

> [!WARNING]
>
> Use `tempFile=false` ao pedir a URL assinada. Anexo de comentário fica no card de forma permanente, e um arquivo temporário é apagado em 48 horas.

```javascript Node.js theme={null}
// 1. Pede a URL assinada
const params = new URLSearchParams({
  fileName: "contrato.pdf",
  contentType: "application/pdf",
  tempFile: "false",
});

const { signedUrl, uuid, filePath } = await fetch(
  `https://api.hustapp.com/file/signature?${params}`,
  { headers: { Authorization: `Bearer ${token}` } }
).then((r) => r.json());

// 2. Envia o arquivo
await fetch(signedUrl, {
  method: "PUT",
  headers: {
    "Content-Type": "application/pdf",
    "Content-Disposition": "attachment; filename=contrato.pdf",
  },
  body: fileBuffer,
});

// 3. Cria o comentário com o anexo
const comment = await fetch("https://api.hustapp.com/task/501/comment", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${token}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    text: "Contrato assinado pelo cliente",
    media: [{ uuid, filePath }],
  }),
}).then((r) => r.json());
```

```python Python theme={null}
import requests

headers = {"Authorization": f"Bearer {token}"}

# 1. Pede a URL assinada
signature = requests.get(
    "https://api.hustapp.com/file/signature",
    headers=headers,
    params={"fileName": "contrato.pdf", "contentType": "application/pdf", "tempFile": "false"},
).json()

# 2. Envia o arquivo
with open("contrato.pdf", "rb") as f:
    requests.put(
        signature["signedUrl"],
        data=f,
        headers={
            "Content-Type": "application/pdf",
            "Content-Disposition": "attachment; filename=contrato.pdf",
        },
    )

# 3. Cria o comentário com o anexo
comment = requests.post(
    "https://api.hustapp.com/task/501/comment",
    headers=headers,
    json={
        "text": "Contrato assinado pelo cliente",
        "media": [{"uuid": signature["uuid"], "filePath": signature["filePath"]}],
    },
).json()
```

```php PHP theme={null}
<?php
// 1. Pede a URL assinada
$query = http_build_query([
    'fileName' => 'contrato.pdf',
    'contentType' => 'application/pdf',
    'tempFile' => 'false',
]);
$ch = curl_init("https://api.hustapp.com/file/signature?{$query}");
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . $token],
]);
$signature = json_decode(curl_exec($ch), true);
curl_close($ch);

// 2. Envia o arquivo
$ch = curl_init($signature['signedUrl']);
curl_setopt_array($ch, [
    CURLOPT_CUSTOMREQUEST => 'PUT',
    CURLOPT_UPLOAD => true,
    CURLOPT_INFILE => fopen('contrato.pdf', 'r'),
    CURLOPT_INFILESIZE => filesize('contrato.pdf'),
    CURLOPT_HTTPHEADER => [
        'Content-Type: application/pdf',
        'Content-Disposition: attachment; filename=contrato.pdf',
    ],
]);
curl_exec($ch);
curl_close($ch);

// 3. Cria o comentário com o anexo
$ch = curl_init('https://api.hustapp.com/task/501/comment');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $token,
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode([
        'text' => 'Contrato assinado pelo cliente',
        'media' => [['uuid' => $signature['uuid'], 'filePath' => $signature['filePath']]],
    ]),
]);
$comment = json_decode(curl_exec($ch), true);
curl_close($ch);
```

```pascal Delphi theme={null}
uses
  System.Net.HttpClient, System.Classes, System.JSON, System.SysUtils;

var
  HttpClient: THTTPClient;
  Response: IHTTPResponse;
  Signature: TJSONObject;
  SignedUrl, FileUuid, FilePath: string;
  FileStream: TFileStream;
begin
  HttpClient := THTTPClient.Create;
  try
    // 1. Pede a URL assinada
    HttpClient.CustomHeaders['Authorization'] := 'Bearer ' + Token;
    Response := HttpClient.Get('https://api.hustapp.com/file/signature' +
      '?fileName=contrato.pdf&contentType=application/pdf&tempFile=false');

    Signature := TJSONObject.ParseJSONValue(Response.ContentAsString) as TJSONObject;
    try
      SignedUrl := Signature.GetValue<string>('signedUrl');
      FileUuid := Signature.GetValue<string>('uuid');
      FilePath := Signature.GetValue<string>('filePath');
    finally
      Signature.Free;
    end;

    // 2. Envia o arquivo, sem o token
    HttpClient.CustomHeaders['Authorization'] := '';
    FileStream := TFileStream.Create('contrato.pdf', fmOpenRead);
    try
      HttpClient.ContentType := 'application/pdf';
      HttpClient.CustomHeaders['Content-Disposition'] := 'attachment; filename=contrato.pdf';
      HttpClient.Put(SignedUrl, FileStream);
    finally
      FileStream.Free;
    end;

    // 3. Cria o comentário com o anexo
    HttpClient.CustomHeaders['Content-Disposition'] := '';
    HttpClient.CustomHeaders['Authorization'] := 'Bearer ' + Token;
    HttpClient.ContentType := 'application/json';
    Response := HttpClient.Post('https://api.hustapp.com/task/501/comment',
      TStringStream.Create(Format(
        '{ "text": "Contrato assinado pelo cliente", ' +
        '"media": [{ "uuid": "%s", "filePath": "%s" }] }',
        [FileUuid, FilePath]), TEncoding.UTF8));
  finally
    HttpClient.Free;
  end;
end;
```

Sem anexo, basta o texto:

```bash theme={null}
curl -X POST https://api.hustapp.com/task/501/comment \
  -H "Authorization: Bearer SEU_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "text": "Cliente pediu desconto de 10%" }'
```

## Excluir comentário

```http theme={null}
DELETE /task/{taskId}/comment/{commentId}
```

Gestores excluem qualquer comentário; os demais usuários, só os próprios.

| Status | Corpo |
| - | - |
| `200` | Comentário excluído. |
| `403` | `{ "message": "Você não tem permissão para excluir este comentário." }` |
| `404` | `{ "message": "TASK_NOT_FOUND" }` ou `COMMENT_NOT_FOUND` |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.