Skip to content

Commit

Permalink
feat: port to kook
Browse files Browse the repository at this point in the history
Signed-off-by: jingfelix <[email protected]>
  • Loading branch information
jingfelix committed Mar 11, 2024
1 parent 921a8dd commit 773579e
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 343 deletions.
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ ENV PYTHONUNBUFFERED=1

# Install pip requirements
COPY requirements.txt .
RUN python -m pip install --no-cache-dir --upgrade repo2lark
RUN python -m pip install --no-cache-dir --upgrade repo2kook

CMD ["uvicorn", "repo2lark:app", "--port", "3030", "--host", "0.0.0.0", "--workers", "4"]
CMD ["uvicorn", "repo2kook:app", "--port", "3030", "--host", "0.0.0.0", "--workers", "4"]
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<div align="center">
<h1>Repo2Lark</h1>
<h1>Repo2Kook</h1>
<a href="https://pypi.org/project/Repo2Lark/"><img src="https://img.shields.io/pypi/v/Repo2Lark" alt="PyPI"></a>
<!-- <a href="https://pypi.org/project/Repo2Lark/"><img src="https://img.shields.io/pypi/pyversions/Repo2Lark" alt="PyPI - Python Version"></a> -->
<a href="https://github.com/jingfelix/Repo2Lark/blob/main/LICENSE"><img src="https://img.shields.io/pypi/l/Repo2Lark" alt="PyPI - License"></a>
<a href="https://pdm-project.org"><img src="https://img.shields.io/badge/pdm-managed-blueviolet" alt="pdm-managed"></a>
<a href="https://zeabur.com?referralCode=jingfelix"><img src="https://img.shields.io/badge/zeabur-deployed-6300FF" alt="Zeabur-Deployed"></a>
<div>
优雅地转发 GitHub Webhook 事件到飞书
优雅地转发 GitHub Webhook 事件到 Kook
</div>
</div>

Expand Down
12 changes: 6 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[project]
name = "Repo2Lark"
version = "0.0.2"
description = "Default template for PDM package"
name = "Repo2Kook"
version = "0.0.1"
description = "Send GitHub Webhook to Kook"
authors = [
{name = "jingfelix", email = "[email protected]"},
]
Expand All @@ -18,11 +18,11 @@ readme = "README.md"
license = {text = "GPLv3"}

[project.urls]
Homepage = "https://github.com/jingfelix/Repo2Lark"
"Bug Tracker" = "https://github.com/jingfelix/Repo2Lark"
Homepage = "https://github.com/jingfelix/Repo2Kook"
"Bug Tracker" = "https://github.com/jingfelix/Repo2Kook"

[project.scripts]
repo2lark = "repo2lark.__init__:run"
repo2kook = "repo2kook.__init__:run"

[build-system]
requires = ["pdm-backend"]
Expand Down
6 changes: 3 additions & 3 deletions src/repo2lark/__init__.py → src/repo2kook/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

app = FastAPI(docs_url=None)

from repo2lark.middleware import VerifySignatureMiddleware
from repo2lark.router import router
from .middleware import VerifySignatureMiddleware
from .router import router

app.include_router(router)
app.add_middleware(VerifySignatureMiddleware)
Expand All @@ -12,4 +12,4 @@
def run():
import uvicorn

uvicorn.run("repo2lark:app", host="0.0.0.0", port=3030, reload=True)
uvicorn.run("repo2kook:app", host="0.0.0.0", port=3030, reload=True)
24 changes: 24 additions & 0 deletions src/repo2kook/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from functools import lru_cache

from pydantic_settings import BaseSettings


@lru_cache()
def get_settings():
return Settings()


class Settings(BaseSettings):
app_name: str = "r2kook"

kook_api_base_url: str = "https://www.kookapp.cn/api/v3"

kook_token: str = ""

github_webhook_secret: str = ""

class Config:
env_file = ".env"


settings = get_settings()
4 changes: 2 additions & 2 deletions src/repo2lark/middleware.py → src/repo2kook/middleware.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware

from repo2lark.config import settings
from repo2lark.utils import get_body, verify_signature
from .config import settings
from .utils import get_body, verify_signature


class VerifySignatureMiddleware(BaseHTTPMiddleware):
Expand Down
File renamed without changes.
52 changes: 20 additions & 32 deletions src/repo2lark/router.py → src/repo2kook/router.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import json
import urllib.parse as urlparse
from typing import Optional

from fastapi import APIRouter, BackgroundTasks, Request
from fastapi.exceptions import HTTPException

from repo2lark.config import settings
from repo2lark.models import IssueCommentEvent, IssueEvent, PREvent, PushEvent
from repo2lark.utils import send_to_lark, truncate
from .config import settings
from .models import IssueCommentEvent, IssueEvent, PREvent, PushEvent
from .utils import send_to_kook, truncate

router = APIRouter()


@router.post("/webhook")
@router.post("/open-apis/bot/v2/hook/{lark_webhook_token}")
# @router.post("/webhook")
# @router.post("/open-apis/bot/v2/hook/{lark_webhook_token}")
@router.post("/kook/{kook_channel_id}")
async def webhook(
request: Request,
lark_webhook_token: Optional[str] = None,
kook_channel_id: str = None,
background_tasks: BackgroundTasks = None,
):
headers = request.headers
Expand All @@ -25,7 +25,7 @@ async def webhook(
body = await request.body()
return await webhook_urlencoded(
request,
lark_webhook_token=lark_webhook_token,
kook_channel_id=kook_channel_id,
payload=body.decode("utf-8"),
background_tasks=background_tasks,
)
Expand All @@ -35,7 +35,7 @@ async def webhook(
payload = dict(urlparse.parse_qsl(body.decode("utf-8")))
return await webhook_urlencoded(
request,
lark_webhook_token=lark_webhook_token,
kook_channel_id=kook_channel_id,
payload=payload.get("payload", None),
background_tasks=background_tasks,
)
Expand All @@ -45,18 +45,14 @@ async def webhook(

async def webhook_urlencoded(
request: Request,
lark_webhook_token: Optional[str] = None,
kook_channel_id: str = None,
payload: str = None,
background_tasks: BackgroundTasks = None,
):
headers = request.headers

if lark_webhook_token is not None:
lark_webhook_url = settings.lark_webhook_base_url + lark_webhook_token
lark_webhook_secret = None
else:
lark_webhook_url = settings.lark_webhook_url
lark_webhook_secret = settings.lark_webhook_secret
if kook_channel_id is None:
raise HTTPException(status_code=400, detail="kook_channel_id cannot be None")

x_github_event = headers.get("X-GitHub-Event", None)
if x_github_event is None:
Expand All @@ -67,10 +63,8 @@ async def webhook_urlencoded(
params = PushEvent(**json.loads(payload))

background_tasks.add_task(
send_to_lark,
settings.push_template_id,
lark_webhook_url=lark_webhook_url,
lark_webhook_secret=lark_webhook_secret,
send_to_kook,
kook_channel_id=kook_channel_id,
variables={
"commiter": params.pusher.name,
"repository": params.repository.full_name,
Expand All @@ -87,10 +81,8 @@ async def webhook_urlencoded(
params = IssueEvent(**json.loads(payload))

background_tasks.add_task(
send_to_lark,
settings.issue_template_id,
lark_webhook_url=lark_webhook_url,
lark_webhook_secret=lark_webhook_secret,
send_to_kook,
kook_channel_id=kook_channel_id,
variables={
"action": params.action.capitalize(),
"repository": params.repository.full_name,
Expand All @@ -107,10 +99,8 @@ async def webhook_urlencoded(
params = IssueCommentEvent(**json.loads(payload))

background_tasks.add_task(
send_to_lark,
settings.issue_comment_template_id,
lark_webhook_url=lark_webhook_url,
lark_webhook_secret=lark_webhook_secret,
send_to_kook,
kook_channel_id=kook_channel_id,
variables={
"action": params.action.capitalize(),
"user": params.comment.user.login,
Expand All @@ -127,10 +117,8 @@ async def webhook_urlencoded(
params = PREvent(**json.loads(payload))

background_tasks.add_task(
send_to_lark,
settings.pr_template_id,
lark_webhook_url=lark_webhook_url,
lark_webhook_secret=lark_webhook_secret,
send_to_kook,
kook_channel_id=kook_channel_id,
variables={
"action": params.action.capitalize(),
"user": params.pull_request.user.login,
Expand Down
69 changes: 44 additions & 25 deletions src/repo2lark/utils.py → src/repo2kook/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from starlette.requests import Request
from starlette.types import Message

from .config import settings


def verify_signature(payload_body, secret_token, signature_header) -> None:
"""Verify that the payload was sent from GitHub by validating SHA256.
Expand Down Expand Up @@ -42,34 +44,51 @@ def gen_sign(timestamp, secret):
return sign


async def send_to_lark(
template_id: str, lark_webhook_url: str, lark_webhook_secret: str, variables: dict
) -> None:
data = {
"msg_type": "interactive",
"card": {
"type": "template",
"data": {
"template_id": template_id,
"template_variable": variables,
},
},
# async def send_to_lark(
# template_id: str, lark_webhook_url: str, lark_webhook_secret: str, variables: dict
# ) -> None:
# data = {
# "msg_type": "interactive",
# "card": {
# "type": "template",
# "data": {
# "template_id": template_id,
# "template_variable": variables,
# },
# },
# }
# if lark_webhook_secret != "" and lark_webhook_secret is not None:
# timestamp = str(int(time.time()))
# sign = gen_sign(timestamp, lark_webhook_secret)
# data["timestamp"] = timestamp
# data["sign"] = sign

# if lark_webhook_url == "" or lark_webhook_url is None:
# raise HTTPException(status_code=500, detail="lark_webhook_url is empty!")

# # TODO 增加超时和重试
# async with httpx.AsyncClient(timeout=15) as client:
# res = await client.post(lark_webhook_url, json=data)

# if res.status_code != 200 or res.json()["code"] != 0:
# raise HTTPException(status_code=500, detail=res.text)


async def send_to_kook(kook_channel_id: str, variables: dict) -> None:
"""Send card message to Kook."""

json = {
"type": 1,
"target_id": kook_channel_id,
"content": variables.get("action", "Action not Found"),
}
if lark_webhook_secret != "" and lark_webhook_secret is not None:
timestamp = str(int(time.time()))
sign = gen_sign(timestamp, lark_webhook_secret)
data["timestamp"] = timestamp
data["sign"] = sign

if lark_webhook_url == "" or lark_webhook_url is None:
raise HTTPException(status_code=500, detail="lark_webhook_url is empty!")

# TODO 增加超时和重试
async with httpx.AsyncClient(timeout=15) as client:
res = await client.post(lark_webhook_url, json=data)

if res.status_code != 200 or res.json()["code"] != 0:
raise HTTPException(status_code=500, detail=res.text)
res = await client.post(
f"{settings.kook_api_base_url}/message/create",
json=json,
headers={"Authorization": f"Bot {settings.kook_token}"},
)


def truncate(text: str, length: int = 80) -> str:
Expand Down
29 changes: 0 additions & 29 deletions src/repo2lark/config.py

This file was deleted.

Loading

0 comments on commit 773579e

Please sign in to comment.