## Скачать вложение комментария таймлайна

`GET /v1/timelines/:commentId/files/:fileRef/download`

Скачивает файл, приложенный к комментарию таймлайна. Ответ — бинарный поток с заголовком `Content-Disposition`.

Эндпоинт принимает **два разных идентификатора** в `fileRef`, потому что клиент может держать любой из них:

- **ID привязки.** Его показывает интерфейс портала, и он же приходит в файловых пользовательских полях. Этот путь считает доступ через сущность-носитель, то есть через сам комментарий, а не через личные права на Диске — поэтому он дотягивается до вложений, которые [скачивание файла Диска](/docs/entities/files/download) отдавать отказывается;
- **ID объекта Диска.** Это ключ объекта в поле `files` ответа [`GET /v1/timelines/:id`](/docs/entities/timelines/get). Путь идёт через личные права на Диске, поэтому может завершиться отказом там, где путь по ID привязки сработал бы.

Сначала комментарий читается сам, затем пробуется ID объекта Диска, и только если его нет в списке файлов комментария — ID привязки. Указывать, какой идентификатор вы передаёте, не нужно. Такой порядок дешевле: документированный случай обходится двумя обращениями к Битрикс24 вместо трёх.

## Параметры

| Параметр | В | Тип | Обяз. | Описание |
|----------|---|-----|:-----:|----------|
| `commentId` | path | number | да | ID комментария таймлайна. Получить: [`GET /v1/timelines`](/docs/entities/timelines/list) |
| `fileRef` | path | number | да | ID привязки либо ID объекта Диска. Второй — ключ объекта в поле `files` ответа [`GET /v1/timelines/:id`](/docs/entities/timelines/get) |

Тело запроса пустое.

## Примеры

### curl — личный ключ

```bash
# По ID объекта Диска — ключ из поля files ответа комментария
curl -OJ -H "X-Api-Key: YOUR_API_KEY" \
  https://vibecode.bitrix24.tech/v1/timelines/67689/files/9747/download

# По ID привязки — если он у вас есть
curl -OJ -H "X-Api-Key: YOUR_API_KEY" \
  https://vibecode.bitrix24.tech/v1/timelines/67689/files/551/download
```

### curl — OAuth-приложение

```bash
curl -OJ \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  https://vibecode.bitrix24.tech/v1/timelines/67689/files/9747/download
```

### JavaScript — личный ключ

```javascript
// Идентификаторы вложений берём из ответа комментария
const comment = await fetch(
  'https://vibecode.bitrix24.tech/v1/timelines/67689',
  { headers: { 'X-Api-Key': 'YOUR_API_KEY' } },
).then(r => r.json())

for (const objectId of Object.keys(comment.data.files ?? {})) {
  const res = await fetch(
    `https://vibecode.bitrix24.tech/v1/timelines/67689/files/${objectId}/download`,
    { headers: { 'X-Api-Key': 'YOUR_API_KEY' } },
  )
  if (!res.ok) {
    const { error } = await res.json()
    console.warn(`${objectId}: ${error.code}`)
    continue
  }
  console.log(objectId, 'байт:', (await res.arrayBuffer()).byteLength)
}
```

### JavaScript — OAuth-приложение

```javascript
const res = await fetch(
  'https://vibecode.bitrix24.tech/v1/timelines/67689/files/9747/download',
  {
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  },
)

const bytes = await res.arrayBuffer()
```

## Заголовки ответа

При успехе возвращается бинарное содержимое файла (HTTP 200). Секции `## Поля ответа` нет — тело ответа не является JSON.

| Заголовок | Пример значения | Описание |
|-----------|-----------------|----------|
| `Content-Type` | `image/gif` | Тип содержимого, как его отдал Битрикс24 |
| `Content-Disposition` | `attachment; filename="scan.pdf"` | Имя файла для сохранения |
| `Content-Length` | `43` | Размер в байтах, если Битрикс24 его сообщил |

## Пример ответа при ошибке

404 — вложение относится к другому комментарию:

```json
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "Attachment 551 does not belong to comment 11111"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 400 | `INVALID_PARAMS` | `commentId` или `fileRef` не является положительным целым числом |
| 401 | `TOKEN_MISSING` | У ключа не настроены токены Битрикс24 |
| 403 | `SCOPE_DENIED` | Ключу не хватает скоупа `crm` |
| 404 | `NOT_FOUND` | Комментария не существует, вложение относится к другому комментарию или к записи другого типа (задаче, предложению) либо его принадлежность комментарию подтвердить не удалось, файл не входит в его список файлов, либо у файла нет адреса для скачивания |
| 502 | `DOWNLOAD_FAILED` | Битрикс24 не отдал файл либо назвал адрес за пределами домена аккаунта — по такому адресу запрос не уходит |

Полный список общих ошибок API — [Ошибки](/docs/errors).

## Известные особенности

- **Вложение обязано относиться к названному комментарию.** Иначе — `404`. Без этой проверки эндпоинт позволял бы перебирать вложения портала.
- **Адрес наружу не отдаётся.** В адресе для скачивания содержится код авторизации, поэтому эндпоинт отдаёт только поток байтов.
- **Поле `urlDownload` из ответа комментария напрямую не работает.** Этот адрес ведёт на страницу Диска, а не в REST, и авторизовать его ключом нельзя: запрос по нему перенаправляет на страницу входа. Скачивайте через этот эндпоинт.
- **Два пути дают разный доступ.** Если по ID объекта Диска приходит отказ по правам, а ID привязки у вас есть — попробуйте его: он считает доступ через комментарий, а не через личное хранилище.
- **Адрес скачивания проверяется, включая перенаправления.** Он приходит в ответе Битрикс24, поэтому эндпоинт сверяет его с доменом аккаунта и по чужому адресу запрос не отправляет — иначе туда ушёл бы код авторизации. Перенаправления эндпоинт проходит сам, проверяя каждый шаг: цепочка ограничена по длине и по времени, а перенаправление на внутренний адрес не выполняется и приводит к `502`.
- **Временная ошибка не выдаётся за `404`.** Если Битрикс24 ответил лимитом запросов, оказался недоступен или сработала защита от повторяющихся ошибок, приходит именно это — `429` либо `502`/`503` с заголовком `Retry-After`, а не «файл не относится к комментарию». Поэтому `404` здесь всегда означает неверную ссылку: повторять запрос по ней бессмысленно, а по `429`/`5xx` — нужно, с задержкой.

## Смотрите также

- [Получить комментарий таймлайна](/docs/entities/timelines/get)
- [Скачать файл дела](/docs/entities/activities/file-download)
- [Скачать файл Диска](/docs/entities/files/download)
- [Таймлайны](/docs/entities/timelines)
