Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 249 additions & 0 deletions .github/workflows/integrations.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
name: Service Integrations Check

# Trigger only on manual dispatch by default for safety
# Optionally uncomment 'push' trigger if you want automatic runs on main branch
on:
workflow_dispatch:
inputs:
verbose:
description: 'Enable verbose output'
required: false
default: 'false'
Comment on lines +7 to +11
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The verbose input parameter is defined but never used in the workflow. Either implement the verbose logging functionality or remove this unused input parameter to avoid confusion.

Suggested change
inputs:
verbose:
description: 'Enable verbose output'
required: false
default: 'false'

Copilot uses AI. Check for mistakes.
# Uncomment to enable automatic runs on push to main
# push:
# branches:
# - main

jobs:
integration-checks:
name: Cross-Platform Integration Checks
runs-on: ubuntu-latest

permissions:
contents: read

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Check Secret Availability
id: secret_check
run: |
echo "::group::Secret Availability Check"
echo "Checking which secrets are configured (values are masked)..."
echo ""

# Function to check if a secret is set
check_secret() {
local secret_name=$1
local secret_value=$2

if [ -n "$secret_value" ]; then
echo "✓ $secret_name: PRESENT"
echo "${secret_name}_AVAILABLE=true" >> $GITHUB_OUTPUT
else
echo "✗ $secret_name: MISSING"
echo "${secret_name}_AVAILABLE=false" >> $GITHUB_OUTPUT
fi
}

# Check all secrets
check_secret "OPENAI_API_KEY" "${{ secrets.OPENAI_API_KEY }}"
check_secret "MANYCHAT_API_KEY" "${{ secrets.MANYCHAT_API_KEY }}"
check_secret "BOTBUILDERS_API_KEY" "${{ secrets.BOTBUILDERS_API_KEY }}"
check_secret "MOLTBOOK_API_KEY" "${{ secrets.MOLTBOOK_API_KEY }}"
check_secret "MOLTBOT_API_KEY" "${{ secrets.MOLTBOT_API_KEY }}"
check_secret "OPENCLAW_API_KEY" "${{ secrets.OPENCLAW_API_KEY }}"
check_secret "GITHUB_PAT" "${{ secrets.GITHUB_PAT }}"
check_secret "WEBHOOK_URL" "${{ secrets.WEBHOOK_URL }}"
check_secret "SERVICE_BASE_URL_OPENCLAW" "${{ secrets.SERVICE_BASE_URL_OPENCLAW }}"

echo ""
echo "::endgroup::"
env:
# All secrets are accessed through the secrets context and automatically masked
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
MANYCHAT_API_KEY: ${{ secrets.MANYCHAT_API_KEY }}
BOTBUILDERS_API_KEY: ${{ secrets.BOTBUILDERS_API_KEY }}
MOLTBOOK_API_KEY: ${{ secrets.MOLTBOOK_API_KEY }}
MOLTBOT_API_KEY: ${{ secrets.MOLTBOT_API_KEY }}
OPENCLAW_API_KEY: ${{ secrets.OPENCLAW_API_KEY }}
GITHUB_PAT: ${{ secrets.GITHUB_PAT }}
WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}
SERVICE_BASE_URL_OPENCLAW: ${{ secrets.SERVICE_BASE_URL_OPENCLAW }}
Comment on lines +63 to +73
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The env block in this step is redundant. The secrets are already being passed directly to the check_secret function via ${{ secrets.SECRET_NAME }} syntax in lines 51-59. The env variables defined here are not used anywhere in the script. This creates unnecessary duplication and could be confusing. Consider removing this entire env block.

Suggested change
env:
# All secrets are accessed through the secrets context and automatically masked
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
MANYCHAT_API_KEY: ${{ secrets.MANYCHAT_API_KEY }}
BOTBUILDERS_API_KEY: ${{ secrets.BOTBUILDERS_API_KEY }}
MOLTBOOK_API_KEY: ${{ secrets.MOLTBOOK_API_KEY }}
MOLTBOT_API_KEY: ${{ secrets.MOLTBOT_API_KEY }}
OPENCLAW_API_KEY: ${{ secrets.OPENCLAW_API_KEY }}
GITHUB_PAT: ${{ secrets.GITHUB_PAT }}
WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}
SERVICE_BASE_URL_OPENCLAW: ${{ secrets.SERVICE_BASE_URL_OPENCLAW }}

Copilot uses AI. Check for mistakes.

- name: OpenAI Integration Check
if: steps.secret_check.outputs.OPENAI_API_KEY_AVAILABLE == 'true'
run: |
echo "::group::OpenAI Connectivity Check"
echo "Performing dry-run connectivity check for OpenAI..."
echo "This is a placeholder check - no actual API calls are made."
echo ""

# Placeholder curl command (dry-run)
echo "Would execute: curl -X GET https://api.openai.com/v1/models -H \"Authorization: Bearer [MASKED]\""
echo "✓ OpenAI integration check: READY (dry-run mode)"
echo "::endgroup::"
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}

- name: OpenAI Integration Check (Skipped)
if: steps.secret_check.outputs.OPENAI_API_KEY_AVAILABLE != 'true'
run: |
echo "⊘ OpenAI integration check: SKIPPED (API key not configured)"

- name: ManyChat Integration Check
if: steps.secret_check.outputs.MANYCHAT_API_KEY_AVAILABLE == 'true'
run: |
echo "::group::ManyChat Connectivity Check"
echo "Performing dry-run connectivity check for ManyChat..."
echo "This is a placeholder check - no actual API calls are made."
echo ""

echo "Would execute: curl -X GET https://api.manychat.com/fb/subscriber -H \"Authorization: Bearer [MASKED]\""
echo "✓ ManyChat integration check: READY (dry-run mode)"
echo "::endgroup::"
env:
MANYCHAT_API_KEY: ${{ secrets.MANYCHAT_API_KEY }}

- name: ManyChat Integration Check (Skipped)
if: steps.secret_check.outputs.MANYCHAT_API_KEY_AVAILABLE != 'true'
run: |
echo "⊘ ManyChat integration check: SKIPPED (API key not configured)"

- name: BotBuilders Integration Check
if: steps.secret_check.outputs.BOTBUILDERS_API_KEY_AVAILABLE == 'true'
run: |
echo "::group::BotBuilders Connectivity Check"
echo "Performing dry-run connectivity check for BotBuilders..."
echo "This is a placeholder check - no actual API calls are made."
echo ""
# Note: Replace example.com URLs with actual API endpoints when ready for production
echo "Would execute: curl -X GET https://api.botbuilders.example.com/status -H \"X-API-Key: [MASKED]\""
echo "✓ BotBuilders integration check: READY (dry-run mode)"
echo "::endgroup::"
env:
BOTBUILDERS_API_KEY: ${{ secrets.BOTBUILDERS_API_KEY }}

- name: BotBuilders Integration Check (Skipped)
if: steps.secret_check.outputs.BOTBUILDERS_API_KEY_AVAILABLE != 'true'
run: |
echo "⊘ BotBuilders integration check: SKIPPED (API key not configured)"

- name: Moltbook Integration Check
if: steps.secret_check.outputs.MOLTBOOK_API_KEY_AVAILABLE == 'true'
run: |
echo "::group::Moltbook Connectivity Check"
echo "Performing dry-run connectivity check for Moltbook..."
echo "This is a placeholder check - no actual API calls are made."
echo ""
# Note: Replace example.com URLs with actual API endpoints when ready for production
echo "Would execute: curl -X GET https://api.moltbook.example.com/health -H \"Authorization: Bearer [MASKED]\""
echo "✓ Moltbook integration check: READY (dry-run mode)"
echo "::endgroup::"
env:
MOLTBOOK_API_KEY: ${{ secrets.MOLTBOOK_API_KEY }}

- name: Moltbook Integration Check (Skipped)
if: steps.secret_check.outputs.MOLTBOOK_API_KEY_AVAILABLE != 'true'
run: |
echo "⊘ Moltbook integration check: SKIPPED (API key not configured)"

- name: Moltbot Integration Check
if: steps.secret_check.outputs.MOLTBOT_API_KEY_AVAILABLE == 'true'
run: |
echo "::group::Moltbot Connectivity Check"
echo "Performing dry-run connectivity check for Moltbot..."
echo "This is a placeholder check - no actual API calls are made."
echo ""
# Note: Replace example.com URLs with actual API endpoints when ready for production
echo "Would execute: curl -X GET https://api.moltbot.example.com/ping -H \"X-API-Key: [MASKED]\""
echo "✓ Moltbot integration check: READY (dry-run mode)"
echo "::endgroup::"
env:
MOLTBOT_API_KEY: ${{ secrets.MOLTBOT_API_KEY }}

- name: Moltbot Integration Check (Skipped)
if: steps.secret_check.outputs.MOLTBOT_API_KEY_AVAILABLE != 'true'
run: |
echo "⊘ Moltbot integration check: SKIPPED (API key not configured)"

- name: OpenClaw Integration Check
if: steps.secret_check.outputs.OPENCLAW_API_KEY_AVAILABLE == 'true'
run: |
echo "::group::OpenClaw Connectivity Check"
echo "Performing dry-run connectivity check for OpenClaw..."
echo "This is a placeholder check - no actual API calls are made."
echo ""
# Note: Replace example.com URLs with actual API endpoints when ready for production
# Use custom base URL if provided, otherwise use default
BASE_URL="${SERVICE_BASE_URL_OPENCLAW:-https://api.openclaw.example.com}"
echo "Base URL: $BASE_URL"

echo "Would execute: curl -X GET $BASE_URL/status -H \"Authorization: Bearer [MASKED]\""
echo "✓ OpenClaw integration check: READY (dry-run mode)"
echo "::endgroup::"
env:
OPENCLAW_API_KEY: ${{ secrets.OPENCLAW_API_KEY }}
SERVICE_BASE_URL_OPENCLAW: ${{ secrets.SERVICE_BASE_URL_OPENCLAW }}

- name: OpenClaw Integration Check (Skipped)
if: steps.secret_check.outputs.OPENCLAW_API_KEY_AVAILABLE != 'true'
run: |
echo "⊘ OpenClaw integration check: SKIPPED (API key not configured)"

- name: GitHub API Integration Check
if: steps.secret_check.outputs.GITHUB_PAT_AVAILABLE == 'true'
run: |
echo "::group::GitHub API Connectivity Check"
echo "Performing dry-run connectivity check for GitHub API..."
echo "This is a placeholder check - no actual API calls are made."
echo ""

echo "Would execute: curl -X GET https://api.github.com/user -H \"Authorization: token [MASKED]\""
echo "✓ GitHub API integration check: READY (dry-run mode)"
echo "::endgroup::"
env:
GITHUB_PAT: ${{ secrets.GITHUB_PAT }}

- name: GitHub API Integration Check (Skipped)
if: steps.secret_check.outputs.GITHUB_PAT_AVAILABLE != 'true'
run: |
echo "⊘ GitHub API integration check: SKIPPED (Personal Access Token not configured)"

- name: Webhook Integration Check
if: steps.secret_check.outputs.WEBHOOK_URL_AVAILABLE == 'true'
run: |
echo "::group::Webhook Connectivity Check"
echo "Performing dry-run connectivity check for Webhook..."
echo "This is a placeholder check - no actual webhook calls are made."
echo ""

echo "Would execute: curl -X POST [WEBHOOK_URL_MASKED] -H \"Content-Type: application/json\" -d '{\"test\": true}'"
echo "✓ Webhook integration check: READY (dry-run mode)"
echo "::endgroup::"
env:
WEBHOOK_URL: ${{ secrets.WEBHOOK_URL }}

- name: Webhook Integration Check (Skipped)
if: steps.secret_check.outputs.WEBHOOK_URL_AVAILABLE != 'true'
run: |
echo "⊘ Webhook integration check: SKIPPED (Webhook URL not configured)"

- name: Summary
if: always()
run: |
echo "::group::Integration Checks Summary"
echo "==============================================="
echo "Service Integration Checks Completed"
echo "==============================================="
echo ""
echo "This workflow performed dry-run connectivity checks"
echo "for all configured service integrations."
echo ""
echo "All checks were executed in safe mode with no"
echo "actual API calls to prevent unintended side effects."
echo ""
echo "Review the logs above to see which services are"
echo "configured and ready for integration."
echo "::endgroup::"
104 changes: 104 additions & 0 deletions config/services.example.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
{
"description": "Example configuration for external service integrations. Copy to services.json and fill in actual values. NEVER commit secrets to version control.",
"services": {
"openai": {
"description": "OpenAI API integration",
"env_vars": {
"OPENAI_API_KEY": {
"description": "OpenAI API key for GPT and other AI services",
"required": true,
"example": "sk-..."
}
}
},
"manychat": {
"description": "ManyChat bot platform integration",
"env_vars": {
"MANYCHAT_API_KEY": {
"description": "ManyChat API key for chatbot operations",
"required": true,
"example": "mc_..."
}
}
},
"botbuilders": {
"description": "BotBuilders platform integration",
"env_vars": {
"BOTBUILDERS_API_KEY": {
"description": "BotBuilders API key",
"required": true,
"example": "bb_..."
}
}
},
"moltbook": {
"description": "Moltbook service integration",
"env_vars": {
"MOLTBOOK_API_KEY": {
"description": "Moltbook API key",
"required": true,
"example": "mb_..."
}
}
},
"moltbot": {
"description": "Moltbot service integration",
"env_vars": {
"MOLTBOT_API_KEY": {
"description": "Moltbot API key",
"required": true,
"example": "mbot_..."
}
}
},
"openclaw": {
"description": "OpenClaw service integration",
"env_vars": {
"OPENCLAW_API_KEY": {
"description": "OpenClaw API key",
"required": true,
"example": "oc_..."
},
"SERVICE_BASE_URL_OPENCLAW": {
"description": "Base URL for OpenClaw API endpoints",
"required": false,
"example": "https://api.openclaw.example.com"
}
}
},
"github": {
"description": "GitHub API integration (beyond current repository)",
"env_vars": {
"GITHUB_PAT": {
"description": "GitHub Personal Access Token for extended API access",
"required": false,
"example": "ghp_..."
}
}
},
"webhooks": {
"description": "Webhook configurations",
"env_vars": {
"WEBHOOK_URL": {
"description": "Generic webhook URL for notifications and callbacks",
"required": false,
"example": "https://example.com/webhook"
}
}
}
},
"service_base_url_pattern": {
"description": "For services requiring custom base URLs, use pattern: SERVICE_BASE_URL_<SERVICE_NAME>",
"examples": [
"SERVICE_BASE_URL_OPENCLAW",
"SERVICE_BASE_URL_MANYCHAT",
"SERVICE_BASE_URL_MOLTBOOK"
]
},
"notes": [
"All API keys should be stored in GitHub Secrets for CI/CD workflows",
"For local development, use .env file (never commit to git)",
"Required secrets must be configured for integrations workflow to succeed",
"Optional secrets will cause their respective checks to be skipped if not present"
]
}