44import hashlib
55import requests
66from msal import ConfidentialClientApplication
7- from datetime import datetime
87
98# --- Determine mode ---
109TEST_MODE = os .getenv ("TEST_MODE" , "true" ).lower () == "true"
@@ -60,17 +59,6 @@ def send_email_via_graph(subject, body):
6059 except Exception as e :
6160 print (f"β Exception occurred while sending email: { e } " )
6261
63- # --- Format GitHub timestamp ---
64- def format_timestamp (ts ):
65- """Convert GitHub timestamp to 'YYYY-MM-DD HH:MM:SS' format."""
66- if not ts :
67- return None
68- try :
69- dt = datetime .strptime (ts , "%Y-%m-%dT%H:%M:%SZ" )
70- return dt .strftime ("%Y-%m-%d %H:%M:%S" )
71- except Exception :
72- return ts # fallback
73-
7462# --- Verify GitHub webhook signature ---
7563def verify_github_signature (payload_body , signature , secret ):
7664 if not secret :
@@ -92,15 +80,15 @@ def github_webhook():
9280 signature = request .headers .get ("X-Hub-Signature-256" )
9381 secret = os .getenv ("GITHUB_WEBHOOK_SECRET" )
9482
95- # Debug logging
83+ # --- Debug logging ---
9684 print ("π₯ Incoming GitHub webhook" )
9785 print (f"π₯ Payload size: { len (payload_body )} bytes" )
9886 print (f"π₯ GitHub Event: { request .headers .get ('X-GitHub-Event' )} " )
9987 print (f"π₯ Signature header: { signature } " )
10088 print (f"π₯ Secret length: { len (secret ) if secret else 'None' } " )
10189
10290 if not verify_github_signature (payload_body , signature , secret ):
103- print ("β Invalid signature! Webhook rejected." )
91+ print (f "β Invalid signature! Webhook rejected." )
10492 return "β Invalid signature" , 401
10593
10694 try :
@@ -112,34 +100,35 @@ def github_webhook():
112100 event = request .headers .get ("X-GitHub-Event" , "" )
113101
114102 if event == "repository" and data .get ("action" ) in ["created" , "deleted" ]:
115- repo = data .get ("repository" , {})
116- action = data ["action" ]
117-
118- repo_name = repo .get ("name" )
119- full_name = repo .get ("full_name" )
120- org = repo .get ("owner" , {}).get ("login" )
121- owner_id = repo .get ("owner" , {}).get ("id" )
122- default_branch = repo .get ("default_branch" )
123- created_at = format_timestamp (repo .get ("created_at" ))
124- updated_at = format_timestamp (repo .get ("updated_at" ))
125- html_url = repo .get ("html_url" )
126-
127- subject = f"[GitHub Alert] Repository { action } : { full_name } "
128- body = f"""
129- A repository was { action } in your GitHub organization.
130-
131- Repository: { repo_name }
132- Full name: { full_name }
133- Organization: { org }
134- Owner ID: { owner_id }
135- Default branch: { default_branch }
136- Created at: { created_at }
137- Last updated: { updated_at }
138- URL: { html_url }
139- """
103+ repo = data ["repository" ]
104+ repo_name = repo ["full_name" ]
105+ visibility_icon = "π Private" if repo .get ("private" ) else "π Public"
106+ owner = repo ["owner" ]["login" ]
107+ default_branch = repo .get ("default_branch" , "N/A" )
108+ created_at = repo .get ("created_at" )
109+ updated_at = repo .get ("updated_at" )
110+ url = repo .get ("html_url" , "" )
111+
112+ # Remove T and Z from timestamps
113+ if created_at :
114+ created_at = created_at .replace ("T" , " " ).replace ("Z" , "" )
115+ if updated_at :
116+ updated_at = updated_at .replace ("T" , " " ).replace ("Z" , "" )
117+
118+ subject = f"[GitHub Alert] Repository { data ['action' ]} : { repo_name } "
119+ body = (
120+ f"A repository was { data ['action' ]} in your GitHub organization.\n \n "
121+ f"π Repository Name: { repo_name } \n "
122+ f"{ visibility_icon } \n "
123+ f"π€ Owner: { owner } \n "
124+ f"πΏ Default branch: { default_branch } \n "
125+ f"π Created at: { created_at } \n "
126+ f"π Last updated: { updated_at } \n "
127+ f"π URL: { url } \n "
128+ )
140129
141130 print (f"π© Sending email alert: { subject } " )
142- send_email_via_graph (subject , body . strip () )
131+ send_email_via_graph (subject , body )
143132 else :
144133 print (f"βΉοΈ Ignored event: { event } , action: { data .get ('action' )} " )
145134
@@ -156,8 +145,8 @@ def health_check():
156145 print ("πΉ TEST_MODE: sending test email" )
157146 send_email_via_graph (
158147 "[Test] Graph Email" ,
159- "The information of Quantori's GitHub repositories has been updated"
148+ "π Repository Name: quantori/sadsrepo \n π Visibility: Private \n π€ Owner: quantori \n πΏ Default branch: main \n π Created at: 2025-09-09 13:06:02 \n π Last updated: 2025-09-09 13:09:20 \n π URL: https://github.com/quantori/sadsrepo "
160149 )
161150 else :
162151 print ("β
Flask is up and listening on /webhook and /health" )
163- app .run (host = "0.0.0.0" , port = int ( os . getenv ( "PORT" , 8000 )) )
152+ app .run (host = "0.0.0.0" , port = 8000 )
0 commit comments