- Created caddyfile-docs-update.txt with Caddy basic auth configuration - Fixed documentation path from /home/klas/langmem-docs to /home/klas/langmem/docs - Added basic auth with credentials: langmem / langmem2025 - Created create-claude-matrix-user.md with user creation instructions - Added get-claude-token.py script for automated Matrix setup - Includes token retrieval, room joining, and configuration export Manual steps required: 1. Update /etc/caddy/Caddyfile with new docs.klas.chat config 2. Reload Caddy: sudo systemctl reload caddy 3. Create Claude Matrix user via admin panel 4. Run get-claude-token.py to complete setup 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
156 lines
5.3 KiB
Python
Executable File
156 lines
5.3 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Get access token for Claude Matrix user and join Home Assistant room
|
|
"""
|
|
|
|
import asyncio
|
|
import httpx
|
|
import json
|
|
|
|
MATRIX_HOMESERVER = "https://matrix.klas.chat"
|
|
CLAUDE_USERNAME = "claude"
|
|
CLAUDE_PASSWORD = "claude_assistant_2025"
|
|
HOME_ASSISTANT_ROOM_ID = "!xZkScMybPseErYMJDz:matrix.klas.chat"
|
|
|
|
async def login_and_get_token():
|
|
"""Login as Claude user and get access token"""
|
|
try:
|
|
async with httpx.AsyncClient() as client:
|
|
# Login request
|
|
response = await client.post(
|
|
f"{MATRIX_HOMESERVER}/_matrix/client/v3/login",
|
|
json={
|
|
"type": "m.login.password",
|
|
"user": CLAUDE_USERNAME,
|
|
"password": CLAUDE_PASSWORD
|
|
}
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
data = response.json()
|
|
access_token = data["access_token"]
|
|
user_id = data["user_id"]
|
|
|
|
print(f"✅ Successfully logged in as {user_id}")
|
|
print(f"🔑 Access Token: {access_token}")
|
|
|
|
return access_token, user_id
|
|
else:
|
|
print(f"❌ Login failed: {response.status_code}")
|
|
print(f"Response: {response.text}")
|
|
return None, None
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error during login: {e}")
|
|
return None, None
|
|
|
|
async def join_home_assistant_room(access_token):
|
|
"""Join the Home Assistant room"""
|
|
try:
|
|
async with httpx.AsyncClient() as client:
|
|
headers = {"Authorization": f"Bearer {access_token}"}
|
|
|
|
# Join room
|
|
response = await client.post(
|
|
f"{MATRIX_HOMESERVER}/_matrix/client/v3/join/{HOME_ASSISTANT_ROOM_ID}",
|
|
headers=headers
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
print(f"✅ Successfully joined Home Assistant room")
|
|
return True
|
|
else:
|
|
print(f"❌ Failed to join room: {response.status_code}")
|
|
print(f"Response: {response.text}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error joining room: {e}")
|
|
return False
|
|
|
|
async def send_test_message(access_token):
|
|
"""Send a test message to verify everything works"""
|
|
try:
|
|
async with httpx.AsyncClient() as client:
|
|
headers = {
|
|
"Authorization": f"Bearer {access_token}",
|
|
"Content-Type": "application/json"
|
|
}
|
|
|
|
message = "🤖 Hello! Claude Assistant is now connected to Matrix and ready to send you updates about your projects."
|
|
|
|
response = await client.post(
|
|
f"{MATRIX_HOMESERVER}/_matrix/client/v3/rooms/{HOME_ASSISTANT_ROOM_ID}/send/m.room.message",
|
|
headers=headers,
|
|
json={
|
|
"msgtype": "m.text",
|
|
"body": message
|
|
}
|
|
)
|
|
|
|
if response.status_code == 200:
|
|
print(f"✅ Test message sent successfully!")
|
|
return True
|
|
else:
|
|
print(f"❌ Failed to send test message: {response.status_code}")
|
|
print(f"Response: {response.text}")
|
|
return False
|
|
|
|
except Exception as e:
|
|
print(f"❌ Error sending test message: {e}")
|
|
return False
|
|
|
|
async def main():
|
|
"""Main function"""
|
|
print("🤖 Setting up Claude Matrix Integration")
|
|
print("=" * 50)
|
|
|
|
# Step 1: Login and get token
|
|
print("\n1. Logging in as Claude user...")
|
|
access_token, user_id = await login_and_get_token()
|
|
|
|
if not access_token:
|
|
print("\n❌ Cannot proceed without access token.")
|
|
print("Make sure the Claude user has been created first!")
|
|
return
|
|
|
|
# Step 2: Join Home Assistant room
|
|
print("\n2. Joining Home Assistant room...")
|
|
joined = await join_home_assistant_room(access_token)
|
|
|
|
if not joined:
|
|
print("\n❌ Cannot proceed without joining the room.")
|
|
return
|
|
|
|
# Step 3: Send test message
|
|
print("\n3. Sending test message...")
|
|
message_sent = await send_test_message(access_token)
|
|
|
|
# Step 4: Output configuration for Claude
|
|
print("\n" + "=" * 50)
|
|
print("🎉 Claude Matrix Setup Complete!")
|
|
print("\n📋 Configuration for Claude's global config:")
|
|
print(f" Matrix Homeserver: {MATRIX_HOMESERVER}")
|
|
print(f" Claude User ID: {user_id}")
|
|
print(f" Claude Access Token: {access_token}")
|
|
print(f" Home Assistant Room: {HOME_ASSISTANT_ROOM_ID}")
|
|
|
|
# Save to file for easy copying
|
|
config = {
|
|
"matrix_homeserver": MATRIX_HOMESERVER,
|
|
"claude_user_id": user_id,
|
|
"claude_access_token": access_token,
|
|
"home_assistant_room_id": HOME_ASSISTANT_ROOM_ID,
|
|
"credentials": {
|
|
"username": CLAUDE_USERNAME,
|
|
"password": CLAUDE_PASSWORD
|
|
}
|
|
}
|
|
|
|
with open("/home/klas/langmem/claude-matrix-config.json", "w") as f:
|
|
json.dump(config, f, indent=2)
|
|
|
|
print(f"\n💾 Configuration saved to: /home/klas/langmem/claude-matrix-config.json")
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main()) |