Skip to content

Commit 9684451

Browse files
hubyrodclaude
andcommitted
Add summarize-group script to fetch and summarize weekly posts
Fetches group config from prod DB, retrieves posts via Slashwork GraphQL API, filters by week, and pipes to Claude CLI for summary. Supports current/previous/weekXX week selection. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 9f4447d commit 9684451

1 file changed

Lines changed: 190 additions & 0 deletions

File tree

summarize-group.sh

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# Usage: ./summarize-group.sh <group-name> [week] [post-count]
5+
# week: "current" (default), "previous", or "weekXX" (e.g. week03, week52)
6+
# Examples:
7+
# ./summarize-group.sh skjs
8+
# ./summarize-group.sh skjs previous
9+
# ./summarize-group.sh skjs week12
10+
# ./summarize-group.sh skjs current 100
11+
12+
GROUP_NAME="${1:?Usage: ./summarize-group.sh <group-name> [current|previous|weekXX] [post-count]}"
13+
WEEK_ARG="${2:-current}"
14+
POST_COUNT="${3:-100}"
15+
16+
# Compute week start (Monday) and end (Sunday 23:59:59) as ISO timestamps
17+
compute_week_range() {
18+
local week_arg="$1"
19+
local year week_num monday_date sunday_date
20+
21+
year=$(date +%Y)
22+
23+
case "$week_arg" in
24+
current)
25+
# Current ISO week number
26+
week_num=$(date +%V)
27+
;;
28+
previous)
29+
# Go back 7 days, get that week number
30+
week_num=$(date -v-7d +%V 2>/dev/null || date -d "7 days ago" +%V)
31+
# Handle year boundary (if previous week is in last year)
32+
local prev_year
33+
prev_year=$(date -v-7d +%Y 2>/dev/null || date -d "7 days ago" +%Y)
34+
year="$prev_year"
35+
;;
36+
week[0-9][0-9])
37+
week_num="${week_arg#week}"
38+
;;
39+
*)
40+
echo "Error: invalid week argument '$week_arg'" >&2
41+
echo "Use 'current', 'previous', or 'weekXX' (e.g. week03, week52)" >&2
42+
exit 1
43+
;;
44+
esac
45+
46+
# Strip leading zero for arithmetic
47+
local wn=$((10#$week_num))
48+
if [ "$wn" -lt 1 ] || [ "$wn" -gt 53 ]; then
49+
echo "Error: week number must be between 01 and 53, got '$week_num'" >&2
50+
exit 1
51+
fi
52+
53+
# macOS date: compute Monday of ISO week
54+
# Jan 4 is always in ISO week 1. Find Monday of week 1, then offset.
55+
local jan4_dow
56+
jan4_dow=$(date -j -f "%Y-%m-%d" "${year}-01-04" +%u 2>/dev/null)
57+
if [ -n "$jan4_dow" ]; then
58+
# macOS date
59+
local jan4_epoch
60+
jan4_epoch=$(date -j -f "%Y-%m-%d" "${year}-01-04" +%s)
61+
local week1_monday_epoch=$(( jan4_epoch - (jan4_dow - 1) * 86400 ))
62+
local target_monday_epoch=$(( week1_monday_epoch + (wn - 1) * 7 * 86400 ))
63+
local target_sunday_epoch=$(( target_monday_epoch + 6 * 86400 ))
64+
monday_date=$(date -r "$target_monday_epoch" +%Y-%m-%d)
65+
sunday_date=$(date -r "$target_sunday_epoch" +%Y-%m-%d)
66+
else
67+
# GNU date fallback
68+
monday_date=$(date -d "${year}-01-04 -$(date -d "${year}-01-04" +%u) days + 1 day + $((wn - 1)) weeks" +%Y-%m-%d)
69+
sunday_date=$(date -d "$monday_date + 6 days" +%Y-%m-%d)
70+
fi
71+
72+
WEEK_START="${monday_date}T00:00:00Z"
73+
WEEK_END="${sunday_date}T23:59:59Z"
74+
WEEK_LABEL="week ${week_num} ${year} (${monday_date}${sunday_date})"
75+
}
76+
77+
compute_week_range "$WEEK_ARG"
78+
79+
# Load .env
80+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
81+
if [ -f "$SCRIPT_DIR/.env" ]; then
82+
set -a
83+
source "$SCRIPT_DIR/.env"
84+
set +a
85+
fi
86+
87+
DB_URL="${POSTGRESQL_ADDON_URI:?Missing POSTGRESQL_ADDON_URI in .env}"
88+
GRAPHQL_URL="${SLASHWORK_GRAPHQL_URL:?Missing SLASHWORK_GRAPHQL_URL in .env}"
89+
90+
# Fetch group ID and auth token from the prod DB
91+
DB_ROW=$(psql "$DB_URL" -t -A -F '|' -c "
92+
SELECT g.slashwork_id, at.token
93+
FROM groups g
94+
JOIN auth_tokens at ON g.auth_token = at.name
95+
WHERE g.name = '$GROUP_NAME'
96+
")
97+
98+
if [ -z "$DB_ROW" ]; then
99+
echo "Error: group '$GROUP_NAME' not found in database" >&2
100+
echo "Available groups:" >&2
101+
psql "$DB_URL" -t -A -c "SELECT name FROM groups ORDER BY name" >&2
102+
exit 1
103+
fi
104+
105+
GROUP_ID=$(echo "$DB_ROW" | cut -d'|' -f1)
106+
AUTH_TOKEN=$(echo "$DB_ROW" | cut -d'|' -f2)
107+
108+
echo "Fetching posts from '$GROUP_NAME' for $WEEK_LABEL..." >&2
109+
110+
QUERY='query FetchGroupPosts($groupId: ID!, $first: Int!) {
111+
fetch__Group(id: $groupId) {
112+
name
113+
posts(first: $first) {
114+
edges {
115+
node {
116+
id
117+
markdown
118+
created
119+
author { id name }
120+
comments(first: 100) {
121+
edges {
122+
node {
123+
markdown
124+
created
125+
author { name }
126+
replies(first: 100) {
127+
edges {
128+
node {
129+
markdown
130+
created
131+
author { name }
132+
}
133+
}
134+
}
135+
}
136+
}
137+
}
138+
}
139+
}
140+
}
141+
}
142+
}'
143+
144+
PAYLOAD=$(jq -n \
145+
--arg query "$QUERY" \
146+
--arg groupId "$GROUP_ID" \
147+
--argjson first "$POST_COUNT" \
148+
'{query: $query, variables: {groupId: $groupId, first: $first}}')
149+
150+
RESPONSE=$(curl -s -f "$GRAPHQL_URL" \
151+
-H "Content-Type: application/json" \
152+
-H "Authorization: Bearer $AUTH_TOKEN" \
153+
-d "$PAYLOAD")
154+
155+
# Check for API errors
156+
API_ERRORS=$(echo "$RESPONSE" | jq -r '.errors // [] | .[].message' 2>/dev/null)
157+
if [ -n "$API_ERRORS" ]; then
158+
echo "GraphQL error: $API_ERRORS" >&2
159+
exit 1
160+
fi
161+
162+
# Extract and format messages, filtering by week date range
163+
MESSAGES=$(echo "$RESPONSE" | jq -r --arg start "$WEEK_START" --arg end "$WEEK_END" '
164+
[(.data.fetch__Group.posts // {edges:[]}).edges[].node
165+
| select(.created >= $start and .created <= $end)]
166+
| if length == 0 then empty else
167+
.[] |
168+
"--- \(.author.name) [\(.created)] ---\n\(.markdown)\n" +
169+
([(.comments // {edges:[]}).edges[].node |
170+
" > \(.author.name) [\(.created)]:\n \(.markdown)\n" +
171+
([(.replies // {edges:[]}).edges[].node |
172+
" >> \(.author.name) [\(.created)]:\n \(.markdown)"
173+
] | join("\n"))
174+
] | join("\n"))
175+
end
176+
')
177+
178+
if [ -z "$MESSAGES" ]; then
179+
echo "No messages found in group '$GROUP_NAME' for $WEEK_LABEL"
180+
exit 0
181+
fi
182+
183+
POST_TOTAL=$(echo "$RESPONSE" | jq --arg start "$WEEK_START" --arg end "$WEEK_END" '
184+
[(.data.fetch__Group.posts // {edges:[]}).edges[].node | select(.created >= $start and .created <= $end)] | length
185+
')
186+
echo "Found $POST_TOTAL posts for $WEEK_LABEL" >&2
187+
188+
SUMMARY=$(echo "$MESSAGES" | claude -p "Summarize the following messages from the '$GROUP_NAME' group for $WEEK_LABEL. Give a concise overview of the key topics, decisions, and action items discussed:")
189+
190+
echo "$SUMMARY"

0 commit comments

Comments
 (0)