[2026-05-15] 스케줄러 인코딩·권한·Discord 알림 수정
- run_*.ps1: PSScriptRoot 경로, claude.cmd 전체경로, UTF-8 BOM 저장으로 한글 깨짐 해결 - settings.json: PYTHONUTF8=1 환경변수, 글로벌 bypassPermissions 추가 - discord_notify.py: 커밋 메시지 불릿 + 커밋 완료 여부만 전송하도록 간소화 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
+18
-25
@@ -1,45 +1,38 @@
|
|||||||
import subprocess, json, urllib.request, datetime, sys
|
import subprocess, json, urllib.request, datetime, sys, pathlib
|
||||||
|
|
||||||
WEBHOOK = "https://discord.com/api/webhooks/1504705352166543370/H3dhs_4LaxnaFj_mhUUi02qpk3JegE_Ji9C6rNpEqRNv_iW6aqvso8VyPw17048Nt0oF"
|
WEBHOOK = "https://discord.com/api/webhooks/1504705352166543370/H3dhs_4LaxnaFj_mhUUi02qpk3JegE_Ji9C6rNpEqRNv_iW6aqvso8VyPw17048Nt0oF"
|
||||||
|
|
||||||
def run(cmd):
|
def run(cmd):
|
||||||
return subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='replace').stdout.strip()
|
return subprocess.run(cmd, capture_output=True, text=True, encoding='utf-8', errors='replace').stdout.strip()
|
||||||
|
|
||||||
import pathlib
|
|
||||||
|
|
||||||
SESSION_SHA_FILE = pathlib.Path('.claude/session_start_sha.txt')
|
SESSION_SHA_FILE = pathlib.Path('.claude/session_start_sha.txt')
|
||||||
|
|
||||||
# 세션 시작 시 저장된 HEAD와 비교해 이번 세션 커밋만 표시
|
|
||||||
start_sha = SESSION_SHA_FILE.read_text().strip() if SESSION_SHA_FILE.exists() else ''
|
start_sha = SESSION_SHA_FILE.read_text().strip() if SESSION_SHA_FILE.exists() else ''
|
||||||
if start_sha:
|
|
||||||
log = run(['git', 'log', '--oneline', f'{start_sha}..HEAD'])
|
|
||||||
else:
|
|
||||||
log = run(['git', 'log', '--oneline', '-5'])
|
|
||||||
|
|
||||||
status = run(['git', 'status', '--short'])
|
|
||||||
diff_stat = run(['git', 'diff', '--stat'])
|
|
||||||
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M')
|
now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M')
|
||||||
|
|
||||||
parts = [f"**[Claude Code 작업완료] {now}**"]
|
if start_sha:
|
||||||
|
messages = run(['git', 'log', '--pretty=format:%s', f'{start_sha}..HEAD'])
|
||||||
|
else:
|
||||||
|
messages = run(['git', 'log', '--pretty=format:%s', '-5'])
|
||||||
|
|
||||||
if log:
|
parts = [f"**[Claude Code] {now}**"]
|
||||||
parts.append(f"```\n{log}\n```")
|
|
||||||
elif not status and not diff_stat:
|
|
||||||
parts.append("_이번 세션 변경사항 없음_")
|
|
||||||
|
|
||||||
if status or diff_stat:
|
if messages:
|
||||||
combined = '\n'.join(filter(None, [status, diff_stat]))
|
bullets = '\n'.join(f"• {m}" for m in messages.splitlines() if m.strip())
|
||||||
parts.append(f"**미커밋 변경:**\n```\n{combined}\n```")
|
parts.append(f"**변경 내용:**\n{bullets}")
|
||||||
|
parts.append("✅ 커밋 완료")
|
||||||
|
else:
|
||||||
|
parts.append("_이번 세션 커밋 없음_")
|
||||||
|
|
||||||
if len(parts) == 1:
|
msg = '\n\n'.join(parts)
|
||||||
parts.append("_변경사항 없음_")
|
|
||||||
|
|
||||||
msg = '\n'.join(parts)
|
|
||||||
if len(msg) > 1990:
|
if len(msg) > 1990:
|
||||||
msg = msg[:1987] + '...'
|
msg = msg[:1987] + '...'
|
||||||
|
|
||||||
data = json.dumps({'content': msg}).encode('utf-8')
|
data = json.dumps({'content': msg}).encode('utf-8')
|
||||||
req = urllib.request.Request(WEBHOOK, data=data, headers={'Content-Type': 'application/json', 'User-Agent': 'DiscordBot (stockbot, 1.0)'}, method='POST')
|
req = urllib.request.Request(
|
||||||
|
WEBHOOK, data=data,
|
||||||
|
headers={'Content-Type': 'application/json', 'User-Agent': 'DiscordBot (stockbot, 1.0)'},
|
||||||
|
method='POST'
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
urllib.request.urlopen(req)
|
urllib.request.urlopen(req)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
{
|
{
|
||||||
"dangerouslySkipPermissions": true,
|
"dangerouslySkipPermissions": true,
|
||||||
|
"env": {
|
||||||
|
"PYTHONUTF8": "1",
|
||||||
|
"PYTHONIOENCODING": "utf-8"
|
||||||
|
},
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"defaultMode": "bypassPermissions",
|
"defaultMode": "bypassPermissions",
|
||||||
"allow": ["Bash(*)", "Edit(*)", "Write(*)", "Read(*)", "Glob(*)", "Grep(*)"]
|
"allow": ["Bash(*)", "Edit(*)", "Write(*)", "Read(*)", "Glob(*)", "Grep(*)"]
|
||||||
|
|||||||
+12
-6
@@ -1,16 +1,22 @@
|
|||||||
# 매매 봇 시작 스크립트
|
# 매매 봇 시작 스크립트
|
||||||
# 작업 스케줄러에서 07:55에 실행 (평일)
|
# 작업 스케줄러에서 07:55에 실행 (평일)
|
||||||
# Claude Code가 /start-bot 커맨드를 실행 → Python 봇을 백그라운드로 띄움
|
|
||||||
|
|
||||||
$PROJECT = "C:\Users\whdwo\OneDrive\바탕 화면\stockbot_v3"
|
$OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
$env:PYTHONIOENCODING = "utf-8"
|
||||||
|
|
||||||
|
$PROJECT = Split-Path -Parent $PSScriptRoot
|
||||||
$LOG = "$PROJECT\logs\bot_start.log"
|
$LOG = "$PROJECT\logs\bot_start.log"
|
||||||
|
$CLAUDE = "C:\Users\whdwo\AppData\Roaming\npm\claude.cmd"
|
||||||
|
$utf8 = New-Object System.Text.UTF8Encoding $false
|
||||||
|
|
||||||
Set-Location $PROJECT
|
Set-Location $PROJECT
|
||||||
|
|
||||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
Add-Content $LOG "[$timestamp] /start-bot 실행"
|
[System.IO.File]::AppendAllText($LOG, "[$timestamp] /start-bot 실행`n", $utf8)
|
||||||
|
|
||||||
claude -p "/start-bot" --dangerously-skip-permissions *>> $LOG
|
& $CLAUDE -p "/start-bot" --dangerously-skip-permissions 2>&1 |
|
||||||
|
ForEach-Object { [System.IO.File]::AppendAllText($LOG, "$_`n", $utf8) }
|
||||||
|
|
||||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
Add-Content $LOG "[$timestamp] /start-bot 완료"
|
[System.IO.File]::AppendAllText($LOG, "[$timestamp] /start-bot 완료`n", $utf8)
|
||||||
|
|||||||
+12
-6
@@ -1,16 +1,22 @@
|
|||||||
# claude_evening 실행 스크립트
|
# claude_evening 실행 스크립트
|
||||||
# 작업 스케줄러에서 15:30에 실행 (평일)
|
# 작업 스케줄러에서 15:30에 실행 (평일)
|
||||||
|
|
||||||
$PROJECT = "C:\Users\whdwo\OneDrive\바탕 화면\stockbot_v3"
|
$OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
$env:PYTHONIOENCODING = "utf-8"
|
||||||
|
|
||||||
|
$PROJECT = Split-Path -Parent $PSScriptRoot
|
||||||
$LOG = "$PROJECT\logs\evening.log"
|
$LOG = "$PROJECT\logs\evening.log"
|
||||||
|
$CLAUDE = "C:\Users\whdwo\AppData\Roaming\npm\claude.cmd"
|
||||||
|
$utf8 = New-Object System.Text.UTF8Encoding $false
|
||||||
|
|
||||||
Set-Location $PROJECT
|
Set-Location $PROJECT
|
||||||
|
|
||||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
Add-Content $LOG "[$timestamp] claude_evening 시작"
|
[System.IO.File]::AppendAllText($LOG, "[$timestamp] claude_evening 시작`n", $utf8)
|
||||||
|
|
||||||
# Claude Code headless 실행
|
& $CLAUDE -p "/evening" --dangerously-skip-permissions 2>&1 |
|
||||||
claude -p "/evening" --dangerously-skip-permissions *>> $LOG
|
ForEach-Object { [System.IO.File]::AppendAllText($LOG, "$_`n", $utf8) }
|
||||||
|
|
||||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
Add-Content $LOG "[$timestamp] claude_evening 완료"
|
[System.IO.File]::AppendAllText($LOG, "[$timestamp] claude_evening 완료`n", $utf8)
|
||||||
|
|||||||
+12
-7
@@ -1,17 +1,22 @@
|
|||||||
# claude_morning 실행 스크립트
|
# claude_morning 실행 스크립트
|
||||||
# 작업 스케줄러에서 08:15에 실행 (평일)
|
# 작업 스케줄러에서 08:15에 실행 (평일)
|
||||||
# claude_morning이 완료되면 08:30 전에 daily_context.json이 준비됨
|
|
||||||
|
|
||||||
$PROJECT = "C:\Users\whdwo\OneDrive\바탕 화면\stockbot_v3"
|
$OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
|
||||||
|
$env:PYTHONIOENCODING = "utf-8"
|
||||||
|
|
||||||
|
$PROJECT = Split-Path -Parent $PSScriptRoot
|
||||||
$LOG = "$PROJECT\logs\morning.log"
|
$LOG = "$PROJECT\logs\morning.log"
|
||||||
|
$CLAUDE = "C:\Users\whdwo\AppData\Roaming\npm\claude.cmd"
|
||||||
|
$utf8 = New-Object System.Text.UTF8Encoding $false
|
||||||
|
|
||||||
Set-Location $PROJECT
|
Set-Location $PROJECT
|
||||||
|
|
||||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
Add-Content $LOG "[$timestamp] claude_morning 시작"
|
[System.IO.File]::AppendAllText($LOG, "[$timestamp] claude_morning 시작`n", $utf8)
|
||||||
|
|
||||||
# Claude Code headless 실행
|
& $CLAUDE -p "/morning" --dangerously-skip-permissions 2>&1 |
|
||||||
claude -p "/morning" --dangerously-skip-permissions *>> $LOG
|
ForEach-Object { [System.IO.File]::AppendAllText($LOG, "$_`n", $utf8) }
|
||||||
|
|
||||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||||
Add-Content $LOG "[$timestamp] claude_morning 완료"
|
[System.IO.File]::AppendAllText($LOG, "[$timestamp] claude_morning 완료`n", $utf8)
|
||||||
|
|||||||
Reference in New Issue
Block a user