django-supchat 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- django_supchat-1.0.0.dist-info/METADATA +625 -0
- django_supchat-1.0.0.dist-info/RECORD +25 -0
- django_supchat-1.0.0.dist-info/WHEEL +5 -0
- django_supchat-1.0.0.dist-info/licenses/LICENSE +714 -0
- django_supchat-1.0.0.dist-info/top_level.txt +1 -0
- supchat/__init__.py +0 -0
- supchat/admin.py +60 -0
- supchat/apps.py +10 -0
- supchat/conf.py +45 -0
- supchat/forms.py +29 -0
- supchat/models.py +114 -0
- supchat/operator_views.py +309 -0
- supchat/permissions.py +68 -0
- supchat/services.py +231 -0
- supchat/signals.py +7 -0
- supchat/sse.py +118 -0
- supchat/static/supchat/operator.css +1047 -0
- supchat/static/supchat/operator.js +895 -0
- supchat/static/supchat/supchat.css +675 -0
- supchat/static/supchat/supchat.js +399 -0
- supchat/templates/supchat/operator/dashboard.html +152 -0
- supchat/templates/supchat/operator/partials/dashboard_content.html +15 -0
- supchat/templates/supchat/widget.html +97 -0
- supchat/urls.py +26 -0
- supchat/views.py +105 -0
|
@@ -0,0 +1,625 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: django-supchat
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: A lightweight, real-time support chat widget for Django powered by SSE
|
|
5
|
+
Author-email: xo-aria <your-email@example.com>
|
|
6
|
+
Maintainer-email: xo-aria <your-email@example.com>
|
|
7
|
+
License: AGPL-3.0
|
|
8
|
+
Project-URL: Homepage, https://github.com/xo-aria/django-supchat
|
|
9
|
+
Project-URL: Documentation, https://github.com/xo-aria/django-supchat#readme
|
|
10
|
+
Project-URL: Repository, https://github.com/xo-aria/django-supchat
|
|
11
|
+
Project-URL: Issues, https://github.com/xo-aria/django-supchat/issues
|
|
12
|
+
Project-URL: Changelog, https://github.com/xo-aria/django-supchat/blob/main/CHANGELOG.md
|
|
13
|
+
Keywords: django,chat,support,real-time,sse,server-sent-events,widget,customer-support,live-chat
|
|
14
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Environment :: Web Environment
|
|
16
|
+
Classifier: Framework :: Django
|
|
17
|
+
Classifier: Framework :: Django :: 4.2
|
|
18
|
+
Classifier: Framework :: Django :: 5.0
|
|
19
|
+
Classifier: Framework :: Django :: 5.1
|
|
20
|
+
Classifier: Intended Audience :: Developers
|
|
21
|
+
Classifier: License :: OSI Approved :: GNU Affero General Public License v3
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Classifier: Programming Language :: Python :: 3
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
27
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
28
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
29
|
+
Classifier: Topic :: Communications :: Chat
|
|
30
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
31
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
32
|
+
Requires-Python: >=3.9
|
|
33
|
+
Description-Content-Type: text/markdown
|
|
34
|
+
License-File: LICENSE
|
|
35
|
+
Requires-Dist: django>=4.2
|
|
36
|
+
Provides-Extra: test
|
|
37
|
+
Requires-Dist: pytest>=7.0; extra == "test"
|
|
38
|
+
Requires-Dist: pytest-django>=4.5; extra == "test"
|
|
39
|
+
Requires-Dist: pytest-cov>=4.0; extra == "test"
|
|
40
|
+
Requires-Dist: pytest-asyncio>=0.21; extra == "test"
|
|
41
|
+
Requires-Dist: factory-boy>=3.3; extra == "test"
|
|
42
|
+
Provides-Extra: dev
|
|
43
|
+
Requires-Dist: django-supchat[test]; extra == "dev"
|
|
44
|
+
Requires-Dist: black>=23.0; extra == "dev"
|
|
45
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
46
|
+
Requires-Dist: mypy>=1.5; extra == "dev"
|
|
47
|
+
Requires-Dist: django-stubs>=4.2; extra == "dev"
|
|
48
|
+
Requires-Dist: pre-commit>=3.4; extra == "dev"
|
|
49
|
+
Dynamic: license-file
|
|
50
|
+
|
|
51
|
+
<div align="center">
|
|
52
|
+
|
|
53
|
+
# 💬 django-supchat
|
|
54
|
+
|
|
55
|
+
### A Lightweight, Real-Time Support Chat for Django
|
|
56
|
+
|
|
57
|
+
[](https://pypi.org/project/django-supchat/)
|
|
58
|
+
[](https://pypi.org/project/django-supchat/)
|
|
59
|
+
[](https://pypi.org/project/django-supchat/)
|
|
60
|
+
[](https://opensource.org/licenses/MIT)
|
|
61
|
+
[](https://pepy.tech/project/django-supchat)
|
|
62
|
+
[](https://github.com/psf/black)
|
|
63
|
+
|
|
64
|
+
**Zero dependencies. No WebSockets. No Redis. No React.**<br>
|
|
65
|
+
Just Django, vanilla JS, and Server-Sent Events.
|
|
66
|
+
|
|
67
|
+
[Installation](#-quick-start) • [Demo](#-screenshots) • [Documentation](#-documentation) • [Examples](#-examples)
|
|
68
|
+
|
|
69
|
+
</div>
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## ✨ Overview
|
|
74
|
+
|
|
75
|
+
**django-supchat** is a production-ready, drop-in support chat widget for Django projects. It provides a beautiful, real-time chat experience between website visitors (guests or authenticated users) and your support team — all powered by Django's ORM and Server-Sent Events (SSE).
|
|
76
|
+
|
|
77
|
+
> 🎯 **Philosophy:** Ship a powerful chat system without the complexity of WebSockets, Redis, or a frontend build step. Just `pip install` and go.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 🚀 Key Features
|
|
82
|
+
|
|
83
|
+
<table>
|
|
84
|
+
<tr>
|
|
85
|
+
<td width="50%">
|
|
86
|
+
|
|
87
|
+
### 🎨 Frontend
|
|
88
|
+
- ✨ Modern glassmorphism UI with smooth animations
|
|
89
|
+
- 🌓 Auto Light/Dark theme (respects OS preference)
|
|
90
|
+
- 🌐 Auto bilingual (Persian/English) with RTL support
|
|
91
|
+
- ⌨️ Real-time typing indicators
|
|
92
|
+
- ✅ Read receipts with visual feedback
|
|
93
|
+
- 📱 Fully responsive (mobile fullscreen)
|
|
94
|
+
- ♿ WCAG 2.1 accessible
|
|
95
|
+
- 🎭 Customizable colors via CSS variables
|
|
96
|
+
|
|
97
|
+
</td>
|
|
98
|
+
<td width="50%">
|
|
99
|
+
|
|
100
|
+
### ⚡ Backend
|
|
101
|
+
- 🔌 **Zero external dependencies** — no Redis, no Channels
|
|
102
|
+
- 📡 Real-time via Server-Sent Events (SSE)
|
|
103
|
+
- 🔒 Signed, HTTP-only guest cookies
|
|
104
|
+
- 🛡️ CSRF protection on all POST endpoints
|
|
105
|
+
- 🚦 Built-in rate limiting (pluggable)
|
|
106
|
+
- 🧹 HTML sanitization & control char stripping
|
|
107
|
+
- 👥 Multi-operator support with assignment
|
|
108
|
+
|
|
109
|
+
</td>
|
|
110
|
+
</tr>
|
|
111
|
+
</table>
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 📦 Quick Start
|
|
116
|
+
|
|
117
|
+
Get up and running in under 2 minutes.
|
|
118
|
+
|
|
119
|
+
### 1. Install
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
pip install django-supchat
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### 2. Configure Django
|
|
126
|
+
|
|
127
|
+
```python
|
|
128
|
+
# settings.py
|
|
129
|
+
INSTALLED_APPS = [
|
|
130
|
+
# ...
|
|
131
|
+
"supchat",
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
# Optional: Customize the widget
|
|
135
|
+
SUPCHAT = {
|
|
136
|
+
"TITLE": "Support",
|
|
137
|
+
"POSITION": "right", # "right" or "left"
|
|
138
|
+
"THEME": "auto", # "auto", "light", or "dark"
|
|
139
|
+
"ALLOW_GUEST": True,
|
|
140
|
+
"MAX_MESSAGE_LENGTH": 2000,
|
|
141
|
+
}
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### 3. Add URLs
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
# urls.py
|
|
148
|
+
from django.urls import include, path
|
|
149
|
+
|
|
150
|
+
urlpatterns = [
|
|
151
|
+
# ...
|
|
152
|
+
path("supchat/", include("supchat.urls")),
|
|
153
|
+
]
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### 4. Run Migrations
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
python manage.py migrate
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### 5. Render the Widget
|
|
163
|
+
|
|
164
|
+
```django
|
|
165
|
+
{% raw %}
|
|
166
|
+
{% load supchat %}
|
|
167
|
+
|
|
168
|
+
<!DOCTYPE html>
|
|
169
|
+
<html lang="en">
|
|
170
|
+
<head>
|
|
171
|
+
<title>My Site</title>
|
|
172
|
+
</head>
|
|
173
|
+
<body>
|
|
174
|
+
<h1>Welcome to my site!</h1>
|
|
175
|
+
|
|
176
|
+
{% supchat %}
|
|
177
|
+
</body>
|
|
178
|
+
</html>
|
|
179
|
+
{% endraw %}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
That's it! 🎉 Your chat widget is live.
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
## 📚 Documentation
|
|
187
|
+
|
|
188
|
+
### Configuration Reference
|
|
189
|
+
|
|
190
|
+
#### Widget Settings
|
|
191
|
+
|
|
192
|
+
| Setting | Type | Default | Description |
|
|
193
|
+
|---------|------|---------|-------------|
|
|
194
|
+
| `TITLE` | `str` | `"Support"` | Widget title displayed in header |
|
|
195
|
+
| `POSITION` | `str` | `"right"` | Widget position: `"right"` or `"left"` |
|
|
196
|
+
| `THEME` | `str` | `"auto"` | Theme: `"auto"`, `"light"`, or `"dark"` |
|
|
197
|
+
| `ALLOW_GUEST` | `bool` | `True` | Allow anonymous visitors to chat |
|
|
198
|
+
| `MAX_MESSAGE_LENGTH` | `int` | `2000` | Maximum characters per message |
|
|
199
|
+
|
|
200
|
+
#### Advanced Settings
|
|
201
|
+
|
|
202
|
+
| Setting | Type | Default | Description |
|
|
203
|
+
|---------|------|---------|-------------|
|
|
204
|
+
| `HEARTBEAT_INTERVAL` | `int` | `25` | SSE heartbeat interval (seconds) |
|
|
205
|
+
| `SSE_RETRY_MS` | `int` | `5000` | SSE reconnection delay (ms) |
|
|
206
|
+
| `GUEST_COOKIE_NAME` | `str` | `"supchat_guest"` | Name of the guest identity cookie |
|
|
207
|
+
| `GUEST_COOKIE_AGE` | `int` | `31536000` | Cookie lifetime (1 year in seconds) |
|
|
208
|
+
| `RATE_LIMIT` | `dict` | `{"MESSAGES": 30, "WINDOW": 60}` | Default rate limit config |
|
|
209
|
+
| `RATE_LIMIT_CALLBACK` | `callable` | `None` | Custom rate limit function |
|
|
210
|
+
|
|
211
|
+
#### Per-Render Overrides
|
|
212
|
+
|
|
213
|
+
You can override settings per template render:
|
|
214
|
+
|
|
215
|
+
```django
|
|
216
|
+
{% raw %}
|
|
217
|
+
{% supchat title="Help Desk" position="left" theme="dark" %}
|
|
218
|
+
{% endraw %}
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
---
|
|
222
|
+
|
|
223
|
+
## 🔐 Security Model
|
|
224
|
+
|
|
225
|
+
django-supchat takes security seriously:
|
|
226
|
+
|
|
227
|
+
- ✅ **CSRF Protection** — All POST endpoints require valid CSRF tokens
|
|
228
|
+
- ✅ **Signed Guest Cookies** — Guest identity stored in signed, HTTP-only cookies
|
|
229
|
+
- ✅ **Conversation Access Control** — Every endpoint (including SSE) verifies access
|
|
230
|
+
- ✅ **Input Sanitization** — HTML stripped, control chars removed, length capped
|
|
231
|
+
- ✅ **XSS Prevention** — Frontend uses `textContent`, never `innerHTML`
|
|
232
|
+
- ✅ **Rate Limiting** — Cache-backed default + pluggable hook for custom logic
|
|
233
|
+
|
|
234
|
+
### Custom Rate Limiting
|
|
235
|
+
|
|
236
|
+
```python
|
|
237
|
+
# settings.py
|
|
238
|
+
def my_rate_limiter(request, action):
|
|
239
|
+
# Return True to allow, False to deny
|
|
240
|
+
if request.user.is_staff:
|
|
241
|
+
return True
|
|
242
|
+
return False # Custom logic
|
|
243
|
+
|
|
244
|
+
SUPCHAT = {
|
|
245
|
+
"RATE_LIMIT_CALLBACK": my_rate_limiter,
|
|
246
|
+
}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
---
|
|
250
|
+
|
|
251
|
+
## 👥 Operator Management
|
|
252
|
+
|
|
253
|
+
### Creating Operators
|
|
254
|
+
|
|
255
|
+
Create `Operator` records in Django admin for your support staff:
|
|
256
|
+
|
|
257
|
+
```python
|
|
258
|
+
from django.contrib.auth import get_user_model
|
|
259
|
+
from supchat.models import Operator
|
|
260
|
+
|
|
261
|
+
User = get_user_model()
|
|
262
|
+
user = User.objects.get(username="support_agent")
|
|
263
|
+
Operator.objects.create(user=user, is_online=True)
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
### Assigning Operators Programmatically
|
|
267
|
+
|
|
268
|
+
```python
|
|
269
|
+
from supchat.services import assign_operator
|
|
270
|
+
|
|
271
|
+
# Auto-assign to current user (if they're an operator)
|
|
272
|
+
assign_operator(request, conversation)
|
|
273
|
+
|
|
274
|
+
# Assign to a specific operator
|
|
275
|
+
assign_operator(request, conversation, operator=some_operator)
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Operator Dashboard
|
|
279
|
+
|
|
280
|
+
Access the operator panel at `/supchat/operator/` (requires staff permissions).
|
|
281
|
+
|
|
282
|
+
Features:
|
|
283
|
+
- 💬 Real-time conversation list with unread badges
|
|
284
|
+
- 📊 Analytics dashboard with 7-day & 30-day charts
|
|
285
|
+
- 🎯 Conversation assignment & status management
|
|
286
|
+
- 🌓 Dark/Light theme toggle
|
|
287
|
+
- 🌐 Bilingual interface (EN/FA)
|
|
288
|
+
|
|
289
|
+
---
|
|
290
|
+
|
|
291
|
+
## 🛠️ Public API
|
|
292
|
+
|
|
293
|
+
The service layer is the stable integration point. Use these functions in your views, signals, or management commands:
|
|
294
|
+
|
|
295
|
+
```python
|
|
296
|
+
from supchat.services import (
|
|
297
|
+
get_or_create_conversation,
|
|
298
|
+
send_message,
|
|
299
|
+
close_conversation,
|
|
300
|
+
assign_operator,
|
|
301
|
+
mark_messages_read,
|
|
302
|
+
)
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
### `get_or_create_conversation(request) → (Conversation, guest_id | None)`
|
|
306
|
+
|
|
307
|
+
Returns an open conversation for the user/guest. Creates one if none exists.
|
|
308
|
+
|
|
309
|
+
```python
|
|
310
|
+
conversation, guest_id = get_or_create_conversation(request)
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### `send_message(request, conversation, text) → Message`
|
|
314
|
+
|
|
315
|
+
Sends a message and broadcasts it via SSE.
|
|
316
|
+
|
|
317
|
+
```python
|
|
318
|
+
message = send_message(request, conversation, "Hello!")
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### `close_conversation(request, conversation) → Conversation`
|
|
322
|
+
|
|
323
|
+
Closes a conversation (operators only).
|
|
324
|
+
|
|
325
|
+
```python
|
|
326
|
+
close_conversation(request, conversation)
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
### `assign_operator(request, conversation, operator=None) → Conversation`
|
|
330
|
+
|
|
331
|
+
Assigns an operator to a conversation.
|
|
332
|
+
|
|
333
|
+
```python
|
|
334
|
+
assign_operator(request, conversation, operator=my_operator)
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### `mark_messages_read(request, conversation, message_ids=None) → int`
|
|
338
|
+
|
|
339
|
+
Marks messages as read. Returns count of updated messages.
|
|
340
|
+
|
|
341
|
+
```python
|
|
342
|
+
count = mark_messages_read(request, conversation)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## 🎨 Customization
|
|
348
|
+
|
|
349
|
+
Override any of these in your project:
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
your_project/
|
|
353
|
+
├── templates/
|
|
354
|
+
│ └── supchat/
|
|
355
|
+
│ └── widget.html # Override the widget template
|
|
356
|
+
└── static/
|
|
357
|
+
└── supchat/
|
|
358
|
+
├── supchat.css # Override styles
|
|
359
|
+
└── supchat.js # Override behavior
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### CSS Variables
|
|
363
|
+
|
|
364
|
+
Customize colors by overriding CSS variables:
|
|
365
|
+
|
|
366
|
+
```css
|
|
367
|
+
.supchat-widget {
|
|
368
|
+
--sc-primary: #6366f1;
|
|
369
|
+
--sc-primary-hover: #4f46e5;
|
|
370
|
+
--sc-bubble-user: linear-gradient(135deg, #6366f1, #8b5cf6);
|
|
371
|
+
--sc-bubble-agent: #ffffff;
|
|
372
|
+
--sc-bg: rgba(255, 255, 255, 0.95);
|
|
373
|
+
--sc-fg: #0f172a;
|
|
374
|
+
--sc-border: rgba(226, 232, 240, 0.8);
|
|
375
|
+
}
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
### JavaScript Events
|
|
379
|
+
|
|
380
|
+
Listen to chat events:
|
|
381
|
+
|
|
382
|
+
```javascript
|
|
383
|
+
document.addEventListener('supchat:open', () => {
|
|
384
|
+
console.log('Chat opened');
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
document.addEventListener('supchat:close', () => {
|
|
388
|
+
console.log('Chat closed');
|
|
389
|
+
});
|
|
390
|
+
|
|
391
|
+
document.addEventListener('supchat:message', (e) => {
|
|
392
|
+
console.log('New message:', e.detail);
|
|
393
|
+
});
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## 🚢 Deployment
|
|
399
|
+
|
|
400
|
+
### SSE Requirements
|
|
401
|
+
|
|
402
|
+
The built-in SSE manager is **process-local** and works great for:
|
|
403
|
+
- Development
|
|
404
|
+
- Single-process deployments
|
|
405
|
+
- Small to medium traffic
|
|
406
|
+
|
|
407
|
+
For **multi-worker deployments** (Gunicorn, uWSGI with multiple workers), clients connected to different workers won't receive broadcasts. Solutions:
|
|
408
|
+
|
|
409
|
+
#### Option 1: Single Worker
|
|
410
|
+
```bash
|
|
411
|
+
gunicorn myproject.wsgi:application --workers 1 --threads 8
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
#### Option 2: Cross-Worker Fanout
|
|
415
|
+
Implement your own broadcast mechanism using Redis Pub/Sub, a message queue, or your cache backend:
|
|
416
|
+
|
|
417
|
+
```python
|
|
418
|
+
# myproject/sse_bridge.py
|
|
419
|
+
from django.core.cache import cache
|
|
420
|
+
from supchat.sse import sse_manager
|
|
421
|
+
|
|
422
|
+
def broadcast_to_all_workers(conversation_id, event, data):
|
|
423
|
+
# Publish to Redis/cache
|
|
424
|
+
cache.set(f"supchat:broadcast:{conversation_id}", {
|
|
425
|
+
"event": event,
|
|
426
|
+
"data": data,
|
|
427
|
+
}, timeout=5)
|
|
428
|
+
|
|
429
|
+
# Each worker subscribes and calls:
|
|
430
|
+
# sse_manager.broadcast(conversation_id, event, data)
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### Proxy Configuration
|
|
434
|
+
|
|
435
|
+
**Nginx:**
|
|
436
|
+
```nginx
|
|
437
|
+
location /supchat/ {
|
|
438
|
+
proxy_pass http://localhost:8000;
|
|
439
|
+
proxy_buffering off; # Critical for SSE
|
|
440
|
+
proxy_cache off;
|
|
441
|
+
proxy_read_timeout 86400s; # Long timeout for SSE
|
|
442
|
+
proxy_send_timeout 86400s;
|
|
443
|
+
}
|
|
444
|
+
```
|
|
445
|
+
|
|
446
|
+
**Apache:**
|
|
447
|
+
```apache
|
|
448
|
+
<Location /supchat/>
|
|
449
|
+
ProxyPass http://localhost:8000/supchat/
|
|
450
|
+
ProxyPassReverse http://localhost:8000/supchat/
|
|
451
|
+
SetEnv proxy-nokeepalive 1
|
|
452
|
+
SetEnv proxy-sendchunked 1
|
|
453
|
+
</Location>
|
|
454
|
+
```
|
|
455
|
+
|
|
456
|
+
---
|
|
457
|
+
|
|
458
|
+
## 🌐 Browser Support
|
|
459
|
+
|
|
460
|
+
| Browser | Version |
|
|
461
|
+
|---------|---------|
|
|
462
|
+
| Chrome | 90+ |
|
|
463
|
+
| Firefox | 88+ |
|
|
464
|
+
| Safari | 14+ |
|
|
465
|
+
| Edge | 90+ |
|
|
466
|
+
| iOS Safari | 14+ |
|
|
467
|
+
| Android Chrome | 90+ |
|
|
468
|
+
|
|
469
|
+
---
|
|
470
|
+
|
|
471
|
+
## 🗺️ Roadmap
|
|
472
|
+
|
|
473
|
+
- [ ] File/image attachments
|
|
474
|
+
- [ ] Message reactions & emoji
|
|
475
|
+
- [ ] Conversation tags & categories
|
|
476
|
+
- [ ] Canned responses / quick replies
|
|
477
|
+
- [ ] Chat transcripts via email
|
|
478
|
+
- [ ] Webhook integrations (Slack, Discord)
|
|
479
|
+
- [ ] Bot/AI auto-responses
|
|
480
|
+
- [ ] Multi-language support (beyond EN/FA)
|
|
481
|
+
- [ ] Mobile SDK (iOS/Android)
|
|
482
|
+
- [ ] WebSocket adapter (optional)
|
|
483
|
+
|
|
484
|
+
---
|
|
485
|
+
|
|
486
|
+
## 🤝 Contributing
|
|
487
|
+
|
|
488
|
+
Contributions are welcome! Here's how:
|
|
489
|
+
|
|
490
|
+
1. Fork the repo
|
|
491
|
+
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
|
492
|
+
3. Commit your changes: `git commit -m 'Add amazing feature'`
|
|
493
|
+
4. Push to the branch: `git push origin feature/amazing-feature`
|
|
494
|
+
5. Open a Pull Request
|
|
495
|
+
|
|
496
|
+
### Development Setup
|
|
497
|
+
|
|
498
|
+
```bash
|
|
499
|
+
git clone https://github.com/xo-aria/django-supchat.git
|
|
500
|
+
cd django-supchat
|
|
501
|
+
pip install -e '.[test]'
|
|
502
|
+
pytest
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## 📄 License & Trademark
|
|
508
|
+
|
|
509
|
+
### Code License
|
|
510
|
+
**django-supchat** is licensed under the **GNU Affero General Public License v3.0 (AGPL-3.0)**.
|
|
511
|
+
|
|
512
|
+
This means:
|
|
513
|
+
- ✅ You can use, modify, and distribute this software
|
|
514
|
+
- ✅ You can use it commercially
|
|
515
|
+
- ⚠️ You **must** disclose source code (even for SaaS/network services)
|
|
516
|
+
- ⚠️ You **must** include the same license in distributions
|
|
517
|
+
- ⚠️ You **must** state changes you made
|
|
518
|
+
|
|
519
|
+
📖 [Read the full AGPL-3.0 license](LICENSE)
|
|
520
|
+
|
|
521
|
+
### Trademark Policy
|
|
522
|
+
The name **"SupChat"** is a trademark of xo-aria. See the [Trademark Policy](TRADEMARK.md) for details on:
|
|
523
|
+
- ✅ How to use the SupChat name
|
|
524
|
+
- ✅ Attribution requirements
|
|
525
|
+
- ❌ What you cannot do
|
|
526
|
+
- 🎨 Logo usage guidelines
|
|
527
|
+
|
|
528
|
+
**Quick Summary:**
|
|
529
|
+
- You **must** keep "SupChat" in the name when distributing
|
|
530
|
+
- You **must** include attribution: `Based on SupChat by xo-aria - https://github.com/xo-aria/django-supchat`
|
|
531
|
+
- You **cannot** rebrand without mentioning SupChat
|
|
532
|
+
- You **cannot** use SupChat logos without permission
|
|
533
|
+
|
|
534
|
+
### Why AGPL-3.0?
|
|
535
|
+
|
|
536
|
+
We chose AGPL-3.0 to:
|
|
537
|
+
1. **Protect user freedom** - Ensure the software stays free
|
|
538
|
+
2. **Close the SaaS loophole** - Even network services must share source code
|
|
539
|
+
3. **Encourage contributions** - Improvements benefit everyone
|
|
540
|
+
4. **Maintain quality** - Prevent closed-source forks from fragmenting the project
|
|
541
|
+
|
|
542
|
+
### Commercial Use
|
|
543
|
+
|
|
544
|
+
Yes, you can use SupChat commercially! Just:
|
|
545
|
+
- ✅ Comply with AGPL-3.0 (disclose source code)
|
|
546
|
+
- ✅ Follow the trademark policy (attribution)
|
|
547
|
+
- ✅ Document your changes
|
|
548
|
+
|
|
549
|
+
Need a **commercial license** without AGPL restrictions? [Contact us](mailto:your-email@example.com).
|
|
550
|
+
|
|
551
|
+
---
|
|
552
|
+
|
|
553
|
+
## 🙏 Attribution
|
|
554
|
+
|
|
555
|
+
If you use SupChat in your project, we'd appreciate:
|
|
556
|
+
|
|
557
|
+
### Required (by license):
|
|
558
|
+
```markdown
|
|
559
|
+
Based on SupChat by xo-aria
|
|
560
|
+
https://github.com/xo-aria/django-supchat
|
|
561
|
+
Licensed under AGPL-3.0
|
|
562
|
+
```
|
|
563
|
+
|
|
564
|
+
### Appreciated (but optional):
|
|
565
|
+
- ⭐ Star the repository on GitHub
|
|
566
|
+
- 📝 Mention "Powered by SupChat" in your docs/about page
|
|
567
|
+
- 🔗 Link back to https://github.com/xo-aria/django-supchat
|
|
568
|
+
- 🐦 Tweet about it (we'd love to see your projects!)
|
|
569
|
+
|
|
570
|
+
---
|
|
571
|
+
|
|
572
|
+
## 📞 Support & Contact
|
|
573
|
+
|
|
574
|
+
### Bug Reports & Feature Requests:
|
|
575
|
+
- 🐛 [GitHub Issues](https://github.com/xo-aria/django-supchat/issues)
|
|
576
|
+
|
|
577
|
+
### Questions & Discussions:
|
|
578
|
+
- 💬 [GitHub Discussions](https://github.com/xo-aria/django-supchat/discussions)
|
|
579
|
+
|
|
580
|
+
### Commercial Licensing:
|
|
581
|
+
- 📧 Email: [your-email@example.com]
|
|
582
|
+
- 💼 Custom licensing available for closed-source projects
|
|
583
|
+
|
|
584
|
+
### Security Issues:
|
|
585
|
+
- 🔒 Please email security issues directly to [your-email@example.com]
|
|
586
|
+
- ⚠️ Do **not** open public issues for security vulnerabilities
|
|
587
|
+
|
|
588
|
+
---
|
|
589
|
+
|
|
590
|
+
<div align="center">
|
|
591
|
+
|
|
592
|
+
**If django-supchat helps your project, please consider:**
|
|
593
|
+
|
|
594
|
+
[⭐ Starring on GitHub](https://github.com/xo-aria/django-supchat) • [🍴 Forking](https://github.com/xo-aria/django-supchat/fork) • [💬 Joining Discussions](https://github.com/xo-aria/django-supchat/discussions)
|
|
595
|
+
|
|
596
|
+
**Made with ❤️ by [xo-aria](https://github.com/xo-aria)**
|
|
597
|
+
|
|
598
|
+
</div>
|
|
599
|
+
|
|
600
|
+
---
|
|
601
|
+
|
|
602
|
+
## 🙏 Acknowledgments
|
|
603
|
+
|
|
604
|
+
- Built with ❤️ for the Django community
|
|
605
|
+
- Inspired by [Intercom](https://www.intercom.com/), [Crisp](https://crisp.chat/), and [Tawk.to](https://www.tawk.to/)
|
|
606
|
+
- Icons from [Lucide](https://lucide.dev/)
|
|
607
|
+
- Charts powered by [Chart.js](https://www.chartjs.org/)
|
|
608
|
+
|
|
609
|
+
---
|
|
610
|
+
|
|
611
|
+
## 📞 Support
|
|
612
|
+
|
|
613
|
+
- 🐛 **Bug Reports:** [GitHub Issues](https://github.com/xo-aria/django-supchat/issues)
|
|
614
|
+
- 💡 **Feature Requests:** [GitHub Discussions](https://github.com/xo-aria/django-supchat/discussions)
|
|
615
|
+
- 📧 **Email:** your-email@example.com
|
|
616
|
+
|
|
617
|
+
---
|
|
618
|
+
|
|
619
|
+
<div align="center">
|
|
620
|
+
|
|
621
|
+
**If django-supchat helps your project, consider giving it a ⭐ on GitHub!**
|
|
622
|
+
|
|
623
|
+
[⭐ Star on GitHub](https://github.com/xo-aria/django-supchat) • [💬 Join Discussions](https://github.com/xo-aria/django-supchat/discussions)
|
|
624
|
+
|
|
625
|
+
</div>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
django_supchat-1.0.0.dist-info/licenses/LICENSE,sha256=VvI2fc6R1Vi6RZvvGTdeKjiXSKX3Auis7sDIU4d1Z1c,37121
|
|
2
|
+
supchat/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
|
+
supchat/admin.py,sha256=G3ZenOsslr3Z35rX0VO82Za7fNr369lwhe-2i3e4Z00,2321
|
|
4
|
+
supchat/apps.py,sha256=mvehTgh-b6jKkX5jYJ5rBY-CR6dd24iYbPXXY3NqByM,293
|
|
5
|
+
supchat/conf.py,sha256=jcrlMBvQfASTsK2lgNIZtWGYJ0mcDrAR8eUj9AgleCo,1521
|
|
6
|
+
supchat/forms.py,sha256=UX5zupN3FvvvGH4dcNZI36TQT1S1ku2LEcwQEzg6dAE,848
|
|
7
|
+
supchat/models.py,sha256=7ecSjyqutKzFx6sof4fUf35Ytmyndj1OhVjaWdOXPJs,3937
|
|
8
|
+
supchat/operator_views.py,sha256=WppZJDFTvz7a5DT6nSs00c9-3_-G0ld77hYD5DDMxFw,11044
|
|
9
|
+
supchat/permissions.py,sha256=2grup1bLIWwvdXBSjCyTJzme99mFnkMmkwv98MDZxdA,2259
|
|
10
|
+
supchat/services.py,sha256=vx3cebjbFy403jBKFGwzea4imfmHZxyr6LvCE6-4u_k,9309
|
|
11
|
+
supchat/signals.py,sha256=uaDV0hPWOrbHQYKo-KjbIw0NKNL8GxnntNTYmwgpbH4,317
|
|
12
|
+
supchat/sse.py,sha256=w0b_om0w6GvPAoh_ZAv20wFDZY9y0mDm7h8YuBakJPo,4173
|
|
13
|
+
supchat/urls.py,sha256=uTxHJcEQJxHuhru5a1w1pBsAYgyWC8LWoQJm3jDwz3M,1885
|
|
14
|
+
supchat/views.py,sha256=2c2BLL7kdQApTCd1t2uz8AAj-hUMUtI_yWjpHVZOw0o,4031
|
|
15
|
+
supchat/static/supchat/operator.css,sha256=7XTrsw_XSUwOgx2LHaOz1LRm552vRfUN7nbZRcbiN5Y,21035
|
|
16
|
+
supchat/static/supchat/operator.js,sha256=zCeb3UL7_sQXCDV9C3x1LVwMb6u7OuPegiePK9Oe8Sc,33905
|
|
17
|
+
supchat/static/supchat/supchat.css,sha256=Vm_k6FgPEVlm1RujSw6K7FDeTy2GSaLhd8egQWhbLfQ,18271
|
|
18
|
+
supchat/static/supchat/supchat.js,sha256=J156LjYoEhptgoBkbAabPVDxgid7ckxEh6sfSJfVMSo,13024
|
|
19
|
+
supchat/templates/supchat/widget.html,sha256=RTB79gkeDGmdtaVuH_-aY1pJ1Skd4HbblUESRe3A4xQ,4426
|
|
20
|
+
supchat/templates/supchat/operator/dashboard.html,sha256=VvZZxxBiE45nJAqo4IWpx9fCq2iqktY1hKMoXzbtA_c,8729
|
|
21
|
+
supchat/templates/supchat/operator/partials/dashboard_content.html,sha256=qZVLO9i0EgWpNf9LrCpcAH4RUKIlLTzE47nJpnnznDM,827
|
|
22
|
+
django_supchat-1.0.0.dist-info/METADATA,sha256=7rx89LsRCY0ZPFfgs1ID9N6re0av0J4ahJVdPcOE2rw,17566
|
|
23
|
+
django_supchat-1.0.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
24
|
+
django_supchat-1.0.0.dist-info/top_level.txt,sha256=Gj6dLcvOBWkB1aVVbGZj5NUYeDX_4KsQaVq5dC1z9NI,8
|
|
25
|
+
django_supchat-1.0.0.dist-info/RECORD,,
|