diff --git a/.github/workflows/update-version.yml b/.github/workflows/update-version.yml new file mode 100644 index 00000000..9637bc85 --- /dev/null +++ b/.github/workflows/update-version.yml @@ -0,0 +1,88 @@ +name: Update WhatsApp Version + +on: + schedule: + # Run on the 1st of every month at 02:00 UTC + - cron: '0 0 * * 0' + workflow_dispatch: + +permissions: + contents: write + pull-requests: write + +jobs: + update-version: + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - uses: actions/checkout@v3 + + - name: Setup Node and Corepack + uses: actions/setup-node@v3.6.0 + with: + node-version: 20.x + + - name: Enable Corepack and Set Yarn Version + run: | + corepack enable + corepack prepare yarn@4.x --activate + + - name: Restore Yarn Cache + uses: actions/cache@v3 + id: yarn-cache + with: + path: .yarn/cache + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install packages + run: yarn install --immutable + + - name: Update WhatsApp Web Version + id: update_version + run: yarn update:version + + - name: Check for changes + id: check_changes + run: | + if git diff --quiet; then + echo "has_changes=false" >> $GITHUB_OUTPUT + else + echo "has_changes=true" >> $GITHUB_OUTPUT + fi + + - name: Create Pull Request + if: steps.check_changes.outputs.has_changes == 'true' + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + BRANCH_NAME="update-version/stable" + + # Configure git + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + # Check if branch exists and delete it + git push origin --delete "$BRANCH_NAME" 2>/dev/null || true + + # Create new branch, commit, and push + git checkout -b "$BRANCH_NAME" + git add src/Defaults/baileys-version.json src/Defaults/index.ts src/Utils/generics.ts + git commit -m "chore: update WhatsApp Web version" + git push origin "$BRANCH_NAME" + + # Create PR using GitHub CLI + gh pr create \ + --title "chore: update WhatsApp Web version" \ + --body "Automated WhatsApp Web version update. + + This PR updates the WhatsApp Web client revision to the latest version fetched from \`web.whatsapp.com\`. + + **Files updated:** + - \`src/Defaults/baileys-version.json\` + - \`src/Defaults/index.ts\` + - \`src/Utils/generics.ts\`" \ + --base master \ + --head "$BRANCH_NAME" || echo "PR already exists or could not be created" diff --git a/package.json b/package.json index ea1698cc..cda0ecaa 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,8 @@ "preinstall": "node ./engine-requirements.js", "release": "release-it", "test": "node --experimental-vm-modules ./node_modules/.bin/jest --testMatch '**/*.test.ts'", - "test:e2e": "node --experimental-vm-modules ./node_modules/.bin/jest --testMatch '**/*.test-e2e.ts'" + "test:e2e": "node --experimental-vm-modules ./node_modules/.bin/jest --testMatch '**/*.test-e2e.ts'", + "update:version": "tsx ./scripts/update-version.ts" }, "dependencies": { "@cacheable/node-cache": "^1.4.0", diff --git a/scripts/update-version.ts b/scripts/update-version.ts new file mode 100644 index 00000000..f540f9d3 --- /dev/null +++ b/scripts/update-version.ts @@ -0,0 +1,149 @@ +#!/usr/bin/env node +/** + * Script to update WhatsApp Web version across the codebase. + * Fetches the latest version from web.whatsapp.com and updates: + * - src/Defaults/baileys-version.json + * - src/Defaults/index.ts + * - src/Utils/generics.ts + * + * Usage: yarn update:version + */ + +import { readFileSync, writeFileSync } from 'fs' +import { dirname, join } from 'path' +import { fileURLToPath } from 'url' +import { fetchLatestWaWebVersion } from '../src/Utils/generics.ts' + +const __filename = fileURLToPath(import.meta.url) +const __dirname = dirname(__filename) +const ROOT_DIR = join(__dirname, '..') + +function updateBaileysVersionJson(version: [number, number, number]): boolean { + const filePath = join(ROOT_DIR, 'src/Defaults/baileys-version.json') + const content = { + version + } + + try { + const currentContent = readFileSync(filePath, 'utf-8') + const currentVersion = JSON.parse(currentContent).version as number[] + + if (currentVersion[0] === version[0] && currentVersion[1] === version[1] && currentVersion[2] === version[2]) { + console.log(`✓ baileys-version.json already up to date`) + return false + } + + writeFileSync(filePath, JSON.stringify(content) + '\n') + console.log(`✓ Updated baileys-version.json: [${currentVersion.join(', ')}] → [${version.join(', ')}]`) + return true + } catch (error) { + console.error(`✗ Failed to update baileys-version.json:`, error) + throw error + } +} + +function updateGenerics(version: [number, number, number]): boolean { + const filePath = join(ROOT_DIR, 'src/Utils/generics.ts') + + try { + const content = readFileSync(filePath, 'utf-8') + const versionRegex = /const baileysVersion = \[(\d+),\s*(\d+),\s*(\d+)\]/ + const match = content.match(versionRegex) + + if (!match) { + throw new Error('Could not find baileysVersion declaration in generics.ts') + } + + const currentVersion = [+match[1]!, +match[2]!, +match[3]!] + + if (currentVersion[0] === version[0] && currentVersion[1] === version[1] && currentVersion[2] === version[2]) { + console.log(`✓ src/Utils/generics.ts already up to date`) + return false + } + + const newContent = content.replace( + versionRegex, + `const baileysVersion = [${version[0]}, ${version[1]}, ${version[2]}]` + ) + + writeFileSync(filePath, newContent) + console.log(`✓ Updated src/Utils/generics.ts: [${currentVersion.join(', ')}] → [${version.join(', ')}]`) + return true + } catch (error) { + console.error(`✗ Failed to update src/Utils/generics.ts:`, error) + throw error + } +} + +function updateIndex(version: [number, number, number]): boolean { + const filePath = join(ROOT_DIR, 'src/Defaults/index.ts') + + try { + const content = readFileSync(filePath, 'utf-8') + const versionRegex = /const version = \[(\d+),\s*(\d+),\s*(\d+)\]/ + const match = content.match(versionRegex) + + if (!match) { + throw new Error('Could not find version declaration in index.ts') + } + + const currentVersion = [+match[1]!, +match[2]!, +match[3]!] + + if (currentVersion[0] === version[0] && currentVersion[1] === version[1] && currentVersion[2] === version[2]) { + console.log(`✓ src/Defaults/index.ts already up to date`) + return false + } + + const newContent = content.replace(versionRegex, `const version = [${version[0]}, ${version[1]}, ${version[2]}]`) + + writeFileSync(filePath, newContent) + console.log(`✓ Updated src/Defaults/index.ts: [${currentVersion.join(', ')}] → [${version.join(', ')}]`) + return true + } catch (error) { + console.error(`✗ Failed to update src/Defaults/index.ts:`, error) + throw error + } +} + +async function main() { + console.log('Fetching latest WhatsApp Web version...\n') + + const result = await fetchLatestWaWebVersion() + + if (!result.isLatest) { + console.error('Failed to fetch latest version:', result.error) + process.exit(1) + } + + console.log(`Latest version: [${result.version.join(', ')}]\n`) + + const updates = [ + updateBaileysVersionJson(result.version), + updateGenerics(result.version), + updateIndex(result.version) + ] + + const hasUpdates = updates.some(Boolean) + + console.log('') + if (hasUpdates) { + console.log('Version update complete!') + // Set GitHub Actions output if running in CI + if (process.env.GITHUB_OUTPUT) { + const { appendFileSync } = await import('fs') + appendFileSync(process.env.GITHUB_OUTPUT, `updated=true\n`) + appendFileSync(process.env.GITHUB_OUTPUT, `version=${result.version.join('.')}\n`) + } + } else { + console.log('All files are already up to date.') + if (process.env.GITHUB_OUTPUT) { + const { appendFileSync } = await import('fs') + appendFileSync(process.env.GITHUB_OUTPUT, `updated=false\n`) + } + } +} + +main().catch(error => { + console.error('Fatal error:', error) + process.exit(1) +}) diff --git a/src/Defaults/baileys-version.json b/src/Defaults/baileys-version.json index 68e0f526..2f3f16d8 100644 --- a/src/Defaults/baileys-version.json +++ b/src/Defaults/baileys-version.json @@ -1,3 +1 @@ -{ - "version": [2, 3000, 1027934701] -} +{"version":[2,3000,1027934701]}