contextbase-plugin-whatsapp-local 0.2.8__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.
- contextbase_plugin_whatsapp_local-0.2.8.dist-info/METADATA +13 -0
- contextbase_plugin_whatsapp_local-0.2.8.dist-info/RECORD +16 -0
- contextbase_plugin_whatsapp_local-0.2.8.dist-info/WHEEL +4 -0
- plugin_whatsapp_local/__init__.py +0 -0
- plugin_whatsapp_local/binding_config.py +18 -0
- plugin_whatsapp_local/component.py +137 -0
- plugin_whatsapp_local/defs/__init__.py +1 -0
- plugin_whatsapp_local/defs/defs.yaml +2 -0
- plugin_whatsapp_local/models/__init__.py +0 -0
- plugin_whatsapp_local/models/base.py +7 -0
- plugin_whatsapp_local/models/ctx.py +260 -0
- plugin_whatsapp_local/models/ingress.py +314 -0
- plugin_whatsapp_local/models/translators.py +321 -0
- plugin_whatsapp_local/plugin.json +7 -0
- plugin_whatsapp_local/sources/__init__.py +1 -0
- plugin_whatsapp_local/sources/snapshot.py +255 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: contextbase-plugin-whatsapp-local
|
|
3
|
+
Version: 0.2.8
|
|
4
|
+
Summary: WhatsApp local plugin for ContextBase
|
|
5
|
+
Author: Alizain Feerasta
|
|
6
|
+
Author-email: Alizain Feerasta <alizain.feerasta@gmail.com>
|
|
7
|
+
Requires-Dist: contextbase-shared-plugins==0.2.8
|
|
8
|
+
Requires-Dist: dagster==1.12.14
|
|
9
|
+
Requires-Dist: dagster-dlt==0.28.14
|
|
10
|
+
Requires-Dist: dlt>=1.26.0
|
|
11
|
+
Requires-Dist: pydantic>=2.12.0
|
|
12
|
+
Requires-Dist: sqlalchemy>=2.0.0
|
|
13
|
+
Requires-Python: >=3.14, <3.15
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
plugin_whatsapp_local/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
+
plugin_whatsapp_local/binding_config.py,sha256=HKdBxiJBVodGfmKU81wMEgqkVVAe2K8-b-D4OGQL1g8,442
|
|
3
|
+
plugin_whatsapp_local/component.py,sha256=PaRcFXZmLtlAJQqyJgZ82Mx9Zkqqwt_OhBabegFZw2Y,4753
|
|
4
|
+
plugin_whatsapp_local/defs/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
5
|
+
plugin_whatsapp_local/defs/defs.yaml,sha256=38drNqOp9m6Xxo8pIWwX66iyQQlT-Q8MUqjBoQZ5uc4,66
|
|
6
|
+
plugin_whatsapp_local/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
plugin_whatsapp_local/models/base.py,sha256=Fp7n4EfxQOxzqm34-D-rYyu60P88eZUIewCBNP_Iuc4,119
|
|
8
|
+
plugin_whatsapp_local/models/ctx.py,sha256=tYoXhusFPtBAbGo1NbrtpKFfWfIez6MTPpoytqfLExA,8511
|
|
9
|
+
plugin_whatsapp_local/models/ingress.py,sha256=kbaUxUyP9VI_UNQMdYhES2xcbJQ_2eOoK7PDTXQFVHk,14763
|
|
10
|
+
plugin_whatsapp_local/models/translators.py,sha256=gIeqiQjnmI7poAniTKyoukeV_pZhiOFZp4DCSIVAnqk,10138
|
|
11
|
+
plugin_whatsapp_local/plugin.json,sha256=xb5rdK4thxvUaS18kYgiua4d7Ac-QnUA5P6beCUiZXY,87
|
|
12
|
+
plugin_whatsapp_local/sources/__init__.py,sha256=U4S_2y3zgLZVfMenHRaJFBW8yqh2mUBuI291LGQVOJ8,35
|
|
13
|
+
plugin_whatsapp_local/sources/snapshot.py,sha256=3iDy_FeIUZSzqUJfdiuZaKWP1yLVkkJ4Uwa6SI3wNzU,8969
|
|
14
|
+
contextbase_plugin_whatsapp_local-0.2.8.dist-info/WHEEL,sha256=i9aSRDivn5iP9LaR1BLQX2GNAuriQWPsFwbbWygTX2k,81
|
|
15
|
+
contextbase_plugin_whatsapp_local-0.2.8.dist-info/METADATA,sha256=otkPzLQCU92lRUrGp_8v-5i_duodSSf69U6HEu8Xzi4,449
|
|
16
|
+
contextbase_plugin_whatsapp_local-0.2.8.dist-info/RECORD,,
|
|
File without changes
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from pydantic import Field
|
|
6
|
+
|
|
7
|
+
from shared_plugins.bindings import BaseBindingConfigModel, ResolvedPath
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class WhatsAppLocalBindingConfig(BaseBindingConfigModel):
|
|
11
|
+
data_dir: ResolvedPath = Field(
|
|
12
|
+
default_factory=lambda: (
|
|
13
|
+
Path.home()
|
|
14
|
+
/ "Library"
|
|
15
|
+
/ "Group Containers"
|
|
16
|
+
/ "group.net.whatsapp.WhatsApp.shared"
|
|
17
|
+
),
|
|
18
|
+
)
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import dagster as dg
|
|
2
|
+
from dagster import AssetExecutionContext
|
|
3
|
+
from dagster_dlt import DagsterDltResource
|
|
4
|
+
from shared_plugins.automation import non_overlapping_automation_condition
|
|
5
|
+
from shared_plugins.bindings import parse_binding_config
|
|
6
|
+
from shared_plugins.control_plane import ControlPlaneClient
|
|
7
|
+
from shared_plugins.dlt import resolve_partition_binding, run_dlt_pipeline
|
|
8
|
+
from shared_plugins.naming import (
|
|
9
|
+
dagster_asset_group_name,
|
|
10
|
+
dagster_asset_tags,
|
|
11
|
+
dagster_dlt_asset_key,
|
|
12
|
+
dagster_partition_def_name,
|
|
13
|
+
dagster_pool_name,
|
|
14
|
+
dlt_source_name,
|
|
15
|
+
plugin_id_from_module,
|
|
16
|
+
)
|
|
17
|
+
from shared_plugins.resources import DLT_RESOURCE
|
|
18
|
+
|
|
19
|
+
from .binding_config import WhatsAppLocalBindingConfig
|
|
20
|
+
from .sources.snapshot import whatsapp_local_snapshot_source
|
|
21
|
+
|
|
22
|
+
PLUGIN_ID = plugin_id_from_module(__file__)
|
|
23
|
+
SNAPSHOT_JOB = "snapshot"
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _build_snapshot_specs(
|
|
27
|
+
partitions_def: dg.PartitionsDefinition,
|
|
28
|
+
automation_condition: dg.AutomationCondition,
|
|
29
|
+
) -> list[dg.AssetSpec]:
|
|
30
|
+
snapshot_source_name = dlt_source_name(PLUGIN_ID, SNAPSHOT_JOB)
|
|
31
|
+
shared = dict(
|
|
32
|
+
group_name=dagster_asset_group_name(PLUGIN_ID),
|
|
33
|
+
tags=dagster_asset_tags(PLUGIN_ID),
|
|
34
|
+
automation_condition=automation_condition,
|
|
35
|
+
partitions_def=partitions_def,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
return [
|
|
39
|
+
dg.AssetSpec(
|
|
40
|
+
key=dagster_dlt_asset_key(snapshot_source_name, "chat_session"),
|
|
41
|
+
**shared,
|
|
42
|
+
),
|
|
43
|
+
dg.AssetSpec(
|
|
44
|
+
key=dagster_dlt_asset_key(snapshot_source_name, "message"),
|
|
45
|
+
**shared,
|
|
46
|
+
),
|
|
47
|
+
dg.AssetSpec(
|
|
48
|
+
key=dagster_dlt_asset_key(snapshot_source_name, "contact"),
|
|
49
|
+
**shared,
|
|
50
|
+
),
|
|
51
|
+
dg.AssetSpec(
|
|
52
|
+
key=dagster_dlt_asset_key(snapshot_source_name, "group_info"),
|
|
53
|
+
**shared,
|
|
54
|
+
),
|
|
55
|
+
dg.AssetSpec(
|
|
56
|
+
key=dagster_dlt_asset_key(snapshot_source_name, "group_member"),
|
|
57
|
+
**shared,
|
|
58
|
+
),
|
|
59
|
+
dg.AssetSpec(
|
|
60
|
+
key=dagster_dlt_asset_key(snapshot_source_name, "profile_push_name"),
|
|
61
|
+
**shared,
|
|
62
|
+
),
|
|
63
|
+
dg.AssetSpec(
|
|
64
|
+
key=dagster_dlt_asset_key(snapshot_source_name, "message_data_item"),
|
|
65
|
+
**shared,
|
|
66
|
+
),
|
|
67
|
+
dg.AssetSpec(
|
|
68
|
+
key=dagster_dlt_asset_key(snapshot_source_name, "aggregate_call_event"),
|
|
69
|
+
**shared,
|
|
70
|
+
),
|
|
71
|
+
dg.AssetSpec(
|
|
72
|
+
key=dagster_dlt_asset_key(snapshot_source_name, "call_event"),
|
|
73
|
+
**shared,
|
|
74
|
+
),
|
|
75
|
+
dg.AssetSpec(
|
|
76
|
+
key=dagster_dlt_asset_key(snapshot_source_name, "call_event_participant"),
|
|
77
|
+
**shared,
|
|
78
|
+
),
|
|
79
|
+
]
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class WhatsAppLocalSyncComponent(dg.Component):
|
|
83
|
+
def build_defs(self, context: dg.ComponentLoadContext) -> dg.Definitions:
|
|
84
|
+
partitions_def = dg.DynamicPartitionsDefinition(
|
|
85
|
+
name=dagster_partition_def_name(PLUGIN_ID)
|
|
86
|
+
)
|
|
87
|
+
snapshot_specs = _build_snapshot_specs(
|
|
88
|
+
partitions_def=partitions_def,
|
|
89
|
+
automation_condition=non_overlapping_automation_condition(
|
|
90
|
+
dg.AutomationCondition.on_missing()
|
|
91
|
+
| dg.AutomationCondition.on_cron("*/15 * * * *")
|
|
92
|
+
),
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
@dg.multi_asset(
|
|
96
|
+
specs=snapshot_specs,
|
|
97
|
+
can_subset=True,
|
|
98
|
+
name="whatsapp_local_snapshot",
|
|
99
|
+
pool=dagster_pool_name(PLUGIN_ID),
|
|
100
|
+
)
|
|
101
|
+
def whatsapp_local_snapshot_assets(
|
|
102
|
+
context: AssetExecutionContext,
|
|
103
|
+
dlt_resource: DagsterDltResource,
|
|
104
|
+
control_plane: dg.ResourceParam[ControlPlaneClient],
|
|
105
|
+
):
|
|
106
|
+
binding = resolve_partition_binding(
|
|
107
|
+
context=context,
|
|
108
|
+
control_plane=control_plane,
|
|
109
|
+
plugin_id=PLUGIN_ID,
|
|
110
|
+
)
|
|
111
|
+
binding_id = str(binding.binding_id)
|
|
112
|
+
cfg = parse_binding_config(binding, WhatsAppLocalBindingConfig)
|
|
113
|
+
|
|
114
|
+
source = whatsapp_local_snapshot_source(binding_id, cfg)
|
|
115
|
+
yield from run_dlt_pipeline(
|
|
116
|
+
context=context,
|
|
117
|
+
dlt_resource=dlt_resource,
|
|
118
|
+
source=source,
|
|
119
|
+
plugin_id=PLUGIN_ID,
|
|
120
|
+
binding_id=binding_id,
|
|
121
|
+
job_name=SNAPSHOT_JOB,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
automation_sensor = dg.AutomationConditionSensorDefinition(
|
|
125
|
+
name="whatsapp_local_automation_sensor",
|
|
126
|
+
target=dg.AssetSelection.assets(whatsapp_local_snapshot_assets),
|
|
127
|
+
default_status=dg.DefaultSensorStatus.RUNNING,
|
|
128
|
+
minimum_interval_seconds=30,
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
return dg.Definitions(
|
|
132
|
+
assets=[whatsapp_local_snapshot_assets],
|
|
133
|
+
sensors=[automation_sensor],
|
|
134
|
+
resources={
|
|
135
|
+
"dlt_resource": DLT_RESOURCE,
|
|
136
|
+
},
|
|
137
|
+
)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
File without changes
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pydantic import AwareDatetime
|
|
4
|
+
from shared_plugins.models import CtxModel
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class ChatSessionRow(CtxModel):
|
|
8
|
+
pk: int
|
|
9
|
+
ent: int | None = None
|
|
10
|
+
opt: int | None = None
|
|
11
|
+
archived: int | None = None
|
|
12
|
+
contact_abid: int | None = None
|
|
13
|
+
flags: int | None = None
|
|
14
|
+
hidden: int | None = None
|
|
15
|
+
identity_verification_epoch: int | None = None
|
|
16
|
+
identity_verification_state: int | None = None
|
|
17
|
+
message_counter: int | None = None
|
|
18
|
+
removed: int | None = None
|
|
19
|
+
session_type: int | None = None
|
|
20
|
+
spotlight_status: int | None = None
|
|
21
|
+
unread_count: int | None = None
|
|
22
|
+
group_info_pk: int | None = None
|
|
23
|
+
last_message_pk: int | None = None
|
|
24
|
+
properties_pk: int | None = None
|
|
25
|
+
last_message_date: AwareDatetime | None = None
|
|
26
|
+
location_sharing_end_date: AwareDatetime | None = None
|
|
27
|
+
contact_identifier: str | None = None
|
|
28
|
+
contact_jid: str | None = None
|
|
29
|
+
etag: str | None = None
|
|
30
|
+
last_message_text: str | None = None
|
|
31
|
+
partner_name: str | None = None
|
|
32
|
+
saved_input: str | None = None
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class MessageRow(CtxModel):
|
|
36
|
+
pk: int
|
|
37
|
+
ent: int | None = None
|
|
38
|
+
opt: int | None = None
|
|
39
|
+
child_messages_delivered_count: int | None = None
|
|
40
|
+
child_messages_played_count: int | None = None
|
|
41
|
+
child_messages_read_count: int | None = None
|
|
42
|
+
data_item_version: int | None = None
|
|
43
|
+
doc_id: int | None = None
|
|
44
|
+
enc_retry_count: int | None = None
|
|
45
|
+
filtered_recipient_count: int | None = None
|
|
46
|
+
flags: int | None = None
|
|
47
|
+
group_event_type: int | None = None
|
|
48
|
+
is_from_me: int | None = None
|
|
49
|
+
message_error_status: int | None = None
|
|
50
|
+
message_status: int | None = None
|
|
51
|
+
message_type: int | None = None
|
|
52
|
+
sort: int | None = None
|
|
53
|
+
spotlight_status: int | None = None
|
|
54
|
+
starred: int | None = None
|
|
55
|
+
chat_session_pk: int | None = None
|
|
56
|
+
group_member_pk: int | None = None
|
|
57
|
+
last_session_pk: int | None = None
|
|
58
|
+
media_item_pk: int | None = None
|
|
59
|
+
message_info_pk: int | None = None
|
|
60
|
+
parent_message_pk: int | None = None
|
|
61
|
+
message_date: AwareDatetime | None = None
|
|
62
|
+
sent_date: AwareDatetime | None = None
|
|
63
|
+
from_jid: str | None = None
|
|
64
|
+
media_section_id: str | None = None
|
|
65
|
+
phash: str | None = None
|
|
66
|
+
stanza_id: str | None = None
|
|
67
|
+
text: str | None = None
|
|
68
|
+
to_jid: str | None = None
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class ContactRow(CtxModel):
|
|
72
|
+
pk: int
|
|
73
|
+
ent: int | None = None
|
|
74
|
+
opt: int | None = None
|
|
75
|
+
disappearing_mode_duration: int | None = None
|
|
76
|
+
phone_status: int | None = None
|
|
77
|
+
section_sort: int | None = None
|
|
78
|
+
sort: int | None = None
|
|
79
|
+
source: int | None = None
|
|
80
|
+
spotlight_status: int | None = None
|
|
81
|
+
sync_policy: int | None = None
|
|
82
|
+
sync_with_server_state: int | None = None
|
|
83
|
+
about_expiration_timestamp: AwareDatetime | None = None
|
|
84
|
+
about_timestamp: AwareDatetime | None = None
|
|
85
|
+
disappearing_mode_timestamp: AwareDatetime | None = None
|
|
86
|
+
last_updated: AwareDatetime | None = None
|
|
87
|
+
about_emoji: str | None = None
|
|
88
|
+
about_text: str | None = None
|
|
89
|
+
business_name: str | None = None
|
|
90
|
+
full_name: str | None = None
|
|
91
|
+
given_name: str | None = None
|
|
92
|
+
highlighted_name: str | None = None
|
|
93
|
+
identifier: str | None = None
|
|
94
|
+
last_name: str | None = None
|
|
95
|
+
lid: str | None = None
|
|
96
|
+
lid_hash: str | None = None
|
|
97
|
+
localized_phone_number: str | None = None
|
|
98
|
+
notes: str | None = None
|
|
99
|
+
phone_number: str | None = None
|
|
100
|
+
phone_number_label: str | None = None
|
|
101
|
+
pn_hash: str | None = None
|
|
102
|
+
search_token_list: str | None = None
|
|
103
|
+
section_title: str | None = None
|
|
104
|
+
unique_id: str | None = None
|
|
105
|
+
username: str | None = None
|
|
106
|
+
whatsapp_id: str | None = None
|
|
107
|
+
device_list: bytes | None = None
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class GroupInfoRow(CtxModel):
|
|
111
|
+
pk: int
|
|
112
|
+
ent: int | None = None
|
|
113
|
+
opt: int | None = None
|
|
114
|
+
state: int | None = None
|
|
115
|
+
chat_session_pk: int | None = None
|
|
116
|
+
last_message_owner_pk: int | None = None
|
|
117
|
+
creation_date: AwareDatetime | None = None
|
|
118
|
+
subject_timestamp: AwareDatetime | None = None
|
|
119
|
+
creator_jid: str | None = None
|
|
120
|
+
owner_jid: str | None = None
|
|
121
|
+
picture_id: str | None = None
|
|
122
|
+
picture_path: str | None = None
|
|
123
|
+
source_jid: str | None = None
|
|
124
|
+
subject_owner_jid: str | None = None
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
class GroupMemberRow(CtxModel):
|
|
128
|
+
pk: int
|
|
129
|
+
ent: int | None = None
|
|
130
|
+
opt: int | None = None
|
|
131
|
+
contact_abid: int | None = None
|
|
132
|
+
is_active: int | None = None
|
|
133
|
+
is_admin: int | None = None
|
|
134
|
+
sender_key_sent: int | None = None
|
|
135
|
+
chat_session_pk: int | None = None
|
|
136
|
+
recent_group_chat_pk: int | None = None
|
|
137
|
+
contact_identifier: str | None = None
|
|
138
|
+
member_jid: str | None = None
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
class ProfilePushNameRow(CtxModel):
|
|
142
|
+
pk: int
|
|
143
|
+
ent: int | None = None
|
|
144
|
+
opt: int | None = None
|
|
145
|
+
jid: str | None = None
|
|
146
|
+
push_name: str | None = None
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
class MessageDataItemRow(CtxModel):
|
|
150
|
+
pk: int
|
|
151
|
+
ent: int | None = None
|
|
152
|
+
opt: int | None = None
|
|
153
|
+
index: int | None = None
|
|
154
|
+
owns_thumbnail: int | None = None
|
|
155
|
+
type: int | None = None
|
|
156
|
+
message_pk: int | None = None
|
|
157
|
+
date: AwareDatetime | None = None
|
|
158
|
+
chat_jid: str | None = None
|
|
159
|
+
content1: str | None = None
|
|
160
|
+
content2: str | None = None
|
|
161
|
+
matched_text: str | None = None
|
|
162
|
+
section_id: str | None = None
|
|
163
|
+
sender_jid: str | None = None
|
|
164
|
+
summary: str | None = None
|
|
165
|
+
thumbnail_path: str | None = None
|
|
166
|
+
title: str | None = None
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
# ---------------------------------------------------------------------------
|
|
170
|
+
# CallHistory.sqlite
|
|
171
|
+
# ---------------------------------------------------------------------------
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class AggregateCallEventRow(CtxModel):
|
|
175
|
+
pk: int
|
|
176
|
+
ent: int | None = None
|
|
177
|
+
opt: int | None = None
|
|
178
|
+
incoming: int | None = None
|
|
179
|
+
missed: int | None = None
|
|
180
|
+
missed_reason: int | None = None
|
|
181
|
+
video: int | None = None
|
|
182
|
+
first_date: AwareDatetime | None = None
|
|
183
|
+
link_token: str | None = None
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
class CallEventRow(CtxModel):
|
|
187
|
+
pk: int
|
|
188
|
+
ent: int | None = None
|
|
189
|
+
opt: int | None = None
|
|
190
|
+
bytes_received: int | None = None
|
|
191
|
+
bytes_sent: int | None = None
|
|
192
|
+
is_lightweight: int | None = None
|
|
193
|
+
outcome: int | None = None
|
|
194
|
+
aggregate_call_event_pk: int | None = None
|
|
195
|
+
aggregate_call_event_fok: int | None = None
|
|
196
|
+
date: AwareDatetime | None = None
|
|
197
|
+
duration: float | None = None
|
|
198
|
+
call_id_string: str | None = None
|
|
199
|
+
group_call_creator_user_jid_string: str | None = None
|
|
200
|
+
group_jid_string: str | None = None
|
|
201
|
+
reminder_id: str | None = None
|
|
202
|
+
scheduled_id: str | None = None
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class CallEventParticipantRow(CtxModel):
|
|
206
|
+
pk: int
|
|
207
|
+
ent: int | None = None
|
|
208
|
+
opt: int | None = None
|
|
209
|
+
outcome: int | None = None
|
|
210
|
+
call_event_pk: int | None = None
|
|
211
|
+
call_event_fok: int | None = None
|
|
212
|
+
jid_string: str | None = None
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
CHAT_SESSION_COLUMNS: dict[str, dict[str, str]] = {
|
|
216
|
+
"session_type": {
|
|
217
|
+
"description": "1 = group chat (1:1 with group_info), 0 = 1:1 DM. Other values exist for broadcasts/statuses."
|
|
218
|
+
},
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
MESSAGE_COLUMNS: dict[str, dict[str, str]] = {
|
|
223
|
+
"is_from_me": {
|
|
224
|
+
"description": "When 1, the phone owner sent the message and group_member_pk is NULL. When 0, resolve sender via group_member_pk."
|
|
225
|
+
},
|
|
226
|
+
"from_jid": {
|
|
227
|
+
"description": "In group messages this is the GROUP's jid, not the sender's. Use group_member_pk for sender identity."
|
|
228
|
+
},
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
GROUP_MEMBER_COLUMNS: dict[str, dict[str, str]] = {
|
|
233
|
+
"member_jid": {
|
|
234
|
+
"description": "Join to contact via lid for @lid jids, via whatsapp_id for @s.whatsapp.net jids — neither column alone covers both."
|
|
235
|
+
},
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
|
|
239
|
+
AGGREGATE_CALL_EVENT_COLUMNS: dict[str, dict[str, str]] = {
|
|
240
|
+
"incoming": {
|
|
241
|
+
"description": "1 if the call group was received, 0 if placed by self. Combine with call_event.group_call_creator_user_jid_string to identify the peer."
|
|
242
|
+
},
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
|
|
246
|
+
CALL_EVENT_COLUMNS: dict[str, dict[str, str]] = {
|
|
247
|
+
"group_call_creator_user_jid_string": {
|
|
248
|
+
"description": "Call initiator's jid — set for ALL calls despite the name, not just group calls. For aggregate_call_event.incoming=0 (outgoing) it equals self; for incoming=1 it equals the peer."
|
|
249
|
+
},
|
|
250
|
+
"outcome": {
|
|
251
|
+
"description": "Undocumented enum at the source (values 0, 1, 4, 5 observed). Prefer `duration > 0` to detect an answered call."
|
|
252
|
+
},
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
|
|
256
|
+
CALL_EVENT_PARTICIPANT_COLUMNS: dict[str, dict[str, str]] = {
|
|
257
|
+
"jid_string": {
|
|
258
|
+
"description": "Other-party jid for this call leg. For outgoing 1:1 this is the peer; if it differs from call_event.group_call_creator_user_jid_string on an incoming call, the call is almost always multi-party (not 1:1)."
|
|
259
|
+
},
|
|
260
|
+
}
|