# How to Integrate Operator Panel as Widget in Odoo CRM

> **Important:** Odoo embedding is **implemented by the client's IT team**. ConnectiveOne does not develop the Odoo module; it provides autologin and iframe parameters.

ConnectiveOne allows embedding the operator panel into Odoo CRM as a widget on a contact, lead, or opportunity card. Managers can handle client dialogues without leaving Odoo.

## When to Use This Integration?

- You need to open client dialogues from **res.partner** / **crm.lead** / **sale.order** cards
- You need to start a new dialogue or continue an existing one by client phone number
- You need the full operator panel or a single chat window only (embed mode)
- Managers already work in Odoo and should not log in to ConnectiveOne separately (via autologin)

## Prerequisites

- Active ConnectiveOne instance with operator panel configured
- Each Odoo manager has an **email** matching the operator email in ConnectiveOne
- Contact card in Odoo has **phone** or another channel identifier (for `init_dialog`)
- ConnectiveOne admin generated a **login_key** for autologin (stored securely on Odoo side)
- Odoo domain is allowed in iframe (CSP / cookies — see [security](#security))

## How Does It Work?

1. A «ConnectiveOne Chat» tab or smart button is added to the Odoo form view.
2. Odoo backend (or a static URL template) builds an **autologin** link with current user and client parameters.
3. The link opens in `<iframe>` — the operator sees the ConnectiveOne operator panel.

General autologin parameters — in [integrate operator panel as widget in CRM/ERP](./integrate-operator-panel-as-widget.md).

---

## Option A: Tab on Contact Card (Recommended)

### Autologin Parameters for Odoo

**Required:**

| Parameter | Value |
|-----------|-------|
| `user` | Current Odoo user email (`res.users`) |
| `login_key` | Autologin key from ConnectiveOne |
| `redirect_module` | `OperatorPanelChats` |
| `init_dialog` | Phone from `res.partner.phone` / `mobile` (normalized) |
| `init_dialog_channel` | Channel: `telegram`, `viber`, `whatsapp`, etc. |
| `init_dialog_bot_id` | ConnectiveOne bot ID |

**Optional:**

| Parameter | Description |
|-----------|-------------|
| `hide_nav` | `1` — hide menu and header |
| `uk` / `en` | UI language (first query parameter after `?`) |
| `chat_room_id` | Open a known existing room |

**Example URL:**

```
https://{instance}.connectiveone.io/autologin?en&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 to Build URL

```python
# models/res_partner.py (fragment)
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?en&{query}"
```

> Store `connectiveone.login_key` in **System Parameters** or Vault; do not embed in public client-side JS.

### XML: Tab with 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>
```

Alternative — **OWL component** or **ir.actions.act_url** with dynamic URL (better for full-height iframe).

### JS: iframe in 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`;
      }
    });
  }
}
```

> Odoo custom views: [Odoo Web Framework](https://www.odoo.com/documentation/19.0/developer/reference/frontend/framework_overview.html).

---

## Option B: Full Operator Panel (No Single Client Binding)

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

Add an Odoo menu item (Settings → Technical → User Interface → Menu Items) with `ir.actions.act_url`.

---

## Option C: Single Dialogue Window Only

If supported on your instance:

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

Combine with autologin first. Confirm **embed mode** availability with your ConnectiveOne team.

---

## Dialogue Create / Lookup Logic

Same as [general CRM widget guide](./integrate-operator-panel-as-widget.md):

1. If dialogues exist for `init_dialog` — connect to first or create new.
2. If client not found — create dialogue in `init_dialog_channel`.
3. If `init_dialog_bot_id` omitted — first bot with matching channel is used.

---

## OP Events Sync → Odoo

To create activities / chatter entries on `chat_created`, `operator_connected`, etc., configure **operator panel webhook** to your Odoo module endpoint.

See [Configure operator panel webhook](../webhook/configure-operator-panel-webhook.md) and [Integrate ConnectiveOne with Odoo CRM](./integrate-connectiveone-with-odoo-crm.md).

---

## Security

- Use **HTTPS** for Odoo and ConnectiveOne
- Do **not** expose `login_key` in public logs; prefer server-side URL building in Odoo
- Restrict `frame-ancestors` / CSP on ConnectiveOne to Odoo domains
- iframe cookies may require `SameSite=None; Secure` — coordinate with instance admin
- Operator email must **match** in Odoo and ConnectiveOne

## Limitations

- Autologin depends on valid `login_key` and operator RBAC in ConnectiveOne
- iframe may be limited by browser or Odoo security policies
- Some Odoo Online plans restrict custom iframe — test on staging

## Related Articles

- [Integrate operator panel as widget (general)](./integrate-operator-panel-as-widget.md)
- [Integrate ConnectiveOne with Odoo CRM](./integrate-connectiveone-with-odoo-crm.md)
- [Configure operator panel webhook](../webhook/configure-operator-panel-webhook.md)
- [Odoo External API](https://www.odoo.com/documentation/19.0/developer/reference/external_api.html)
- [What are integrations](../../explanation/what-are-integrations.md)
