diff --git a/.gitea/workflowsssss/docker-build.yml b/.gitea/workflowsssss/docker-build.yml deleted file mode 100644 index 3fa0d82..0000000 --- a/.gitea/workflowsssss/docker-build.yml +++ /dev/null @@ -1,163 +0,0 @@ -name: Build and Publish Docker Images - -on: - push: - branches: [ main, develop ] - tags: [ 'v*' ] - pull_request: - branches: [ main ] - -env: - REGISTRY: docker.io - IMAGE_NAME_DISCORD_BOT: uptime-kuma-discord-bot - IMAGE_NAME_WEB_BACKEND: uptime-kuma-web-backend - -jobs: - build-and-push: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to Docker Hub - if: github.event_name != 'pull_request' - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Extract metadata for Discord Bot - id: meta-discord-bot - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=raw,value=latest,enable={{is_default_branch}} - - - name: Extract metadata for Web Backend - id: meta-web-backend - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=raw,value=latest,enable={{is_default_branch}} - - - name: Build and push Discord Bot image - uses: docker/build-push-action@v5 - with: - context: ./Bot - file: ./Bot/Dockerfile - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta-discord-bot.outputs.tags }} - labels: ${{ steps.meta-discord-bot.outputs.labels }} - platforms: linux/amd64,linux/arm64 - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Build and push Web Backend image - uses: docker/build-push-action@v5 - with: - context: ./Web - file: ./Web/Dockerfile - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta-web-backend.outputs.tags }} - labels: ${{ steps.meta-web-backend.outputs.labels }} - platforms: linux/amd64,linux/arm64 - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Generate SBOM for Discord Bot - if: github.event_name != 'pull_request' - uses: anchore/sbom-action@v0 - with: - image: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:${{ steps.meta-discord-bot.outputs.version }} - format: spdx-json - output-file: discord-bot-sbom.spdx.json - - - name: Generate SBOM for Web Backend - if: github.event_name != 'pull_request' - uses: anchore/sbom-action@v0 - with: - image: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:${{ steps.meta-web-backend.outputs.version }} - format: spdx-json - output-file: web-backend-sbom.spdx.json - - - name: Upload SBOM artifacts - if: github.event_name != 'pull_request' - uses: actions/upload-artifact@v4 - with: - name: sbom-artifacts - path: | - discord-bot-sbom.spdx.json - web-backend-sbom.spdx.json - retention-days: 30 - - security-scan: - runs-on: ubuntu-latest - needs: build-and-push - if: github.event_name != 'pull_request' - permissions: - contents: read - security-events: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Run Trivy vulnerability scanner for Discord Bot - uses: aquasecurity/trivy-action@master - with: - image-ref: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:latest - format: 'sarif' - output: 'discord-bot-trivy-results.sarif' - - - name: Run Trivy vulnerability scanner for Web Backend - uses: aquasecurity/trivy-action@master - with: - image-ref: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:latest - format: 'sarif' - output: 'web-backend-trivy-results.sarif' - - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: | - discord-bot-trivy-results.sarif - web-backend-trivy-results.sarif - - notify: - runs-on: ubuntu-latest - needs: [build-and-push, security-scan] - if: always() && github.event_name != 'pull_request' - - steps: - - name: Notify on success - if: needs.build-and-push.result == 'success' && needs.security-scan.result == 'success' - run: | - echo "✅ Docker images built and published successfully!" - echo "Discord Bot: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:latest" - echo "Web Backend: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:latest" - - - name: Notify on failure - if: needs.build-and-push.result == 'failure' || needs.security-scan.result == 'failure' - run: | - echo "❌ Docker build or security scan failed!" - exit 1 diff --git a/.gitea/workflowsssss/docker-compose-test.yml b/.gitea/workflowsssss/docker-compose-test.yml deleted file mode 100644 index 1073d90..0000000 --- a/.gitea/workflowsssss/docker-compose-test.yml +++ /dev/null @@ -1,125 +0,0 @@ -name: Test Docker Compose Setup - -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main ] - -env: - COMPOSE_PROJECT_NAME: uptime-kuma-test - -jobs: - test-compose: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Create test environment file - run: | - cat > .env << EOF - DISCORD_TOKEN=test_token_12345 - GUILD_ID=123456789012345678 - CHANNEL_ID=123456789012345678 - CLIENT_ID=123456789012345678 - UPDATE_TIME=60 - UPTIME_KUMA_URL=https://test.example.com/metrics - UPTIME_KUMA_API_KEY=test_api_key_12345 - EOF - - - name: Build Docker images - run: | - docker-compose build --no-cache - - - name: Start services - run: | - docker-compose up -d - sleep 30 - - - name: Check service health - run: | - # Check if web backend is responding - curl -f http://localhost:8080/back-end.php || exit 1 - - # Check container status - docker-compose ps - - # Check logs for errors - docker-compose logs --tail=50 - - - name: Test web backend endpoint - run: | - # Test the PHP endpoint (should fail gracefully with test data) - response=$(curl -s -w "%{http_code}" http://localhost:8080/back-end.php) - echo "Response: $response" - # Accept both 200 (success) and 500 (expected failure with test data) - if [[ "$response" =~ ^(200|500)$ ]]; then - echo "✅ Web backend endpoint is responding" - else - echo "❌ Web backend endpoint failed" - exit 1 - fi - - - name: Verify container logs - run: | - # Check Discord bot logs for startup - docker-compose logs discord-bot | grep -E "(Bot is online|Error)" || echo "No startup messages found" - - # Check web backend logs - docker-compose logs web-backend | grep -E "(Apache|PHP)" || echo "No backend messages found" - - - name: Cleanup - if: always() - run: | - docker-compose down -v - docker system prune -f - - lint-dockerfiles: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Run hadolint on Dockerfiles - uses: hadolint/hadolint-action@v3.1.0 - with: - dockerfile: Bot/Dockerfile - failure-threshold: warning - - - name: Run hadolint on Web Dockerfile - uses: hadolint/hadolint-action@v3.1.0 - with: - dockerfile: Web/Dockerfile - failure-threshold: warning - - validate-compose: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Validate docker-compose.yml - run: | - docker-compose config --quiet - echo "✅ docker-compose.yml is valid" - - - name: Check for required environment variables - run: | - # Check if all required env vars are referenced in docker-compose.yml - required_vars=("DISCORD_TOKEN" "GUILD_ID" "CHANNEL_ID" "CLIENT_ID" "UPTIME_KUMA_URL" "UPTIME_KUMA_API_KEY") - - for var in "${required_vars[@]}"; do - if grep -q "\${$var}" docker-compose.yml; then - echo "✅ $var is referenced in docker-compose.yml" - else - echo "❌ $var is missing from docker-compose.yml" - exit 1 - fi - done diff --git a/.gitea/workflowsssss/release.yml b/.gitea/workflowsssss/release.yml deleted file mode 100644 index acba42c..0000000 --- a/.gitea/workflowsssss/release.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: Create Release - -on: - push: - tags: - - 'v*' - -env: - REGISTRY: docker.io - IMAGE_NAME_DISCORD_BOT: uptime-kuma-discord-bot - IMAGE_NAME_WEB_BACKEND: uptime-kuma-web-backend - -jobs: - create-release: - runs-on: ubuntu-latest - permissions: - contents: write - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Extract version from tag - id: version - run: | - VERSION=${GITHUB_REF#refs/tags/} - VERSION=${VERSION#v} - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "tag=v$VERSION" >> $GITHUB_OUTPUT - - - name: Generate changelog - id: changelog - run: | - # Get commits since last tag - if git describe --tags --abbrev=0 HEAD~1 >/dev/null 2>&1; then - PREV_TAG=$(git describe --tags --abbrev=0 HEAD~1) - echo "Changes since $PREV_TAG:" - git log --pretty=format:"- %s (%h)" $PREV_TAG..HEAD - else - echo "Initial release" - git log --pretty=format:"- %s (%h)" - fi > CHANGELOG.md - - - name: Create Release - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ steps.version.outputs.tag }} - name: Release ${{ steps.version.outputs.tag }} - body: | - ## What's Changed - - ${{ steps.changelog.outputs.content }} - - ## Docker Images - - ### Discord Bot - ```bash - docker pull ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:${{ steps.version.outputs.version }} - docker pull ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:latest - ``` - - ### Web Backend - ```bash - docker pull ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:${{ steps.version.outputs.version }} - docker pull ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:latest - ``` - - ## Quick Start - - ```bash - # Clone the repository - git clone - cd UptimeKuma-DiscordBot - - # Copy environment template - cp env.example .env - - # Edit .env with your values - # Then start with Docker Compose - docker-compose up -d - ``` - - See [DOCKER_SETUP.md](DOCKER_SETUP.md) for detailed instructions. - files: | - CHANGELOG.md - draft: false - prerelease: false - - - name: Update Docker Hub description - if: success() - run: | - echo "🎉 Release ${{ steps.version.outputs.tag }} created successfully!" - echo "Docker images will be automatically built and pushed by the docker-build workflow." diff --git a/.github/workflows/docker-build.yml b/.github/workflows/docker-build.yml deleted file mode 100644 index 3fa0d82..0000000 --- a/.github/workflows/docker-build.yml +++ /dev/null @@ -1,163 +0,0 @@ -name: Build and Publish Docker Images - -on: - push: - branches: [ main, develop ] - tags: [ 'v*' ] - pull_request: - branches: [ main ] - -env: - REGISTRY: docker.io - IMAGE_NAME_DISCORD_BOT: uptime-kuma-discord-bot - IMAGE_NAME_WEB_BACKEND: uptime-kuma-web-backend - -jobs: - build-and-push: - runs-on: ubuntu-latest - permissions: - contents: read - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to Docker Hub - if: github.event_name != 'pull_request' - uses: docker/login-action@v3 - with: - registry: ${{ env.REGISTRY }} - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Extract metadata for Discord Bot - id: meta-discord-bot - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=raw,value=latest,enable={{is_default_branch}} - - - name: Extract metadata for Web Backend - id: meta-web-backend - uses: docker/metadata-action@v5 - with: - images: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }} - tags: | - type=ref,event=branch - type=ref,event=pr - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=raw,value=latest,enable={{is_default_branch}} - - - name: Build and push Discord Bot image - uses: docker/build-push-action@v5 - with: - context: ./Bot - file: ./Bot/Dockerfile - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta-discord-bot.outputs.tags }} - labels: ${{ steps.meta-discord-bot.outputs.labels }} - platforms: linux/amd64,linux/arm64 - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Build and push Web Backend image - uses: docker/build-push-action@v5 - with: - context: ./Web - file: ./Web/Dockerfile - push: ${{ github.event_name != 'pull_request' }} - tags: ${{ steps.meta-web-backend.outputs.tags }} - labels: ${{ steps.meta-web-backend.outputs.labels }} - platforms: linux/amd64,linux/arm64 - cache-from: type=gha - cache-to: type=gha,mode=max - - - name: Generate SBOM for Discord Bot - if: github.event_name != 'pull_request' - uses: anchore/sbom-action@v0 - with: - image: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:${{ steps.meta-discord-bot.outputs.version }} - format: spdx-json - output-file: discord-bot-sbom.spdx.json - - - name: Generate SBOM for Web Backend - if: github.event_name != 'pull_request' - uses: anchore/sbom-action@v0 - with: - image: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:${{ steps.meta-web-backend.outputs.version }} - format: spdx-json - output-file: web-backend-sbom.spdx.json - - - name: Upload SBOM artifacts - if: github.event_name != 'pull_request' - uses: actions/upload-artifact@v4 - with: - name: sbom-artifacts - path: | - discord-bot-sbom.spdx.json - web-backend-sbom.spdx.json - retention-days: 30 - - security-scan: - runs-on: ubuntu-latest - needs: build-and-push - if: github.event_name != 'pull_request' - permissions: - contents: read - security-events: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Run Trivy vulnerability scanner for Discord Bot - uses: aquasecurity/trivy-action@master - with: - image-ref: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:latest - format: 'sarif' - output: 'discord-bot-trivy-results.sarif' - - - name: Run Trivy vulnerability scanner for Web Backend - uses: aquasecurity/trivy-action@master - with: - image-ref: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:latest - format: 'sarif' - output: 'web-backend-trivy-results.sarif' - - - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: | - discord-bot-trivy-results.sarif - web-backend-trivy-results.sarif - - notify: - runs-on: ubuntu-latest - needs: [build-and-push, security-scan] - if: always() && github.event_name != 'pull_request' - - steps: - - name: Notify on success - if: needs.build-and-push.result == 'success' && needs.security-scan.result == 'success' - run: | - echo "✅ Docker images built and published successfully!" - echo "Discord Bot: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:latest" - echo "Web Backend: ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:latest" - - - name: Notify on failure - if: needs.build-and-push.result == 'failure' || needs.security-scan.result == 'failure' - run: | - echo "❌ Docker build or security scan failed!" - exit 1 diff --git a/.github/workflows/docker-compose-test.yml b/.github/workflows/docker-compose-test.yml deleted file mode 100644 index 1073d90..0000000 --- a/.github/workflows/docker-compose-test.yml +++ /dev/null @@ -1,125 +0,0 @@ -name: Test Docker Compose Setup - -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main ] - -env: - COMPOSE_PROJECT_NAME: uptime-kuma-test - -jobs: - test-compose: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Create test environment file - run: | - cat > .env << EOF - DISCORD_TOKEN=test_token_12345 - GUILD_ID=123456789012345678 - CHANNEL_ID=123456789012345678 - CLIENT_ID=123456789012345678 - UPDATE_TIME=60 - UPTIME_KUMA_URL=https://test.example.com/metrics - UPTIME_KUMA_API_KEY=test_api_key_12345 - EOF - - - name: Build Docker images - run: | - docker-compose build --no-cache - - - name: Start services - run: | - docker-compose up -d - sleep 30 - - - name: Check service health - run: | - # Check if web backend is responding - curl -f http://localhost:8080/back-end.php || exit 1 - - # Check container status - docker-compose ps - - # Check logs for errors - docker-compose logs --tail=50 - - - name: Test web backend endpoint - run: | - # Test the PHP endpoint (should fail gracefully with test data) - response=$(curl -s -w "%{http_code}" http://localhost:8080/back-end.php) - echo "Response: $response" - # Accept both 200 (success) and 500 (expected failure with test data) - if [[ "$response" =~ ^(200|500)$ ]]; then - echo "✅ Web backend endpoint is responding" - else - echo "❌ Web backend endpoint failed" - exit 1 - fi - - - name: Verify container logs - run: | - # Check Discord bot logs for startup - docker-compose logs discord-bot | grep -E "(Bot is online|Error)" || echo "No startup messages found" - - # Check web backend logs - docker-compose logs web-backend | grep -E "(Apache|PHP)" || echo "No backend messages found" - - - name: Cleanup - if: always() - run: | - docker-compose down -v - docker system prune -f - - lint-dockerfiles: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Run hadolint on Dockerfiles - uses: hadolint/hadolint-action@v3.1.0 - with: - dockerfile: Bot/Dockerfile - failure-threshold: warning - - - name: Run hadolint on Web Dockerfile - uses: hadolint/hadolint-action@v3.1.0 - with: - dockerfile: Web/Dockerfile - failure-threshold: warning - - validate-compose: - runs-on: ubuntu-latest - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Validate docker-compose.yml - run: | - docker-compose config --quiet - echo "✅ docker-compose.yml is valid" - - - name: Check for required environment variables - run: | - # Check if all required env vars are referenced in docker-compose.yml - required_vars=("DISCORD_TOKEN" "GUILD_ID" "CHANNEL_ID" "CLIENT_ID" "UPTIME_KUMA_URL" "UPTIME_KUMA_API_KEY") - - for var in "${required_vars[@]}"; do - if grep -q "\${$var}" docker-compose.yml; then - echo "✅ $var is referenced in docker-compose.yml" - else - echo "❌ $var is missing from docker-compose.yml" - exit 1 - fi - done diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index acba42c..0000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: Create Release - -on: - push: - tags: - - 'v*' - -env: - REGISTRY: docker.io - IMAGE_NAME_DISCORD_BOT: uptime-kuma-discord-bot - IMAGE_NAME_WEB_BACKEND: uptime-kuma-web-backend - -jobs: - create-release: - runs-on: ubuntu-latest - permissions: - contents: write - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Extract version from tag - id: version - run: | - VERSION=${GITHUB_REF#refs/tags/} - VERSION=${VERSION#v} - echo "version=$VERSION" >> $GITHUB_OUTPUT - echo "tag=v$VERSION" >> $GITHUB_OUTPUT - - - name: Generate changelog - id: changelog - run: | - # Get commits since last tag - if git describe --tags --abbrev=0 HEAD~1 >/dev/null 2>&1; then - PREV_TAG=$(git describe --tags --abbrev=0 HEAD~1) - echo "Changes since $PREV_TAG:" - git log --pretty=format:"- %s (%h)" $PREV_TAG..HEAD - else - echo "Initial release" - git log --pretty=format:"- %s (%h)" - fi > CHANGELOG.md - - - name: Create Release - uses: softprops/action-gh-release@v1 - with: - tag_name: ${{ steps.version.outputs.tag }} - name: Release ${{ steps.version.outputs.tag }} - body: | - ## What's Changed - - ${{ steps.changelog.outputs.content }} - - ## Docker Images - - ### Discord Bot - ```bash - docker pull ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:${{ steps.version.outputs.version }} - docker pull ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_DISCORD_BOT }}:latest - ``` - - ### Web Backend - ```bash - docker pull ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:${{ steps.version.outputs.version }} - docker pull ${{ env.REGISTRY }}/${{ secrets.DOCKER_USERNAME }}/${{ env.IMAGE_NAME_WEB_BACKEND }}:latest - ``` - - ## Quick Start - - ```bash - # Clone the repository - git clone - cd UptimeKuma-DiscordBot - - # Copy environment template - cp env.example .env - - # Edit .env with your values - # Then start with Docker Compose - docker-compose up -d - ``` - - See [DOCKER_SETUP.md](DOCKER_SETUP.md) for detailed instructions. - files: | - CHANGELOG.md - draft: false - prerelease: false - - - name: Update Docker Hub description - if: success() - run: | - echo "🎉 Release ${{ steps.version.outputs.tag }} created successfully!" - echo "Docker images will be automatically built and pushed by the docker-build workflow." diff --git a/Bot/index.js b/Bot/index.js index 8ebacdb..4e7c4a9 100644 --- a/Bot/index.js +++ b/Bot/index.js @@ -20,9 +20,9 @@ const client = new Client({ }); let monitorMessages = { - Gaming: null, - Discord: null, - Web: null + 'Web Services': null, + 'Infrastructure': null, + 'Network': null }; client.once('ready', async () => { @@ -56,25 +56,56 @@ async function updateMessages() { const response = await axios.get(config.backendUrl); const monitors = response.data; + + // Check if the backend returned an error + if (monitors.error) { + console.error('Backend API error:', monitors.message); + return; + } + + // Ensure monitors is an array + if (!Array.isArray(monitors)) { + console.error('Backend returned invalid data format:', typeof monitors); + return; + } + + console.log(`Fetched ${monitors.length} monitors from backend`); + console.log('Monitor names:', monitors.map(m => m.monitor_name)); - const gamingMonitors = monitors.filter(monitor => [ - 'Lobby', 'Skyblock', 'Survival', 'Creative', 'KitPvP', 'Factions', 'Prison', 'Skywars' + const webServicesMonitors = monitors.filter(monitor => [ + 'Main Page', 'Pelican', 'Jellyfin', 'Proxmox', 'Jellyseerr', + 'CPanel', 'WHMCS', 'Gitea', 'Nextcloud', 'Radarr', 'Sonarr', + 'Prowlarr', 'Nginx Proxy Manager', 'Authentik', 'n8n', 'HA Proxy' ].includes(monitor.monitor_name)); - const discordMonitors = monitors.filter(monitor => [ - 'Discord bot', 'Status bot' + const infrastructureMonitors = monitors.filter(monitor => [ + 'a01.pve.hrs', 'a05.pve.hrs', 'a07.pve.hrs', 'a08.pve.hrs', 'a09.pve.hrs', + '01.bw.hrs', '01.ga.hrs', '01.ha.hrs', '01.lh.hrs', '01.nc.hrs' ].includes(monitor.monitor_name)); - const webMonitors = monitors.filter(monitor => [ - 'web1', 'web2', 'web3' + const networkMonitors = monitors.filter(monitor => [ + '01.sh.hrs', '01.rs.hrs', '01.pe.hrs', '01.pt.hrs', '01.rr.hrs', + '01.wn.hrs', '02.pe.hrs', '01.cp.hrs', '02.cp.hrs', 'a06' ].includes(monitor.monitor_name)); - await sendMonitorsMessage(channel, 'Gaming', gamingMonitors); - await sendMonitorsMessage(channel, 'Discord', discordMonitors); - await sendMonitorsMessage(channel, 'Web', webMonitors); + console.log(`Web Services: ${webServicesMonitors.length}, Infrastructure: ${infrastructureMonitors.length}, Network: ${networkMonitors.length}`); + + await sendMonitorsMessage(channel, 'Web Services', webServicesMonitors); + // await sendMonitorsMessage(channel, 'Infrastructure', infrastructureMonitors); + //await sendMonitorsMessage(channel, 'Network', networkMonitors); } catch (error) { - console.error('Error:', error); + console.error('Error updating messages:', error); + + // If it's an axios error, log more details + if (error.response) { + console.error('Backend API error:', error.response.status, error.response.statusText); + console.error('Response data:', error.response.data); + } else if (error.request) { + console.error('No response from backend API:', error.request); + } else { + console.error('Request setup error:', error.message); + } } } @@ -100,6 +131,11 @@ async function sendMonitorsMessage(channel, category, monitors) { return `${statusEmoji} | ${monitor.monitor_name}`; }).join('\n'); + // Ensure description is not empty (Discord.js validation requirement) + if (!description || description.trim() === '') { + description = `No ${category.toLowerCase()} monitors found.`; + } + let embed = new EmbedBuilder() .setTitle(`${category} Monitor`) .setColor('#0099ff') diff --git a/Web/back-end.php b/Web/back-end.php index 368012a..1423758 100644 --- a/Web/back-end.php +++ b/Web/back-end.php @@ -53,10 +53,26 @@ if ($http_status == 200) { // Set the content type of the response to JSON header('Content-Type: application/json'); + + // Log debug information + error_log("UptimeKuma API Response Status: $http_status"); + error_log("Parsed monitors count: " . count($data)); + // Output the data in JSON format echo json_encode($data, JSON_PRETTY_PRINT); } else { + // Log the error + error_log("UptimeKuma API Error: HTTP Status Code: $http_status"); + error_log("Response: " . substr($response, 0, 500)); + + // Set the content type of the response to JSON + header('Content-Type: application/json'); + // Output an error message if the request was not successful - echo "Failed to fetch data. HTTP Status Code: $http_status"; + echo json_encode([ + 'error' => true, + 'message' => "Failed to fetch data. HTTP Status Code: $http_status", + 'data' => [] + ], JSON_PRETTY_PRINT); } ?> \ No newline at end of file diff --git a/back-end.php.json b/back-end.php.json new file mode 100644 index 0000000..ededcfa --- /dev/null +++ b/back-end.php.json @@ -0,0 +1,330 @@ +[ + { + "monitor_name": "a06", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.10.16", + "monitor_port": "null", + "status": 0 + }, + { + "monitor_name": "Main Page", + "monitor_type": "http", + "monitor_url": "https:\/\/hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Pelican", + "monitor_type": "http", + "monitor_url": "https:\/\/pelican.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Jellyfin", + "monitor_type": "http", + "monitor_url": "https:\/\/jellyfin.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Proxmox", + "monitor_type": "http", + "monitor_url": "https:\/\/proxmox.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Jellyseerr", + "monitor_type": "http", + "monitor_url": "https:\/\/jellyseerr.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "CPanel", + "monitor_type": "http", + "monitor_url": "https:\/\/cpanel.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "WHMCS", + "monitor_type": "http", + "monitor_url": "https:\/\/portal.hudsonriggs.systems\/", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Gitea", + "monitor_type": "http", + "monitor_url": "https:\/\/git.hudsonriggs.systems\/", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Nextcloud", + "monitor_type": "http", + "monitor_url": "https:\/\/cloud.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Radarr", + "monitor_type": "http", + "monitor_url": "https:\/\/radarr.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Sonarr", + "monitor_type": "http", + "monitor_url": "https:\/\/sonarr.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Prowlarr", + "monitor_type": "http", + "monitor_url": "https:\/\/prowlarr.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.sh.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.30.116", + "monitor_port": "null", + "status": 0 + }, + { + "monitor_name": "01.rs.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.30.127", + "monitor_port": "null", + "status": 0 + }, + { + "monitor_name": "LXC", + "monitor_type": "group", + "monitor_url": "https:\/\/", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "VM", + "monitor_type": "group", + "monitor_url": "https:\/\/", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.bw.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.30.120", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.ga.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.30.113", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.ha.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.30.123", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.lh.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.30.137", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.nc.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.30.117", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.oo.hrs", + "monitor_type": "ping", + "monitor_url": "", + "monitor_hostname": "192.168.30.126", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.pe.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.30.110", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.pt.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.30.115", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.rr.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.30.121", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.wn.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.20.124", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "02.pe.hrs", + "monitor_type": "ping", + "monitor_url": "192.168.30.111", + "monitor_hostname": "192.168.30.111", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "01.cp.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.20.108", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "02.cp.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.254.6", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "PVE", + "monitor_type": "group", + "monitor_url": "https:\/\/", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "a01.pve.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.10.11", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "a05.pve.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.10.15", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "a07.pve.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.10.17", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "a08.pve.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.10.18", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "a09.pve.hrs", + "monitor_type": "ping", + "monitor_url": "https:\/\/", + "monitor_hostname": "192.168.10.19", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Hosts", + "monitor_type": "group", + "monitor_url": "https:\/\/", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Nginx Proxy Manager", + "monitor_type": "http", + "monitor_url": "https:\/\/ngpm.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "Authentik", + "monitor_type": "http", + "monitor_url": "https:\/\/authentik.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "n8n", + "monitor_type": "http", + "monitor_url": "https:\/\/n8n.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + }, + { + "monitor_name": "HA Proxy", + "monitor_type": "http", + "monitor_url": "https:\/\/haproxy.hudsonriggs.systems", + "monitor_hostname": "null", + "monitor_port": "null", + "status": 1 + } +] \ No newline at end of file