# Як інтегрувати операторську панель як віджет у Odoo CRM

> **Важливо:** вбудовування в Odoo **робить IT-команда клієнта**. ConnectiveOne не розробляє Odoo-модуль; надає autologin та параметри iframe.

ConnectiveOne дозволяє вбудувати операторську панель в Odoo CRM як віджет у картці контакта, ліда або угоди. Менеджер може вести діалог з клієнтом, не виходячи з Odoo.

## Коли використовувати цю інтеграцію?

- Потрібно відкривати діалоги з клієнтами з картки **res.partner** / **crm.lead** / **sale.order**
- Потрібно ініціювати новий діалог або продовжити існуючий за номером телефону клієнта
- Потрібно показати повну операторську панель або лише вікно одного чату (embed mode)
- Менеджери вже працюють в Odoo і не повинні окремо логінитися в ConnectiveOne (через autologin)

## Передумови

- Активний інстанс ConnectiveOne з налаштованою операторською панеллю
- У Odoo для кожного менеджера є **email**, що збігається з email оператора в ConnectiveOne
- У картці контакта в Odoo заповнено **телефон** або інший ідентифікатор каналу (для `init_dialog`)
- Адміністратор ConnectiveOne згенерував **login_key** для autologin (безпечне зберігання на стороні Odoo)
- Домен Odoo дозволений для відображення в iframe (CSP / cookies — див. [безпека](#безпека))

## Як це працює?

1. У form view Odoo додається вкладка або smart button «Чат ConnectiveOne».
2. Backend Odoo (або статичний шаблон URL) формує посилання **autologin** з параметрами поточного користувача та клієнта.
3. Посилання відкривається в `<iframe>` — оператор бачить операторську панель ConnectiveOne.

Загальний опис параметрів autologin — у [інтеграції ОП як віджету в CRM/ERP](./integrate-operator-panel-as-widget.md).

---

## Варіант A: вкладка в картці контакта (рекомендовано)

### Параметри autologin для Odoo

**Обов'язкові:**

| Параметр | Значення |
|----------|----------|
| `user` | Email поточного користувача Odoo (`res.users`) |
| `login_key` | Ключ autologin з ConnectiveOne |
| `redirect_module` | `OperatorPanelChats` |
| `init_dialog` | Телефон з `res.partner.phone` / `mobile` (нормалізований) |
| `init_dialog_channel` | Канал: `telegram`, `viber`, `whatsapp` тощо |
| `init_dialog_bot_id` | ID бота ConnectiveOne |

**Додаткові:**

| Параметр | Опис |
|----------|------|
| `hide_nav` | `1` — приховати меню та header |
| `uk` / `en` | Мова інтерфейсу (перший query-параметр після `?`) |
| `chat_room_id` | Якщо відомий існуючий діалог — відкрити його напряму |

**Приклад URL:**

```
https://{instance}.connectiveone.io/autologin?uk&user=manager@company.com&login_key={SECRET}&redirect_module=OperatorPanelChats&hide_nav=1&init_dialog=380671234567&init_dialog_channel=telegram&init_dialog_bot_id=12
```

### Python: server action для формування URL

```python
# models/res_partner.py (фрагмент)
import urllib.parse

def _get_connectiveone_embed_url(self):
    self.ensure_one()
    user = self.env.user
    phone = (self.mobile or self.phone or "").replace(" ", "").replace("-", "")
    base = self.env["ir.config_parameter"].sudo().get_param(
        "connectiveone.instance_url",
        "https://your-instance.connectiveone.io",
    )
    login_key = self.env["ir.config_parameter"].sudo().get_param("connectiveone.login_key")
    bot_id = self.env["ir.config_parameter"].sudo().get_param("connectiveone.default_bot_id", "1")
    channel = self.env["ir.config_parameter"].sudo().get_param("connectiveone.default_channel", "telegram")
    params = {
        "user": user.email or user.login,
        "login_key": login_key,
        "redirect_module": "OperatorPanelChats",
        "hide_nav": "1",
        "init_dialog": phone,
        "init_dialog_channel": channel,
        "init_dialog_bot_id": bot_id,
    }
    query = urllib.parse.urlencode(params)
    return f"{base}/autologin?uk&{query}"
```

> Зберігайте `connectiveone.login_key` у **System Parameters** або Vault; не вбудовуйте в клієнтський JS у відкритому вигляді.

### XML: вкладка з iframe (Odoo 16+)

```xml
<!-- views/res_partner_views.xml -->
<record id="view_partner_form_connectiveone" model="ir.ui.view">
  <field name="name">res.partner.form.connectiveone</field>
  <field name="model">res.partner</field>
  <field name="inherit_id" ref="base.view_partner_form"/>
  <field name="arch" type="xml">
    <xpath expr="//notebook" position="inside">
      <page string="ConnectiveOne" name="connectiveone_chat">
        <field name="connectiveone_embed_url" widget="html" readonly="1"/>
      </page>
    </xpath>
  </field>
</record>
```

Альтернатива — **OWL-компонент** або **ir.actions.act_url** з динамічним URL (зручніше для resize iframe на всю висоту вікна).

### JS: iframe у custom widget (Odoo Web)

```javascript
/** @odoo-module **/
import { registry } from "@web/core/registry";
import { Component, onMounted, useRef } from "@odoo/owl";

export class ConnectiveOneChatIframe extends Component {
  static template = "your_module.ConnectiveOneChatIframe";
  setup() {
    this.iframeRef = useRef("iframe");
    onMounted(() => {
      const iframe = this.iframeRef.el;
      if (iframe) {
        iframe.style.height = `${window.innerHeight - 120}px`;
      }
    });
  }
}
```

```xml
<!-- static/src/xml/connectiveone_chat.xml -->
<t t-name="your_module.ConnectiveOneChatIframe">
  <iframe t-ref="iframe"
          t-att-src="props.embedUrl"
          style="width:100%; border:0;"
          sandbox="allow-scripts allow-same-origin allow-forms allow-popups"/>
</t>
```

> Документація Odoo щодо кастомних view: [Odoo Web Framework](https://www.odoo.com/documentation/19.0/developer/reference/frontend/framework_overview.html).

---

## Варіант B: повна операторська панель (без прив'язки до одного клієнта)

Якщо потрібен доступ до всіх чатів менеджера:

```
https://{instance}.connectiveone.io/autologin?uk&user={email}&login_key={SECRET}&redirect_module=OperatorPanelChats&hide_nav=1
```

Додайте пункт меню Odoo (Settings → Technical → User Interface → Menu Items) з `ir.actions.act_url`.

---

## Варіант C: embed лише вікна діалогу

Якщо підтримується на вашому інстансі — відкрийте конкретну кімнату:

```
https://{instance}.connectiveone.io/operator_panel/chats?chat_room_id={ID}&hide_nav=1
```

Поєднайте з autologin (спочатку авторизація, потім redirect на room). Уточніть у команди ConnectiveOne наявність **embed mode** для вашої версії.

---

## Логіка створення / пошуку діалогу

Поведінка така сама, як у [загальній інструкції для CRM](./integrate-operator-panel-as-widget.md):

1. Якщо знайдено діалоги з `init_dialog` — підключення до першого або створення нового.
2. Якщо клієнта не знайдено — створюється новий діалог у каналі `init_dialog_channel`.
3. Якщо `init_dialog_bot_id` не вказано — береться перший бот з відповідним каналом.

---

## Синхронізація подій OP → Odoo

Щоб створювати activity / запис у chatter Odoo при `chat_created`, `operator_connected` тощо, налаштуйте **webhook панелі оператора** на endpoint вашого Odoo-модуля.

Див. [Як налаштувати webhook панелі оператора](../webhook/configure-operator-panel-webhook.md) та [Як інтегрувати ConnectiveOne з Odoo CRM](./integrate-connectiveone-with-odoo-crm.md).

---

## Безпека

- Використовуйте **HTTPS** для Odoo та ConnectiveOne
- **Не** передавайте `login_key` у публічних логах або query string у браузерних закладках без потреби; краще формувати URL на **сервері** Odoo
- Обмежте `frame-ancestors` / CSP на інстансі ConnectiveOne доменами Odoo
- Для cookies в iframe може знадобитися `SameSite=None; Secure` — узгодьте з адміністратором інстансу
- Email оператора в Odoo та ConnectiveOne повинні **збігатися**

## Обмеження

- Autologin залежить від коректного `login_key` та RBAC оператора в ConnectiveOne
- Iframe може бути обмежений політикою безпеки браузера або Odoo
- Деякі модулі Odoo Online обмежують custom iframe — перевірте на staging

## Пов'язані статті

- [Інтеграція операторської панелі як віджету (загальна)](./integrate-operator-panel-as-widget.md)
- [Як інтегрувати ConnectiveOne з Odoo CRM](./integrate-connectiveone-with-odoo-crm.md)
- [Як налаштувати webhook панелі оператора](../webhook/configure-operator-panel-webhook.md)
- [Odoo External API](https://www.odoo.com/documentation/19.0/developer/reference/external_api.html)
- [Що таке інтеграції](../../explanation/what-are-integrations.md)
