Skip to content

Instantly share code, notes, and snippets.

@qsun
Created July 20, 2025 23:48
Show Gist options
  • Select an option

  • Save qsun/7e6ed61feecf77d700a8281a00cb0149 to your computer and use it in GitHub Desktop.

Select an option

Save qsun/7e6ed61feecf77d700a8281a00cb0149 to your computer and use it in GitHub Desktop.
When claude code finishes the conversation, send a slack message to remind myself
#!/usr/bin/env python3
import json
import sys
import os
import requests
from urllib.parse import quote
from datetime import datetime
# ~/.claude/settings.json
'''
{
"permissions": {
"allow": [
"Bash(git push:*)",
"Bash(git checkout:*)",
"Bash(git add:*)",
"Bash(grep:*)",
"Bash(find:*)",
"Bash(nslookup:*)",
"Bash(aws elbv2 describe-load-balancers:*)",
"Bash(kubectl get:*)",
"Bash(kubectl describe:*)",
"Bash(kubectl logs:*)",
"Bash(curl:*)",
"Bash(jira create:*)",
"WebFetch(domain:docs.anthropic.com)",
"Bash(aws logs :*)"
],
"deny": []
},
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "/home/qsun/bins/finish.py"
}
]
}
],
"Stop": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "python3 /home/qsun/bins/finish.py"
}
]
}
]
}
}
'''
SLACK_WEBHOOK_URL = "https://hooks.slack.com/services/XX/YYY/ZZZ"
LOG_FILE = "/tmp/finish.log"
def log_session(project_name, last_prompt, session_id, transcript_path):
"""Log session information to persistent log file."""
try:
timestamp = datetime.now().isoformat()
log_entry = {
"timestamp": timestamp,
"session_id": session_id,
"project_name": project_name,
"last_prompt": last_prompt,
"transcript_path": transcript_path
}
with open(LOG_FILE, 'a') as f:
f.write(json.dumps(log_entry) + '\n')
except Exception as e:
print(f"Error writing to log file: {e}")
def send_slack_notification(project_name, last_prompt, session_id, transcript_path):
"""Send notification to Slack when Claude Code conversation finishes."""
# Read last prompt from transcript if available
last_user_message = "No prompt available"
if transcript_path and os.path.exists(transcript_path):
try:
with open(transcript_path, 'r') as f:
lines = f.readlines()
# Parse JSONL format and find last user message
for line in reversed(lines):
line = line.strip()
if not line:
continue
try:
entry = json.loads(line)
# Look for user type messages
if (entry.get('type') == 'user' and
'message' in entry and
entry['message'].get('role') == 'user'):
content = entry['message'].get('content', '')
if isinstance(content, str) and content.strip():
last_user_message = content.strip()
break
except json.JSONDecodeError:
continue
except Exception:
pass
# If last_prompt is provided, use it instead
if last_prompt:
last_user_message = last_prompt
# Truncate long messages
if len(last_user_message) > 200:
last_user_message = last_user_message[:197] + "..."
message = {
"text": f"🤖 Claude Code Session Finished",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"*Claude Code Session Finished*\n\n*Project:* `{project_name}`\n*Session ID:* `{session_id}`\n*Last Prompt:* {last_user_message}"
}
}
]
}
try:
response = requests.post(SLACK_WEBHOOK_URL, json=message, timeout=10)
if response.status_code == 200:
print("Slack notification sent successfully")
else:
print(f"Failed to send Slack notification: {response.status_code}")
except Exception as e:
print(f"Error sending Slack notification: {e}")
def main():
try:
# Read JSON data from stdin
input_data = json.loads(sys.stdin.read())
# Extract required information
session_id = input_data.get("session_id", "unknown")
cwd = input_data.get("cwd", os.getcwd())
transcript_path = input_data.get("transcript_path")
# Get project name from cwd
project_name = os.path.basename(cwd) if cwd else "unknown"
# Extract last prompt if available
last_prompt = input_data.get("last_prompt", "")
# Log session to persistent file
log_session(project_name, last_prompt, session_id, transcript_path)
# Send Slack notification
send_slack_notification(project_name, last_prompt, session_id, transcript_path)
# Exit successfully
sys.exit(0)
except Exception as e:
print(f"Hook error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment