## Overview This integration bridges **OpenProject**, a project management tool, and **Matrix/Element**, a decentralized communication platform, using **Matrix Hookshot**. The integration enables seamless project collaboration by syncing users, projects, and notifications between OpenProject and Matrix/Element. ### Key Features 1. **Permission Management**: * Adding a user to a Matrix channel grants them the appropriate permissions in the corresponding OpenProject project. 2. **Project Room Creation**: * Automatically creates a Matrix room when a new project is created in OpenProject. 3. **User Synchronization**: * Adding/removing members in OpenProject reflects in the linked Matrix room. 4. **Future Enhancements**: * Subscription to OpenProject notifications in Matrix. * Real-time work package updates in Matrix. ## Prerequisites 1. **Matrix Hookshot**: * Clone your fork of the [Matrix Hookshot repository](https://github.com/girish17/matrix-hookshot). * Install Node.js (v16 or later). 2. **OpenProject**: * Access to an OpenProject instance with API enabled. * Generate an API token for the bot. 3. **Matrix Server**: * Access to a Matrix server. * Create a bot account and generate an access token. 4. **Configuration Files**: * Update `config.yaml` and `.env` with OpenProject and Matrix details. ## Installation ### Step 1: Clone and Set Up the Project ```bash git clone https://github.com/girish17/matrix-hookshot.git cd matrix-hookshot npm install ``` ### Step 2: Configure Environment Variables Create a `.env` file with the following: ```env OPENPROJECT_URL=https://openproject.example.com OPENPROJECT_API_KEY=your_api_key MATRIX_HOMESERVER=https://matrix.example.com MATRIX_ACCESS_TOKEN=your_bot_access_token ``` ### Step 3: Configure Hookshot Update the `config.yaml` file: ```yaml integrations: openproject: url: "https://openproject.example.com" api_key: "your_api_key" ``` ### Step 4: Build the Project ```bash npm run build ``` ### Step 5: Run the Server ```bash npm start ``` ## Features ### 1\. Adding Users to Matrix Channels * **Trigger**: A user joins a Matrix room linked to an OpenProject project. * **Action**: The bot maps the Matrix user to an OpenProject user and updates their project membership. #### Workflow 1. The `m.room.member` event is captured by the Matrix Hookshot bot. 2. The bot retrieves the project ID linked to the room. 3. The user is added to the OpenProject project with the required permissions. #### Example Code (Matrix Event Listener) ```typescript async function onRoomMemberEvent(event, roomId) { if (event.membership === "join") { const userId = event.state_key; const projectId = await getLinkedProjectId(roomId); const openProjectUser = await mapMatrixUserToOpenProject(userId); if (openProjectUser) { await addUserToOpenProject(projectId, openProjectUser); } } } ``` ### 2\. Automatically Creating Project Rooms * **Trigger**: A new project is created in OpenProject. * **Action**: A private Matrix room is created, and the project is linked to the room. #### Workflow 1. A webhook from OpenProject triggers the bot. 2. The bot creates a private Matrix room with the project name. 3. The room ID and project ID are stored for synchronization. #### Example Code (Project Creation Handler) ```typescript async function onProjectCreated(project) { const room = await matrixClient.createRoom({ visibility: "private", name: project.name, topic: `OpenProject: ${project.name}`, }); await linkRoomToProject(room.room_id, project.id); } ``` ### 3\. Synchronizing Members * **Trigger**: Member changes in OpenProject (add/remove). * **Action**: Reflect these changes in the linked Matrix room. #### Workflow 1. Periodic synchronization task or OpenProject webhook triggers the bot. 2. Compare OpenProject members with Matrix room members. 3. Add/remove users in the Matrix room to match OpenProject. #### Example Code (Synchronization Task) ```typescript async function syncProjectMembers(projectId, roomId) { const projectMembers = await getOpenProjectMembers(projectId); const roomMembers = await getMatrixRoomMembers(roomId); for (const member of projectMembers) { if (!roomMembers.includes(member)) { await addMemberToMatrixRoom(roomId, member); } } for (const member of roomMembers) { if (!projectMembers.includes(member)) { await removeMemberFromMatrixRoom(roomId, member); } } } ``` ## Testing ### Local Testing 1. **Run Locally**: ```bash npm start ``` 1. **Use Ngrok**: ```bash ngrok http 9000 ``` 1. Configure the Ngrok URL in OpenProject webhook settings. 2. Trigger events (e.g., project creation, member addition) and verify in Matrix. ### Test Cases

Feature

Test Scenario

Expected Outcome

User joins Matrix room

Join a linked room

User added to OpenProject project

Project creation

Create a project in OpenProject

Matrix room created and linked

Member synchronization

Add/remove members in OpenProject

Members synced in Matrix room

## Deployment 1. **Build and Package**: ```bash npm run build ``` 1. **Deploy on Server**: * Use Docker or a cloud service (AWS, DigitalOcean). * Ensure environment variables are securely configured. 2. **Webhook Setup**: * Configure OpenProject to send webhooks to the bot’s endpoint. ## Future Work * Subscription to OpenProject notifications in Matrix rooms. * Opening work packages directly in Matrix. * Improved error handling and logging. ## Resources * [Matrix Hookshot Documentation](https://github.com/matrix-org/matrix-hookshot) * [OpenProject API Documentation](https://docs.openproject.org/api/)