Enable bot responses to ourselves

This commit is contained in:
Jack Kingsman
2026-01-29 12:15:30 -08:00
parent bcde4dd12e
commit 302973cc44
10 changed files with 36 additions and 28 deletions
+2 -6
View File
@@ -225,7 +225,7 @@ async def run_bot_for_message(
is_outgoing: bool = False, is_outgoing: bool = False,
) -> None: ) -> None:
""" """
Run all enabled bots for an incoming message. Run all enabled bots for a message (incoming or outgoing).
This is the main entry point called by message handlers after This is the main entry point called by message handlers after
a message is successfully decrypted and stored. Bots run serially, a message is successfully decrypted and stored. Bots run serially,
@@ -240,12 +240,8 @@ async def run_bot_for_message(
channel_name: Channel name (e.g. "#general"), None for DMs channel_name: Channel name (e.g. "#general"), None for DMs
sender_timestamp: Sender's timestamp from the message sender_timestamp: Sender's timestamp from the message
path: Hex-encoded routing path path: Hex-encoded routing path
is_outgoing: Whether this is our own outgoing message (skip bot) is_outgoing: Whether this is our own outgoing message
""" """
# Don't respond to our own outgoing messages
if is_outgoing:
return
# Early check if any bots are enabled (will re-check after sleep) # Early check if any bots are enabled (will re-check after sleep)
from app.repository import AppSettingsRepository from app.repository import AppSettingsRepository
+3 -3
View File
@@ -322,8 +322,8 @@ async def create_dm_message_from_decrypted(
# Update contact's last_contacted timestamp (for sorting) # Update contact's last_contacted timestamp (for sorting)
await ContactRepository.update_last_contacted(conversation_key, received) await ContactRepository.update_last_contacted(conversation_key, received)
# Run bot if enabled (for incoming DMs only, not historical decryption or outgoing) # Run bot if enabled (for all real-time DMs, including our own outgoing messages)
if trigger_bot and not outgoing: if trigger_bot:
from app.bot import run_bot_for_message from app.bot import run_bot_for_message
# Get contact name for the bot # Get contact name for the bot
@@ -339,7 +339,7 @@ async def create_dm_message_from_decrypted(
channel_name=None, channel_name=None,
sender_timestamp=decrypted.timestamp, sender_timestamp=decrypted.timestamp,
path=path, path=path,
is_outgoing=False, is_outgoing=outgoing,
) )
return msg_id return msg_id
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -13,7 +13,7 @@
<link rel="shortcut icon" href="/favicon.ico" /> <link rel="shortcut icon" href="/favicon.ico" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" /> <link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" /> <link rel="manifest" href="/site.webmanifest" />
<script type="module" crossorigin src="/assets/index-BtBXI4sW.js"></script> <script type="module" crossorigin src="/assets/index-DIU0_HcJ.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DiCOP9Mw.css"> <link rel="stylesheet" crossorigin href="/assets/index-DiCOP9Mw.css">
</head> </head>
<body> <body>
+9 -1
View File
@@ -871,7 +871,15 @@ export function SettingsModal({
<div className="p-3 bg-yellow-500/10 border border-yellow-500/30 rounded-md"> <div className="p-3 bg-yellow-500/10 border border-yellow-500/30 rounded-md">
<p className="text-sm text-yellow-500"> <p className="text-sm text-yellow-500">
<strong>Security Warning:</strong> This feature executes arbitrary Python code on <strong>Security Warning:</strong> This feature executes arbitrary Python code on
the server. Only enable if you understand the security implications. the server. Only run trusted code, and be cautious of arbitrary usage of message
parameters.
</p>
</div>
<div className="p-3 bg-yellow-500/10 border border-yellow-500/30 rounded-md">
<p className="text-sm text-yellow-500">
<strong>Don&apos;t wreck the mesh!</strong> Bots process ALL messages, including
their own. Be careful of creating infinite loops!
</p> </p>
</div> </div>
+8 -4
View File
@@ -344,9 +344,13 @@ class TestRunBotForMessage:
yield yield
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_skips_outgoing_messages(self): async def test_runs_for_outgoing_messages(self):
"""Bot is not triggered for outgoing messages.""" """Bot is triggered for outgoing messages (user can trigger their own bots)."""
with patch("app.repository.AppSettingsRepository") as mock_repo: with patch("app.repository.AppSettingsRepository") as mock_repo:
mock_settings = MagicMock()
mock_settings.bots = [] # No enabled bots, but settings ARE checked
mock_repo.get = AsyncMock(return_value=mock_settings)
await run_bot_for_message( await run_bot_for_message(
sender_name="Me", sender_name="Me",
sender_key="abc123", sender_key="abc123",
@@ -356,8 +360,8 @@ class TestRunBotForMessage:
is_outgoing=True, is_outgoing=True,
) )
# Should not even check settings # Should check settings (outgoing no longer skipped)
mock_repo.get.assert_not_called() mock_repo.get.assert_called_once()
@pytest.mark.asyncio @pytest.mark.asyncio
async def test_skips_when_no_enabled_bots(self): async def test_skips_when_no_enabled_bots(self):