> ## Documentation Index
> Fetch the complete documentation index at: https://ayakaleaf-pro.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Синхронізація з Dropbox

> Дозвольте користувачам синхронізувати свої проєкти з папкою у їхньому Dropbox у розгортанні Kubernetes.

Синхронізація з Dropbox використовує три частини кожного пода Ayakaleaf Pro, і всі три запускаються лише з `DROPBOX_ENABLED: "true"`:

* **web** (модуль `dropbox`): прив'язка, діалог Dropbox проєкту та webhook, який викликає Dropbox.
* **third-party-datastore**: окрема служба всередині пода, яка опрацьовує чергу змін, що їх треба надіслати до Dropbox або отримати з нього.
* **document-updater**: з увімкненим Dropbox він у фоновому режимі записує зміни з редактора в MongoDB через кілька хвилин після того, як усі залишили проєкт; лише тоді вони потрапляють до Dropbox.

Створіть застосунок Dropbox і прочитайте, як працює синхронізація, у розділі [Синхронізація з Dropbox](https://ayakaleaf-pro.mintlify.site/uk/on-premises/configuration/overleaf-toolkit/integrations/dropbox-synchronisation.md); ця сторінка описує, як перенести це в Kubernetes.

| | |
| - | - |
| Служби | web (модуль `dropbox`), third-party-datastore і document-updater, у кожному поді Ayakaleaf Pro |
| Dropbox → Overleaf | `POST ${OVERLEAF_SITE_URL}/dropbox/webhook` з інтернету, підписаний секретом застосунку |
| Под → Dropbox | `https://api.dropboxapi.com` і `https://content.dropboxapi.com` |
| Браузер → Dropbox | `https://www.dropbox.com/oauth2/authorize`, а потім назад до `${OVERLEAF_SITE_URL}/user/dropbox/oauth/callback` |
| Стан | черга незавершених змін і її блокування в Redis; стан синхронізації в MongoDB (`dropboxEntities`, `dropboxProjects`) |
| Фонова робота | third-party-datastore перевіряє свою чергу щосекунди; document-updater записує проєкти, які ніхто не відкривав протягом 3 хвилин |

### Конфігурація

**1. ConfigMap**

```yaml title="30-config.yaml (additions)" theme={null}
  DROPBOX_ENABLED: "true"
  DROPBOX_APP_KEY: <app key>
  DROPBOX_APP_NAME: Overleaf      # the folder name under Apps/ in Dropbox
  # optional: send the requests to Dropbox through an HTTP proxy
  # DROPBOX_SYNC_PROXY_URL: http://proxy.example.com:3128
```

`GIT_BRIDGE_ENABLED: "true"` і StatefulSet git-bridge з розділу [Інтеграція з Git](https://ayakaleaf-pro.mintlify.site/uk/on-premises/configuration/kubernetes/integrations/git-integration.md) мають бути налаштовані: без них налаштування облікового запису приховують розділ синхронізації проєктів.

**2. Secret**

```bash theme={null}
kubectl -n overleaf patch secret overleaf-secrets --type merge -p '{"stringData":{
  "DROPBOX_APP_SECRET":"<app secret>",
  "DROPBOX_TOKEN_CIPHER_PASSWORD":"'"$(openssl rand -hex 32)"'"}}'
```

`DROPBOX_TOKEN_CIPHER_PASSWORD` шифрує токени Dropbox користувачів у MongoDB. Кожна репліка має використовувати те саме значення, а його подальша зміна змушує кожного користувача знову прив'язати Dropbox.

**3. Створіть індекси бази даних**

Один раз виконайте команди створення індексів із розділу [Створення індексів бази даних](https://ayakaleaf-pro.mintlify.site/uk/on-premises/configuration/overleaf-toolkit/integrations/dropbox-synchronisation.md#create-the-database-indexes) на первинному вузлі набору реплік:

```bash wrap theme={null}
kubectl -n overleaf exec -i mongo-0 -- mongosh --quiet \
  'mongodb://mongo-0.mongo:27017,mongo-1.mongo:27017,mongo-2.mongo:27017/sharelatex?replicaSet=overleaf' <<'EOF'
db.dropboxEntities.createIndex(
  { 'overleaf.userId': 1, 'dropbox.id': 1 },
  { name: 'overleaf.userId_1_dropbox.id_1', unique: true,
    partialFilterExpression: { 'dropbox.id': { $exists: true } } })
db.dropboxEntities.createIndex(
  { 'overleaf.userId': 1, 'overleaf.id': 1 },
  { name: 'overleaf.userId_1_overleaf.id_1', unique: true,
    partialFilterExpression: { 'overleaf.id': { $exists: true } } })
db.dropboxEntities.createIndex({ 'overleaf.userId': 1, 'dropbox.pathLower': 'hashed' })
db.dropboxProjects.createIndex({ userId: 1, projectId: 1 }, { name: 'projectId_userId_1', unique: true })
db.dropboxProjects.createIndex({ userId: 1, dropboxId: 1 }, { name: 'userId_dropboxId_1', unique: true })
EOF
```

**4. Застосуйте й перезапустіть**

```bash theme={null}
kubectl apply -f 30-config.yaml
kubectl -n overleaf rollout restart deployment/overleaf     # or statefulset/overleaf
kubectl -n overleaf exec deploy/overleaf -- tail -n 5 /var/log/overleaf/third-party-datastore.log
```

`third-party-datastore.log` існує, лише коли `DROPBOX_ENABLED` дорівнює `"true"`.

**5. Відкрийте webhook для інтернету**

Dropbox має мати доступ до `${OVERLEAF_SITE_URL}/dropbox/webhook` з інтернету. Якщо ваш ingress або балансувальник навантаження дозволяє ззовні лише деякі шляхи чи мережі, дозвольте цей; це єдиний шлях, який викликає Dropbox. Перевірте його ззовні кластера:

```bash theme={null}
curl "https://overleaf.example.com/dropbox/webhook?challenge=test"   # prints: test
```

Потім додайте webhook у Dropbox App Console, як описано на сторінці Toolkit.

### Кілька реплік

Нічого додаткового, окрім спільного `DROPBOX_TOKEN_CIPHER_PASSWORD`:

* Webhook може надійти на будь-яку репліку. Він лише ставить зміну в чергу в Redis.
* Кожна репліка запускає third-party-datastore, і кожна працює зі спільною чергою. Черга користувача захоплюється з блокуванням у Redis, тож зміни певного користувача одночасно надсилає або отримує лише одна репліка.
* document-updater кожної репліки у фоновому режимі записує неактивні проєкти. Кожен проєкт береться зі спільного списку в Redis, тож записується один раз.

### Перевірено в Kubernetes

Із макетом API Dropbox, у Kubernetes 1.37 із трьома репліками за HAProxy, наші наскрізні тести синхронізації з Dropbox проходять (59 випадків): прив'язка та скасування прив'язки; надсилання до Dropbox проєктів, правок, бінарних файлів, перейменувань, переміщень і видалень, включно з правкою в редакторі, що надходить через фоновий запис після закриття проєкту, без компіляції чи «sync now»; застосування змін, зроблених у Dropbox, через webhook (перевірочний challenge і перевірка підпису), нові проєкти з нових папок, видалені папки проєктів; проєкти з однаковою назвою; діалог Dropbox у редакторі та «sync now» з його обмеженням частоти; повторні спроби, обмеження частоти й тайм-аути Dropbox; облікові записи, прив'язку яких скасовано, коли Dropbox заповнено, він відхиляє токен або призупинений; призупинені облікові записи Overleaf; і відповідь webhook, коли third-party-datastore не працює.


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