karrio-server-events 2025.5rc1__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.
- karrio/server/events/__init__.py +3 -0
- karrio/server/events/admin.py +3 -0
- karrio/server/events/apps.py +11 -0
- karrio/server/events/filters.py +63 -0
- karrio/server/events/migrations/0001_initial.py +65 -0
- karrio/server/events/migrations/0002_event.py +39 -0
- karrio/server/events/migrations/0003_auto_20220303_1210.py +25 -0
- karrio/server/events/migrations/0004_custom_migration_2022_4.py +41 -0
- karrio/server/events/migrations/0005_event_event_object_idx.py +18 -0
- karrio/server/events/migrations/0006_webhook_events_alter_event_data.py +85 -0
- karrio/server/events/migrations/0007_auto_20221130_0255.py +30 -0
- karrio/server/events/migrations/0008_alter_event_type.py +18 -0
- karrio/server/events/migrations/0009_alter_webhook_enabled_events.py +45 -0
- karrio/server/events/migrations/__init__.py +0 -0
- karrio/server/events/models.py +83 -0
- karrio/server/events/router.py +3 -0
- karrio/server/events/serializers/__init__.py +1 -0
- karrio/server/events/serializers/base.py +63 -0
- karrio/server/events/serializers/event.py +9 -0
- karrio/server/events/serializers/webhook.py +27 -0
- karrio/server/events/signals.py +138 -0
- karrio/server/events/task_definitions/__init__.py +1 -0
- karrio/server/events/task_definitions/base/__init__.py +64 -0
- karrio/server/events/task_definitions/base/archiving.py +58 -0
- karrio/server/events/task_definitions/base/tracking.py +227 -0
- karrio/server/events/task_definitions/base/webhook.py +116 -0
- karrio/server/events/tasks.py +20 -0
- karrio/server/events/tests/__init__.py +7 -0
- karrio/server/events/tests/test_events.py +138 -0
- karrio/server/events/tests/test_tracking_tasks.py +345 -0
- karrio/server/events/tests/test_webhooks.py +132 -0
- karrio/server/events/tests.py +3 -0
- karrio/server/events/urls.py +10 -0
- karrio/server/events/views/__init__.py +2 -0
- karrio/server/events/views/webhooks.py +173 -0
- karrio/server/graph/schemas/__init__.py +1 -0
- karrio/server/graph/schemas/events/__init__.py +47 -0
- karrio/server/graph/schemas/events/inputs.py +43 -0
- karrio/server/graph/schemas/events/mutations.py +56 -0
- karrio/server/graph/schemas/events/types.py +79 -0
- karrio_server_events-2025.5rc1.dist-info/METADATA +28 -0
- karrio_server_events-2025.5rc1.dist-info/RECORD +44 -0
- karrio_server_events-2025.5rc1.dist-info/WHEEL +5 -0
- karrio_server_events-2025.5rc1.dist-info/top_level.txt +2 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
from django.apps import AppConfig
|
2
|
+
from django.utils.translation import gettext_lazy as _
|
3
|
+
|
4
|
+
|
5
|
+
class EventsConfig(AppConfig):
|
6
|
+
name = 'karrio.server.events'
|
7
|
+
verbose_name = _('Custom Pricing')
|
8
|
+
|
9
|
+
def ready(self):
|
10
|
+
from karrio.server.events import signals
|
11
|
+
signals.register_signals()
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import typing
|
2
|
+
from django.db.models import Q
|
3
|
+
|
4
|
+
import karrio.server.events.serializers as serializers
|
5
|
+
import karrio.server.events.models as models
|
6
|
+
import karrio.server.filters as filters
|
7
|
+
|
8
|
+
|
9
|
+
class WebhookFilter(filters.FilterSet):
|
10
|
+
created_after = filters.DateTimeFilter(field_name="created_at", lookup_expr="gte")
|
11
|
+
created_before = filters.DateTimeFilter(field_name="created_at", lookup_expr="lte")
|
12
|
+
description = filters.CharFilter(field_name="description", lookup_expr="icontains")
|
13
|
+
events = filters.MultipleChoiceFilter(
|
14
|
+
field_name="enabled_events",
|
15
|
+
method="events_filter",
|
16
|
+
choices=[(s, s) for s in serializers.EVENT_TYPES],
|
17
|
+
)
|
18
|
+
disabled = filters.BooleanFilter(field_name="disabled")
|
19
|
+
test_mode = filters.BooleanFilter(field_name="test_mode")
|
20
|
+
url = filters.CharFilter(field_name="url", lookup_expr="icontains")
|
21
|
+
|
22
|
+
class Meta:
|
23
|
+
model = models.Webhook
|
24
|
+
fields: typing.List[str] = []
|
25
|
+
|
26
|
+
def events_filter(self, queryset, name, values):
|
27
|
+
if any(values):
|
28
|
+
query = Q(enabled_events__icontains=values[0])
|
29
|
+
|
30
|
+
for value in values[1:]:
|
31
|
+
query &= Q(enabled_events__icontains=value)
|
32
|
+
|
33
|
+
return queryset.filter(query | Q(enabled_events__icontains="all"))
|
34
|
+
|
35
|
+
return queryset.filter(enabled_events__icontains="all")
|
36
|
+
|
37
|
+
|
38
|
+
class EventFilter(filters.FilterSet):
|
39
|
+
entity_id = filters.CharFilter(method="entity_filter", field_name="response")
|
40
|
+
date_after = filters.DateTimeFilter(field_name="created_at", lookup_expr="gte")
|
41
|
+
date_before = filters.DateTimeFilter(field_name="created_at", lookup_expr="lte")
|
42
|
+
type = filters.MultipleChoiceFilter(
|
43
|
+
field_name="type",
|
44
|
+
method="types_filter",
|
45
|
+
choices=[
|
46
|
+
(c.value, c.value)
|
47
|
+
for c in list(serializers.EventTypes)
|
48
|
+
if c != serializers.EventTypes.all
|
49
|
+
],
|
50
|
+
)
|
51
|
+
|
52
|
+
class Meta:
|
53
|
+
model = models.Event
|
54
|
+
fields: typing.List[str] = []
|
55
|
+
|
56
|
+
def entity_filter(self, queryset, name, value):
|
57
|
+
try:
|
58
|
+
return queryset.filter(data__id=value)
|
59
|
+
except:
|
60
|
+
return queryset
|
61
|
+
|
62
|
+
def types_filter(self, queryset, name, values):
|
63
|
+
return queryset.filter(Q(type__in=values))
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# Generated by Django 3.1.7 on 2021-03-16 23:17
|
2
|
+
|
3
|
+
from django.conf import settings
|
4
|
+
import django.contrib.postgres.fields
|
5
|
+
from django.db import migrations, models
|
6
|
+
import django.db.models.deletion
|
7
|
+
import functools
|
8
|
+
import karrio.server.core.models
|
9
|
+
|
10
|
+
|
11
|
+
class Migration(migrations.Migration):
|
12
|
+
|
13
|
+
initial = True
|
14
|
+
|
15
|
+
dependencies = [
|
16
|
+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
17
|
+
]
|
18
|
+
|
19
|
+
operations = [
|
20
|
+
migrations.CreateModel(
|
21
|
+
name="Webhook",
|
22
|
+
fields=[
|
23
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
24
|
+
("updated_at", models.DateTimeField(auto_now=True)),
|
25
|
+
(
|
26
|
+
"id",
|
27
|
+
models.CharField(
|
28
|
+
default=functools.partial(
|
29
|
+
karrio.server.core.models.uuid, *(), **{"prefix": "web_"}
|
30
|
+
),
|
31
|
+
editable=False,
|
32
|
+
max_length=50,
|
33
|
+
primary_key=True,
|
34
|
+
serialize=False,
|
35
|
+
),
|
36
|
+
),
|
37
|
+
(
|
38
|
+
"enabled_events",
|
39
|
+
karrio.server.core.fields.MultiChoiceField(blank=True),
|
40
|
+
),
|
41
|
+
("url", models.URLField()),
|
42
|
+
("test_mode", models.BooleanField()),
|
43
|
+
("disabled", models.BooleanField(default=False, null=True)),
|
44
|
+
(
|
45
|
+
"description",
|
46
|
+
models.CharField(blank=True, max_length=200, null=True),
|
47
|
+
),
|
48
|
+
("last_event_at", models.DateTimeField(null=True)),
|
49
|
+
("failure_streak_count", models.IntegerField(default=0)),
|
50
|
+
(
|
51
|
+
"created_by",
|
52
|
+
models.ForeignKey(
|
53
|
+
on_delete=django.db.models.deletion.CASCADE,
|
54
|
+
to=settings.AUTH_USER_MODEL,
|
55
|
+
),
|
56
|
+
),
|
57
|
+
],
|
58
|
+
options={
|
59
|
+
"verbose_name": "Webhook",
|
60
|
+
"verbose_name_plural": "Webhooks",
|
61
|
+
"db_table": "webhook",
|
62
|
+
"ordering": ["-created_at"],
|
63
|
+
},
|
64
|
+
),
|
65
|
+
]
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Generated by Django 3.2.9 on 2021-11-13 13:38
|
2
|
+
|
3
|
+
from django.conf import settings
|
4
|
+
from django.db import migrations, models
|
5
|
+
import django.db.models.deletion
|
6
|
+
import functools
|
7
|
+
import karrio.server.core.models.base
|
8
|
+
import karrio.server.core.utils
|
9
|
+
|
10
|
+
|
11
|
+
class Migration(migrations.Migration):
|
12
|
+
|
13
|
+
dependencies = [
|
14
|
+
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
15
|
+
('events', '0001_initial'),
|
16
|
+
]
|
17
|
+
|
18
|
+
operations = [
|
19
|
+
migrations.CreateModel(
|
20
|
+
name='Event',
|
21
|
+
fields=[
|
22
|
+
('created_at', models.DateTimeField(auto_now_add=True)),
|
23
|
+
('updated_at', models.DateTimeField(auto_now=True)),
|
24
|
+
('id', models.CharField(default=functools.partial(karrio.server.core.models.base.uuid, *(), **{'prefix': 'evt_'}), editable=False, max_length=50, primary_key=True, serialize=False)),
|
25
|
+
('type', models.CharField(max_length=50)),
|
26
|
+
('data', models.JSONField(default=functools.partial(karrio.server.core.utils.identity, *(), **{'value': {}}))),
|
27
|
+
('test_mode', models.BooleanField()),
|
28
|
+
('pending_webhooks', models.IntegerField(default=0)),
|
29
|
+
('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
30
|
+
],
|
31
|
+
options={
|
32
|
+
'verbose_name': 'Event',
|
33
|
+
'verbose_name_plural': 'Events',
|
34
|
+
'db_table': 'event',
|
35
|
+
'ordering': ['-created_at'],
|
36
|
+
},
|
37
|
+
bases=(karrio.server.core.models.base.ControlledAccessModel, models.Model),
|
38
|
+
),
|
39
|
+
]
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Generated by Django 3.2.11 on 2022-03-03 12:10
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
import functools
|
5
|
+
import karrio.server.core.models.base
|
6
|
+
|
7
|
+
|
8
|
+
class Migration(migrations.Migration):
|
9
|
+
|
10
|
+
dependencies = [
|
11
|
+
('events', '0002_event'),
|
12
|
+
]
|
13
|
+
|
14
|
+
operations = [
|
15
|
+
migrations.AddField(
|
16
|
+
model_name='webhook',
|
17
|
+
name='secret',
|
18
|
+
field=models.CharField(default=functools.partial(karrio.server.core.models.base.uuid, *(), **{'prefix': 'whsec_'}), max_length=100),
|
19
|
+
),
|
20
|
+
migrations.AlterField(
|
21
|
+
model_name='webhook',
|
22
|
+
name='id',
|
23
|
+
field=models.CharField(default=functools.partial(karrio.server.core.models.base.uuid, *(), **{'prefix': 'weh_'}), editable=False, max_length=50, primary_key=True, serialize=False),
|
24
|
+
),
|
25
|
+
]
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Generated by Django 3.2.3 on 2022-03-28 03:40
|
2
|
+
|
3
|
+
from django.db import migrations
|
4
|
+
|
5
|
+
|
6
|
+
def forwards_func(apps, schema_editor):
|
7
|
+
db_alias = schema_editor.connection.alias
|
8
|
+
Event = apps.get_model("events", "Event")
|
9
|
+
Webhook = apps.get_model("events", "Webhook")
|
10
|
+
|
11
|
+
for event in Event.objects.using(db_alias).filter(type__icontains=".").iterator():
|
12
|
+
event.type = event.type.replace(".", "_")
|
13
|
+
event.save()
|
14
|
+
|
15
|
+
for webhook in Webhook.objects.using(db_alias).all():
|
16
|
+
webhook.enabled_events = [e.replace(".", "_") for e in webhook.enabled_events]
|
17
|
+
webhook.save()
|
18
|
+
|
19
|
+
|
20
|
+
def reverse_func(apps, schema_editor):
|
21
|
+
db_alias = schema_editor.connection.alias
|
22
|
+
Event = apps.get_model("events", "Event")
|
23
|
+
Webhook = apps.get_model("events", "Webhook")
|
24
|
+
|
25
|
+
for event in Event.objects.using(db_alias).filter(type__icontains=".").iterator():
|
26
|
+
event.type = event.type.replace("_", ".")
|
27
|
+
event.save()
|
28
|
+
|
29
|
+
for webhook in Webhook.objects.using(db_alias).all():
|
30
|
+
webhook.enabled_events = [e.replace("_", ".") for e in webhook.enabled_events]
|
31
|
+
webhook.save()
|
32
|
+
|
33
|
+
|
34
|
+
class Migration(migrations.Migration):
|
35
|
+
dependencies = [
|
36
|
+
("events", "0003_auto_20220303_1210"),
|
37
|
+
]
|
38
|
+
|
39
|
+
operations = [
|
40
|
+
migrations.RunPython(forwards_func, reverse_func),
|
41
|
+
]
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Generated by Django 3.2.13 on 2022-07-10 13:07
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
import django.db.models.fields.json
|
5
|
+
|
6
|
+
|
7
|
+
class Migration(migrations.Migration):
|
8
|
+
|
9
|
+
dependencies = [
|
10
|
+
('events', '0004_custom_migration_2022_4'),
|
11
|
+
]
|
12
|
+
|
13
|
+
operations = [
|
14
|
+
migrations.AddIndex(
|
15
|
+
model_name='event',
|
16
|
+
index=models.Index(django.db.models.fields.json.KeyTextTransform('id', 'data'), condition=models.Q(('data__id__isnull', False)), name='event_object_idx'),
|
17
|
+
),
|
18
|
+
]
|
@@ -0,0 +1,85 @@
|
|
1
|
+
# Generated by Django 4.1.3 on 2022-11-30 00:34
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
from django.conf import settings
|
5
|
+
import functools
|
6
|
+
import karrio.server.core.fields
|
7
|
+
import karrio.server.core.models
|
8
|
+
|
9
|
+
|
10
|
+
def forwards_func(apps, schema_editor):
|
11
|
+
db_alias = schema_editor.connection.alias
|
12
|
+
Webhook = apps.get_model("events", "Webhook")
|
13
|
+
webhooks = (
|
14
|
+
Webhook.objects.using(db_alias).raw(
|
15
|
+
"SELECT id, to_jsonb(enabled_events) AS enabled_events FROM webhook"
|
16
|
+
)
|
17
|
+
if "postgres" in settings.DB_ENGINE
|
18
|
+
else Webhook.objects.using(db_alias).all()
|
19
|
+
)
|
20
|
+
_webhooks = []
|
21
|
+
|
22
|
+
for webhook in webhooks:
|
23
|
+
webhook.events = webhook.enabled_events
|
24
|
+
_webhooks.append(webhook)
|
25
|
+
|
26
|
+
Webhook.objects.using(db_alias).bulk_update(_webhooks, ["events"])
|
27
|
+
|
28
|
+
|
29
|
+
def reverse_func(apps, schema_editor):
|
30
|
+
pass
|
31
|
+
|
32
|
+
|
33
|
+
class Migration(migrations.Migration):
|
34
|
+
dependencies = [
|
35
|
+
("events", "0005_event_event_object_idx"),
|
36
|
+
]
|
37
|
+
|
38
|
+
operations = [
|
39
|
+
migrations.AddField(
|
40
|
+
model_name="webhook",
|
41
|
+
name="events",
|
42
|
+
field=karrio.server.core.fields.MultiChoiceField(
|
43
|
+
choices=[
|
44
|
+
("all", "all"),
|
45
|
+
("shipment_purchased", "shipment_purchased"),
|
46
|
+
("shipment_cancelled", "shipment_cancelled"),
|
47
|
+
("shipment_fulfilled", "shipment_fulfilled"),
|
48
|
+
("tracker_created", "tracker_created"),
|
49
|
+
("tracker_updated", "tracker_updated"),
|
50
|
+
("order_created", "order_created"),
|
51
|
+
("order_updated", "order_updated"),
|
52
|
+
("order_fulfilled", "order_fulfilled"),
|
53
|
+
("order_cancelled", "order_cancelled"),
|
54
|
+
("order_delivered", "order_delivered"),
|
55
|
+
("batch_queued", "batch_queued"),
|
56
|
+
("batch_failed", "batch_failed"),
|
57
|
+
("batch_running", "batch_running"),
|
58
|
+
("batch_completed", "batch_completed"),
|
59
|
+
],
|
60
|
+
default=functools.partial(
|
61
|
+
karrio.server.core.models._identity, *(), **{"value": []}
|
62
|
+
),
|
63
|
+
help_text="Webhook events",
|
64
|
+
),
|
65
|
+
),
|
66
|
+
migrations.AlterField(
|
67
|
+
model_name="event",
|
68
|
+
name="data",
|
69
|
+
field=models.JSONField(
|
70
|
+
default=functools.partial(
|
71
|
+
karrio.server.core.models._identity, *(), **{"value": {}}
|
72
|
+
)
|
73
|
+
),
|
74
|
+
),
|
75
|
+
migrations.RunPython(forwards_func, reverse_func),
|
76
|
+
migrations.RemoveField(
|
77
|
+
model_name="webhook",
|
78
|
+
name="enabled_events",
|
79
|
+
),
|
80
|
+
migrations.RenameField(
|
81
|
+
model_name="webhook",
|
82
|
+
old_name="events",
|
83
|
+
new_name="enabled_events",
|
84
|
+
),
|
85
|
+
]
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Generated by Django 4.1.3 on 2022-11-30 02:55
|
2
|
+
|
3
|
+
from django.db import migrations
|
4
|
+
import karrio.lib as lib
|
5
|
+
|
6
|
+
|
7
|
+
def forwards_func(apps, schema_editor):
|
8
|
+
db_alias = schema_editor.connection.alias
|
9
|
+
Webhook = apps.get_model("events", "Webhook")
|
10
|
+
_webhooks = []
|
11
|
+
|
12
|
+
for webhook in Webhook.objects.using(db_alias).all().iterator():
|
13
|
+
webhook.enabled_events = lib.to_dict(webhook.enabled_events)
|
14
|
+
_webhooks.append(webhook)
|
15
|
+
|
16
|
+
Webhook.objects.using(db_alias).bulk_update(_webhooks, ["enabled_events"])
|
17
|
+
|
18
|
+
|
19
|
+
def reverse_func(apps, schema_editor):
|
20
|
+
pass
|
21
|
+
|
22
|
+
|
23
|
+
class Migration(migrations.Migration):
|
24
|
+
dependencies = [
|
25
|
+
("events", "0006_webhook_events_alter_event_data"),
|
26
|
+
]
|
27
|
+
|
28
|
+
operations = [
|
29
|
+
migrations.RunPython(forwards_func, reverse_func),
|
30
|
+
]
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# Generated by Django 4.1.3 on 2022-12-10 17:09
|
2
|
+
|
3
|
+
from django.db import migrations, models
|
4
|
+
|
5
|
+
|
6
|
+
class Migration(migrations.Migration):
|
7
|
+
|
8
|
+
dependencies = [
|
9
|
+
("events", "0007_auto_20221130_0255"),
|
10
|
+
]
|
11
|
+
|
12
|
+
operations = [
|
13
|
+
migrations.AlterField(
|
14
|
+
model_name="event",
|
15
|
+
name="type",
|
16
|
+
field=models.CharField(db_index=True, max_length=50),
|
17
|
+
),
|
18
|
+
]
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Generated by Django 4.2 on 2023-04-18 10:18
|
2
|
+
|
3
|
+
from django.db import migrations
|
4
|
+
import functools
|
5
|
+
import karrio.server.core.fields
|
6
|
+
import karrio.server.core.models
|
7
|
+
|
8
|
+
|
9
|
+
class Migration(migrations.Migration):
|
10
|
+
dependencies = [
|
11
|
+
("events", "0008_alter_event_type"),
|
12
|
+
]
|
13
|
+
|
14
|
+
operations = [
|
15
|
+
migrations.AlterField(
|
16
|
+
model_name="webhook",
|
17
|
+
name="enabled_events",
|
18
|
+
field=karrio.server.core.fields.MultiChoiceField(
|
19
|
+
choices=[
|
20
|
+
("all", "all"),
|
21
|
+
("shipment_purchased", "shipment_purchased"),
|
22
|
+
("shipment_cancelled", "shipment_cancelled"),
|
23
|
+
("shipment_fulfilled", "shipment_fulfilled"),
|
24
|
+
("shipment_out_for_delivery", "shipment_out_for_delivery"),
|
25
|
+
("shipment_needs_attention", "shipment_needs_attention"),
|
26
|
+
("shipment_delivery_failed", "shipment_delivery_failed"),
|
27
|
+
("tracker_created", "tracker_created"),
|
28
|
+
("tracker_updated", "tracker_updated"),
|
29
|
+
("order_created", "order_created"),
|
30
|
+
("order_updated", "order_updated"),
|
31
|
+
("order_fulfilled", "order_fulfilled"),
|
32
|
+
("order_cancelled", "order_cancelled"),
|
33
|
+
("order_delivered", "order_delivered"),
|
34
|
+
("batch_queued", "batch_queued"),
|
35
|
+
("batch_failed", "batch_failed"),
|
36
|
+
("batch_running", "batch_running"),
|
37
|
+
("batch_completed", "batch_completed"),
|
38
|
+
],
|
39
|
+
default=functools.partial(
|
40
|
+
karrio.server.core.models._identity, *(), **{"value": []}
|
41
|
+
),
|
42
|
+
help_text="Webhook events",
|
43
|
+
),
|
44
|
+
),
|
45
|
+
]
|
File without changes
|
@@ -0,0 +1,83 @@
|
|
1
|
+
from functools import partial
|
2
|
+
from django.db import models
|
3
|
+
from django.conf import settings
|
4
|
+
from django.db.models.fields import json
|
5
|
+
|
6
|
+
import karrio.server.core.models as core
|
7
|
+
import karrio.server.core.fields as core_fields
|
8
|
+
import karrio.server.events.serializers.base as serializers
|
9
|
+
|
10
|
+
|
11
|
+
@core.register_model
|
12
|
+
class Webhook(core.OwnedEntity):
|
13
|
+
HIDDEN_PROPS = (*(("org",) if settings.MULTI_ORGANIZATIONS else tuple()),)
|
14
|
+
|
15
|
+
class Meta:
|
16
|
+
db_table = "webhook"
|
17
|
+
verbose_name = "Webhook"
|
18
|
+
verbose_name_plural = "Webhooks"
|
19
|
+
ordering = ["-created_at"]
|
20
|
+
|
21
|
+
id = models.CharField(
|
22
|
+
max_length=50,
|
23
|
+
primary_key=True,
|
24
|
+
default=partial(core.uuid, prefix="weh_"),
|
25
|
+
editable=False,
|
26
|
+
)
|
27
|
+
|
28
|
+
enabled_events = core_fields.MultiChoiceField(
|
29
|
+
choices=serializers.EVENT_TYPES,
|
30
|
+
default=core.field_default([]),
|
31
|
+
help_text="Webhook events",
|
32
|
+
)
|
33
|
+
url = models.URLField(max_length=200)
|
34
|
+
secret = models.CharField(
|
35
|
+
max_length=100, default=partial(core.uuid, prefix="whsec_")
|
36
|
+
)
|
37
|
+
test_mode = models.BooleanField(null=False)
|
38
|
+
disabled = models.BooleanField(null=True, default=False)
|
39
|
+
description = models.CharField(max_length=200, null=True, blank=True)
|
40
|
+
last_event_at = models.DateTimeField(null=True)
|
41
|
+
|
42
|
+
# System Reference fields
|
43
|
+
failure_streak_count = models.IntegerField(default=0)
|
44
|
+
|
45
|
+
def __str__(self):
|
46
|
+
return f"{self.id} + {self.url}"
|
47
|
+
|
48
|
+
@property
|
49
|
+
def object_type(self):
|
50
|
+
return "webhook"
|
51
|
+
|
52
|
+
|
53
|
+
class Event(core.OwnedEntity):
|
54
|
+
HIDDEN_PROPS = (*(("org",) if settings.MULTI_ORGANIZATIONS else tuple()),)
|
55
|
+
|
56
|
+
class Meta:
|
57
|
+
db_table = "event"
|
58
|
+
verbose_name = "Event"
|
59
|
+
verbose_name_plural = "Events"
|
60
|
+
ordering = ["-created_at"]
|
61
|
+
indexes = [
|
62
|
+
models.Index(
|
63
|
+
json.KeyTextTransform("id", "data"),
|
64
|
+
condition=models.Q(data__id__isnull=False),
|
65
|
+
name="event_object_idx",
|
66
|
+
),
|
67
|
+
]
|
68
|
+
|
69
|
+
id = models.CharField(
|
70
|
+
max_length=50,
|
71
|
+
primary_key=True,
|
72
|
+
default=partial(core.uuid, prefix="evt_"),
|
73
|
+
editable=False,
|
74
|
+
)
|
75
|
+
|
76
|
+
type = models.CharField(max_length=50, db_index=True)
|
77
|
+
data = models.JSONField(default=core.field_default({}))
|
78
|
+
test_mode = models.BooleanField(null=False)
|
79
|
+
pending_webhooks = models.IntegerField(default=0)
|
80
|
+
|
81
|
+
@property
|
82
|
+
def object_type(self):
|
83
|
+
return "event"
|
@@ -0,0 +1 @@
|
|
1
|
+
from karrio.server.events.serializers.base import *
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import karrio.lib as lib
|
2
|
+
import karrio.server.serializers as serializers
|
3
|
+
|
4
|
+
|
5
|
+
class EventTypes(lib.StrEnum):
|
6
|
+
all = "all"
|
7
|
+
shipment_purchased = "shipment_purchased"
|
8
|
+
shipment_cancelled = "shipment_cancelled"
|
9
|
+
shipment_fulfilled = "shipment_fulfilled"
|
10
|
+
shipment_out_for_delivery = "shipment_out_for_delivery"
|
11
|
+
shipment_needs_attention = "shipment_needs_attention"
|
12
|
+
shipment_delivery_failed = "shipment_delivery_failed"
|
13
|
+
tracker_created = "tracker_created"
|
14
|
+
tracker_updated = "tracker_updated"
|
15
|
+
order_created = "order_created"
|
16
|
+
order_updated = "order_updated"
|
17
|
+
order_fulfilled = "order_fulfilled"
|
18
|
+
order_cancelled = "order_cancelled"
|
19
|
+
order_delivered = "order_delivered"
|
20
|
+
batch_queued = "batch_queued"
|
21
|
+
batch_failed = "batch_failed"
|
22
|
+
batch_running = "batch_running"
|
23
|
+
batch_completed = "batch_completed"
|
24
|
+
|
25
|
+
|
26
|
+
EVENT_TYPES = [(c.value, c.value) for c in list(EventTypes)]
|
27
|
+
|
28
|
+
|
29
|
+
class WebhookData(serializers.Serializer):
|
30
|
+
url = serializers.URLField(
|
31
|
+
required=True, help_text="The URL of the webhook endpoint."
|
32
|
+
)
|
33
|
+
description = serializers.CharField(
|
34
|
+
required=False,
|
35
|
+
allow_blank=True,
|
36
|
+
allow_null=True,
|
37
|
+
help_text="An optional description of what the webhook is used for.",
|
38
|
+
)
|
39
|
+
enabled_events = serializers.ListField(
|
40
|
+
required=True,
|
41
|
+
child=serializers.ChoiceField(choices=EVENT_TYPES),
|
42
|
+
help_text="The list of events to enable for this endpoint.",
|
43
|
+
)
|
44
|
+
disabled = serializers.BooleanField(
|
45
|
+
required=False,
|
46
|
+
allow_null=True,
|
47
|
+
help_text="Indicates that the webhook is disabled",
|
48
|
+
)
|
49
|
+
|
50
|
+
|
51
|
+
class Webhook(serializers.EntitySerializer, WebhookData):
|
52
|
+
object_type = serializers.CharField(
|
53
|
+
default="webhook", help_text="Specifies the object type"
|
54
|
+
)
|
55
|
+
last_event_at = serializers.DateTimeField(
|
56
|
+
required=False,
|
57
|
+
allow_null=True,
|
58
|
+
help_text="The datetime of the last event sent.",
|
59
|
+
)
|
60
|
+
secret = serializers.CharField(help_text="Header signature secret")
|
61
|
+
test_mode = serializers.BooleanField(
|
62
|
+
help_text="Specified whether it was created with a carrier in test mode",
|
63
|
+
)
|
@@ -0,0 +1,9 @@
|
|
1
|
+
import karrio.server.serializers as serializers
|
2
|
+
import karrio.server.events.models as models
|
3
|
+
|
4
|
+
|
5
|
+
@serializers.owned_model_serializer
|
6
|
+
class EventSerializer(serializers.ModelSerializer):
|
7
|
+
class Meta:
|
8
|
+
model = models.Event
|
9
|
+
exclude = ["created_at", "updated_at", "created_by"]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
from karrio.server.serializers import owned_model_serializer
|
2
|
+
from karrio.server.events.serializers import WebhookData, Webhook
|
3
|
+
import karrio.server.events.models as models
|
4
|
+
|
5
|
+
|
6
|
+
@owned_model_serializer
|
7
|
+
class WebhookSerializer(WebhookData):
|
8
|
+
def create(self, validated_data: dict, context, **kwargs) -> models.Webhook:
|
9
|
+
return models.Webhook.objects.create(
|
10
|
+
test_mode=getattr(context, "test_mode", False),
|
11
|
+
**validated_data,
|
12
|
+
)
|
13
|
+
|
14
|
+
def update(
|
15
|
+
self, instance: models.Webhook, validated_data: dict, **kwargs
|
16
|
+
) -> models.Webhook:
|
17
|
+
if (
|
18
|
+
"disabled" in validated_data
|
19
|
+
and validated_data["disabled"] != instance.disabled
|
20
|
+
):
|
21
|
+
instance.failure_streak_count = 0
|
22
|
+
|
23
|
+
for key, val in validated_data.items():
|
24
|
+
setattr(instance, key, val)
|
25
|
+
|
26
|
+
instance.save()
|
27
|
+
return instance
|