From 431e5c63aa269c9b5836fd5915db8340294aebb6 Mon Sep 17 00:00:00 2001 From: armistace Date: Wed, 4 Jun 2025 16:56:08 +1000 Subject: [PATCH] first pass at docker run --- .gitignore | 1 + n8n_test.sh | 4 +++ requirements.txt | 1 + src/ai_generators/ollama_md_generator.py | 10 ++++++ src/main.py | 30 ++++++++++++++++ src/notifications/__init__.py | 0 src/notifications/n8n.py | 45 ++++++++++++++++++++++++ src/test_n8n.py | 16 +++++++++ 8 files changed, 107 insertions(+) create mode 100755 n8n_test.sh create mode 100644 src/notifications/__init__.py create mode 100644 src/notifications/n8n.py create mode 100644 src/test_n8n.py diff --git a/.gitignore b/.gitignore index 9ede049..876d65e 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ __pycache__ pyproject.toml .ropeproject generated_files/* +pyright* diff --git a/n8n_test.sh b/n8n_test.sh new file mode 100755 index 0000000..2d2d499 --- /dev/null +++ b/n8n_test.sh @@ -0,0 +1,4 @@ +export N8N_SECRET='11ECjor0@iM9CR3XxEn2GkNl' +export N8N_WEBHOOK_URL='http://192.168.178.159:5678/webhook-test/e054ae2d-95d0-4999-9cc7-6f8fa0d44c8f' + +python src/test_n8n.py diff --git a/requirements.txt b/requirements.txt index 116f45e..a508493 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,3 +4,4 @@ gitpython PyGithub chromadb langchain-ollama +PyJWT diff --git a/src/ai_generators/ollama_md_generator.py b/src/ai_generators/ollama_md_generator.py index c70c790..c2e430a 100644 --- a/src/ai_generators/ollama_md_generator.py +++ b/src/ai_generators/ollama_md_generator.py @@ -154,9 +154,19 @@ class OllamaGenerator: with open(filename, "w") as f: f.write(self.generate_markdown()) + # TODO: Make this generic a "create message for system" if you will + # This will allow me to control the system and human prompt at the client + # level rather than having to play within the class def generate_commit_message(self): prompt_system = "You are a blog creator commiting a piece of content to a central git repo" prompt_human = f"Generate a 5 word git commit message describing {self.response}" messages = [("system", prompt_system), ("human", prompt_human),] commit_message = self.llm.invoke(messages).text() return commit_message + + def generate_notification_summary(self): + prompt_system = "You are a blog creator notifiying the final editor of the final creation of blog" + prompt_human = f"Generate a 50 word summary describing {self.response}" + messages = [("system", prompt_system), ("human", prompt_human),] + notification_message = self.llm.invoke(messages).text() + return notification_message diff --git a/src/main.py b/src/main.py index 07817fc..9be942e 100644 --- a/src/main.py +++ b/src/main.py @@ -1,7 +1,10 @@ import ai_generators.ollama_md_generator as omg import trilium.notes as tn import repo_management.repo_manager as git_repo +from notifications.n8n import N8NWebhookJwt import string,os +from datetime import datetime + tril = tn.TrilumNotes() @@ -26,9 +29,36 @@ for note in tril_notes: tril_notes[note]['title']) blog_path = f"/blog_creator/generated_files/{os_friendly_title}.md" ai_gen.save_to_file(blog_path) + + # Generate commit messages and push to repo commit_message = ai_gen.generate_commit_message() git_user = os.environ["GIT_USER"] git_pass = os.environ["GIT_PASS"] repo_manager = git_repo.GitRepository("blog/", git_user, git_pass) repo_manager.create_copy_commit_push(blog_path, os_friendly_title, commit_message) + + # Generate notification for Matrix + notification_message = ai_gen.generate_notification_summary() + secret_key = os.environ['N8N_SECRET'] + webhook_url = os.environ['N8N_WEBHOOK_URL'] + git_branch_url = f'https://git.aridgwayweb.com/armistace/blog/src/branch/{os_friendly_tile}' + notification_string = f""" +

{tril_notes[note]['title']}

+

Summary

+

{notification_message}

+

Branch

+

{os_friendly_title}

+

Link to Branch

+ """ + + payload = { + "message": f"{notification_string}", + "timestamp": datetime.now().isoformat() + } + + webhook_client = N8NWebhookJwt(secret_key, webhook_url) + + n8n_result = webhook_client.send_webhook(payload) + + print(f"N8N response: {n8n_result}") diff --git a/src/notifications/__init__.py b/src/notifications/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/notifications/n8n.py b/src/notifications/n8n.py new file mode 100644 index 0000000..d9f4b3e --- /dev/null +++ b/src/notifications/n8n.py @@ -0,0 +1,45 @@ +from datetime import datetime, timedelta +import jwt +import requests +from typing import Dict, Optional + +class N8NWebhookJwt: + def __init__(self, secret_key: str, webhook_url: str): + self.secret_key = secret_key + self.webhook_url = webhook_url + self.token_expiration = datetime.now() + timedelta(hours=1) + + def _generate_jwt_token(self, payload: Dict) -> str: + """Generate JWT token with the given payload.""" + # Include expiration time (optional) + payload["exp"] = self.token_expiration.timestamp() + encoded_jwt = jwt.encode( + payload, + self.secret_key, + algorithm="HS256", + ) + return encoded_jwt #jwt.decode(encoded_jwt, self.secret_key, algorithms=['HS256']) + + def send_webhook(self, payload: Dict) -> Dict: + """Send a webhook request with JWT authentication.""" + # Generate JWT token + token = self._generate_jwt_token(payload) + + # Set headers with JWT token + headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "application/json" + } + + # Send POST request + response = requests.post( + self.webhook_url, + json=payload, + headers=headers + ) + + # Handle response + if response.status_code == 200: + return {"status": "success", "response": response.json()} + else: + return {"status": "error", "response": response.status_code, "message": response.text} diff --git a/src/test_n8n.py b/src/test_n8n.py new file mode 100644 index 0000000..3e485b8 --- /dev/null +++ b/src/test_n8n.py @@ -0,0 +1,16 @@ +import os +from datetime import datetime +from notifications.n8n import N8NWebhookJwt + +secret_key = os.environ['N8N_SECRET'] +webhook_url = os.environ['N8N_WEBHOOK_URL'] + +payload = { + "message": "Hello, N8N webhook with JWT!", + "timestamp": datetime.now().isoformat() +} + +webhook_client = N8NWebhookJwt(secret_key, webhook_url) + +result = webhook_client.send_webhook(payload) +print(result['status'])