social-autoposter 1.3.8 → 1.3.9
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.
- package/package.json +1 -1
- package/scripts/reddit_browser.py +141 -30
package/package.json
CHANGED
|
@@ -295,22 +295,52 @@ def _refresh_browser_lock():
|
|
|
295
295
|
|
|
296
296
|
|
|
297
297
|
def get_browser_and_page(playwright):
|
|
298
|
-
"""
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
298
|
+
"""Get a logged-in Reddit page, preferring CDP-attach over launch_persistent_context.
|
|
299
|
+
|
|
300
|
+
Two paths:
|
|
301
|
+
1. CDP-attach (preferred on appmaker/e2b VM and any host running a visible
|
|
302
|
+
logged-in Chromium): connect to the existing browser, find a context with
|
|
303
|
+
a live reddit_session cookie, open a NEW PAGE on that context.
|
|
304
|
+
2. launch_persistent_context fallback: when CDP isn't available OR contexts
|
|
305
|
+
have no reddit_session (laptop where reddit-agent MCP isolates its session
|
|
306
|
+
in an invisible context).
|
|
307
|
+
|
|
308
|
+
Why CDP-attach matters: appmaker's visible Chromium permanently holds
|
|
309
|
+
/root/.chromium-profile. launch_persistent_context collides on profile leveldb
|
|
310
|
+
locks, loads a partial session, and EVERY post returns account_blocked_in_sub
|
|
311
|
+
because the comment form never renders. Attaching to the live context dodges
|
|
312
|
+
the collision entirely.
|
|
313
|
+
|
|
314
|
+
Returns (browser, page, is_cdp). When is_cdp=True, callers must close ONLY
|
|
315
|
+
the page (not page.context) and NOT the browser; closing context[0] or the
|
|
316
|
+
CDP browser would kill the user's visible session.
|
|
307
317
|
"""
|
|
308
318
|
_acquire_browser_lock()
|
|
309
319
|
cdp_port = find_reddit_cdp_port()
|
|
310
320
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
321
|
+
if cdp_port:
|
|
322
|
+
try:
|
|
323
|
+
cdp_browser = playwright.chromium.connect_over_cdp(f"http://localhost:{cdp_port}")
|
|
324
|
+
for ctx in cdp_browser.contexts:
|
|
325
|
+
try:
|
|
326
|
+
cookies = ctx.cookies("https://www.reddit.com/")
|
|
327
|
+
except Exception:
|
|
328
|
+
cookies = []
|
|
329
|
+
has_session = any(
|
|
330
|
+
c.get("name") == "reddit_session" and c.get("value")
|
|
331
|
+
for c in cookies
|
|
332
|
+
)
|
|
333
|
+
if has_session:
|
|
334
|
+
page = ctx.new_page()
|
|
335
|
+
return cdp_browser, page, True
|
|
336
|
+
try:
|
|
337
|
+
cdp_browser.close()
|
|
338
|
+
except Exception:
|
|
339
|
+
pass
|
|
340
|
+
except Exception:
|
|
341
|
+
pass
|
|
342
|
+
|
|
343
|
+
# Fallback: launch our own persistent context against PROFILE_DIR.
|
|
314
344
|
# Retry on Chromium SingletonLock collisions (MCP holds the OS-level profile
|
|
315
345
|
# lock for its entire server lifetime; the JSON lock can expire while the
|
|
316
346
|
# OS lock is still held).
|
|
@@ -496,9 +526,18 @@ def post_comment(thread_url, text):
|
|
|
496
526
|
}
|
|
497
527
|
|
|
498
528
|
finally:
|
|
499
|
-
|
|
529
|
+
try:
|
|
530
|
+
if is_cdp:
|
|
531
|
+
page.close()
|
|
532
|
+
else:
|
|
533
|
+
page.context.close()
|
|
534
|
+
except Exception:
|
|
535
|
+
pass
|
|
500
536
|
if not is_cdp:
|
|
501
|
-
|
|
537
|
+
try:
|
|
538
|
+
browser.close()
|
|
539
|
+
except Exception:
|
|
540
|
+
pass
|
|
502
541
|
|
|
503
542
|
|
|
504
543
|
def reply_to_comment(comment_permalink, text, dm_id=None):
|
|
@@ -736,9 +775,18 @@ def reply_to_comment(comment_permalink, text, dm_id=None):
|
|
|
736
775
|
}
|
|
737
776
|
|
|
738
777
|
finally:
|
|
739
|
-
|
|
778
|
+
try:
|
|
779
|
+
if is_cdp:
|
|
780
|
+
page.close()
|
|
781
|
+
else:
|
|
782
|
+
page.context.close()
|
|
783
|
+
except Exception:
|
|
784
|
+
pass
|
|
740
785
|
if not is_cdp:
|
|
741
|
-
|
|
786
|
+
try:
|
|
787
|
+
browser.close()
|
|
788
|
+
except Exception:
|
|
789
|
+
pass
|
|
742
790
|
|
|
743
791
|
|
|
744
792
|
def edit_comment(comment_permalink, new_text):
|
|
@@ -859,9 +907,18 @@ def edit_comment(comment_permalink, new_text):
|
|
|
859
907
|
}
|
|
860
908
|
|
|
861
909
|
finally:
|
|
862
|
-
|
|
910
|
+
try:
|
|
911
|
+
if is_cdp:
|
|
912
|
+
page.close()
|
|
913
|
+
else:
|
|
914
|
+
page.context.close()
|
|
915
|
+
except Exception:
|
|
916
|
+
pass
|
|
863
917
|
if not is_cdp:
|
|
864
|
-
|
|
918
|
+
try:
|
|
919
|
+
browser.close()
|
|
920
|
+
except Exception:
|
|
921
|
+
pass
|
|
865
922
|
|
|
866
923
|
|
|
867
924
|
def edit_thread(thread_permalink, new_body):
|
|
@@ -956,9 +1013,18 @@ def edit_thread(thread_permalink, new_body):
|
|
|
956
1013
|
}
|
|
957
1014
|
|
|
958
1015
|
finally:
|
|
959
|
-
|
|
1016
|
+
try:
|
|
1017
|
+
if is_cdp:
|
|
1018
|
+
page.close()
|
|
1019
|
+
else:
|
|
1020
|
+
page.context.close()
|
|
1021
|
+
except Exception:
|
|
1022
|
+
pass
|
|
960
1023
|
if not is_cdp:
|
|
961
|
-
|
|
1024
|
+
try:
|
|
1025
|
+
browser.close()
|
|
1026
|
+
except Exception:
|
|
1027
|
+
pass
|
|
962
1028
|
|
|
963
1029
|
|
|
964
1030
|
def unread_dms():
|
|
@@ -1135,9 +1201,18 @@ def unread_dms():
|
|
|
1135
1201
|
return unique
|
|
1136
1202
|
|
|
1137
1203
|
finally:
|
|
1138
|
-
|
|
1204
|
+
try:
|
|
1205
|
+
if is_cdp:
|
|
1206
|
+
page.close()
|
|
1207
|
+
else:
|
|
1208
|
+
page.context.close()
|
|
1209
|
+
except Exception:
|
|
1210
|
+
pass
|
|
1139
1211
|
if not is_cdp:
|
|
1140
|
-
|
|
1212
|
+
try:
|
|
1213
|
+
browser.close()
|
|
1214
|
+
except Exception:
|
|
1215
|
+
pass
|
|
1141
1216
|
|
|
1142
1217
|
|
|
1143
1218
|
def read_conversation(chat_url, max_messages=20):
|
|
@@ -1293,9 +1368,18 @@ def read_conversation(chat_url, max_messages=20):
|
|
|
1293
1368
|
return result
|
|
1294
1369
|
|
|
1295
1370
|
finally:
|
|
1296
|
-
|
|
1371
|
+
try:
|
|
1372
|
+
if is_cdp:
|
|
1373
|
+
page.close()
|
|
1374
|
+
else:
|
|
1375
|
+
page.context.close()
|
|
1376
|
+
except Exception:
|
|
1377
|
+
pass
|
|
1297
1378
|
if not is_cdp:
|
|
1298
|
-
|
|
1379
|
+
try:
|
|
1380
|
+
browser.close()
|
|
1381
|
+
except Exception:
|
|
1382
|
+
pass
|
|
1299
1383
|
|
|
1300
1384
|
|
|
1301
1385
|
def _load_active_reddit_campaigns_for_dm():
|
|
@@ -1564,9 +1648,18 @@ def send_dm(chat_url, message, dm_id=None):
|
|
|
1564
1648
|
}
|
|
1565
1649
|
|
|
1566
1650
|
finally:
|
|
1567
|
-
|
|
1651
|
+
try:
|
|
1652
|
+
if is_cdp:
|
|
1653
|
+
page.close()
|
|
1654
|
+
else:
|
|
1655
|
+
page.context.close()
|
|
1656
|
+
except Exception:
|
|
1657
|
+
pass
|
|
1568
1658
|
if not is_cdp:
|
|
1569
|
-
|
|
1659
|
+
try:
|
|
1660
|
+
browser.close()
|
|
1661
|
+
except Exception:
|
|
1662
|
+
pass
|
|
1570
1663
|
|
|
1571
1664
|
|
|
1572
1665
|
def compose_dm(recipient, subject, body):
|
|
@@ -1859,9 +1952,18 @@ def compose_dm(recipient, subject, body):
|
|
|
1859
1952
|
return {"ok": True, "thread_url": page.url}
|
|
1860
1953
|
|
|
1861
1954
|
finally:
|
|
1862
|
-
|
|
1955
|
+
try:
|
|
1956
|
+
if is_cdp:
|
|
1957
|
+
page.close()
|
|
1958
|
+
else:
|
|
1959
|
+
page.context.close()
|
|
1960
|
+
except Exception:
|
|
1961
|
+
pass
|
|
1863
1962
|
if not is_cdp:
|
|
1864
|
-
|
|
1963
|
+
try:
|
|
1964
|
+
browser.close()
|
|
1965
|
+
except Exception:
|
|
1966
|
+
pass
|
|
1865
1967
|
|
|
1866
1968
|
|
|
1867
1969
|
def scrape_views(username, max_scrolls=300):
|
|
@@ -2022,9 +2124,18 @@ def scrape_views(username, max_scrolls=300):
|
|
|
2022
2124
|
except Exception as e:
|
|
2023
2125
|
return {"ok": False, "error": str(e)}
|
|
2024
2126
|
finally:
|
|
2025
|
-
|
|
2127
|
+
try:
|
|
2128
|
+
if is_cdp:
|
|
2129
|
+
page.close()
|
|
2130
|
+
else:
|
|
2131
|
+
page.context.close()
|
|
2132
|
+
except Exception:
|
|
2133
|
+
pass
|
|
2026
2134
|
if not is_cdp:
|
|
2027
|
-
|
|
2135
|
+
try:
|
|
2136
|
+
browser.close()
|
|
2137
|
+
except Exception:
|
|
2138
|
+
pass
|
|
2028
2139
|
|
|
2029
2140
|
|
|
2030
2141
|
def main():
|