# Email to Ticket API – Endpoint Examples

**Module:** Setup → Email to Ticket  
**Base URL:** `/api/v1/web`  
**Permission:** `setup-email-to-ticket` (except Process Incoming, which uses a secret header).

---

## API collection (endpoints)

| # | Method | Endpoint | Auth |
|---|--------|----------|------|
| 1 | POST | `/api/v1/web/email-to-ticket/process-incoming` | `X-Email-To-Ticket-Secret` |
| 2 | GET | `/api/v1/web/email-to-ticket` | Bearer |
| 3 | PUT | `/api/v1/web/email-to-ticket/settings` | Bearer |
| 4 | POST | `/api/v1/web/email-to-ticket/emails` | Bearer |
| 5 | PUT | `/api/v1/web/email-to-ticket/emails/{id}` | Bearer |
| 6 | DELETE | `/api/v1/web/email-to-ticket/emails/{id}` | Bearer |
| 7 | POST | `/api/v1/web/email-to-ticket/emails/{id}/toggle-status` | Bearer |

**Postman:** Import `docs/Email_To_Ticket_API.postman_collection.json`.

---

## Authentication (توضيح المصادقة)

هناك طريقتان للمصادقة حسب نوع الـ endpoint:

### 1. Process Incoming Email فقط — استخدام الـ Secret في الـ Header (بدون Bearer)

- **لماذا؟** هذا الـ endpoint يُستدعى من **خدمة الاستماع للإيميل (Email Listener)** على السيرفر، وليس من مستخدم مسجّل دخوله. لذلك لا يوجد "مستخدم" لاستخدام توكن خاص به.
- **كيف؟** أرسل قيمة سرية (Secret) في الـ header باسم `X-Email-To-Ticket-Secret`. القيمة نفسها المُعرّفة في `.env` باسم `EMAIL_TO_TICKET_PROCESS_SECRET`.
- **مثال في Postman:** لا تضف `Authorization: Bearer ...`. أضف فقط الـ header:
  - `X-Email-To-Ticket-Secret`: `{{email_to_ticket_secret}}` (والقيمة الفعلية = قيمة الـ env).

**Example:** Only add the secret header; do **not** send `Authorization: Bearer ...` for this endpoint.

```
X-Email-To-Ticket-Secret: roms-email-to-ticket-8f3a2b1c4d5e6f7a9b0c1d2e3f4a5b6c
```

(The secret is **not** generated by the app — you create it: add it to `.env` as `EMAIL_TO_TICKET_PROCESS_SECRET`, then use the same value in Postman. Example above; change in production. To generate: `openssl rand -hex 32`.)

---

### 2. باقي الـ endpoints (Page Data, Settings, Emails) — استخدام Bearer Token

- **لماذا؟** هذه الـ endpoints تُستدعى من **واجهة الإعداد (Setup)** من متصفح المستخدم. المستخدم يكون مسجّل دخوله ويحتاج صلاحية `setup-email-to-ticket`.
- **كيف؟** بعد تسجيل الدخول (Login) تحصل على توكن (token). أرسله في الـ header:
  - `Authorization: Bearer {{auth_token}}`
- **مثال في Postman:** في مجموعة الـ collection، الـ Auth الافتراضي هو Bearer ويملأ `auth_token` تلقائياً. للـ Process Incoming فقط يتم تجاوز الـ Auth (No Auth) واستخدام الـ header أعلاه.

**Example:** Send the user token in the header.

```
Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGc...
```

---

| Endpoint | Who calls it? | Auth method |
|----------|----------------|-------------|
| **POST process-incoming** | Email Listener (server/service) | Header: `X-Email-To-Ticket-Secret` only — **no Bearer** |
| **GET, PUT, POST, DELETE** (page, settings, emails) | Logged-in user (Setup UI) | Header: `Authorization: Bearer {token}` |

---

## Request body examples (all endpoints)

| Endpoint | Method | Auth | Request body |
|----------|--------|------|--------------|
| `/email-to-ticket/process-incoming` | POST | Header `X-Email-To-Ticket-Secret` | See example below |
| `/email-to-ticket` | GET | Bearer | *No body* |
| `/email-to-ticket/settings` | PUT | Bearer | `{"default_ticket_type": 1, "default_priority": 3}` |
| `/email-to-ticket/emails` | POST | Bearer | `{"email": "support@example.com", "label": "Main Support"}` |
| `/email-to-ticket/emails/{id}` | PUT | Bearer | `{"label": "Primary Support"}` or `{"email": "new@example.com", "label": "Support"}` |
| `/email-to-ticket/emails/{id}` | DELETE | Bearer | *No body* |
| `/email-to-ticket/emails/{id}/toggle-status` | POST | Bearer | *No body* |

**PUT Save Settings** – `default_ticket_type`: 1 = Issue, 2 = New Feature. `default_priority`: 1 = Critical, 2 = High, 3 = Medium, 4 = Low.

**POST Add Email** – `email` required (valid format), `label` or `name` optional.

**PUT Update Email** – `label` optional; `email` only when `email_editable` is true (no email received yet).

**POST Process Incoming Email** – Called by the Email Listener. Auth: header `X-Email-To-Ticket-Secret` (no Bearer). Body: `to`, `from`, `from_name`, `subject`, `body`, optional `attachments`, `message_id`, `references`, `in_reply_to`.

---

## Process incoming email (listener only)

**POST** `/api/v1/web/email-to-ticket/process-incoming`

Used by the Email Listener Service. Requires header `X-Email-To-Ticket-Secret` = `EMAIL_TO_TICKET_PROCESS_SECRET`. No Bearer token.

**Headers:** `Accept: application/json`, `Content-Type: application/json`, `X-Email-To-Ticket-Secret: <secret>`

**Body (JSON):**
```json
{
  "to": "support@example.com",
  "from": "client@example.com",
  "from_name": "Client Name",
  "subject": "Issue with login",
  "body": "I cannot log in to the portal. Please help.",
  "attachments": [],
  "message_id": null,
  "references": null,
  "in_reply_to": null
}
```

**Response (200):** `{"message": "Processed", "data": {"action": "created"|"reply_added"|"rejected"|"reply_closed", "message": "...", "ticket_id": 123, "ticket_number": "#ST-123"}}`

---

## Get page data (current configuration + support emails + options)

**GET** `/api/v1/web/email-to-ticket`

Returns headline, description, current configuration card data, support email list, and dropdown options for default type/priority.

**Example:**
```http
GET /api/v1/web/email-to-ticket
Authorization: Bearer {token}
```

**Response (200):**
```json
{
  "data": {
    "headline": "Email to Ticket",
    "description": "Configure how incoming emails are converted into support tickets",
    "current_configuration": {
      "active_emails_count": 2,
      "default_type": 1,
      "default_type_label": "Issue",
      "default_priority": 3,
      "default_priority_label": "Medium"
    },
    "support_email_addresses": [
      {
        "id": 1,
        "email": "support@example.com",
        "label": "Main Support",
        "name": "Main Support",
        "status": "active",
        "status_label": "Active",
        "is_active": true,
        "has_received_email": false,
        "email_editable": true
      },
      {
        "id": 2,
        "email": "help@example.com",
        "label": "Help Desk",
        "name": "Help Desk",
        "status": "inactive",
        "status_label": "Inactive",
        "is_active": false,
        "has_received_email": true,
        "email_editable": false
      }
    ],
    "default_ticket_type": 1,
    "default_priority": 3,
    "default_ticket_type_options": [
      { "value": 1, "label": "Issue" },
      { "value": 2, "label": "New Feature" }
    ],
    "default_priority_options": [
      { "value": 1, "label": "Critical" },
      { "value": 2, "label": "High" },
      { "value": 3, "label": "Medium" },
      { "value": 4, "label": "Low" }
    ]
  }
}
```

---

## Save default ticket settings

**PUT** `/api/v1/web/email-to-ticket/settings`

Updates default ticket type and default priority used when converting incoming emails to tickets.

**Body (JSON):**
| Field                 | Type | Required | Description                                      |
|-----------------------|------|----------|--------------------------------------------------|
| default_ticket_type   | int  | Yes      | 1 = Issue, 2 = New Feature                       |
| default_priority      | int  | Yes      | 1 = Critical, 2 = High, 3 = Medium, 4 = Low      |

**Example:**
```http
PUT /api/v1/web/email-to-ticket/settings
Authorization: Bearer {token}
Content-Type: application/json

{
  "default_ticket_type": 1,
  "default_priority": 3
}
```

**Response (200):**
```json
{
  "status": 200,
  "message": "Settings saved successfully",
  "data": {
    "default_ticket_type": 1,
    "default_priority": 3
  }
}
```

---

## Add support email address

**POST** `/api/v1/web/email-to-ticket/emails`

Adds a new support email. Saved with status **Active**.

**Body (JSON or form-data):**
| Field  | Type   | Required | Description                    |
|--------|--------|----------|--------------------------------|
| email  | string | Yes      | Valid email (e.g. support@example.com) |
| name   | string | No       | Label/display name             |
| label  | string | No       | Same as name (optional)        |

**Example:**
```http
POST /api/v1/web/email-to-ticket/emails
Authorization: Bearer {token}
Content-Type: application/json

{
  "email": "support@example.com",
  "label": "Main Support"
}
```

**Response (200):**
```json
{
  "status": 200,
  "message": "Email added successfully",
  "data": {
    "id": 1,
    "email": "support@example.com",
    "label": "Main Support",
    "status": "active",
    "status_label": "Active"
  }
}
```

**Validation:** `email` must be a valid email format and unique.

---

## Update support email address

**PUT** `/api/v1/web/email-to-ticket/emails/{id}`

Updates label/name. The **email** field can only be changed if the address has not yet received any email (`email_editable: true`).

**Body (JSON):**
| Field  | Type   | Required | Description                    |
|--------|--------|----------|--------------------------------|
| email  | string | No*      | New email (*only if email_editable) |
| name   | string | No       | Label/display name             |
| label  | string | No       | Same as name                    |

**Example – update label only:**
```http
PUT /api/v1/web/email-to-ticket/emails/1
Authorization: Bearer {token}
Content-Type: application/json

{
  "label": "Primary Support"
}
```

**Example – update email (only when no email received yet):**
```http
PUT /api/v1/web/email-to-ticket/emails/1
Authorization: Bearer {token}
Content-Type: application/json

{
  "email": "new-support@example.com",
  "label": "Support"
}
```

**Response (200):**
```json
{
  "status": 200,
  "message": "Email updated successfully"
}
```

---

## Delete support email address

**DELETE** `/api/v1/web/email-to-ticket/emails/{id}`

Soft-deletes the support email address.

**Example:**
```http
DELETE /api/v1/web/email-to-ticket/emails/1
Authorization: Bearer {token}
```

**Response (200):**
```json
{
  "status": 200,
  "message": "Email removed successfully"
}
```

---

## Toggle support email status (Active / Inactive)

**POST** `/api/v1/web/email-to-ticket/emails/{id}/toggle-status`

Switches the support email between Active and Inactive.

**Example:**
```http
POST /api/v1/web/email-to-ticket/emails/1/toggle-status
Authorization: Bearer {token}
```

**Response (200):**
```json
{
  "status": 200,
  "message": "Status updated",
  "data": {
    "is_active": false,
    "status": "inactive"
  }
}
```

---

## Error responses

**403 Forbidden – missing permission:**
```json
{
  "status": 403,
  "message": "User does not have the right permissions."
}
```

**422 Validation Error (e.g. invalid email or duplicate):**
```json
{
  "message": "The email has already been taken.",
  "errors": {
    "email": ["The email has already been taken."]
  }
}
```

**404 Not Found (invalid email id):**
```json
{
  "status": 404,
  "message": "No query results for model [SupportEmailAddress] {id}"
}
```
