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
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,8 @@ terraform.tfstate
terraform.tfstate.backup
*.env
src/requirements.txt


.structurizr/
docs/c4/index/
docs/c4/logs/
10 changes: 10 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: v0.14.10
hooks:
# Run the linter.
- id: ruff-check
args: [--fix]
# Run the formatter.
- id: ruff-format
2 changes: 2 additions & 0 deletions config/production/config.yaml.example
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,5 @@ JOURNAL_FILE: journal.org
AUTHORIZED_CHAT_IDS: "888888888"
IGNORED_CHAT_IDS: "1234567890"
FORWARD_UNAUTHORIZED_TO: "999999999"

SENTRY_DSN: "https://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@xxxxxxxxxxxxxxxxx.ingest.de.sentry.io/7777777777777777"
8 changes: 8 additions & 0 deletions config/production/secrets.env.example
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
GCP_ACCOUNT=example@gmail.com
GCP_PROJECT_NAME=bot-org

# GitHub Settings
GITHUB_TOKEN=github_pat_your_token_here
GITHUB_REPO=username/repo-name

# Org Settings (optional, defaults shown)
# ORG_JOURNAL_FILE=journal.md
# ORG_TODO_FILE=todo.org
10 changes: 9 additions & 1 deletion dev.env
Original file line number Diff line number Diff line change
@@ -1,2 +1,10 @@
# Bot Settings
BOT_TOKEN=9999999999:AAAAAAAAAAA999aaaaaaaaaaaaaaaaaaaaa
GITHUB_TOKEN=github_pat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

# GitHub Settings
GITHUB_TOKEN=github_pat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
GITHUB_REPO=iamkarlson/my-notes

# Org Settings (optional, defaults shown)
ORG_JOURNAL_FILE=journal.md
ORG_TODO_FILE=todo.org
9 changes: 9 additions & 0 deletions docs/c4/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
services:
structurizr:
#image: structurizr/onpremises
image: structurizr/lite
ports:
- "8080:8080"
volumes:
- .:/usr/local/structurizr
container_name: structurizr
292 changes: 292 additions & 0 deletions docs/c4/workspace.dsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,292 @@
workspace "Org Bot" "Architecture model for Org Bot system" {

model {
user = person "Beatiful you" "Telegram user interacting with the bot"

terraform = softwareSystem "Terraform" "IaC for provisioning and managing cloud resources"

orgBot = softwareSystem "Org Bot" "Telegram bot for managing org-mode notes and journal entries" {

main = container "Main" "Entry point for the bot application" "Python" {
tags "Container"

httpEntrypoint = component "HTTP Entrypoint" "GCP Cloud Function handler for incoming webhooks" "Python" {
tags "Component"
}

botInitializer = component "Bot Initializer" "Creates and manages bot instances" "Python" {
tags "Component"
}

messageHandler = component "Message Handler" "Handles incoming Telegram messages" "Python" {
tags "Component"
}

messageProcessor = component "Message Processor" "Processes commands and non-command messages" "Python" {
tags "Component"
}

messageSender = component "Message Sender" "Sends responses back to Telegram" "Python" {
tags "Component"
}

sentryInit = component "Sentry Initialization" "Initializes error tracking" "Python" {
tags "Component"
}
}

config = container "Config" "Configuration management" "Python" {
tags "Container"

commandInit = component "Command Initialization" "Initializes bot commands" "Python" {
tags "Component"
}

actionConfig = component "Action Configuration" "Configures journal, todo, and reply actions" "Python" {
tags "Component"
}

envConfig = component "Environment Configuration" "Loads environment variables" "Python" {
tags "Component"
}
}

auth = container "Auth" "Authentication and authorization" "Python" {
tags "Container"

authCheck = component "Authorization Check" "Validates if message comes from authorized chat" "Python" {
tags "Component"
}

ignoreCheck = component "Ignore Check" "Checks if message comes from ignored chat" "Python" {
tags "Component"
}

unauthorizedForwarder = component "Unauthorized Forwarder" "Forwards unauthorized messages to admin" "Python" {
tags "Component"
}
}

orgApi = container "Org API" "API for org-mode operations" "Python" {
tags "Container"

initializer = component "Initializer" "Initializes org API client" "Python" {
tags "Component"
}

entryFinder = component "Entry Finder" "Finds entries in org files by message links" "Python" {
tags "Component"
}

topLevelFinder = component "Top Level Finder" "Finds top-level non-reply entries" "Python" {
tags "Component"
}

replyInserter = component "Reply Inserter" "Inserts replies at correct org hierarchy position" "Python" {
tags "Component"
}

fileCreator = component "File Creator" "Creates new files in repository" "Python" {
tags "Component"
}

textAppender = component "Text Appender" "Appends text to org files" "Python" {
tags "Component"
}
}

utils = container "Utils" "Utility functions" "Python" {
tags "Container"

messageTextExtractor = component "Message Text Extractor" "Extracts text from various message types" "Python" {
tags "Component"
}
}

baseCommand = container "Base Command" "Base class for bot commands" "Python" {
tags "Container"

commandBase = component "Command Base" "Abstract base class for all commands" "Python" {
tags "Component"
}
}

commands = container "Commands" "Bot command handlers module" "Python" {
tags "Module"

startCommand = component "Start Command" "Handles /start command" "Python" {
tags "Component"
}

infoCommand = component "Info Command" "Handles /info command" "Python" {
tags "Component"
}

webhookCommand = component "Webhook Command" "Handles webhook operations" "Python" {
tags "Component"
}

}

actions = container "Actions" "Journal, todo, and reply actions module" "Python" {
tags "Module"
postToJournal = component "Post to Journal" "Handles posting entries to journal" "Python" {
tags "Component"
}

postToTodo = component "Post to Todo" "Handles posting entries to todo list" "Python" {
tags "Component"
}

postReply = component "Post Reply" "Handles posting replies to entries" "Python" {
tags "Component"
}
}

tracing = container "Tracing" "Logging and tracing module" "Python" {
tags "Module"

gcp_log = component "Log" "Logging utilities" "Python" {
tags "Component"
}
}
}

# Relationships - System Level
user -> orgBot "Interacts with"
orgBot -> terraform "Deployed using"

# Relationships - Container Level
main -> commands
main -> config "Get / commands"
main -> config "Get actions"
main -> auth
main -> orgApi
main -> utils
main -> gcp_log "Configure GCP structured logging"

commands -> tracing "Uses for logging"

actions -> tracing "Uses for logging"

orgApi -> config
auth -> config

# Relationships - Component Level (Main)
httpEntrypoint -> messageHandler "Delegates to"
messageHandler -> authCheck "Checks authorization"
messageHandler -> messageProcessor "Processes message"
messageProcessor -> commandInit "Gets commands"
messageProcessor -> actionConfig "Gets actions"
messageProcessor -> messageTextExtractor "Extracts text"
messageHandler -> messageSender "Sends response"
messageSender -> botInitializer "Gets bot instance"

# Relationships - Component Level (Config)
commandInit -> envConfig
actionConfig -> envConfig

# Relationships - Component Level (Auth)
authCheck -> envConfig
authCheck -> unauthorizedForwarder "Forwards unauthorized"
ignoreCheck -> envConfig

# Relationships - Component Level (Org API)
entryFinder -> topLevelFinder "Finds parent"
replyInserter -> entryFinder
replyInserter -> topLevelFinder
textAppender -> fileCreator "May create file"

# Relationships - Component Level (Base Command)
commandBase -> initializer

# Relationships - Component Level (Commands)
startCommand -> commandBase "Extends"
infoCommand -> commandBase "Extends"
webhookCommand -> commandBase "Extends"

# Relationships - Component Level (Actions)
postToJournal -> commandBase "Extends"
postToJournal -> textAppender "Appends text to journal.org"

postToTodo -> commandBase "Extends"
postToTodo -> textAppender "Appends text to todo.org"

postReply -> commandBase "Extends"
postReply -> replyInserter "Inserts reply"
}

views {
systemContext orgBot "SystemContext" {
include *
}

container orgBot "Containers" {
include *
}

component main "MainComponents" {
include *
}

component config "ConfigComponents" {
include *
}

component auth "AuthComponents" {
include *
}

component orgApi "OrgApiComponents" {
include *
}

component utils "UtilsComponents" {
include *
}

component baseCommand "BaseCommandComponents" {
include *
}

component commands "CommandsComponents" {
include *
}

component actions "ActionsComponents" {
include *
}

component tracing "TracingComponents" {
include *
}

styles {
element "Software System" {
background #1168bd
color #ffffff
}
element "Container" {
background #438dd5
color #ffffff
}
element "Module" {
background #85bbf0
color #000000
}
element "Component" {
background #a5c9f5
color #000000
}
element "Person" {
shape person
background #08427b
color #ffffff
}
}

theme https://static.structurizr.com/themes/google-cloud-platform-v1.5/theme.json

}

}
Loading
Loading