# GameForge Integration - Implementation Examples This document provides practical examples for integrating AeThex Connect with GameForge. --- ## Example 1: Complete Project Lifecycle ### Step 1: Create Project in GameForge ```javascript // GameForge: src/services/projectService.js const crypto = require('crypto'); function generateSignature(payload, secret) { const timestamp = Date.now().toString(); const data = JSON.stringify(payload); return { signature: crypto .createHmac('sha256', secret) .update(`${timestamp}.${data}`) .digest('hex'), timestamp }; } async function createProject(projectData, userId) { // 1. Create project in GameForge database const project = await db.projects.create({ name: projectData.name, description: projectData.description, owner_id: userId, created_at: new Date() }); // 2. Get owner's AeThex identifier const owner = await db.users.findById(userId); const ownerIdentifier = `${owner.username}@dev.aethex.dev`; // 3. Provision AeThex Connect channels const connectPayload = { projectId: project.id, name: project.name, ownerId: userId, ownerIdentifier: ownerIdentifier, teamMembers: [], settings: { autoProvisionChannels: true, defaultChannels: ['general', 'dev', 'art', 'design'], customChannels: [] } }; const { signature, timestamp } = generateSignature( connectPayload, process.env.AETHEX_CONNECT_API_SECRET ); try { const response = await fetch('https://connect.aethex.app/api/gameforge/projects', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-GameForge-API-Key': process.env.AETHEX_CONNECT_API_KEY, 'X-GameForge-Signature': signature, 'X-GameForge-Timestamp': timestamp }, body: JSON.stringify(connectPayload) }); const connectData = await response.json(); if (connectData.success) { // Store integration data await db.projects.update(project.id, { connect_domain: connectData.integration.domain, connect_channels: connectData.integration.channels }); console.log(`✅ Provisioned ${connectData.integration.channels.length} channels`); } else { console.error('Failed to provision AeThex Connect:', connectData.error); } } catch (error) { console.error('AeThex Connect provisioning error:', error); // Non-critical - project still created } return project; } ``` ### Step 2: Add Team Members ```javascript // GameForge: src/services/teamService.js async function addTeamMember(projectId, userId, role) { // 1. Add to GameForge team const teamMember = await db.projectTeams.create({ project_id: projectId, user_id: userId, role: role, joined_at: new Date() }); // 2. Get user's AeThex identifier const user = await db.users.findById(userId); const identifier = `${user.username}@dev.aethex.dev`; // 3. Update AeThex Connect const payload = { action: 'add', members: [{ userId: userId, identifier: identifier, role: role }] }; const { signature, timestamp } = generateSignature( payload, process.env.AETHEX_CONNECT_API_SECRET ); try { const response = await fetch( `https://connect.aethex.app/api/gameforge/projects/${projectId}/team`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', 'X-GameForge-API-Key': process.env.AETHEX_CONNECT_API_KEY, 'X-GameForge-Signature': signature, 'X-GameForge-Timestamp': timestamp }, body: JSON.stringify(payload) } ); const data = await response.json(); console.log(`✅ Added to ${data.updated[0].addedToChannels.length} channels`); } catch (error) { console.error('Failed to update AeThex Connect team:', error); } return teamMember; } async function removeTeamMember(projectId, userId) { // 1. Remove from GameForge team await db.projectTeams.delete({ project_id: projectId, user_id: userId }); // 2. Remove from AeThex Connect const payload = { action: 'remove', members: [{ userId: userId }] }; const { signature, timestamp } = generateSignature( payload, process.env.AETHEX_CONNECT_API_SECRET ); await fetch( `https://connect.aethex.app/api/gameforge/projects/${projectId}/team`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', 'X-GameForge-API-Key': process.env.AETHEX_CONNECT_API_KEY, 'X-GameForge-Signature': signature, 'X-GameForge-Timestamp': timestamp }, body: JSON.stringify(payload) } ); } async function updateMemberRole(projectId, userId, newRole) { // 1. Update in GameForge await db.projectTeams.update({ project_id: projectId, user_id: userId }, { role: newRole }); // 2. Update in AeThex Connect const user = await db.users.findById(userId); const payload = { action: 'update_role', members: [{ userId: userId, identifier: `${user.username}@dev.aethex.dev`, role: newRole }] }; const { signature, timestamp } = generateSignature( payload, process.env.AETHEX_CONNECT_API_SECRET ); await fetch( `https://connect.aethex.app/api/gameforge/projects/${projectId}/team`, { method: 'PATCH', headers: { 'Content-Type': 'application/json', 'X-GameForge-API-Key': process.env.AETHEX_CONNECT_API_KEY, 'X-GameForge-Signature': signature, 'X-GameForge-Timestamp': timestamp }, body: JSON.stringify(payload) } ); } ``` ### Step 3: Send Notifications ```javascript // GameForge: src/services/buildService.js async function onBuildComplete(buildId, projectId, status) { const build = await db.builds.findById(buildId); const notification = { channelName: 'dev', type: 'build', title: `Build #${build.number} ${status === 'success' ? 'Completed' : 'Failed'}`, message: status === 'success' ? `Build completed successfully in ${formatDuration(build.duration)}` : `Build failed: ${build.error}`, metadata: { buildNumber: build.number, status: status, duration: build.duration, commitHash: build.commit_hash.substring(0, 7), branch: build.branch }, actions: [ { label: 'View Build', url: `https://gameforge.aethex.dev/projects/${projectId}/builds/${buildId}` }, { label: 'View Logs', url: `https://gameforge.aethex.dev/projects/${projectId}/builds/${buildId}/logs` } ] }; const { signature, timestamp } = generateSignature( notification, process.env.AETHEX_CONNECT_API_SECRET ); await fetch( `https://connect.aethex.app/api/gameforge/projects/${projectId}/notify`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-GameForge-API-Key': process.env.AETHEX_CONNECT_API_KEY, 'X-GameForge-Signature': signature, 'X-GameForge-Timestamp': timestamp }, body: JSON.stringify(notification) } ); } // GameForge: src/services/gitService.js async function onCommitPushed(commitData, projectId) { const notification = { channelName: 'dev', type: 'commit', title: 'New Commit Pushed', message: commitData.message, metadata: { author: commitData.author, hash: commitData.hash.substring(0, 7), branch: commitData.branch, filesChanged: commitData.stats.filesChanged }, actions: [ { label: 'View Commit', url: `https://gameforge.aethex.dev/projects/${projectId}/commits/${commitData.hash}` } ] }; const { signature, timestamp } = generateSignature( notification, process.env.AETHEX_CONNECT_API_SECRET ); await fetch( `https://connect.aethex.app/api/gameforge/projects/${projectId}/notify`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-GameForge-API-Key': process.env.AETHEX_CONNECT_API_KEY, 'X-GameForge-Signature': signature, 'X-GameForge-Timestamp': timestamp }, body: JSON.stringify(notification) } ); } // GameForge: src/services/deploymentService.js async function onDeploymentComplete(deploymentId, projectId, status) { const deployment = await db.deployments.findById(deploymentId); const notification = { channelName: 'general', type: 'deployment', title: `Deployment ${status === 'success' ? 'Successful' : 'Failed'}`, message: status === 'success' ? `Successfully deployed to ${deployment.environment}` : `Deployment to ${deployment.environment} failed`, metadata: { environment: deployment.environment, version: deployment.version, status: status }, actions: [ { label: 'View Deployment', url: `https://gameforge.aethex.dev/projects/${projectId}/deployments/${deploymentId}` } ] }; const { signature, timestamp } = generateSignature( notification, process.env.AETHEX_CONNECT_API_SECRET ); await fetch( `https://connect.aethex.app/api/gameforge/projects/${projectId}/notify`, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-GameForge-API-Key': process.env.AETHEX_CONNECT_API_KEY, 'X-GameForge-Signature': signature, 'X-GameForge-Timestamp': timestamp }, body: JSON.stringify(notification) } ); } ``` ### Step 4: Archive Project ```javascript // GameForge: src/services/projectService.js async function archiveProject(projectId) { // 1. Archive in GameForge await db.projects.update(projectId, { is_archived: true, archived_at: new Date() }); // 2. Archive AeThex Connect channels const { signature, timestamp } = generateSignature( {}, process.env.AETHEX_CONNECT_API_SECRET ); await fetch( `https://connect.aethex.app/api/gameforge/projects/${projectId}`, { method: 'DELETE', headers: { 'Content-Type': 'application/json', 'X-GameForge-API-Key': process.env.AETHEX_CONNECT_API_KEY, 'X-GameForge-Signature': signature, 'X-GameForge-Timestamp': timestamp } } ); } ``` --- ## Example 2: Embedded Chat Component ### React Integration ```javascript // GameForge: src/pages/ProjectPage.jsx import React from 'react'; import { useParams } from 'react-router-dom'; import GameForgeChat from '@aethex/connect/components/GameForgeChat'; export default function ProjectPage() { const { projectId } = useParams(); return (