æ10äžã®å€§åŠçãã坿¥æãæã¡ã§æ60äžãäŒç€Ÿéœåã§è§£éãããŠåå ¥0ãããããClaude Codeã§èªåŸç°å¢ãçµã¿çŽããŠä»ã¯æå120äžã§ãããã®é£èŒã¯ãå人éçºã®éç£ããšããããŒãã§ãç§ãå®éã«èžã¿æããŠãã穎ãå ±æããŠããŸãã
ä»åã¯ãããžã§ããæ¯æ¥èµ°ã£ãŠããã®ã«ææã0ä»¶ã®ãŸãŸèª°ã«ãæ°ã¥ãããªãã£ãã ãšãã話ã§ãã
ãªããã®ä»çµã¿ãå¹ãã®ã
ãžã§ãã¯æ²é»ãããexit 0ã¯æåãæå³ããªã
èªååã®æãã¯ãå£ããŠãé³ãããªãããšã§ãã
ç§ã®Instagramèªåãããã·ã¹ãã ïŒsocial-autolikeïŒã®ãžã§ãã¯ã2026-08-09ã®æãŸã§æ£åžžã«åããŠããŸããââå°ãªããšãããèŠããŠããŸãããig-2ãšããã¢ã«ãŠã³ãã«çŽã¥ãã¬ãŒã³ã¯ã1æ¥12åã¹ã±ãžã¥ãŒã«å®è¡ãããŠããããã°ã«ã¯ãã®éœåºŠãå®äºããšèšé²ãããŠãããç£èŠã®ããã·ã¥ããŒãã«ã¯ãšã©ãŒãé£ãã§ããªãã£ãã
宿 ã¯ããããä»¶æ°=0ããã©ããŒä»¶æ°=0ãäžä»¶ãäœãããŠããªãç¶æ ããäœæ¥ãç¶ããŠããŸããã
åå ã¯åçŽã§ããig-2ã®ã¢ã«ãŠã³ãã¯ãã°ã¢ãŠãç¶æ
ã«ãã£ããInstagramã®ã»ãã·ã§ã³ãåããŠãããã§ãããžã§ãã¯ãã°ã¢ãŠãç»é¢ãåã«ããŠã察象ãå°œããããæ¡ä»¶ã«åãã¢ã«ãŠã³ãããªãã£ãããšã㊠exit 0 ãè¿ãç¶ããŠããã®ã§ãã
DOMå€å®ã¯Instagramã®ãã°ã¢ãŠãç»é¢ãçŽ éãããã
åœæã®ãžã§ãã«ã¯ãã°ã€ã³å€å®ã®ã³ãŒãããããŸãããsocial-autolike/src/run.js ã® needLogin() ã¯ã倧ãŸãã«èšããšæ¬¡ã®2æ¡ä»¶ã§ãã°ã€ã³ãå¿
èŠãšå€æããŠããŸããã
- URLã«
/loginãå«ã - æ¬æã«ããã°ã€ã³ããšããèªãããããã€
article/[role=feed]/video/main/[data-e2e]ã®ãããã®èŠçŽ ãååšããªã
åé¡ã¯2çªç®ã®æ¡ä»¶ã®åŸåã§ãã
Instagramã®ãã°ã¢ãŠãç»é¢ã«ã¯ main èŠçŽ ããããŸããããã¯ä»ãå€ãããååšãããããŒãžã®ã»ãã³ãã£ãã¯æ§é ãšããŠé
眮ãããèŠçŽ ã§ããDOMå€å®ããmain ã0ä»¶ãªãèŠãã°ã€ã³ããšããçºæ³ã§çµãŸããŠããããããã°ã¢ãŠãç»é¢ãéããŠã main ã1ä»¶èŠã€ãã£ãŠããŸããå€å®ã¯ããæããŠããŸããã
ã»ã¬ã¯ã¿ã¯ããã°ã€ã³ç»é¢ã£ãœããªããããæž¬ã£ãŠãããã§ãå®éã«ç¥ãããã®ã¯ãä»ãã®ãã©ãŠã¶ã§ãã°ã€ã³ããŠãããããšããèªèšŒç¶æ ãã®ãã®ã§ãããã®2ã€ã¯å¥ç©ã§ãUIã®æ§é ãå€ããã°åè ã¯ç°¡åã«ããæããã
Cookieã¯èªèšŒç¶æ ãã®ãã®ã§ãã
Chromeã®ã»ãã·ã§ã³ç®¡çã¯ãDefault/Network/CookiesïŒChromeã®ããŒãžã§ã³ã«ãã£ãŠã¯ Default/CookiesïŒãšããSQLiteããŒã¿ããŒã¹ãã¡ã€ã«ã«èšé²ãããŠããŸããInstagramã®ãã°ã€ã³ç¶æ
㯠sessionid ãšããååã®Cookieã§ç®¡çãããŠããããã®Cookieã instagram.com ãã¡ã€ã³ã«å¯ŸããŠååšãããªãããã®ãããã¡ã€ã«ã¯ãã°ã€ã³æžã¿ã§ãã
DOMãšã®æ±ºå®çãªéãã¯ãããã¯UIã®èŠãç®ã§ã¯ãªããèªèšŒã®äºå®ãã®ãã®ã ãšããããšã§ããInstagramãã©ãã ããã¶ã€ã³ãå€ããŠãããã°ã¢ãŠãç»é¢ã«ã©ããªèŠçŽ ã远å ããŠããsessionid Cookieã®æç¡ã¯ãã°ã€ã³ç¶æ
ãš1察1ã§å¯Ÿå¿ããŠããŸãã
Cookieãäžæ¬¡æ å ±ã«ãããšããã®ã¯ããæšæž¬ããããŠäºå®ãèŠãããšãã転æã§ãã
ãã®è©±ãããªãã«é¢ä¿ããçç±
PlaywrightãPuppeteerãbrowser-useããããã¯Claude Codeã§çµãã èªååââ圢ã¯äœã§ãããChromeãChromiumã®ãããã¡ã€ã«ã䜿ã£ãŠWebãµãŒãã¹ã«ã¢ã¯ã»ã¹ããŠããèªååã¯ãå šéšåãåé¡ãæ±ãåŸãŸãã
ãžã§ãããææ=0ä»¶ã§exit 0ããè¿ããšããããããæ¬åœã«å¯Ÿè±¡ãç¡ãã£ããã®ãããã°ã¢ãŠãããŠããŠäœãèŠããŠããªãã£ããã®ãããããªãã¯ä»ã©ããã£ãŠåºå¥ããŠããã§ããããã
ç£èŠã°ã©ãã®æ°åã0ã«åŒµãä»ããŠããŠãããšã©ãŒãé£ãã§ããªããã°æ°ã¥ãã«ãããæ°ã¥ãããšãããã§ã«æ°æ¥ã¶ãã®ææãæ¶ããŠããŸããç§ã®å Žåãig-2ã¯äœæ¥ã¶ã倱ã£ãŠãããããæ£ç¢ºã«ã¯ããããŸããã§ããã
ä»åå®è£
ãã profile-session-guard.sh ã¯ããã®åãã«çããããã®ã¹ã¯ãªããã§ããChromeã®Cookie DBãçŽæ¥èªãã§ãã»ãã·ã§ã³ãçããŠãããããäºåã«ç¢ºèªããåããŠãããªãéç¥ããŠã¬ãŒã³ãæ¢ããã以äžã§ãã®å
šäœåã説æããŸãã
å šäœã®æµã
æŠèгïŒ4ã€ã®ã¹ããã
ã¹ã¯ãªãããããããšã¯å€§ãã4段éã§ãã
[èšå®ãã¡ã€ã«3æ¬]
accounts.json
ig-reply-accounts.json ââ [ãããã¡ã€ã«diräžèЧã解決]
post-accounts.json + éè€ã1ä»¶ã«éçŽ
+ åºå®2ä»¶ïŒå¥ãªãïŒ
â
[åãããã¡ã€ã«dirã§Cookie DBãæ¢ã]
Default/Network/Cookies
Default/Cookies ââ [èŠã€ãã£ãã mktemp ã§ã³ããŒ]
Network/Cookies
Cookies
â
[sqlite3 ã§Cookieãæ€çŽ¢]
platformå¥ã®SQLã¯ãšãª ââ [OK / EXPIRED / UNKNOWN ãå€å®]
ã³ããŒã¯çµäºæã«åé€
â
[çµæãéèšããŠstateãã¡ã€ã«ãšç
§å]
åãæ¹ãååãšåã â éç¥ã¹ããã
æ°ããåã â Discordéç¥ + exit 1
å
šå¡OK â exit 0
é ã远ã£ãŠèŠãŠãããŸãã
ãããã¡ã€ã«dirãèšå®ãã¡ã€ã«ãã解決ãã
ã¹ã¯ãªããã®æåã®ä»äºã¯ãã©ã®ãããã¡ã€ã«ãæ€æ»ããããã確å®ããããšã§ãã
ãã€ãŠã®å®è£
ã¯ãããã¡ã€ã«dirã®ãªã¹ããã¹ã¯ãªããå
ã«çŽæžãããŠããŸããããã®çµæãäœã£ãç¿æ¥ã« metrics-hub/profiles/tiktok ãš tiktok2 ãšãããå®éã®ãžã§ããã䜿ãããŠããªãå€ãdirãããã°ã€ã³åãããšããŠèª€å ±ãããã®ã§ããå®éã®TikTokã¬ãŒã³ã¯ social-autolike/accounts.json ã® reuseProfile ãã£ãŒã«ãã§å¥ã®dirã䜿ã£ãŠããŸãããçŽæžããªã¹ãã¯äœæããç¬éããè
ãå§ããŸãã
çŸåšã®å®è£ ã¯ããžã§ããå®éã«åç §ããŠããèšå®ãã¡ã€ã«ãã解決ããŸãã
load_accounts() {
local lane platform dir
if ! "$JQ" -r --arg root "$ROOT" \
'.accounts[] | [.id, .platform, (.reuseProfile // ($root + "/profiles/" + .id))] | @tsv' \
"$ACCOUNTS_CONFIG" >"$SOURCE_FILE"; then
log "unknown resolver: accounts.json could not be read"
return 1
fi
while IFS=$'\t' read -r lane platform dir; do
add_candidate "$dir" "$platform" "$lane"
done <"$SOURCE_FILE"
}
jq ã¯ãšãªã® .reuseProfile // ($root + "/profiles/" + .id) ããã€ã³ãã§ããèšå®ãã¡ã€ã«ã« reuseProfile ãæžãããŠããã°ãã®ãã¹ã䜿ãããªããã° profiles/<id> ãšããããã©ã«ããã¹ã«ãã©ãŒã«ããã¯ãããããã¯ãžã§ãæ¬äœã® src/lib.js ã® profileDir() ãšåã解決ã«ãŒã«ã§ããèšå®ãã¡ã€ã«ãæ£æ¬ãªã®ã§ããžã§ããåç
§ããdirãšã¹ã¯ãªãããæ€æ»ããdirãäžèŽãç¶ããŸãã
åæ§ã®åŠçã ig-reply-accounts.jsonïŒèªåè¿ä¿¡ã¬ãŒã³çšïŒãš post-accounts.jsonïŒæçš¿ã¬ãŒã³çšïŒã«ãè¡ããããã«å¥ãªãã®åºå®2ä»¶ã远å ããŸãã
add_candidate "~/dev/bokuwalily-sns/profiles/ig-post" "instagram" "bokuwalily-sns:ig-post"
add_candidate "~/dev/brand-404/profiles/ig-o81" "instagram" "brand-404:ig-o81"
åäžã®ãããã¡ã€ã«dirãè€æ°ã®ã¬ãŒã³ãåç
§ããã±ãŒã¹ããããŸãïŒig-1-live ã ig-autoreply:ig-1 ãš ig-1 ãäž¡æ¹äœ¿ããªã©ïŒããããéè€ããŠæ€æ»ããã®ã¯ç¡é§ãªã®ã§ãcanonical ãã¹ã§éè€æé€ããŠããæ€æ»ã«ãŒãã«å
¥ããŸãããã ãã¬ãŒã³åã¯æšãŠããåŸã§ãã°ãšéç¥æã«ãã©ã®ã¬ãŒã³ãæ¢ãŸããããæžãããã«ä¿æããŸãã
[2026-08-09 07:10:05] resolved 22 unique existing profiles
çŽæžãã§ã¯ååšããªãdirãæ€æ»å¯Ÿè±¡ã«å«ãŸããŠããŸããããadd_candidate 㯠[ ! -d "$dir" ] ã確èªããŠã¹ãããããã®ã§ããŸã äœãããŠããªãdirã¯æ€æ»ããšã©ãŒãåºãŸããã
Cookie DBãèŠã€ããŠã³ããŒãã
åãããã¡ã€ã«dirã«å¯Ÿã㊠find_cookie_db 颿°ãèµ°ããŸãã
find_cookie_db() {
local dir="$1" candidate
COOKIE_DB=""
for candidate in \
"$dir/Default/Network/Cookies" \
"$dir/Default/Cookies" \
"$dir/Network/Cookies" \
"$dir/Cookies"; do
if [ -f "$candidate" ]; then
COOKIE_DB="$candidate"
return 0
fi
done
return 1
}
Chromeã¯ããŒãžã§ã³ã«ãã£ãŠCookieãã¡ã€ã«ã®é
眮ãç°ãªããŸããDefault/Network/Cookies ãçŸè¡ã§ãããå€ããããã¡ã€ã«ãäžéšã®ChromiumããŒã¹ãã©ãŠã¶ã§ã¯ Default/Cookies ã Network/Cookies ã«ããå Žåãããã4ãã¿ãŒã³ã詊ããŠæåã«èŠã€ãã£ããã®ã䜿ããŸãã
èŠã€ãã£ãã å¿
ã mktemp ã§ã³ããŒããŠããèªã¿ãŸãã
TEMP_COOKIE_DB=$(mktemp /tmp/profile-session-guard.cookies.XXXXXX)
if [ -z "$TEMP_COOKIE_DB" ] || ! /bin/cp "$COOKIE_DB" "$TEMP_COOKIE_DB" 2>/dev/null; then
CHECK_DETAIL="Cookies DB copy failed"
[ -n "$TEMP_COOKIE_DB" ] && /bin/rm -f "$TEMP_COOKIE_DB"
TEMP_COOKIE_DB=""
return
fi
Chromeãèµ·åããŠããŠCookie DBãæŽãã§ããå ŽåãçŽæ¥ sqlite3 ã§éãããšãããšããã¯ãšã©ãŒã«ãªããŸããã³ããŒãåã£ãŠããèªãããšã§ãChromeã®çšŒåç¶æ
ã«é¢ä¿ãªãèªã¿åºããŸããã³ããŒã¯ trap cleanup EXIT ã§ç»é²ããã¯ãªãŒã³ã¢ãã颿°ã確å®ã«æ¶ããŸãã
platformããšã«SQLã¯ãšãªãåãæ¿ãã
Cookie DBã¯SQLiteãªã®ã§ãã³ããŒã«å¯Ÿã㊠sqlite3 ã§ã¯ãšãªãæããŸããéèŠãªã®ã¯ãplatformã«ãã£ãŠç¢ºèªãã¹ãCookieåãç°ãªãããšã§ãã
cookie_query() {
case "$1" in
x)
printf "%s" "select count(*) from cookies where name='auth_token' and (host_key like '%x.com%' or host_key like '%twitter.com%');"
;;
instagram)
printf "%s" "select count(*) from cookies where name='sessionid' and host_key like '%instagram.com%';"
;;
threads)
printf "%s" "select count(*) from cookies where name='sessionid' and host_key like '%threads%';"
;;
tiktok)
printf "%s" "select count(*) from cookies where name in ('sessionid','sessionid_ss','sid_tt') and host_key like '%tiktok%';"
;;
esac
}
TikTokã3ã€ã®Cookieåã IN ã§æ€çŽ¢ããŠããçç±ã¯ã宿ž¬ã§å€æããäºå®ã«åºã¥ããŸããTikTokã®ã»ãã·ã§ã³ç®¡çã¯Cookieã®çµã¿åãããç°å¢ãã¢ã«ãŠã³ãã«ãã£ãŠç°ãªãã皌åäžã®ã¢ã«ãŠã³ã tt-1 ãå®éã«3çš®ãã¹ãŠãæã£ãŠããããšã確èªãããŸããããã sessionid 1æ¬ã ãã§å€å®ããã°ãsessionid_ss ã sid_tt ã ããæã£ãŠããã¢ã«ãŠã³ããããã°ã¢ãŠãããšèª€å€å®ããŸããçããŠããã¢ã«ãŠã³ããæ¢ããããšã¯ããã°ã¢ãŠããèŠèœãšãããããããæªãã
count(*) ãè¿ã£ãŠããã®ã§ã0 ãªã EXPIREDã1 以äžãªãåœè©²platformã¯OKã§ããè€æ°ã®platformã1ã€ã®ãããã¡ã€ã«ãå
Œããå ŽåïŒinstagram,threads ã®ãããªè€åãããã¡ã€ã«ïŒã¯ã1ã€ã§ãåããŠããæç¹ã§ EXPIRED ã«ãªããŸãã
count=$(/usr/bin/sqlite3 "$TEMP_COOKIE_DB" "$query" 2>/dev/null)
sqlite_rc=$?
if [ "$sqlite_rc" -ne 0 ] || ! printf '%s' "$count" | /usr/bin/grep -Eq '^[0-9]+$'; then
unknown=1
CHECK_DETAIL="sqlite3 failed for $platform"
elif [ "$count" -eq 0 ]; then
CHECK_STATUS="EXPIRED"
CHECK_DETAIL="required cookie missing for $platform"
break
fi
sqlite3 ã®çµäºã³ãŒããšåºåå€ã®äž¡æ¹ãæ€èšŒããŠããã®ã¯ãDBãå£ããŠãããæ³å®å€ã®ãã©ãŒãããã ã£ããããã±ãŒã¹ãžã®å¯ŸåŠã§ãããã®å Žå㯠EXPIRED ã§ã¯ãªã UNKNOWN ãšããŠåŠçããèª€å ±ãé¿ããŸãã17ã¬ãŒã³ãå
šåæ¢ããã»ããã1ã¬ãŒã³ã®åããèŠéãããæå®³ã倧ããã
ç¶æ ã®å€åã ãéç¥ãã
22ãããã¡ã€ã«ãå šéšæ€æ»ãçµãã£ããéèšããŸãã
log "check complete ok=$ok expired=$expired unknown=$unknown"
ããã§ãã®ãŸãŸéç¥ãé£ã°ããšãæ¯ååãã¢ã«ãŠã³ããåãããŸãŸã§ã1æ¥2åéç¥ãæ¥ç¶ããŸãã éç¥ãå€ããããšæ¬ç©ã®ç·æ¥éç¥ãåãããââããã¯å¥ã®åé¡ãšããŠå®éã«çµéšãã話ã§ãæ¬æ¥ need-login ãšããŠå±ãã¹ãã¢ã©ãŒãããã€ãžã§ã¹ãã«èœã¡ãŠããããšããããŸããã
ãã®ãããååã®åããªã¹ãã state ãã¡ã€ã«ã«ä¿åããå
容ãå€ãã£ããšãã ãéç¥ããŸãã
previous=""
[ -f "$STATE_FILE" ] && previous=$(/bin/cat "$STATE_FILE" 2>/dev/null)
if [ -n "$broken" ]; then
if [ "$broken" = "$previous" ]; then
log "login missing unchanged ($broken); notification skipped"
else
body="ð ãã°ã€ã³åã: $broken â 該åœã¬ãŒã³ã¯ææãŒãã®ãŸãŸ exit 0 ãè¿ãç¶ããŸããåãã°ã€ã³ãå¿
èŠ"
if notify "$body"; then
log "notified login missing ($broken)"
fi
fi
write_state "$broken"
exit 1
fi
write_state ""
exit 0
éç¥æã« $broken ãå«ããŠããŸãããããã¯åãªãã¢ã«ãŠã³ãåã§ã¯ãªã ig-2(ig-2, ig-autoreply:ig-2) ãšãã圢åŒã§ããåãããããã¡ã€ã«ãããæ¢ãŸãã¬ãŒã³ãã©ãããã®ã»ãã人éã®å€æææãšããŠæçšãªã®ã§ãã©ã®ã¬ãŒã³ãåç
§ããŠããããæ¬åŒ§å
ã«ç€ºããŠããŸãã
launchdã«ã¯07:10ãš19:10ã®1æ¥2åã§ç»é²ããŠãããŸããNiceValue=10 / ProcessType=Background / LowPriorityIO=true ã®3ããŒã§äœåªå
床åããŠãããä»ã®åŠçã«å²ã蟌ã¿ãŸããã
å®è£ ã®è©³çް
deduplicate_profilesïŒåãdirãè€æ°ã¬ãŒã³ãåç §ããçŸå®
ig-1-live ãšãããããã¡ã€ã«dirã¯ãig-autoreply:ig-1 ãš ig-1 ãšãã2ã€ã®ã¬ãŒã³ããåæã«åç
§ãããŠããŸãã2忀æ»ããã®ã¯ç¡é§ã§ããããã©ã®ã¬ãŒã³ãæ¢ãŸããããšããæ
å ±ã¯æšãŠãããªãããã®2èŠä»¶ãåæã«æºããã®ã deduplicate_profiles ã§ãã
deduplicate_profiles() {
LC_ALL=C sort -t "$TAB" -k1,1 -k3,3 "$CANDIDATES_FILE" | \
awk -F '\t' '
{
dir = $1; platform = $2; lane = $3
if (!(dir in seen)) {
seen[dir] = 1
order[++count] = dir
platforms[dir] = platform
lanes[dir] = lane
} else {
if (index("," platforms[dir] ",", "," platform ",") == 0) {
platforms[dir] = platforms[dir] "," platform
}
if (index("," lanes[dir] ",", "," lane ",") == 0) {
lanes[dir] = lanes[dir] ", " lane
}
}
}
END {
for (i = 1; i <= count; i++) {
dir = order[i]
printf "%s\t%s\t%s\n", dir, platforms[dir], lanes[dir]
}
}
' >"$PROFILES_FILE"
}
index("," platforms[dir] ",", "," platform ",") == 0 ãšãããã§ãã¯ãããã§ã«åãplatformãå«ãŸããŠããªãããã®ç¢ºèªã§ããååŸã«ã«ã³ããè¶³ããŠããæ€çŽ¢ããããšã§éšåäžèŽãé²ãã§ããŸãââinstagram ãæ€çŽ¢ãããšã instagram,threads ã®äžã® instagram ãã¡ãããš1ä»¶ãšããŠæ°ããããã®å·¥å€«ã§ããorder é
åã§æ¿å
¥é ãä¿æããEND ãããã¯ã§é çªã©ããã«åºåããŠããã®ã¯ããã°ã®èªã¿ãããã®ããã§ãã
Discordãžå±ãéç¥æ¬æã¯ ig-2(ig-2, ig-autoreply:ig-2) ãšãã圢åŒã«ãªããŸãããããã¡ã€ã«åã§ã¯ãªãã¬ãŒã³åãæ¬åŒ§å
ã«åºãã®ã¯ããig-2ãåããããããig-autoreplyã®ig-2ãæ¢ãŸããã®ã»ãã人éã®æ¬¡ã®è¡åãæç¢ºã«ãªãããã§ãããããã¡ã€ã«åãèŠãŠããã©ã®ãžã§ãã®ã©ã®ãšã³ããªãã€ã³ãããã¯å³åº§ã«ããããŸãããã¬ãŒã³åãªãã³ãŒãäžã®èµ·ç¹ã«1察1ã§å¯Ÿå¿ããŠããŸãã
ã¡ã€ã³ã«ãŒãïŒBROKEN_FILEã«ç©ãã§åŸã§éèšãã
22ãããã¡ã€ã«ãé çªã«åŠçããã«ãŒãã¯ã·ã³ãã«ã§ãã
while IFS=$'\t' read -r dir platforms lanes; do
[ -n "$dir" ] || continue
name=${dir##*/}
check_profile "$dir" "$platforms"
case "$CHECK_STATUS" in
OK)
log "ok $name ($platforms; lanes=$lanes; dir=$dir)"
ok=$((ok + 1))
;;
EXPIRED)
log "login missing $name ($platforms; lanes=$lanes; dir=$dir)"
printf '%s(%s)\n' "$name" "$lanes" >>"$BROKEN_FILE"
expired=$((expired + 1))
;;
*)
log "unknown $name ($platforms; lanes=$lanes; dir=$dir): $CHECK_DETAIL"
unknown=$((unknown + 1))
;;
esac
done <"$PROFILES_FILE"
EXPIRED ã«ãªã£ããããã¡ã€ã«ã¯å³åº§ã«éç¥ãéãããBROKEN_FILE ãšããäžæãã¡ã€ã«ã«1è¡ãã€æžã蟌ã¿ãŸããå
šä»¶åŠçãçµãã£ãŠããéèšããŠ1åã§éç¥ããããã§ãããããã¡ã€ã«ã22ä»¶ãã£ãŠ4ä»¶åããŠãããšãã1ä»¶ããšã«éç¥ãé£ã¹ã°Discordã«4飿ã«ãªããŸãããã°ã€ã³åãã¯é »åºŠãäœã代ããã«ç·æ¥æ§ãé«ãââéç¥ãè€æ°æ¥ãããšèªäœããè€æ°ã®ã¢ã©ãŒããæ¥ãŠããããšããŠèªèã®éªéãããŸãã
BROKEN_FILEãã«ãŒãåŸã« while IFS= read -r item ã§ã»ãã³ãã³åºåãã®æååã«ç³ãã®ãåãçºæ³ã§ãã1ä»¶ã®éç¥æ¬æã§ãã©ããšã©ããåããŠãããããäŒããŸãã
trap cleanup EXITïŒ6åã®tempãã¡ã€ã«ã確å®ã«æ¶ã
cleanup() {
local file
for file in "$TEMP_COOKIE_DB" "$CANDIDATES_FILE" "$PROFILES_FILE" \
"$SOURCE_FILE" "$BROKEN_FILE"; do
[ -n "$file" ] && /bin/rm -f "$file"
done
}
trap cleanup EXIT
trap 'exit 130' HUP INT TERM
ãã®ã¹ã¯ãªãã㯠mktemp ãæå€§27ååŒã³ãŸãïŒåºå®ã®4ãã¡ã€ã«ïŒãããã¡ã€ã«ããšã®Cookieã³ããŒæå€§22ä»¶ïŒwrite_stateå
ã®1ä»¶ïŒãtrap cleanup EXIT ããªããã° set -u ã«ããæªå®çŸ©å€æ°åç
§ã sqlite3 ã®ã¯ã©ãã·ã¥ã§äžæãããšã /tmp ã«Cookieãã¡ã€ã«ã®ã³ããŒãæ®ããŸããCookieã¯èªèšŒæ
å ±ãªã®ã§ /tmp ã«æ®åãããã®ã¯ãŸããã
HUP INT TERM ã®ãã©ããã exit 130 ãè¿ããŠããã®ã¯ãCtrl-Cãlaunchdããã®åæ¢ã·ã°ãã«ã§ exit 0 ãè¿ããªãããã§ããlaunchd㯠exit 0 ããæ£åžžçµäºããšèšé²ããŸãã匷å¶åæ¢ãšæ£åžžçµäºãåºå¥ããŠããã°ã§åŸãããlaunchdãæ¢ãããããã¹ã¯ãªãããæ£åžžå®äºããããã倿ã§ããããã«ããŠããŸãã
write_state ã® atomic write
write_state() {
local value="$1" temp_state
temp_state="$STATE_FILE.tmp.$$"
printf '%s' "$value" >"$temp_state" && /bin/mv "$temp_state" "$STATE_FILE"
}
> ã§çŽæ¥ $STATE_FILE ãäžæžãããã®ã§ã¯ãªãã$STATE_FILE.tmp.$$ ã«æžããŠãã mv ããçç±ã¯ãæžã蟌ã¿ãšèªã¿èŸŒã¿ã®ç«¶åãé²ãããã§ããlaunchdã§1æ¥2åèµ·åããŠããå Žåãæåå®è¡ãšã®éè€ãå°æ¥çãªintervalççž®ã§åæå®è¡ãèµ·ãããšãã> ã®çŽæžãã¯ãæžã蟌ã¿éäžã®ç©ºãã¡ã€ã«ãå¥ããã»ã¹ãèªããç¶æ
ãäœããŸããmv ã¯inodeåäœã®æäœã§atomicãªã®ã§ãèªã¿æã¯ãåã®å®å
šãªå€ãããæ°ããå®å
šãªå€ãããèŠãŸããããã¡ã€ã«åã« $$ïŒããã»ã¹IDïŒãå«ããŠããã®ã¯ãè€æ°ããã»ã¹ãåæã«tempãã¡ã€ã«ãäœã£ããšãã®è¡çªãé²ãããã§ãã
ç§ãè©°ãŸã£ã話
è©°ãŸãâ ïŒçŽæžããªã¹ãã¯ç¿æã«è ã£ãŠãã
æåã®ããŒãžã§ã³ã¯ãããã¡ã€ã«dirãé åã§çŽæžãããŠããŸããã
# åæå®è£
ïŒå逿žã¿ã»æ¬äŒŒã³ãŒãïŒ
PROFILES=(
"~/dev/social-autolike/profiles/ig-1"
"~/dev/social-autolike/profiles/ig-2"
"~/dev/social-autolike/profiles/tt-1"
"~/dev/metrics-hub/profiles/tiktok" # â éºç©
"~/dev/metrics-hub/profiles/tiktok2" # â éºç©
)
çç¶ïŒç¿æã®07:10å®è¡ãã°ã« metrics-hub/profiles/tiktok ãš tiktok2 ãEXPIREDãšããŠäžãããDiscordã«ã¢ã©ãŒããé£ãã ã
åå ïŒTikTokã¬ãŒã³ tt-1ã3 ã®å®æ
㯠accounts.json ã® reuseProfile ãã£ãŒã«ãã§ social-autolike/profiles/tt-N ãæããŠããŸãããmetrics-hub/profiles/tiktok ã¯ä»¥åã®éçºãµã€ã¯ã«ã§äœ¿ã£ãŠããdirã§ãçŸåšã©ã®ãžã§ããããåç
§ãããŠããªããç§ãã䜿ã£ãŠãããšæã£ãŠãåæããdirãšããžã§ããå®éã«äœ¿ã£ãŠããdirã¯å¥ã®ãã®ã§ããã
ããäžã€èŠèœãšããŠããã®ã¯éæ¹åã®åé¡ã§ããçŽæžããªã¹ãã«ã¯ ig-autoreply:ig-1 ãåç
§ããŠããæ§ metrics-hub/profiles/instagram ãå
¥ã£ãŠããªãã£ããèª€å ±ã1ä»¶åºããåãããžãã¯ããå¥ã®èŠèœãšãã1ä»¶é ããŠããŸãããçŽæžãã¯èª€å ±ãšèŠèœãšããåæã«äœãã
çŽãæ¹ïŒaccounts.json ã® .reuseProfile // ($root + "/profiles/" + .id) ãšãã jq ã¯ãšãªã§åç解決ããããžã§ãæ¬äœã® src/lib.js ãæã€ profileDir() ãšåäžèŠåãªã®ã§ãèšå®ãã¡ã€ã«ã倿Žãããšãèªåçã«ã¹ã¯ãªããåŽã远éããŸããä¿®æ£åŸã®ååå®è¡ã§ã22件解決 / ok 20 / expired 2ããšããçµæãåºãŠãèª€å ±ããŠãã2ä»¶ãæ¶ãã代ããã«èŠèœãšããŠããæ§ metrics-hub/profiles/instagram ã®å€±å¹ãæ°ãã«æ€åºãããŸããã
è©°ãŸãâ¡ïŒTikTok ã sessionid 1æ¬ã§èŠããçããå¢ãæ¢ãã
TikTok ã®å€å®ãæžãããšããä»ã®platformãšåãçºæ³ã§æžããŸããã
-- åæå®è£
select count(*) from cookies where name='sessionid' and host_key like '%tiktok%';
ããã皌åäžã® tt-1 ã«åœãŠããšãããcount=0 ãè¿ã£ãŠããŠEXPIREDå€å®ã«ãªããŸããã
çç¶ïŒTikTokã®ã¢ã¯ãã£ããªã¢ã«ãŠã³ãããã°ã€ã³åããšããŠæ€åºãããã
åå ïŒCookieã³ããŒã«å¯Ÿã㊠sqlite3 ã§çŽæ¥ç¢ºèªãããšãããtt-1 ã«ã¯ sessionid ãšããè¡ããããŸããã§ãããå®éã«å
¥ã£ãŠããã®ã¯ sessionid_ss ãš sid_tt ã®2è¡ã§ããã
name | host_key
sessionid_ss | .tiktok.com
sid_tt | .tiktok.com
TikTokã®Cookieæ§æã¯ç°å¢ãã¢ã«ãŠã³ãã®å±æ§ã«ãã£ãŠéããsessionid ã ããæã€ãããã¡ã€ã«ã»sessionid_ss ã ãã®ãããã¡ã€ã«ã»3çš®ãã¹ãŠãæã€ãããã¡ã€ã«ãæ··åšããŠããŸããã1çš®é¡ã«æ±ºãæã¡ãããšããããæã£ãŠããªãæ£åžžãªã¢ã«ãŠã³ãã誀æ€ç¥ããŸãã
çŽãæ¹ïŒIN ('sessionid','sessionid_ss','sid_tt') ã§æããŠããããã1è¡ã§ãååšããã°OKãã«ãããéèŠãªã®ã¯ã3çš®ãšãå¿
èŠãã§ã¯ãªãã3çš®ã®ãã¡å°ãªããšã1çš®ãããã°æå¹ããšããå€å®æ¹åã§ãããçããŠããã®ã«NGã«ããããšã©ãŒã¯ãåããŠããã®ã«OKã«ããããšã©ãŒããæªãââåè
ã¯åããŠããæ©æ¢°ãèªåã§æ¢ããè¡çºã ããã§ãã
è©°ãŸãâ¢ïŒChromeãèµ·åäžã ãšsqlite3ãSQLITE_BUSYãè¿ãã
æåã¯ã³ããŒãªãã§Cookie DBããã®ãŸãŸèªãããšããŠããŸããã
# ã³ããŒãªãçïŒåæå®è£
ïŒ
count=$(/usr/bin/sqlite3 "$COOKIE_DB" "$query" 2>/dev/null)
echo "rc=$?" # â rc=5 (SQLITE_BUSY)
çç¶ïŒChromeãèµ·åããŠããæé垯ã«å®è¡ãããšããã¹ãŠã®ãããã¡ã€ã«ãUNKNOWNã«ãªãã
åå ïŒChromeã¯Cookies DBã«å¯ŸããŠWALã¢ãŒãã®ããã¯ãæã£ãŠãããå€éšããã»ã¹ãçŽæ¥éãããšãããšSQLITE_BUSYïŒãšã©ãŒã³ãŒã5ïŒãè¿ããŸãã07:10ã®å®æå®è¡ã¯æã®Chromeãç«ã¡äžãã£ãŠããæé垯ã«éãªãããšãå€ããã»ãŒæ¯åã³ã±ãŠããŸããã
sqlite3 ã®ãšã©ãŒã UNKNOWN ã«ããããžãã¯ããã£ããããå
šãããã¡ã€ã«ãUNKNOWNæ±ãã«ãªã£ãŠéç¥ãé£ã°ãããã°ãèŠããŸã§æ°ã¥ããŸããã§ãããUNKNOWNèšèšãèª€å ±ãé²ãã§ãããäžæ¹ã§ããUNKNOWNã22件䞊ãã§ããããšããç¶æ
ãæ¯æ¥çæããŠããããšã«ãªããŸãã
çŽãæ¹ïŒmktemp ã§ãã¡ã€ã«ã·ã¹ãã äžã®å¥ã³ããŒãäœããã³ããŒã«å¯ŸããŠã¯ãšãªãæãããã³ããŒã¯ã¹ãããã·ã§ãããªã®ã§Chromeã®ããã¯ç¶æ
ãšç¡é¢ä¿ã§ããã³ããŒã倱æããå Žå㯠CHECK_DETAIL="Cookies DB copy failed" ãšã㊠UNKNOWN ã§ç¶è¡ãããã®1ä»¶ã ããé£ã°ããŠæ®ãã®ãããã¡ã€ã«ã®æ€æ»ã¯ç¶ç¶ããŸãã
è©°ãŸãâ£ïŒunfollow ã® give-up æ©æ§ããã°ã¢ãŠãäžã«å°åž³ãçŒãããšãã
ããã¯ã»ãã·ã§ã³åããèŠèœãšãããšã§ãã©ãã ãæ·±ã穎ã«èœã¡ãããšãã話ã§ãã
unfollow-core.js ã«ã¯çޝèš6åã®å€±æã§çžæããã©ããŒå°åž³ããç©çåé€ããæ©èœããããŸãïŒquarantineã®æ°žä¹
ã«ãŒããæã¡åãããã®give-upèšèšã§ãïŒãåãæ¥ãunfollowãžã§ãã1æ¥1åâ1æ¥4åã«å¢ãã倿Žãå
¥ããŸããã
ig-2 㯠sessionid ã倱ã£ãŠããŸããããã°ã¢ãŠãç¶æ
ã§ã¢ã³ãã©ããŒæäœãããããšãããšãInstagramã¯ãã°ã€ã³APIãžãªãã€ã¬ã¯ãããããžã§ãã«ãšã£ãŠã¯ãæäœã倱æãããã«èŠããŸãã1æ¥4åã®ããŒã¹ã§å€±æã«ãŠã³ããç©ã¿äžãããšãããã**threshold ã®6ã«éããã®ã¯2æ¥ãèŠããŸããã**å°åž³è¡ãåé€ããããšããã®çžæã¯äºåºŠãšã¢ã³ãã©ããŒã§ããªããªããŸãââèšé²ãã®ãã®ãæ¶ããŠããããã§ãã
çç¶ïŒçŽåã§æ¢ããããå®å®³ãªãïŒïŒã»ãã·ã§ã³åãã®ã¢ã«ãŠã³ãã§ãžã§ããèµ°ãç¶ãã倱æã«ãŠã³ããæ¥å¢ããŠããã
åå ã®é£éïŒãã°ã¢ãŠã â å šæäœãã倱æãæ±ã â give-upã«ãŠã³ããå¢å â thresholdè¶ éã§å°åž³è¡ãåé€ãåé¡ã¯ã倱æãã®åå ããç°å¢åŽïŒãã°ã¢ãŠãïŒããã察象åŽïŒæ¬åœã«æäœã§ããªãçžæïŒãããåºå¥ããŠããªãã£ãããšã§ãã
çŽãæ¹ïŒunfollow-sweep.js ã®èµ·åçŽåŸããã©ãŠã¶ãéãåã«Cookieã確èªãããã°ã¢ãŠã確å®ãªãå°åž³ã«ã quarantine ã«ã1ãã€ããæžããå³çµäºããã
const loginState = await hasValidSessionCookie(profileDir, 'instagram')
if (shouldAbortForLogin(loginState)) {
await stop({ stopReason: 'need-login' })
return
}
shouldAbortForLogin ã¯çŽç²é¢æ°ã§ trueïŒCookieç¢ºèªæžã¿ïŒâ ç¶è¡ / falseïŒãã°ã¢ãŠã確å®ïŒâ äžæ / nullïŒå€å®äžèœïŒâ ç¶è¡ ã®3å€ãè¿ããŸããnull ã§ç¶è¡ããã®ã¯ããå€å®ã§ããªãã£ãããšããã°ã¢ãŠãããŠãããã¯å¥ã®äºè±¡ã ããã§ããããã§æ¢ãããšãCookieãèªããªãã ãã§çããŠããã¢ã«ãŠã³ããå
šåæ¢ããŸãã
æèšïŒã倱æãããã®ãæšãŠããæ©æ§ãèšèšãããšãã倱æã®åå ãç°å¢åŽïŒãã°ã¢ãŠãã»ã¬ãŒãå¶éã»ãããã¯ãŒã¯æïŒã§ããå Žåãåãåããªããã°ãæ£ããããŒã¿ãæšãŠãããšã«ãªããŸããgive-up ãš health-check ã¯å¿ ãã»ããã§èšèšããã
è©°ãŸãâ€ïŒéç¥ãå€ãããŠæ¬ç©ã®ãã°ã€ã³åãéç¥ãåããã
profile-session-guard.sh ãåããããåã®è©±ã§ããDiscordã®éç¥ã«ãŒã¿ãŒã« ããã\d+ä»¶ ãšãã DENY ãã¿ãŒã³ãå
¥ã£ãŠããŸããââææã¬ããŒãããã€ãžã§ã¹ãã«èœãšãããã§ãã
åé¡ã¯ããã°ã€ã³åããæ€åºãããžã§ãã ããã0ä»¶ (need-login) ãšããã¡ãã»ãŒãžãéã£ããšããããã\d+ä»¶ ã®ãã¿ãŒã³ã ããã0ä»¶ ã«ããããããŠãã€ãžã§ã¹ããžèœãšããŠããããšã§ãã\d+ ã¯ãŒã以äžã®æ°åã«ãããããââã0ä»¶ããã1000ä»¶ããåããã¿ãŒã³ã§é£²ãŸããŸãã
çç¶ïŒãžã§ãããã°ã€ã³åããå ±åããŠããã®ã«ãDiscordã®alerts channelã«äœãæ¥ãªãããã€ãžã§ã¹ãã®äžã«åãŸã£ãŠããã
çŽãæ¹ïŒneed-login / æªãã°ã€ã³ / åãã°ã€ã³ / ã»ãã·ã§ã³åã / GUIãã°ã€ã³ / åçµ / permanently ãHARD_ACTIONãšããŠå
šDENYã«ãŒã«ããå
ã«è©äŸ¡ãã圢ãžå€æŽããããã°ã€ã³åãã¯äººéãæåã§GUIãæäœããªããã°çµ¶å¯Ÿã«å埩ããªãçš®é¡ã®ã¢ã©ãŒãã§ããéç¥ãæ¥ãªããã°å¯ŸåŠãå§ãŸããªãããæ¬äººãæãåãããªããã°è§£æ±ºããªããç³»ã®ã¢ã©ãŒãã¯ãã«ãŒã¿ãŒã®DENYã«é£²ãŸããããšã絶察ã«èš±ããŠã¯ãããªãã
ã€ãŸãããã€ã³ã
ååã»äžæ®µã§åå¥ã®çµç·¯ã詳ããæžããŸãããããã§ã¯åãæ§é ãèžãã§ããæ¹ãèªåã®ã³ãŒããç¹æ€ã§ãããããè©°ãŸãã®ãã¿ãŒã³ãç®æ¡æžãã§ç¶²çŸ ããŸãã
DOMã»URLå€å®ã®éç
-
Instagramã®ãã°ã¢ãŠãç»é¢ã«ã¯
mainèŠçŽ ãååšãããneedLogin()ããarticle/[role=feed]/video/main/[data-e2e]ã®ãããã0ä»¶ããæ¡ä»¶ã«ããŠããããããã°ã¢ãŠãç»é¢ã§ãmainã1ä»¶ãããããŠå€å®ãããæãããig-2ã¯ãã®ç¶æ ã§1æ¥12åèµ°ããããã0ã»ãã©ããŒ0ã®ãŸãŸäœæ¥ã誰ã«ãæ°ã¥ãããªãã£ãã -
URLã«
/loginãå«ãŸããªããã°ã¢ãŠãç¶æ ãããã ãªãã€ã¬ã¯ãã®ã¿ã€ãã³ã°æ¬¡ç¬¬ããããã¯ãµãŒãã¹ããã°ã¢ãŠãåŸã«å¥ç»é¢ãèŠããå ŽåãURLå€å®ãå€ããã - ããã°ã€ã³ç»é¢ã£ãœããããšããã°ã€ã³ããŠããããã¯å¥ã®åãã ã åè ã¯UIã®å¯ç£ç©ã§ããµãŒãã¹åŽã®ãã¶ã€ã³å€æŽã§å³åº§ã«ããæãããåŸè ã¯èªèšŒç¶æ ãã®ãã®ã§ãããCookieãæ£æ¬ã
-
DOMå€å®ãæ¶ãå¿
èŠã¯ãªãã
hasValidSessionCookieã false ãè¿ãããå³äžæãããã以å€ã¯æ¢åã® DOM å€å®ã«å§ãããCookie å€å®ãš DOM å€å®ã¯ OR ã§ã¯ãªããåæ®µã®ã²ãŒããšããŠé 眮ããã
ãããã¡ã€ã«ãã¹è§£æ±ºã®èœãšã穎
-
çŽæžããªã¹ãã¯äœæããç¬éããè
ãå§ããã
~/dev/metrics-hub/profiles/tiktokãštiktok2ãã¹ã¯ãªããå é åã«åæããããå®éã® TikTok ã¬ãŒã³ tt-1ã3 ã¯accounts.jsonã®reuseProfileãã£ãŒã«ãã§~/dev/social-autolike/profiles/tt-Nãåç §ããŠãããäœæç¿æ¥ã®07:10å®è¡ã§ãã®2ä»¶ãEXPIREDãšããŠèª€å ±ãããã -
èª€å ±ãšèŠèœãšãã¯åæã«çºçããã 䜿ãããŠããªãdirã誀EXPIREDã«ããåãããžãã¯ãã
ig-autoreply:ig-1ãåç §ããŠãã~/dev/metrics-hub/profiles/instagramã®å€±å¹ãèŠèœãšããŠãããçŽæžãã¯ãèªåãæã£ãŠããæ§æãã§ãã£ãŠãå®éã«åããŠããæ§æãã§ã¯ãªãã -
reuseProfileãã£ãŒã«ãã«ããå·®ãæ¿ããèæ ®ããŠããªããšå¿ ããºã¬ããprofiles/<id>ãšããããã©ã«ããã¹ã決ãæã¡ãããªã¹ãã¯ãreuseProfileã§å¥dirã«å·®ãæ¿ãã£ãŠããã¢ã«ãŠã³ããèŠéãã -
èšå®ãã¡ã€ã«ããåç解決ããå Žåããžã§ãæ¬äœã®è§£æ±ºèŠåãšäžèŽãããã
profile-session-guard.shã®load_accounts()ã§äœ¿ã£ãŠãã jq ã¯ãšãª.reuseProfile // ($root + "/profiles/" + .id)ã¯ãsrc/lib.jsã®profileDir()ãšåäžèŠåããããäžèŽããªããšã¹ã¯ãªãããšãžã§ããå¥ã ã®dirãèŠãã
TikTokåºæã®èœãšã穎
-
sessionid1æ¬ã ãã§å€å®ãããšçšŒåäžã®ã¢ã«ãŠã³ããæ¢ããã 皌åäžã® tt-1 ã«å¯ŸããŠselect count(*) from cookies where name='sessionid' and host_key like '%tiktok%'ãå®è¡ãããšãã count=0ãå®éã«å ¥ã£ãŠããã®ã¯sessionid_ssãšsid_ttã®2è¡ã ã£ãã -
3çš®ã®ã©ããå
¥ã£ãŠãããã¯ã¢ã«ãŠã³ããšç°å¢ã«ãã£ãŠç°ãªãã
sessionidã ãã®ãããã¡ã€ã«ã»sessionid_ssã ãã®ãããã¡ã€ã«ã»3çš®ãã¹ãŠæã€ãããã¡ã€ã«ãæ··åšãããIN ('sessionid','sessionid_ss','sid_tt')ã§ããããã1çš®ã§ãããã°OKãã«ããã®ã宿ž¬ã«åºã¥ãæ£è§£ã - ã3çš®ãšãå¿ èŠãã«ãããšæ£åžžãªã¢ã«ãŠã³ããåœé°æ§ã§æ¢ããã ãçããŠããã®ã«NGãã¯ãåããŠããã®ã«OKãããæªããåè ã¯åããŠããæ©æ¢°ãèªåã§æ¢ããè¡çºã
SQLiteã»ãã¡ã€ã«æäœã®èœãšã穎
-
Chromeèµ·åäžã« Cookie DB ãçŽæ¥éããšSQLITE_BUSYïŒçµäºã³ãŒã5ïŒãè¿ãã ã³ããŒãªãå®è£
ã§ã¯07:10ã®å®æå®è¡ã§ã»ãŒæ¯åå
šãããã¡ã€ã«ãUNKNOWNã«ãªã£ãŠããã
mktempã§ã¹ãããã·ã§ãããåã£ãŠããèªããš Chromeã®ããã¯ç¶æ ã«é¢ä¿ãªãèªã¿åºããã -
mktempèªäœã倱æããããšãããã/tmpãæºæ¯ã»ããŠã³ã倱æãªã©ãTEMP_COOKIE_DBã空æåã®ãŸãŸsqlite3ã«æž¡ããšäºæããªããã¡ã€ã«ãäœãã[ -z "$TEMP_COOKIE_DB" ]ãã§ãã¯ã¯å¿ é ã -
Cookieãã¡ã€ã«ã®ãã¹ã¯ããŒãžã§ã³ã§å€ããã
Default/Network/CookiesïŒçŸè¡ChromeïŒã»Default/Cookiesã»Network/Cookiesã»Cookiesã®4ãã¿ãŒã³ãé ã«è©ŠããŠæåã«èŠã€ãã£ããã®ã䜿ããªããšãå€ããããã¡ã€ã«ãäžéšã® Chromium ç³»ãã©ãŠã¶ã§ DB ãèŠã€ãããªãã - Cookieã®å€ã¯æå·åãããŠããã®ã§åŸ©å·ããããšããªãã Chrome 㯠AES-256-GCM ã§æå·åããŠãããè¡ã®ååšïŒcount > 0ïŒã ãã確èªãããå€ãèªãããšããŠããã€ããªãè¿ãã ãã
-
sqlite3ã®çµäºã³ãŒããšåºåå€ã®äž¡æ¹ãæ€èšŒããã DB ãå£ããŠããã»æ³å®å€ãã©ãŒãããã®ãšãçµäºã³ãŒãã0ã§ã空æåãè¿ãããšããããgrep -Eq '^[0-9]+$'ã§æ°å€ãã§ãã¯ãã»ããã§è¡ãã
éç¥ã»ç£èŠã®èœãšã穎
-
\d+ã¯0ä»¶ãå«ãã éç¥ã«ãŒã¿ãŒã«ããã\d+ä»¶ã® DENY ãã¿ãŒã³ããããšããã0ä»¶ (need-login)ããã€ãžã§ã¹ãã«èœã¡ããalerts channel ã«äœãå±ããããã°ãæããŸã§ãã°ã€ã³åãã«æ°ã¥ããªãã£ãå®äŸã - åãåããç¶ããš1æ¥2åÃNæ¥ã§éç¥ã飜åããã state ãã¡ã€ã«ã«ååã®åãäžèЧãä¿åããå 容ãåããªãéç¥ãéããªãèšèšã«ããªããšãæ¯ååãã¢ã«ãŠã³ãã§é³Žãç¶ããŠããã€ãã®ãã€ããšããŠç¡èŠãããããã«ãªãã
-
ãããã¡ã€ã«åããæ¢ãŸãã¬ãŒã³åã®ã»ãã人éã®å€æææã«ãªãã
ig-2 ãåãããšããéç¥ããig-2(ig-2, ig-autoreply:ig-2) ãåããã®ã»ãããæ¬¡ã«äœããã¹ãããå³åº§ã«ãããããããã¡ã€ã«åã¯ãã¡ã€ã«ã·ã¹ãã ã®éœåã§ããã人éã¯ã¬ãŒã³åã®ã»ãããžã§ããšã®å¯Ÿå¿ãçè§£ããŠããã
give-upæ©æ§ãšã®çµã¿åããã®èœãšã穎
-
ãã°ã¢ãŠãäžã«ã倱æçޝç©âå°åž³åé€ãæ©æ§ãåããšæ£ããããŒã¿ãæ¶ããã
unfollow-core.jsã®UNFOLLOW_GIVEUP_FAILS = 6ã¯quarantineã®æ°žä¹ ã«ãŒããæã€ããã®èšèšã ãããã°ã¢ãŠãç¶æ ã§ã¯å šã¢ã³ãã©ããŒæäœãã倱æãæ±ãã«ãªãã1æ¥4åã®ãžã§ããèµ°ãã°2æ¥ä»¥å ã«çޝèš6åã«éããå°åž³è¡ãç©çåé€ããããåé€ããããšäºåºŠãšåŸ©å ã§ããªãã - 倱æã®åå ããç°å¢åŽããã察象åŽãããåºå¥ããŠããªããšæšãŠãŠã¯ãããªãããŒã¿ãæšãŠãã ãã°ã¢ãŠãã»ã¬ãŒãå¶éã»ãããã¯ãŒã¯æã¯ãç°å¢ãå£ããŠãããã§ãã£ãŠãçžæãè§£é€ã§ããªãããšã¯å¥ç©ãgive-up èšèšãšã»ãã·ã§ã³ health-check ã¯å¿ ããã¢ã§å®è£ ããã
- å€å®äžèœïŒnullïŒã¯ãã°ã¢ãŠã確å®ïŒfalseïŒãšåãæ±ãã«ããŠã¯ãããªãã Cookieãèªããªãçç±ã¯ããŸããŸããããå€å®ã§ããªãã£ãããšããã°ã¢ãŠãããŠããããåäžèŠãããšãCookie DBãèŠã€ãããªãã ãã§å šã¬ãŒã³ãæ¢ãŸãã
ãã¹ããã©ã¯ãã£ã¹
1. æ»æŽ»ã®äžæ¬¡æ å ±ãCookieã«çœ®ã
DOMã»URLã»ããŒãžã¿ã€ãã«ã¯UIã®å¯ç£ç©ãèªèšŒç¶æ
ãç¥ããããªãèªèšŒç¶æ
ãã®ãã®ãèŠããcookie_query() ãæãã SQL ã¯1è¡ã§ãã°ã€ã³ç¶æ
ã確å®ãããã
# instagram ã®äŸ
printf "%s" "select count(*) from cookies where name='sessionid' and host_key like '%instagram.com%';"
UI ãã©ãå€ãã£ãŠããsessionid Cookie ã®æç¡ã¯ Instagram ã®ãã°ã€ã³ç¶æ
ãš1察1ã§å¯Ÿå¿ããã
2. å¿ ãmktempã§ã³ããŒããŠããèªã
TEMP_COOKIE_DB=$(mktemp /tmp/profile-session-guard.cookies.XXXXXX)
[ -z "$TEMP_COOKIE_DB" ] || /bin/cp "$COOKIE_DB" "$TEMP_COOKIE_DB" 2>/dev/null || return
# ...ã¯ãšãªå®è¡...
/bin/rm -f "$TEMP_COOKIE_DB"
ã³ããŒã¯ã¹ãããã·ã§ãããªã®ã§Chromeã®WALããã¯ã«é¢ä¿ãªãèªãããCookieã¯èªèšŒæ
å ±ãªã®ã§ trap cleanup EXIT ã§ç¢ºå®ã«æ¶ãã
3. ãããã¡ã€ã«ãã¹ã¯ãžã§ãæ¬äœãšåãèŠåã§åç解決ãã
"$JQ" -r --arg root "$ROOT" \
'.accounts[] | [.id, .platform, (.reuseProfile // ($root + "/profiles/" + .id))] | @tsv' \
"$ACCOUNTS_CONFIG"
èšå®ãã¡ã€ã«ãå€ãããšããã¹ã¯ãªããåŽãèªå远éããã解決èŠåã src/lib.js ã® profileDir() ãšäžèŽãããããšãéµãçŽæžãããç¬éããè
ãå§ããã
4. TikTokã¯INæ€çŽ¢ã§3çš®ãŸãšããŠããããã1çš®ããã°OKãã«ãã
select count(*) from cookies
where name in ('sessionid','sessionid_ss','sid_tt')
and host_key like '%tiktok%';
宿ž¬ã§ tt-1 㯠sessionid_ss ãš sid_tt ã®2è¡ãæã¡ãsessionid ã¯ååšããªãã£ãã1çš®ã«æ±ºãæã¡ãããšç°å¢å·®ã§åœé°æ§ãåºãã
5. å€å®ã§ããªããšãã¯UNKNOWNã§ç¶è¡ãEXPIREDã«ããªã
if [ "$sqlite_rc" -ne 0 ] || ! printf '%s' "$count" | /usr/bin/grep -Eq '^[0-9]+$'; then
unknown=1
CHECK_DETAIL="sqlite3 failed for $platform"
continue # EXPIREDã«ã¯ããªã
fi
æªå¯Ÿå¿platformã»DBãå£ããŠããã»mktempã倱æããå Žåã¯EXPIREDã§ã¯ãªãUNKNOWNã§åŠçããã17ã¬ãŒã³ãå šåæ¢ããã»ãã1ã¬ãŒã³ã®åããèŠéãããæå®³ã倧ããç°å¢ã§ã¯ãfail-safeã¯UNKNOWNïŒç¶è¡ã«ãªãã
6. give-upãšhealth-checkãã»ããã§èšèšãã
ç Žå£çãªæäœïŒå°åž³åé€ã»quarantineæžã蟌ã¿ïŒã®åã«ãèªåãæ£åžžã«åããç¶æ ãã確èªããã²ãŒãã眮ãã
const loginState = await hasValidSessionCookie(profileDir, 'instagram')
if (shouldAbortForLogin(loginState)) {
await stop({ stopReason: 'need-login' })
return // å°åž³ã«1ãã€ããæžããªã
}
shouldAbortForLogin ã¯çŽç²é¢æ°ã§ trueïŒæå¹ïŒâç¶è¡ / falseïŒãã°ã¢ãŠã確å®ïŒâäžæ / nullïŒå€å®äžèœïŒâç¶è¡ ã®3å€ãå€å®äžèœã¯ç¶è¡ââããã§æ¢ãããš Cookieãèªããªãã ãã§å
šåæ¢ããã
7. ç¶æ ã®å€åã ãéç¥ãã
[ -f "$STATE_FILE" ] && previous=$(/bin/cat "$STATE_FILE" 2>/dev/null)
if [ "$broken" = "$previous" ]; then
log "login missing unchanged ($broken); notification skipped"
else
notify "ð ãã°ã€ã³åã: $broken ..."
fi
write_state "$broken"
åãåããç¶ãéã¯éç¥ãé£ã°ããªããéç¥ãå€ããããšæ¬ç©ã®ã¢ã©ãŒããåãããââããã¯å¥ã®å®å®³ãšããŠçµéšãã話ã
8. HARD_ACTIONãã¿ãŒã³ãå šDENYã«ãŒã«ããå ã«è©äŸ¡ãã
éç¥ã«ãŒã¿ãŒã«ä»¥äžãHARD_ACTIONãšããŠæäžäœã«ç»é²ããã
need-login / æªãã°ã€ã³ / åãã°ã€ã³ / ã»ãã·ã§ã³åã /
GUIãã°ã€ã³ / åçµ / permanently / sessionid.{0,10}倱å¹
ããã\d+ä»¶ ã® DENY ãã¿ãŒã³ã ããã0ä»¶ (need-login) ã飲ãã§ããå®äŸããã£ãããæ¬äººãGUIãæäœããªããã°çµ¶å¯Ÿã«å埩ããªããçš®é¡ã®ã¢ã©ãŒããåããããšãæ°ã¥ããŸã§ã®å
𿥿°ã倱ãããææã«ãªãã
9. éç¥æã«ã¬ãŒã³åãå«ãã
ð ãã°ã€ã³åã: ig-2(ig-2, ig-autoreply:ig-2) â 該åœã¬ãŒã³ã¯ææãŒãã®ãŸãŸ exit 0 ãè¿ãç¶ããŸããåãã°ã€ã³ãå¿
èŠ
ãããã¡ã€ã«å ig-2 ã ãã§ã¯ãã©ã®ãžã§ããæ¢ãŸããããããããªããã¬ãŒã³åãæ¬åŒ§ã«å
¥ãããšãåãåã£ã人éã®æ¬¡ã®è¡åãæç¢ºã«ãªããdeduplicateæã«ã¬ãŒã³åãæšãŠãªãã®ã¯ãã®ããã
10. åäždirãè€æ°ã¬ãŒã³ãåç §ãããªã1åã ãæ€æ»ããŠã¬ãŒã³åã¯ä¿æãã
ig-1-live ã ig-1 ãš ig-autoreply:ig-1 ã®äž¡ã¬ãŒã³ãåç
§ããŠããå Žåã2忀æ»ã¯ç¡é§ãã€ã¬ãŒã³æ
å ±ã忣ãããcanonical ãã¹ã§éè€æé€ããã¬ãŒã³åã¯ã«ã³ãåºåãã§ä¿æããã
lanes[dir] = lanes[dir] ", " lane # ig-1, ig-autoreply:ig-1
11. ååšããªãdirã¯ã¹ãããããŠãšã©ãŒã«ãéç¥ã«ãåºããªã
if [ ! -d "$dir" ]; then
log "skip missing $dir ($platform; lane=$lane)"
return 0
fi
ãŸã äœãããŠããªãã»åé€ããããããã¡ã€ã«ãUNKNOWNã§åŠçãããšãç°å¢æ§ç¯éäžã®ã¬ãŒã³ãæ¯åãã€ãºãåºããååšç¢ºèªããŠããåè£ã«è¿œå ããã
12. write_stateã¯atomic writeã«ãã
temp_state="$STATE_FILE.tmp.$$"
printf '%s' "$value" >"$temp_state" && /bin/mv "$temp_state" "$STATE_FILE"
> ã§çŽæ¥äžæžããããšãæžã蟌ã¿éäžã®ç©ºãã¡ã€ã«ããå¥ããã»ã¹ãèªãç«¶åãäœããmv ã¯inodeåäœã®atomicæäœãããã»ã¹ID $$ ãtempãã¡ã€ã«åã«å«ããããšã§è€æ°ããã»ã¹åæå®è¡æã®è¡çªãé²ãã
13. Cookieãã¹ã¯4ãã¿ãŒã³é çªã«è©Šã
for candidate in \
"$dir/Default/Network/Cookies" \
"$dir/Default/Cookies" \
"$dir/Network/Cookies" \
"$dir/Cookies"; do
[ -f "$candidate" ] && COOKIE_DB="$candidate" && return 0
done
Chromeã®ããŒãžã§ã³ãäžéšã® Chromium ç³»ãã©ãŠã¶ã§ãã¹ãéãã1ãã¿ãŒã³æ±ºãæã¡ã«ãããšãããã¡ã€ã«ã®äžéšã§åžžã«DBæªæ€åºã«ãªãã
ãŸãšã
ã»ãã·ã§ã³æ»æŽ»ã®å€å®ããããŒãžãã©ãèŠãããããããCookieãå®åšãããããžç§»ãââãã®è»¢æã¯ãæè¡çãªå®è£ ã®è©±ã§ãããšåæã«ããäœãäžæ¬¡æ å ±ã«ãããããšããèšèšææ³ã®è©±ã§ãã
ig-2 ãäœæ¥ãããã0ä»¶ã§èµ°ãç¶ããåå ã¯ãå€å®ããèªèšŒç¶æ
ã®æšæž¬ãã«äŸåããŠããããšã§ãããmain èŠçŽ ã1ä»¶ããã°ããã¶ããã°ã€ã³ããŠããããšçµè«ã¥ããŠãããCookieãçŽæ¥èªãã°1ã¯ãšãªã§ç¢ºå®ã§ããã®ã«ããã®åããç«ãŠãŠããªãã£ãã
profile-session-guard.sh ãæåã®å®è¡ã§åºããæ°å㯠resolved 22 unique existing profiles / ok=20 / expired=2 ã§ãããçŽæžããªã¹ãã§èª€å ±ããŠãã2ä»¶ãæ¶ããçŽæžãã§ã¯èŠèœãšããŠããå¥ã®å€±å¹ã1ä»¶æ°ãã«æ€åºããããèª€å ±ãšèŠèœãšããåæã«äœãââããã¯æ¯å©ã§ã¯ãªãå®éã«èµ·ããããšã§ãã
èªååç°å¢ã倧ãããªãã»ã©ãåå¥ã®å€±æã¯ãææãå°ãªãããšããèŠããªããªããŸãããšã©ãŒãé³ãç«ãŠãªããªããäœãããŠããªãç¶æ ããåé¡ãªãããšããŠèšé²ãããããã®ã¹ã¯ãªãããè§£ããŠããã®ã¯æè¡çãªåé¡ã ãã§ãªãããå£ããŠãé³ãããªãããšããæ§é ã®åé¡ã§ãã
ã»ãã·ã§ã³ãåãããšãã人éã«å±ããŸã§ã®æéããã®ãŸãŸå€±ãããææã«ãªããŸããCookieãäžæ¬¡æ å ±ã«ããããšãéç¥ãå€ååã ãéãããšãgive-upãšhealth-checkãã»ããã§èšèšããããšââãã®3ã€ãåãæ¥ã«4ç®æãžç¬ç«ã«å®è£ ããããšã«ãªã£ãã®ããæ°ã¥ããŠããŸãã°ãå šéšåãæ§é ã®åé¡ãã ã£ãããã§ãã
ä»çµã¿ã®å šäœåã»æ120äžã®å èš³ã»30æ¥æé ã¯æænoteã«ãŸãšããŠããŸãã
ð Claude CodeèªåŸç°å¢ã§ãå®éã©ã皌ãã â ä»çµã¿ã»å®äŸã»å§ãæ¹ã»ãµããŒã
LilyïŒ@bokuwalilyïŒâ å人éçºè ãClaude Code ã§èªåååºç€ãçµã¿ãªãããiOSã¢ããªãWebãµãŒãã¹ãéç£ããŠããŸã
- å¶äœç©ã»èšäºã¯ bokuwalily.com ã«ãŸãšããŠããŸãð¥ïž
- AIã§ãå¯ãŠãŠãåãä»çµã¿ããäœã£ãŠæ120äžã«ãã話㯠noteã®ææèšäº ã«ð°
- OSS: github.com/bokuwalily ð
- ææ°æ å ±ã»ãåãåãã㯠X @bokuwalily ãžð
çããã® â€ïž ãã·ã§ã¢ãå±ã¿ã«ãªããŸãïŒ