diff --git a/skills/org-skill-credentials-vault.org b/skills/org-skill-credentials-vault.org index 9e9df26..483f821 100644 --- a/skills/org-skill-credentials-vault.org +++ b/skills/org-skill-credentials-vault.org @@ -102,6 +102,7 @@ This function is the secure getter for all system secrets. It prioritizes the Va (:groq "GROQ_API_KEY") (:openrouter "OPENROUTER_API_KEY") (:telegram "TELEGRAM_BOT_TOKEN") + (:signal "SIGNAL_ACCOUNT_NUMBER") (t nil)))) (when (and env-var (eq type :api-key)) (uiop:getenv env-var)))))) diff --git a/skills/org-skill-gateway-signal.org b/skills/org-skill-gateway-signal.org index a8989f6..4e3af56 100644 --- a/skills/org-skill-gateway-signal.org +++ b/skills/org-skill-gateway-signal.org @@ -43,10 +43,10 @@ Wraps the `signal-cli` binary. Polling is done in a background thread to prevent #+end_src ** State: Signal Identity -The primary account number used for communication. +Retrieves the Signal account number from the secure vault. #+begin_src lisp :tangle ../src/gateway-signal.lisp -(defvar *signal-account* "+13322690326") +(defun get-signal-account () (vault-get-secret :signal)) #+end_src ** State: Polling Thread @@ -65,11 +65,12 @@ Executes the `signal-cli send` command. (declare (ignore context)) (let* ((payload (getf action :payload)) (chat-id (or (getf payload :chat-id) (getf action :chat-id))) - (text (or (getf payload :text) (getf action :text)))) - (when (and chat-id text) + (text (or (getf payload :text) (getf action :text))) + (account (get-signal-account))) + (when (and account chat-id text) (kernel-log "SIGNAL: Sending message to ~a..." chat-id) (handler-case - (uiop:run-program (list "signal-cli" "-u" *signal-account* "send" "-m" text chat-id) + (uiop:run-program (list "signal-cli" "-u" account "send" "-m" text chat-id) :output :string :error-output :string) (error (c) (kernel-log "SIGNAL ERROR: ~a" c)))))) #+end_src @@ -80,26 +81,28 @@ Polls for new messages and injects them into the kernel. #+begin_src lisp :tangle ../src/gateway-signal.lisp (defun signal-process-updates () "Polls for new messages via signal-cli and injects them into the kernel." - (handler-case - (let* ((output (uiop:run-program (list "signal-cli" "-u" *signal-account* "receive" "--json") - :output :string :error-output :string :ignore-error-status t)) - (lines (cl-ppcre:split "\\n" output))) - (dolist (line lines) - (when (and line (> (length line) 0)) - (let* ((json (ignore-errors (cl-json:decode-json-from-string line))) - (envelope (cdr (assoc :envelope json))) - (source (cdr (assoc :source envelope))) - (data-message (cdr (assoc :data-message envelope))) - (text (cdr (assoc :message data-message)))) - (when (and source text) - (kernel-log "SIGNAL: Received message from ~a" source) - (inject-stimulus - (list :type :EVENT - :payload (list :sensor :chat-message - :channel :signal - :chat-id source - :text text)))))))) - (error (c) (kernel-log "SIGNAL POLL ERROR: ~a" c)))) + (let ((account (get-signal-account))) + (when account + (handler-case + (let* ((output (uiop:run-program (list "signal-cli" "-u" account "receive" "--json") + :output :string :error-output :string :ignore-error-status t)) + (lines (cl-ppcre:split "\\n" output))) + (dolist (line lines) + (when (and line (> (length line) 0)) + (let* ((json (ignore-errors (cl-json:decode-json-from-string line))) + (envelope (cdr (assoc :envelope json))) + (source (cdr (assoc :source envelope))) + (data-message (cdr (assoc :data-message envelope))) + (text (cdr (assoc :message data-message)))) + (when (and source text) + (kernel-log "SIGNAL: Received message from ~a" source) + (inject-stimulus + (list :type :EVENT + :payload (list :sensor :chat-message + :channel :signal + :chat-id source + :text text)))))))) + (error (c) (kernel-log "SIGNAL POLL ERROR: ~a" c)))))) #+end_src ** Start Polling diff --git a/src/credentials-vault.lisp b/src/credentials-vault.lisp index 039c32f..7c36e65 100644 --- a/src/credentials-vault.lisp +++ b/src/credentials-vault.lisp @@ -23,6 +23,7 @@ (:groq "GROQ_API_KEY") (:openrouter "OPENROUTER_API_KEY") (:telegram "TELEGRAM_BOT_TOKEN") + (:signal "SIGNAL_ACCOUNT_NUMBER") (t nil)))) (when (and env-var (eq type :api-key)) (uiop:getenv env-var)))))) diff --git a/src/gateway-signal.lisp b/src/gateway-signal.lisp index be8b574..700efee 100644 --- a/src/gateway-signal.lisp +++ b/src/gateway-signal.lisp @@ -1,6 +1,6 @@ (in-package :org-agent) -(defvar *signal-account* "+13322690326") +(defun get-signal-account () (vault-get-secret :signal)) (defvar *signal-polling-thread* nil) @@ -9,40 +9,43 @@ (declare (ignore context)) (let* ((payload (getf action :payload)) (chat-id (or (getf payload :chat-id) (getf action :chat-id))) - (text (or (getf payload :text) (getf action :text)))) - (when (and chat-id text) + (text (or (getf payload :text) (getf action :text))) + (account (get-signal-account))) + (when (and account chat-id text) (kernel-log "SIGNAL: Sending message to ~a..." chat-id) (handler-case - (uiop:run-program (list "signal-cli" "-u" *signal-account* "send" "-m" text chat-id) + (uiop:run-program (list "signal-cli" "-u" account "send" "-m" text chat-id) :output :string :error-output :string) (error (c) (kernel-log "SIGNAL ERROR: ~a" c)))))) (defun signal-process-updates () "Polls for new messages via signal-cli and injects them into the kernel." - (handler-case - (let* ((output (uiop:run-program (list "signal-cli" "-u" *signal-account* "receive" "--json") - :output :string :error-output :string :ignore-error-status t)) - (lines (cl-ppcre:split "\\n" output))) - (dolist (line lines) - (when (and line (> (length line) 0)) - (let* ((json (ignore-errors (cl-json:decode-json-from-string line))) - (envelope (cdr (assoc :envelope json))) - (source (cdr (assoc :source envelope))) - (data-message (cdr (assoc :data-message envelope))) - (text (cdr (assoc :message data-message)))) - (when (and source text) - (kernel-log "SIGNAL: Received message from ~a" source) - (inject-stimulus - (list :type :EVENT - :payload (list :sensor :chat-message - :channel :signal - :chat-id source - :text text)))))))) - (error (c) (kernel-log "SIGNAL POLL ERROR: ~a" c)))) + (let ((account (get-signal-account))) + (when account + (handler-case + (let* ((output (uiop:run-program (list "signal-cli" "-u" account "receive" "--json") + :output :string :error-output :string :ignore-error-status t)) + (lines (cl-ppcre:split "\\n" output))) + (dolist (line lines) + (when (and line (> (length line) 0)) + (let* ((json (ignore-errors (cl-json:decode-json-from-string line))) + (envelope (cdr (assoc :envelope json))) + (source (cdr (assoc :source envelope))) + (data-message (cdr (assoc :data-message envelope))) + (text (cdr (assoc :message data-message)))) + (when (and source text) + (kernel-log "SIGNAL: Received message from ~a" source) + (inject-stimulus + (list :type :EVENT + :payload (list :sensor :chat-message + :channel :signal + :chat-id source + :text text)))))))) + (error (c) (kernel-log "SIGNAL POLL ERROR: ~a" c)))))) (defun start-signal-gateway () "Initializes the Signal background thread." - (unless (and *signal-polling-thread* (bt:thread-alive-p *signal-polling-thread*)) + (unless (and *telegram-polling-thread* (bt:thread-alive-p *telegram-polling-thread*)) (setf *signal-polling-thread* (bt:make-thread (lambda ()