#!/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())