pr-webhook / index.py
hari-huynh
Add code to send mesage to specific thread in Slack
04417e3
from flask import Flask, request, jsonify
from tool import create_session, get_pull_request_overview, get_diff, send_slack_message, save_md_report, reply_slack_thread
from dotenv import load_dotenv
import os
from agent.code_review import code_review_agent, read_text_file, DiffDeps
# Set up ENVIRONMENT VARIABLE
load_dotenv()
WORKSPACE_ID = os.getenv("WORKSPACE_ID")
BITBUCKET_USERNAME = os.getenv("BITBUCKET_USERNAME")
BITBUCKET_APP_PASSWORD = os.getenv("BITBUCKET_APP_PASSWORD")
DEFAULT_BASE_URL = os.getenv("DEFAULT_BASE_URL")
REPO_SLUG = os.getenv("REPO_SLUG")
SLACK_WEBHOOK_URL = os.getenv("SLACK_WEBHOOK_URL")
SLACK_BOT_TOKEN = os.getenv("SLACK_BOT_TOKEN")
SLACK_CHANNEL = os.getenv("SLACK_CHANNEL")
app = Flask(__name__)
@app.route("/webhook", methods=["POST"])
def webhook():
event_key = request.headers.get("X-Event-Key") # ví dụ: pullrequest:created, repo:push
payload = request.json
print("=== Webhook Received ===")
print("Event:", event_key)
# Xử lý Pull Request event
if event_key and event_key.startswith("pullrequest"):
if payload and "pullrequest" in payload:
pr = payload["pullrequest"]
pr_info = {
"id": pr.get("id"),
"title": pr.get("title"),
"state": pr.get("state"),
"author": pr.get("author", {}).get("display_name"),
"source_branch": pr.get("source", {}).get("branch", {}).get("name"),
"destination_branch": pr.get("destination", {}).get("branch", {}).get("name"),
}
print("Pull Request Info:", pr_info)
# Chỉ xử lý khi có đủ thông tin PR
if pr_info["id"]:
try:
PR_ID = pr_info["id"]
session = create_session(BITBUCKET_USERNAME, BITBUCKET_APP_PASSWORD)
data = get_pull_request_overview(
session = session,
workspace = WORKSPACE_ID,
repo_slug = REPO_SLUG,
pr_id = PR_ID,
base_url = DEFAULT_BASE_URL
)
title = data["title"]
description = data["description"]
source_branch = data["source"]["branch"]["name"]
destination_branch = data["destination"]["branch"]["name"]
author = data["author"]["display_name"]
created_on = data["created_on"]
reviewers = data.get("reviewers", [])
reviewer_mentions = " ".join([f"@{r.get('nickname')}" for r in reviewers]) if reviewers else "None"
pr_link = data["links"]["html"]["href"]
changelog = data["summary"]["raw"]
diff_url = data["links"]["diff"]["href"]
# Tạo nội dung PR
pr_report = (
f"# [{REPO_SLUG}] PR #{PR_ID}: {title}\n"
f"*{description}*\n\n"
f"**🌿 Branch Information:**\n"
f"- **Source Branch:** {source_branch} → **Target Branch:** {destination_branch}\n\n"
f"**👤 Người tạo:** {author}\n\n"
f"**📅 Thời gian tạo:** {created_on}\n\n"
f"**👥 Reviewers:**\n{reviewer_mentions}\n\n"
f"**🔗 Link Pull Request:** {pr_link}\n"
)
print(pr_report)
# Lấy diff và chạy agent
diff = get_diff(session, diff_url)
print("Running Agent ...")
code_review_result = code_review_agent.run_sync("", deps = DiffDeps(diff = diff[:-10_000]))
code_review_text = getattr(code_review_result, "output", None) or str(code_review_result)
# Gộp thông tin PR + kết quả review vào 1 lần gửi
code_review_message = (
f"## 🤖 Code Review Summary\n\n"
f"{code_review_text}"
)
resp = send_slack_message(
message_text = pr_report,
webhook_url = SLACK_WEBHOOK_URL,
bot_token = SLACK_BOT_TOKEN,
channel = "pull-request",
blocks = [
{
"type": "markdown",
"text": pr_report
}
]
)
first_message_ts = resp["response"]["ts"] # lấy ts để trả lời sau
reply_slack_thread(
thread_ts=first_message_ts,
message_text=code_review_message,
channel="pull-request",
blocks = [
{
"type": "markdown",
"text": pr_report
}
]
)
print("Sent combined PR + code review")
return jsonify({"status": "ok", "message": "Pull request processed successfully"}), 200
except Exception as exc:
print("Error processing pull request:", str(exc))
return jsonify({"status": "error", "message": str(exc)}), 500
else:
return jsonify({"status": "error", "message": "Invalid pull request data"}), 400
else:
return jsonify({"status": "error", "message": "No pull request data in payload"}), 400
# Xử lý các event khác
elif event_key and event_key.startswith("repo"):
print("Repository event received:", event_key)
return jsonify({"status": "ok", "message": "Repository event received"}), 200
else:
print("Unknown event type:", event_key)
return jsonify({"status": "ok", "message": "Event received but not processed"}), 200
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860)