Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions .github/workflows/summarise_upcoming_events.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
name: Summarise Upcoming Meetup Events

on:
pull_request:
types: [opened, synchronize, reopened ]
workflow_dispatch:
schedule:
- cron: '0 7 * * 1' # Monday at 7am GMT

jobs:
summarise_events_with_llms:
summarise_events_with_llm:
if: github.repository == 'Women-Coding-Community/WomenCodingCommunity.github.io'
runs-on: ubuntu-latest

Expand Down Expand Up @@ -35,7 +37,8 @@ jobs:
- name: Run summary script
run: |
cd tools/llm_meetup_summary
python summarise_events_with_llms.py --channel events
if [ -z "$OPENAI_API_KEY" ]; then echo "Error: OPENAI_API_KEY is not set"; exit 1; fi
python llm_event_summary.py --channel events
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}
SLACK_BOT_WEBHOOK: ${{ secrets.SLACK_BOT_WEBHOOK }}
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ tools/blog_automation/service_account_key.json
tools/blog_automation/venv
.env
tools/llm_meetup_summary/venv
tools/llm_meetup_summary/examples/current_prompt.md

# A .secrets file can be used for locally testing a .GitHub Action
tools/llm_meetup_summary/.secrets

# Claude Code local settings (may contain personal preferences)
.claude/settings.local.json
Expand Down
118 changes: 0 additions & 118 deletions tools/llm_meetup_summary/examples/current_prompt.md

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@

dotenv.load_dotenv()

OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
if not OPENAI_API_KEY:
raise KeyError("OPENAI_API_KEY is not set in environment variables")

# Get current folder
current_folder = os.path.dirname(os.path.abspath(__file__))

Expand All @@ -18,39 +22,10 @@
MODEL = "gpt-4.1-nano"
REQUIRED_EVENT_FIELDS = ['title', 'description', 'date', 'time', 'link']

try:
SLACK_TEST_WEBHOOK= os.getenv('SLACK_BOT_TEST_WEBHOOK')
SLACK_WEBHOOK= os.getenv('SLACK_BOT_WEBHOOK')
except KeyError as e:
raise KeyError(f"Environment variable not set: {e}")

# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

def summarise_events_with_llm(events_file=EVENTS_FILE):
try:
events = _load_events(events_file)
future_events = _filter_future_events(events)

print("Future Events:\n", future_events)

if not future_events:
logger.warning("No future events found")
return "No upcoming events scheduled."

formatted_events = _format_events_as_markdown(future_events)

print("Formatted Events for LLM:\n", formatted_events[:2000])

llm_summary = _get_llm_summary(formatted_events)
except Exception as e:
logger.error(f"Error summarizing events: {e}", exc_info=True)
raise

formatted_summary = _format_for_slack(llm_summary)
return formatted_summary

def _load_events(events_file):
try:
with open(events_file) as f:
Expand Down Expand Up @@ -151,7 +126,7 @@ def _get_llm_summary(formatted_events):

response = openai.chat.completions.create(
model=MODEL,
messages=[{"role": "user", "content": prompt}]
messages=[{"role": "user", "content": prompt}],
)

summary = response.choices[0].message.content
Expand All @@ -170,15 +145,37 @@ def _format_for_slack(text):
text = re.sub(r'\[([^\]]+)\]\(([^)]+)\)', r'<\2|\1>', text)
return text

def _post_to_slack(message, slack_webhook_url=SLACK_TEST_WEBHOOK):
if not slack_webhook_url:
raise ValueError("SLACK_SUMMARY_WEBHOOK not set in environment variables")

def _post_to_slack(message, slack_webhook_url):
response = requests.post(slack_webhook_url, json={'text': message})
response.raise_for_status()
logger.info("Message posted to Slack successfully")

def load_events_and_summarise(events_file=EVENTS_FILE):
try:
events = _load_events(events_file)
future_events = _filter_future_events(events)

print("Future Events:\n", future_events)

if not future_events:
logger.warning("No future events found")
return "No upcoming events scheduled."

formatted_events = _format_events_as_markdown(future_events)

llm_summary = _get_llm_summary(formatted_events)
except Exception as e:
logger.error(f"Error summarizing events: {e}", exc_info=True)
raise

formatted_summary = _format_for_slack(llm_summary)
return formatted_summary

if __name__ == "__main__":
dotenv.load_dotenv()

print('Enter main function')

parser = argparse.ArgumentParser(description="Summarise upcoming Meetup events and post to Slack.")
parser.add_argument(
"--channel",
Expand All @@ -190,15 +187,20 @@ def _post_to_slack(message, slack_webhook_url=SLACK_TEST_WEBHOOK):
args = parser.parse_args()

test_mode_activated = args.channel == "test-meetup-summaries"

if test_mode_activated:
slack_webhook_url = SLACK_TEST_WEBHOOK
logger.info("Running in test mode.")
SLACK_WEBHOOK= os.getenv('SLACK_BOT_TEST_WEBHOOK')
else:
slack_webhook_url = SLACK_WEBHOOK
logger.info("Running in production mode.")
SLACK_WEBHOOK= os.getenv('SLACK_BOT_WEBHOOK')

if SLACK_WEBHOOK is None:
raise KeyError("SLACK_BOT_TEST_WEBHOOK or SLACK_BOT_WEBHOOK must be set in environment variables")

try:
summary = summarise_events_with_llm(args.events_file)
_post_to_slack(summary, slack_webhook_url)
summary = load_events_and_summarise(args.events_file)
_post_to_slack(summary, slack_webhook_url=SLACK_WEBHOOK)
except Exception as e:
logger.error(f"Failed to summarize and post events: {e}", exc_info=True)
raise
4 changes: 2 additions & 2 deletions tools/llm_meetup_summary/tests/tests.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from llm_meetup_summary.summarise_events_with_llms import summarize_meetup_events_with_llms
from tools.llm_meetup_summary.llm_event_summary import summarize_meetup_events_with_llms

import pytest
from unittest.mock import patch, mock_open, MagicMock
Expand All @@ -11,7 +11,7 @@
# Add parent directory to path for absolute imports
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from llm_meetup_summary.summarise_events_with_llms import (
from tools.llm_meetup_summary.llm_event_summary import (
_get_llm_summary,
_format_for_slack,
_validate_event,
Expand Down
Loading