locketnoni 1.0.2__tar.gz
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.
- locketnoni-1.0.2/LICENSE +21 -0
- locketnoni-1.0.2/PKG-INFO +497 -0
- locketnoni-1.0.2/README.md +465 -0
- locketnoni-1.0.2/locketlam/__init__.py +29 -0
- locketnoni-1.0.2/locketlam/__main__.py +41 -0
- locketnoni-1.0.2/locketlam/caption_presets.json +2021 -0
- locketnoni-1.0.2/locketlam/client.py +137 -0
- locketnoni-1.0.2/locketlam/device.py +189 -0
- locketnoni-1.0.2/locketlam/exceptions.py +18 -0
- locketnoni-1.0.2/locketlam/modules/chat.py +484 -0
- locketnoni-1.0.2/locketlam/modules/friends.py +189 -0
- locketnoni-1.0.2/locketlam/modules/moments.py +1420 -0
- locketnoni-1.0.2/locketlam/modules/user.py +187 -0
- locketnoni-1.0.2/locketlam/session.py +125 -0
- locketnoni-1.0.2/locketnoni.egg-info/PKG-INFO +497 -0
- locketnoni-1.0.2/locketnoni.egg-info/SOURCES.txt +23 -0
- locketnoni-1.0.2/locketnoni.egg-info/dependency_links.txt +1 -0
- locketnoni-1.0.2/locketnoni.egg-info/requires.txt +4 -0
- locketnoni-1.0.2/locketnoni.egg-info/top_level.txt +1 -0
- locketnoni-1.0.2/pyproject.toml +47 -0
- locketnoni-1.0.2/setup.cfg +4 -0
- locketnoni-1.0.2/setup.py +7 -0
- locketnoni-1.0.2/tests/test_client.py +20 -0
- locketnoni-1.0.2/tests/test_optimizations.py +23 -0
- locketnoni-1.0.2/tests/test_video_upload.py +89 -0
locketnoni-1.0.2/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 LAMDev x DaLyMMO.com
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: locketnoni
|
|
3
|
+
Version: 1.0.2
|
|
4
|
+
Summary: Unofficial Python API client for Locket Camera with full iOS device emulation. Developed by LAMDev x DaLyMMO.com
|
|
5
|
+
Author: LAMDev x DaLyMMO.com
|
|
6
|
+
Author-email: "LAMDev x DaLyMMO.com" <lamdev2104@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/leanhminh2104/locketlam
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/leanhminh2104/locketlam/issues
|
|
10
|
+
Keywords: locket,locket-camera,locket-api,locketlam,ios-client,reverse-engineered
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Classifier: Operating System :: OS Independent
|
|
23
|
+
Requires-Python: >=3.8
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: requests>=2.28.0
|
|
27
|
+
Requires-Dist: websockets>=11.0
|
|
28
|
+
Requires-Dist: pillow>=9.0.0
|
|
29
|
+
Requires-Dist: imageio-ffmpeg>=0.4.8
|
|
30
|
+
Dynamic: author
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
|
|
33
|
+
๏ปฟ# ๐ LocketLam - The Ultimate Python SDK for Locket Camera
|
|
34
|
+
|
|
35
|
+
<p align="center">
|
|
36
|
+
<img src="https://raw.githubusercontent.com/leanhminh2104/locketlam/main/assets/banner.PNG" alt="LocketLam Banner" width="700" onerror="this.style.display='none'"/>
|
|
37
|
+
</p>
|
|
38
|
+
|
|
39
|
+
<p align="center">
|
|
40
|
+
<b>A production-ready, feature-complete Python client library for Locket Camera with authentic iOS hardware simulation.</b>
|
|
41
|
+
</p>
|
|
42
|
+
|
|
43
|
+
<p align="center">
|
|
44
|
+
<a href="https://pypi.org/project/locketlam/"><img src="https://img.shields.io/pypi/v/locketlam.svg?style=flat-square&color=blue" alt="PyPI Version"></a>
|
|
45
|
+
<a href="https://pypi.org/project/locketlam/"><img src="https://img.shields.io/pypi/pyversions/locketlam.svg?style=flat-square" alt="Python Versions"></a>
|
|
46
|
+
<a href="https://github.com/leanhminh2104/locketlam/blob/main/LICENSE"><img src="https://img.shields.io/badge/License-MIT-green.svg?style=flat-square" alt="License MIT"></a>
|
|
47
|
+
<a href="https://pepy.tech/project/locketlam"><img src="https://img.shields.io/pypi/dm/locketlam.svg?style=flat-square" alt="Downloads"></a>
|
|
48
|
+
<a href="https://github.com/leanhminh2104/locketlam/blob/main/README_VI.md"><img src="https://img.shields.io/badge/Language-Vietnamese-red.svg?style=flat-square" alt="Vietnamese Docs"></a>
|
|
49
|
+
</p>
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## ๐๏ธ Documentation Map
|
|
54
|
+
|
|
55
|
+
> **You are here: README** โ the front page. Read this to understand what the library does and whether it suits your needs.
|
|
56
|
+
|
|
57
|
+
| If you want to... | Go to |
|
|
58
|
+
|:---|:---|
|
|
59
|
+
| ๐ **Install & run your first snippet** | You're in the right place โ see [Quick Start](#-quick-start) below |
|
|
60
|
+
| ๐ ๏ธ **Integrate into your project step by step** | โก๏ธ [INTEGRATION.md](https://github.com/leanhminh2104/locketlam/blob/main/docs/INTEGRATION.md) (EN) ยท [INTEGRATION_VI.md](https://github.com/leanhminh2104/locketlam/blob/main/docs/INTEGRATION_VI.md) (VI) |
|
|
61
|
+
| ๐ **Look up a specific method / parameter** | โก๏ธ [FEATURES.md](https://github.com/leanhminh2104/locketlam/blob/main/docs/FEATURES.md) (EN) ยท [FEATURES_VI.md](https://github.com/leanhminh2104/locketlam/blob/main/docs/FEATURES_VI.md) (VI) |
|
|
62
|
+
| ๐ก **Copy-paste complete working scripts** | โก๏ธ [examples/en/](https://github.com/leanhminh2104/locketlam/tree/main/examples/en/) (EN) ยท [examples/vi/](https://github.com/leanhminh2104/locketlam/tree/main/examples/vi/) (VI) |
|
|
63
|
+
| ๐ฌ๐ง **Read this page in Vietnamese** | โก๏ธ [README_VI.md](https://github.com/leanhminh2104/locketlam/blob/main/README_VI.md) |
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## ๐ Table of Contents
|
|
68
|
+
|
|
69
|
+
- [Overview](#-overview)
|
|
70
|
+
- [Key Features](#-key-features)
|
|
71
|
+
- [Installation](#-installation)
|
|
72
|
+
- [Quick Start](#-quick-start)
|
|
73
|
+
- [Comprehensive API Reference](#-comprehensive-api-reference)
|
|
74
|
+
- [1. Authentication & Session Management](#1-authentication--session-management)
|
|
75
|
+
- [2. User Profile Management](#2-user-profile-management)
|
|
76
|
+
- [3. Moments (Feed & Uploads)](#3-moments-feed--uploads)
|
|
77
|
+
- [4. Friends, Groups & Blocking](#4-friends-groups--blocking)
|
|
78
|
+
- [5. Chat & Real-Time WebSockets](#5-chat--real-time-websockets)
|
|
79
|
+
- [6. Device Profile Customization](#6-device-profile-customization)
|
|
80
|
+
- [7. Error Handling](#7-error-handling)
|
|
81
|
+
- [Examples](#-examples)
|
|
82
|
+
- [Contributing](#-contributing)
|
|
83
|
+
- [Support & Donations (Sponsor)](#-support--donations-sponsor)
|
|
84
|
+
- [Copyright & License](#-copyright--license)
|
|
85
|
+
- [Disclaimer](#-disclaimer)
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## ๐ Overview
|
|
90
|
+
|
|
91
|
+
**`locketlam`** is a reverse-engineered Python SDK designed to provide direct programmatic access to the Locket Camera backend. It allows developers, bot creators, and automation engineers to interact seamlessly with Locket accounts using pure Python, without needing an iOS device running.
|
|
92
|
+
|
|
93
|
+
---
|
|
94
|
+
|
|
95
|
+
## โจ Key Features
|
|
96
|
+
|
|
97
|
+
- ๐ฑ **100% Authentic iOS Hardware Emulation**: Sends real iPhone hardware identifiers (iPhone 13 Pro through iPhone 15 Pro Max), bundle IDs (`com.locket.Locket`), Firebase GMPIDs, and Google Protobuf analytics flags to ensure requests are never blocked or flagged.
|
|
98
|
+
- ๐ **Autonomous Token Renewal**: Automatic background Firebase JWT `idToken` refreshing whenever a token is near expiry.
|
|
99
|
+
- ๐ผ๏ธ **Smart Media Pipeline**: Built-in Pillow conversion automatically transforms `.jpg`, `.png`, and other standard formats into Locket-optimized `.webp` format, uploaded via Google Cloud Storage Resumable protocol.
|
|
100
|
+
- โก **Real-Time WebSocket Support**: Asynchronous live event listener for direct chat messages via `wss://api.locketcamera.com/wss_v2/chat`.
|
|
101
|
+
- ๐ก๏ธ **Defensive Architecture**: Strongly-typed exceptions (`AuthenticationError`, `StorageUploadError`, `LocketAPIError`) for robust error handling.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## ๐ฆ Installation
|
|
106
|
+
|
|
107
|
+
Install the library directly from PyPI:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
pip install locketlam
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Or install with development dependencies:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
pip install locketlam[dev]
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
To install from source in editable mode:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
git clone https://github.com/leanhminh2104/locketlam.git
|
|
123
|
+
cd locketlam
|
|
124
|
+
pip install -e .
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## โก Quick Start
|
|
130
|
+
|
|
131
|
+
```python
|
|
132
|
+
from locketlam import LocketClient
|
|
133
|
+
|
|
134
|
+
# 1. Initialize client (auto-loads locketlam_session.json if available)
|
|
135
|
+
client = LocketClient(session_path="locketlam_session.json")
|
|
136
|
+
|
|
137
|
+
# 2. Authenticate if first time
|
|
138
|
+
if not client.is_authenticated():
|
|
139
|
+
client.login("your_email@gmail.com", "your_password")
|
|
140
|
+
print("Logged in successfully! User UID:", client.session.uid)
|
|
141
|
+
|
|
142
|
+
# 3. Fetch profile
|
|
143
|
+
profile = client.user.get_profile()
|
|
144
|
+
print(f"Welcome, {profile.get('first_name')} {profile.get('last_name')} (@{profile.get('username')})")
|
|
145
|
+
|
|
146
|
+
# 4. Post a moment photo
|
|
147
|
+
moment = client.moments.post(
|
|
148
|
+
image="daily_snapshot.jpg",
|
|
149
|
+
caption="Captured with locketlam! โจ",
|
|
150
|
+
is_private=False
|
|
151
|
+
)
|
|
152
|
+
print("Moment posted successfully! ID:", moment.get("canonical_uid"))
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## ๐ Comprehensive API Reference
|
|
158
|
+
|
|
159
|
+
### 1. Authentication & Session Management
|
|
160
|
+
|
|
161
|
+
The `SessionManager` handles credentials, refresh tokens, and JWT tokens securely.
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from locketlam import LocketClient
|
|
165
|
+
|
|
166
|
+
client = LocketClient(session_path="session.json")
|
|
167
|
+
|
|
168
|
+
# Login with email and password
|
|
169
|
+
session_data = client.login("email@example.com", "password")
|
|
170
|
+
|
|
171
|
+
# Check authentication state
|
|
172
|
+
if client.is_authenticated():
|
|
173
|
+
print("User UID:", client.session.uid)
|
|
174
|
+
print("Access Token:", client.session.id_token[:20] + "...")
|
|
175
|
+
|
|
176
|
+
# Force manual token refresh
|
|
177
|
+
client.session.refresh()
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
### 2. User Profile Management
|
|
183
|
+
|
|
184
|
+
Access via `client.user`:
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
# 1. Get profile (self or another user by UID)
|
|
188
|
+
my_profile = client.user.get_profile()
|
|
189
|
+
other_profile = client.user.get_profile(user_uid="TARGET_USER_UID")
|
|
190
|
+
|
|
191
|
+
# 2. Update display name
|
|
192
|
+
client.user.update_name(first_name="Lam", last_name="Dev")
|
|
193
|
+
|
|
194
|
+
# 3. Update birthdate (format: YYYY-MM-DD)
|
|
195
|
+
client.user.update_birthdate("2006-04-21")
|
|
196
|
+
|
|
197
|
+
# 4. Update avatar picture
|
|
198
|
+
client.user.update_avatar("https://firebasestorage.googleapis.com/...")
|
|
199
|
+
|
|
200
|
+
# 5. Sync client data (push notifications, app version)
|
|
201
|
+
client.user.sync_client_data(push_notifications=True)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
### 3. Moments (Feed & Uploads)
|
|
207
|
+
|
|
208
|
+
Access via `client.moments`:
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
from locketlam import NoteType
|
|
212
|
+
|
|
213
|
+
# 1. Post a photo moment with rich gradient badge pill (Supports 158+ presets!)
|
|
214
|
+
photo_moment = client.moments.post(
|
|
215
|
+
image="photo.jpg", # File path, bytes, or Storage URL
|
|
216
|
+
note_type=NoteType.FLEX_DEN_HOI_THO_CUOI, # Preset pill badge (custom gradient)
|
|
217
|
+
is_private=False, # True = sent only to self (sent_to_self_only)
|
|
218
|
+
recipients=None # Specific friends (or None for all)
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
# 2. Post with custom caption, custom gradient colors and custom emoji
|
|
222
|
+
custom_moment = client.moments.post(
|
|
223
|
+
image="photo.jpg",
|
|
224
|
+
caption="Coding with AI",
|
|
225
|
+
icon="โก",
|
|
226
|
+
colors=["#FF416C", "#8A2387"],
|
|
227
|
+
is_private=False
|
|
228
|
+
)
|
|
229
|
+
|
|
230
|
+
# 3. Post a video moment (Supports auto-compression HEVC < 6 MB, 15s to 5-10 mins)
|
|
231
|
+
video_moment = client.moments.post(
|
|
232
|
+
image="thumb.jpg", # Video thumbnail image
|
|
233
|
+
video="clip_10s.mp4", # Video file path, bytes, or Storage URL
|
|
234
|
+
note_type=NoteType.MUSIC # Dynamic music overlay
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
# 4. Retrieve actual shared moments by Username (e.g. latest moments of a friend)
|
|
238
|
+
friend_moments = client.moments.get_posts_by_username("friend_username", limit=10)
|
|
239
|
+
for m in friend_moments:
|
|
240
|
+
print(m["moment_uid"], m["thumbnail_url"], m["caption"])
|
|
241
|
+
|
|
242
|
+
# 5. React to a friend's moment with emoji
|
|
243
|
+
client.moments.react(moment_uid="MOMENT_ID", reaction="โค๏ธ")
|
|
244
|
+
|
|
245
|
+
# 6. Fetch moment view count and viewer list
|
|
246
|
+
views = client.moments.get_views(moment_uid="MOMENT_ID")
|
|
247
|
+
print("Views count:", views.get("count"))
|
|
248
|
+
print("Viewers:", views.get("moment_views"))
|
|
249
|
+
|
|
250
|
+
# 7. Comment on a moment (attaches to moment and appears in direct chat)
|
|
251
|
+
client.moments.comment(
|
|
252
|
+
moment_uid="MOMENT_ID",
|
|
253
|
+
receiver_uid="FRIEND_UID",
|
|
254
|
+
text="Great shot!"
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
# 7. Mark moment as viewed
|
|
258
|
+
client.moments.mark_as_viewed(moment_uid="MOMENT_ID")
|
|
259
|
+
|
|
260
|
+
# 8. Fetch weekly Rollcall event posts
|
|
261
|
+
rollcall = client.moments.get_rollcall_posts()
|
|
262
|
+
print("Rollcall posts:", rollcall.get("posts", []))
|
|
263
|
+
|
|
264
|
+
# 9. Fetch latest feed from friends
|
|
265
|
+
feed = client.moments.get_latest()
|
|
266
|
+
for post in feed:
|
|
267
|
+
print(post.get("user"), post.get("caption"), post.get("thumbnail_url"))
|
|
268
|
+
|
|
269
|
+
# 10. Delete a moment
|
|
270
|
+
client.moments.delete(moment_uid="MOMENT_CANONICAL_UID")
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
---
|
|
274
|
+
|
|
275
|
+
### 4. Friends, Groups & Blocking
|
|
276
|
+
|
|
277
|
+
Access via `client.friends`:
|
|
278
|
+
|
|
279
|
+
```python
|
|
280
|
+
# 1. Retrieve all friends with full profile details (UID, Names, Username, Avatar)
|
|
281
|
+
friends = client.friends.get_all_friends()
|
|
282
|
+
for f in friends:
|
|
283
|
+
print(f"Friend: {f.get('first_name')} (@{f.get('username')}) - UID: {f.get('uid')}")
|
|
284
|
+
|
|
285
|
+
# 2. Retrieve groups state
|
|
286
|
+
groups_state = client.friends.get_groups_and_friends()
|
|
287
|
+
|
|
288
|
+
# 3. Resolve invite token from public profile link (https://locket.cam/<username>)
|
|
289
|
+
token = client.friends.resolve_invite_token_from_username("friend_username")
|
|
290
|
+
print("Invite Token:", token)
|
|
291
|
+
|
|
292
|
+
# 4. Fetch user details from invite token
|
|
293
|
+
user_info = client.friends.fetch_user_by_invite_token(token)
|
|
294
|
+
print("User info:", user_info)
|
|
295
|
+
|
|
296
|
+
# 5. Send friend request by username or UID
|
|
297
|
+
client.friends.send_request_by_username("friend_username")
|
|
298
|
+
# Or: client.friends.send_request(user_uid="TARGET_USER_UID")
|
|
299
|
+
|
|
300
|
+
# 6. Accept incoming friend request
|
|
301
|
+
client.friends.accept_request(user_uid="TARGET_USER_UID")
|
|
302
|
+
|
|
303
|
+
# 7. Remove (unfriend), Block & Unblock
|
|
304
|
+
client.friends.remove(user_uid="TARGET_USER_UID")
|
|
305
|
+
client.friends.block(user_uid="TARGET_USER_UID") # Blocks user & automatically unfriends them on Locket
|
|
306
|
+
client.friends.unblock(user_uid="TARGET_USER_UID") # Unblocks user (removes from blocked_users)
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
### 5. Chat & Real-Time WebSockets
|
|
312
|
+
|
|
313
|
+
Access via `client.chat`:
|
|
314
|
+
|
|
315
|
+
```python
|
|
316
|
+
# 1. Send direct message or emoji
|
|
317
|
+
client.chat.send_message(
|
|
318
|
+
receiver_uid="FRIEND_UID",
|
|
319
|
+
text="Hey, check out this moment! โค๏ธ"
|
|
320
|
+
)
|
|
321
|
+
|
|
322
|
+
# 2. Share a moment into chat (standalone or with text)
|
|
323
|
+
# a) Send standalone moment:
|
|
324
|
+
client.chat.send_moment(
|
|
325
|
+
receiver_uid="FRIEND_UID",
|
|
326
|
+
moment_uid="MOMENT_UID" # Your moment UID or a friend's moment UID
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
# b) Send moment with accompanying text message:
|
|
330
|
+
client.chat.send_moment(
|
|
331
|
+
receiver_uid="FRIEND_UID",
|
|
332
|
+
moment_uid="MOMENT_UID",
|
|
333
|
+
text="Check out this awesome moment!"
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
# 3. Get inbox conversations list
|
|
337
|
+
conversations = client.chat.get_conversations()
|
|
338
|
+
|
|
339
|
+
# 4. Retrieve live chronological messages from server
|
|
340
|
+
messages = client.chat.get_messages(other_user_id="FRIEND_UID")
|
|
341
|
+
|
|
342
|
+
# 4. React with single or multi-emoji combo to a message
|
|
343
|
+
client.chat.send_reaction(conversation_id="CONV_ID", message_id="MSG_ID", emoji="โค๏ธ")
|
|
344
|
+
client.chat.send_reaction(conversation_id="CONV_ID", message_id="MSG_ID", emoji="๐ฅ๐ฅฐ")
|
|
345
|
+
|
|
346
|
+
# 5. Remove / unreact an emoji reaction
|
|
347
|
+
client.chat.remove_reaction(conversation_id="CONV_ID", message_id="MSG_ID")
|
|
348
|
+
|
|
349
|
+
# 6. Recall / unsend your own message
|
|
350
|
+
client.chat.delete_message(conversation_uid="CONV_ID", message_uid="MSG_ID")
|
|
351
|
+
|
|
352
|
+
# 7. Mark conversation as read (send_read_receipt=False for Ghost / Incognito mode)
|
|
353
|
+
client.chat.mark_as_read(conversation_uid="CONV_ID", send_read_receipt=True)
|
|
354
|
+
client.chat.mark_as_read(conversation_uid="CONV_ID", send_read_receipt=False)
|
|
355
|
+
|
|
356
|
+
# 8. Listen to live incoming messages over WebSocket
|
|
357
|
+
import asyncio
|
|
358
|
+
|
|
359
|
+
async def on_new_message(msg):
|
|
360
|
+
print("New incoming message:", msg)
|
|
361
|
+
|
|
362
|
+
# Start event loop
|
|
363
|
+
asyncio.run(client.chat.listen_realtime("FRIEND_UID", on_new_message))
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
### 6. Device Profile Customization
|
|
369
|
+
|
|
370
|
+
By default, `locketlam` picks a realistic iPhone profile. You can also specify custom hardware attributes:
|
|
371
|
+
|
|
372
|
+
```python
|
|
373
|
+
from locketlam import LocketClient, DeviceProfile
|
|
374
|
+
|
|
375
|
+
custom_device = DeviceProfile(
|
|
376
|
+
model_info={
|
|
377
|
+
"model": "iPhone16,1",
|
|
378
|
+
"name": "iPhone 15 Pro",
|
|
379
|
+
"hw": "hw/iPhone16_1",
|
|
380
|
+
"ios": "18.1.0"
|
|
381
|
+
},
|
|
382
|
+
app_version="2.68.0",
|
|
383
|
+
build_number="2523"
|
|
384
|
+
)
|
|
385
|
+
|
|
386
|
+
client = LocketClient(session_path="session.json", device=custom_device)
|
|
387
|
+
print("Emulating:", client.device.user_agent)
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
---
|
|
391
|
+
|
|
392
|
+
### 7. Error Handling
|
|
393
|
+
|
|
394
|
+
All custom exceptions inherit from `LocketError`:
|
|
395
|
+
|
|
396
|
+
```python
|
|
397
|
+
from locketlam.exceptions import (
|
|
398
|
+
LocketError,
|
|
399
|
+
AuthenticationError,
|
|
400
|
+
LocketAPIError,
|
|
401
|
+
StorageUploadError
|
|
402
|
+
)
|
|
403
|
+
|
|
404
|
+
try:
|
|
405
|
+
client.login("user@email.com", "wrong_password")
|
|
406
|
+
except AuthenticationError as e:
|
|
407
|
+
print("Auth Failed:", e)
|
|
408
|
+
except StorageUploadError as e:
|
|
409
|
+
print("Media Upload Failed:", e)
|
|
410
|
+
except LocketAPIError as e:
|
|
411
|
+
print(f"API Error (Status {e.status_code}):", e)
|
|
412
|
+
except LocketError as e:
|
|
413
|
+
print("General Locket Error:", e)
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
---
|
|
417
|
+
|
|
418
|
+
## ๐ก Examples
|
|
419
|
+
|
|
420
|
+
The [`examples/`](https://github.com/leanhminh2104/locketlam/tree/main/examples/) directory contains complete, runnable scripts for every feature:
|
|
421
|
+
|
|
422
|
+
| Feature | Script |
|
|
423
|
+
|:---|:---|
|
|
424
|
+
| Login & Session | [`examples/en/01_login_and_session.py`](https://github.com/leanhminh2104/locketlam/blob/main/examples/en/01_login_and_session.py) |
|
|
425
|
+
| User Profile | [`examples/en/02_user_profile.py`](https://github.com/leanhminh2104/locketlam/blob/main/examples/en/02_user_profile.py) |
|
|
426
|
+
| Post Photo & NoteType | [`examples/en/03_post_image_moment.py`](https://github.com/leanhminh2104/locketlam/blob/main/examples/en/03_post_image_moment.py) |
|
|
427
|
+
| Post Video & HEVC | [`examples/en/04_post_video_moment.py`](https://github.com/leanhminh2104/locketlam/blob/main/examples/en/04_post_video_moment.py) |
|
|
428
|
+
| Feed & Reactions | [`examples/en/05_feed_views_reactions.py`](https://github.com/leanhminh2104/locketlam/blob/main/examples/en/05_feed_views_reactions.py) |
|
|
429
|
+
| Friends & Contacts | [`examples/en/06_friends_and_contacts.py`](https://github.com/leanhminh2104/locketlam/blob/main/examples/en/06_friends_and_contacts.py) |
|
|
430
|
+
| Chat & Real-Time | [`examples/en/07_chat_and_reactions.py`](https://github.com/leanhminh2104/locketlam/blob/main/examples/en/07_chat_and_reactions.py) |
|
|
431
|
+
| Interactive CLI | [`examples/en/interactive_demo.py`](https://github.com/leanhminh2104/locketlam/blob/main/examples/en/interactive_demo.py) |
|
|
432
|
+
|
|
433
|
+
```bash
|
|
434
|
+
python examples/en/interactive_demo.py
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
> ๐ For a full step-by-step integration guide, see [`docs/INTEGRATION.md`](https://github.com/leanhminh2104/locketlam/blob/main/docs/INTEGRATION.md).
|
|
438
|
+
> ๐ For the complete API catalog, see [`docs/FEATURES.md`](https://github.com/leanhminh2104/locketlam/blob/main/docs/FEATURES.md).
|
|
439
|
+
|
|
440
|
+
---
|
|
441
|
+
|
|
442
|
+
## ๐ Next Steps
|
|
443
|
+
|
|
444
|
+
| Document | Description |
|
|
445
|
+
|:---|:---|
|
|
446
|
+
| [๐ docs/INTEGRATION.md](https://github.com/leanhminh2104/locketlam/blob/main/docs/INTEGRATION.md) | Step-by-step integration guide with real code snippets for every feature (EN - Primary) |
|
|
447
|
+
| [๐ docs/INTEGRATION_VI.md](https://github.com/leanhminh2104/locketlam/blob/main/docs/INTEGRATION_VI.md) | Step-by-step integration guide in Vietnamese (VI - Secondary) |
|
|
448
|
+
| [๐ docs/FEATURES.md](https://github.com/leanhminh2104/locketlam/blob/main/docs/FEATURES.md) | Full API catalog โ all classes, methods and parameters (EN) |
|
|
449
|
+
| [๐ docs/FEATURES_VI.md](https://github.com/leanhminh2104/locketlam/blob/main/docs/FEATURES_VI.md) | Full API catalog in Vietnamese (VI) |
|
|
450
|
+
| [๐ก examples/en/](https://github.com/leanhminh2104/locketlam/tree/main/examples/en/) | 8 complete runnable example scripts (English) |
|
|
451
|
+
| [๐ก examples/vi/](https://github.com/leanhminh2104/locketlam/tree/main/examples/vi/) | 8 complete runnable example scripts (Vietnamese) |
|
|
452
|
+
|
|
453
|
+
---
|
|
454
|
+
|
|
455
|
+
## ๐ค Contributing
|
|
456
|
+
|
|
457
|
+
Contributions, bug reports, and feature requests are welcome!
|
|
458
|
+
|
|
459
|
+
1. Fork the Project.
|
|
460
|
+
2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`).
|
|
461
|
+
3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`).
|
|
462
|
+
4. Push to the Branch (`git push origin feature/AmazingFeature`).
|
|
463
|
+
5. Open a Pull Request.
|
|
464
|
+
|
|
465
|
+
---
|
|
466
|
+
|
|
467
|
+
## ๐ Support & Donations (Sponsor)
|
|
468
|
+
|
|
469
|
+
If you find **`locketlam`** helpful in your projects, automations, or research, please consider supporting the development. Your contribution helps maintain the library, reverse-engineer future Locket updates, and keep the project active!
|
|
470
|
+
|
|
471
|
+
<div align="center">
|
|
472
|
+
|
|
473
|
+
| Gateway / Method | Payment Details |
|
|
474
|
+
| :--- | :--- |
|
|
475
|
+
| ๐ **Official Donation Portal** | [https://leanhminh.io.vn/donate](https://leanhminh.io.vn/donate) |
|
|
476
|
+
| ๐ฆ **MB Bank (Vietnam Banking)** | Account Number: `2104200637`<br>Account Holder: **LE VAN ANH MINH** |
|
|
477
|
+
| ๐ฆ **ACB Bank (Asia Commercial Bank)** | Account Number: `22002921`<br>Account Holder: **LE VAN ANH MINH** |
|
|
478
|
+
| ๐ก **Binance (UID / Pay ID)** | `283319011` |
|
|
479
|
+
| ๐ณ **PayPal (Global)** | [paypal.me/leanhminh2104](https://paypal.me/leanhminh2104) |
|
|
480
|
+
|
|
481
|
+
</div>
|
|
482
|
+
|
|
483
|
+
> *Every contribution, no matter how small, is deeply appreciated. Thank you very much! โค๏ธ*
|
|
484
|
+
|
|
485
|
+
---
|
|
486
|
+
|
|
487
|
+
## ๐ Copyright & License
|
|
488
|
+
|
|
489
|
+
Copyright ยฉ 2026 **LAMDev x DaLyMMO.com**.
|
|
490
|
+
|
|
491
|
+
Distributed under the **MIT License**. See [`LICENSE`](https://github.com/leanhminh2104/locketlam/blob/main/LICENSE) for more information.
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## โ ๏ธ Disclaimer
|
|
496
|
+
|
|
497
|
+
This library is an unofficial, reverse-engineered project created for educational and developer interoperability purposes. It is **not** endorsed by, associated with, or affiliated with Locket Camera, Inc. Please use this tool responsibly and respect Locket Camera's terms of service and community guidelines.
|