add ci for tg bot
Deploy app frontend / app frontend (push) Failing after 54s
Deploy service couchdb / service couchdb (push) Successful in 38s
Deploy db-migrations / db-migrations (push) Failing after 50s
Deploy service message-delivery-method-web-push / service message-delivery-method-web-push (push) Failing after 1m27s
Deploy service tg-bot / service tg-bot (push) Failing after 44s
Deploy app frontend / app frontend (push) Failing after 54s
Deploy service couchdb / service couchdb (push) Successful in 38s
Deploy db-migrations / db-migrations (push) Failing after 50s
Deploy service message-delivery-method-web-push / service message-delivery-method-web-push (push) Failing after 1m27s
Deploy service tg-bot / service tg-bot (push) Failing after 44s
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
name: Deploy service tg-bot
|
||||
run-name: ${{ github.actor }} deployed to build branch
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
paths:
|
||||
- 'services/tg-bot/**'
|
||||
- 'packages/couchdb-changes-stream/**'
|
||||
- '.gitea/workflows/deploy-service-tg-bot.yaml'
|
||||
- 'docker-compose.yml'
|
||||
- 'package.json'
|
||||
- 'pnpm-lock.yaml'
|
||||
|
||||
jobs:
|
||||
service tg-bot:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
env:
|
||||
COUCHDB_USER: ${{ secrets.COUCHDB_USER }}
|
||||
COUCHDB_PASSWORD: ${{ secrets.COUCHDB_PASSWORD }}
|
||||
VAPID_SUBJECT: ${{ vars.VAPID_SUBJECT }}
|
||||
GCM_API_KEY: ${{ vars.GCM_API_KEY }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '22'
|
||||
|
||||
- name: install dependencies
|
||||
run: |
|
||||
corepack enable pnpm && corepack use pnpm@8.15.9
|
||||
pnpm install --filter ./services/tg-bot
|
||||
|
||||
- name: build service
|
||||
run: |
|
||||
pnpm run --filter ./services/tg-bot build
|
||||
pnpm --filter ./services/tg-bot deploy --prod build/service-tg-bot
|
||||
|
||||
- name: build docker image
|
||||
run: MESSAGE_DELIVERY_METHOD_WEB_PUSH_TAG=commit-${{env.GITHUB_SHA}} docker compose -p hereconnect build tg-bot
|
||||
|
||||
- name: start container
|
||||
run: MESSAGE_DELIVERY_METHOD_WEB_PUSH_TAG=commit-${{env.GITHUB_SHA}} docker compose -p hereconnect up -d --pull never --wait tg-bot
|
||||
|
||||
- name: rename to latest
|
||||
run: docker tag hereconnect/service-tg-bot:commit-${{env.GITHUB_SHA}} hereconnect/service-tg-bot:latest
|
||||
|
||||
- name: rollback on failure
|
||||
if: failure()
|
||||
env:
|
||||
COUCHDB_TAG: latest
|
||||
run: docker compose -p hereconnect up -d --pull never --wait tg-bot
|
||||
|
||||
- name: cleanup docker image
|
||||
if: always()
|
||||
run: docker rmi hereconnect/service-tg-bot:commit-${{env.GITHUB_SHA}}
|
||||
@@ -60,3 +60,25 @@ services:
|
||||
options:
|
||||
max-size: "100m"
|
||||
max-file: "10"
|
||||
|
||||
tg-bot:
|
||||
image: hereconnect/service-tg-bot:${MESSAGE_DELIVERY_METHOD_WEB_PUSH_TAG:-latest}
|
||||
build:
|
||||
context: build/service-tg-bot
|
||||
dockerfile: ../../services/tg-bot/Dockerfile
|
||||
environment:
|
||||
- API_URL=http://${COUCHDB_USER}:${COUCHDB_PASSWORD}@couchdb:5984
|
||||
- BOT_TOKEN=${BOT_TOKEN:-}
|
||||
- READ_BASE_URL=${READ_BASE_URL:-}
|
||||
depends_on:
|
||||
couchdb:
|
||||
condition: service_healthy
|
||||
restart: true
|
||||
db-migrations:
|
||||
condition: service_completed_successfully
|
||||
restart: unless-stopped
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "100m"
|
||||
max-file: "10"
|
||||
|
||||
+4
-3
@@ -15,10 +15,11 @@
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"start": "npm run start --workspace=apps/frontend",
|
||||
"build": "npm run build:deploy:services:message-delivery-method-web-push && npm run build:deploy:services:db-migrations",
|
||||
"build:deploy:services:message-delivery-method-web-push": "npm -w ./services/message-delivery-method-web-push run build && pnpm --filter ./services/message-delivery-method-web-push deploy --prod build/service-message-delivery-method-web-push",
|
||||
"start": "pnpm run --filter ./apps/frontend dev",
|
||||
"build": "npm run build:deploy:services:db-migrations && npm run build:deploy:services:message-delivery-method-web-push && npm run build:deploy:services:tg-bot",
|
||||
"build:deploy:services:db-migrations": "pnpm --filter ./services/db-migrations deploy --prod build/service-db-migrations",
|
||||
"build:deploy:services:message-delivery-method-web-push": "npm -w ./services/message-delivery-method-web-push run build && pnpm --filter ./services/message-delivery-method-web-push deploy --prod build/service-message-delivery-method-web-push",
|
||||
"build:deploy:services:tg-bot": "pnpm --filter ./services/tg-bot deploy --prod build/service-tg-bot",
|
||||
"test": "npm run test --workspaces",
|
||||
"lint": "npm run lint --workspaces"
|
||||
},
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
{
|
||||
"name": "@hereconnect/constants",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.ts",
|
||||
"types": "dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.js",
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
{
|
||||
"name": "@hereconnect/lib-service-health-checkserver",
|
||||
"version": "1.0.0",
|
||||
"main": "src/health-server.ts",
|
||||
"type": "module",
|
||||
"main": "dist/health-server.js",
|
||||
"types": "dist/health-server.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./src/health-server.ts",
|
||||
"default": "./src/health-server.ts"
|
||||
"import": "./dist/health-server.js",
|
||||
"types": "./dist/health-server.d.ts",
|
||||
"default": "./dist/health-server.js"
|
||||
}
|
||||
},
|
||||
"files": ["src/**/*"],
|
||||
"files": ["dist/**/*"],
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"lint": "tsc --noEmit src/health-server.ts",
|
||||
"build": "pnpm run lint"
|
||||
"build": "tsc",
|
||||
"prepare": "npm run build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.17.6",
|
||||
|
||||
@@ -1,10 +1,15 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"declaration": true,
|
||||
"emitDeclarationOnly": true,
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "node",
|
||||
"outDir": "./dist",
|
||||
"strict": true,
|
||||
"types": ["node"]
|
||||
"types": ["node"],
|
||||
"esModuleInterop": true,
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": ["index.ts"]
|
||||
"files": ["src/health-server.ts"],
|
||||
"exclude": ["node_modules", "dist"]
|
||||
}
|
||||
Generated
+10
-265
@@ -331,6 +331,9 @@ importers:
|
||||
|
||||
services/tg-bot:
|
||||
dependencies:
|
||||
'@grammyjs/conversations':
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0(grammy@1.33.0)
|
||||
'@hereconnect/constants':
|
||||
specifier: workspace:^
|
||||
version: link:../../packages/constants
|
||||
@@ -383,9 +386,6 @@ importers:
|
||||
specifier: ^3.3.2
|
||||
version: 3.3.2
|
||||
devDependencies:
|
||||
'@grammyjs/conversations':
|
||||
specifier: ^1.2.0
|
||||
version: 1.2.0(grammy@1.33.0)
|
||||
'@grammyjs/types':
|
||||
specifier: ^3.17.0
|
||||
version: 3.17.0
|
||||
@@ -416,12 +416,6 @@ importers:
|
||||
'@typescript-eslint/parser':
|
||||
specifier: ^8.18.0
|
||||
version: 8.18.0(eslint@9.16.0)(typescript@5.7.2)
|
||||
esbuild:
|
||||
specifier: ^0.24.0
|
||||
version: 0.24.0
|
||||
esbuild-copy-static-files:
|
||||
specifier: ^0.1.0
|
||||
version: 0.1.0
|
||||
eslint:
|
||||
specifier: ^9.16.0
|
||||
version: 9.16.0
|
||||
@@ -748,14 +742,14 @@ packages:
|
||||
|
||||
/@deno/shim-deno-test@0.4.0:
|
||||
resolution: {integrity: sha512-oYWcD7CpERZy/TXMTM9Tgh1HD/POHlbY9WpzmAk+5H8DohcxG415Qws8yLGlim3EaKBT2v3lJv01x4G0BosnaQ==}
|
||||
dev: true
|
||||
dev: false
|
||||
|
||||
/@deno/shim-deno@0.16.1:
|
||||
resolution: {integrity: sha512-s9v0kzF5bm/o9TgdwvsraHx6QNllYrXXmKzgOG2lh4LFXnVMr2gpjK/c/ve6EflQn1MqImcWmVD8HAv5ahuuZQ==}
|
||||
dependencies:
|
||||
'@deno/shim-deno-test': 0.4.0
|
||||
which: 2.0.2
|
||||
dev: true
|
||||
dev: false
|
||||
|
||||
/@emnapi/runtime@1.3.1:
|
||||
resolution: {integrity: sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==}
|
||||
@@ -783,15 +777,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/aix-ppc64@0.24.0:
|
||||
resolution: {integrity: sha512-WtKdFM7ls47zkKHFVzMz8opM7LkcsIp9amDUBIAWirg70RM71WRSjdILPsY5Uv1D42ZpUfaPILDlfactHgsRkw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [aix]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-arm64@0.21.5:
|
||||
resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -810,15 +795,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-arm64@0.24.0:
|
||||
resolution: {integrity: sha512-Vsm497xFM7tTIPYK9bNTYJyF/lsP590Qc1WxJdlB6ljCbdZKU9SY8i7+Iin4kyhV/KV5J2rOKsBQbB77Ab7L/w==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-arm@0.21.5:
|
||||
resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -837,15 +813,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-arm@0.24.0:
|
||||
resolution: {integrity: sha512-arAtTPo76fJ/ICkXWetLCc9EwEHKaeya4vMrReVlEIUCAUncH7M4bhMQ+M9Vf+FFOZJdTNMXNBrWwW+OXWpSew==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-x64@0.21.5:
|
||||
resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -864,15 +831,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/android-x64@0.24.0:
|
||||
resolution: {integrity: sha512-t8GrvnFkiIY7pa7mMgJd7p8p8qqYIz1NYiAoKc75Zyv73L3DZW++oYMSHPRarcotTKuSs6m3hTOa5CKHaS02TQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [android]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/darwin-arm64@0.21.5:
|
||||
resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -891,15 +849,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/darwin-arm64@0.24.0:
|
||||
resolution: {integrity: sha512-CKyDpRbK1hXwv79soeTJNHb5EiG6ct3efd/FTPdzOWdbZZfGhpbcqIpiD0+vwmpu0wTIL97ZRPZu8vUt46nBSw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/darwin-x64@0.21.5:
|
||||
resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -918,15 +867,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/darwin-x64@0.24.0:
|
||||
resolution: {integrity: sha512-rgtz6flkVkh58od4PwTRqxbKH9cOjaXCMZgWD905JOzjFKW+7EiUObfd/Kav+A6Gyud6WZk9w+xu6QLytdi2OA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/freebsd-arm64@0.21.5:
|
||||
resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -945,15 +885,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/freebsd-arm64@0.24.0:
|
||||
resolution: {integrity: sha512-6Mtdq5nHggwfDNLAHkPlyLBpE5L6hwsuXZX8XNmHno9JuL2+bg2BX5tRkwjyfn6sKbxZTq68suOjgWqCicvPXA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/freebsd-x64@0.21.5:
|
||||
resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -972,15 +903,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/freebsd-x64@0.24.0:
|
||||
resolution: {integrity: sha512-D3H+xh3/zphoX8ck4S2RxKR6gHlHDXXzOf6f/9dbFt/NRBDIE33+cVa49Kil4WUjxMGW0ZIYBYtaGCa2+OsQwQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [freebsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-arm64@0.21.5:
|
||||
resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -999,15 +921,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-arm64@0.24.0:
|
||||
resolution: {integrity: sha512-TDijPXTOeE3eaMkRYpcy3LarIg13dS9wWHRdwYRnzlwlA370rNdZqbcp0WTyyV/k2zSxfko52+C7jU5F9Tfj1g==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-arm@0.21.5:
|
||||
resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1026,15 +939,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-arm@0.24.0:
|
||||
resolution: {integrity: sha512-gJKIi2IjRo5G6Glxb8d3DzYXlxdEj2NlkixPsqePSZMhLudqPhtZ4BUrpIuTjJYXxvF9njql+vRjB2oaC9XpBw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-ia32@0.21.5:
|
||||
resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1053,15 +957,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-ia32@0.24.0:
|
||||
resolution: {integrity: sha512-K40ip1LAcA0byL05TbCQ4yJ4swvnbzHscRmUilrmP9Am7//0UjPreh4lpYzvThT2Quw66MhjG//20mrufm40mA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-loong64@0.21.5:
|
||||
resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1080,15 +975,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-loong64@0.24.0:
|
||||
resolution: {integrity: sha512-0mswrYP/9ai+CU0BzBfPMZ8RVm3RGAN/lmOMgW4aFUSOQBjA31UP8Mr6DDhWSuMwj7jaWOT0p0WoZ6jeHhrD7g==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [loong64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-mips64el@0.21.5:
|
||||
resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1107,15 +993,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-mips64el@0.24.0:
|
||||
resolution: {integrity: sha512-hIKvXm0/3w/5+RDtCJeXqMZGkI2s4oMUGj3/jM0QzhgIASWrGO5/RlzAzm5nNh/awHE0A19h/CvHQe6FaBNrRA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [mips64el]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-ppc64@0.21.5:
|
||||
resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1134,15 +1011,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-ppc64@0.24.0:
|
||||
resolution: {integrity: sha512-HcZh5BNq0aC52UoocJxaKORfFODWXZxtBaaZNuN3PUX3MoDsChsZqopzi5UupRhPHSEHotoiptqikjN/B77mYQ==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ppc64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-riscv64@0.21.5:
|
||||
resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1161,15 +1029,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-riscv64@0.24.0:
|
||||
resolution: {integrity: sha512-bEh7dMn/h3QxeR2KTy1DUszQjUrIHPZKyO6aN1X4BCnhfYhuQqedHaa5MxSQA/06j3GpiIlFGSsy1c7Gf9padw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [riscv64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-s390x@0.21.5:
|
||||
resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1188,15 +1047,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-s390x@0.24.0:
|
||||
resolution: {integrity: sha512-ZcQ6+qRkw1UcZGPyrCiHHkmBaj9SiCD8Oqd556HldP+QlpUIe2Wgn3ehQGVoPOvZvtHm8HPx+bH20c9pvbkX3g==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [s390x]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-x64@0.21.5:
|
||||
resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1215,15 +1065,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/linux-x64@0.24.0:
|
||||
resolution: {integrity: sha512-vbutsFqQ+foy3wSSbmjBXXIJ6PL3scghJoM8zCL142cGaZKAdCZHyf+Bpu/MmX9zT9Q0zFBVKb36Ma5Fzfa8xA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [linux]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/netbsd-x64@0.21.5:
|
||||
resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1242,15 +1083,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/netbsd-x64@0.24.0:
|
||||
resolution: {integrity: sha512-hjQ0R/ulkO8fCYFsG0FZoH+pWgTTDreqpqY7UnQntnaKv95uP5iW3+dChxnx7C3trQQU40S+OgWhUVwCjVFLvg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [netbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/openbsd-arm64@0.23.1:
|
||||
resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==}
|
||||
engines: {node: '>=18'}
|
||||
@@ -1260,15 +1092,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/openbsd-arm64@0.24.0:
|
||||
resolution: {integrity: sha512-MD9uzzkPQbYehwcN583yx3Tu5M8EIoTD+tUgKF982WYL9Pf5rKy9ltgD0eUgs8pvKnmizxjXZyLt0z6DC3rRXg==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [openbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/openbsd-x64@0.21.5:
|
||||
resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1287,15 +1110,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/openbsd-x64@0.24.0:
|
||||
resolution: {integrity: sha512-4ir0aY1NGUhIC1hdoCzr1+5b43mw99uNwVzhIq1OY3QcEwPDO3B7WNXBzaKY5Nsf1+N11i1eOfFcq+D/gOS15Q==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [openbsd]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/sunos-x64@0.21.5:
|
||||
resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1314,15 +1128,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/sunos-x64@0.24.0:
|
||||
resolution: {integrity: sha512-jVzdzsbM5xrotH+W5f1s+JtUy1UWgjU0Cf4wMvffTB8m6wP5/kx0KiaLHlbJO+dMgtxKV8RQ/JvtlFcdZ1zCPA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [sunos]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-arm64@0.21.5:
|
||||
resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1341,15 +1146,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-arm64@0.24.0:
|
||||
resolution: {integrity: sha512-iKc8GAslzRpBytO2/aN3d2yb2z8XTVfNV0PjGlCxKo5SgWmNXx82I/Q3aG1tFfS+A2igVCY97TJ8tnYwpUWLCA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [arm64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-ia32@0.21.5:
|
||||
resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1368,15 +1164,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-ia32@0.24.0:
|
||||
resolution: {integrity: sha512-vQW36KZolfIudCcTnaTpmLQ24Ha1RjygBo39/aLkM2kmjkWmZGEJ5Gn9l5/7tzXA42QGIoWbICfg6KLLkIw6yw==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [ia32]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-x64@0.21.5:
|
||||
resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -1395,15 +1182,6 @@ packages:
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@esbuild/win32-x64@0.24.0:
|
||||
resolution: {integrity: sha512-7IAFPrjSQIJrGsK6flwg7NFmwBoSTyF3rl7If0hNUFQU4ilTsEPL6GuMuU9BfIWVVGuRnuIidkSMC+c0Otu8IA==}
|
||||
engines: {node: '>=18'}
|
||||
cpu: [x64]
|
||||
os: [win32]
|
||||
requiresBuild: true
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@eslint-community/eslint-utils@4.4.1(eslint@9.15.0):
|
||||
resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
@@ -1504,7 +1282,7 @@ packages:
|
||||
o-son: 1.0.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
dev: false
|
||||
|
||||
/@grammyjs/types@3.17.0:
|
||||
resolution: {integrity: sha512-e8AR3xQwRAFX248E7Qw/7mIu1OzvoXloJzOBJVtuPKzzL7tGkn5trZAdZUBgGViVQg5ZwVS/x9N2nRrcyH/DfA==}
|
||||
@@ -3017,6 +2795,7 @@ packages:
|
||||
engines: {node: '>=6.5'}
|
||||
dependencies:
|
||||
event-target-shim: 5.0.1
|
||||
dev: false
|
||||
|
||||
/acorn-jsx@5.3.2(acorn@8.14.0):
|
||||
resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
|
||||
@@ -3614,10 +3393,6 @@ packages:
|
||||
resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==}
|
||||
dev: true
|
||||
|
||||
/esbuild-copy-static-files@0.1.0:
|
||||
resolution: {integrity: sha512-KlpmYqANA1t2nZavEdItfcOjJC6wbHA21v35HJWN32DddGTWKNNGDKljUzbCPojmpD+wAw8/DXr5abJ4jFCE0w==}
|
||||
dev: true
|
||||
|
||||
/esbuild@0.21.5:
|
||||
resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -3681,38 +3456,6 @@ packages:
|
||||
'@esbuild/win32-x64': 0.23.1
|
||||
dev: true
|
||||
|
||||
/esbuild@0.24.0:
|
||||
resolution: {integrity: sha512-FuLPevChGDshgSicjisSooU0cemp/sGXR841D5LHMB7mTVOmsEHcAxaH3irL53+8YDIeVNQEySh4DaYU/iuPqQ==}
|
||||
engines: {node: '>=18'}
|
||||
hasBin: true
|
||||
requiresBuild: true
|
||||
optionalDependencies:
|
||||
'@esbuild/aix-ppc64': 0.24.0
|
||||
'@esbuild/android-arm': 0.24.0
|
||||
'@esbuild/android-arm64': 0.24.0
|
||||
'@esbuild/android-x64': 0.24.0
|
||||
'@esbuild/darwin-arm64': 0.24.0
|
||||
'@esbuild/darwin-x64': 0.24.0
|
||||
'@esbuild/freebsd-arm64': 0.24.0
|
||||
'@esbuild/freebsd-x64': 0.24.0
|
||||
'@esbuild/linux-arm': 0.24.0
|
||||
'@esbuild/linux-arm64': 0.24.0
|
||||
'@esbuild/linux-ia32': 0.24.0
|
||||
'@esbuild/linux-loong64': 0.24.0
|
||||
'@esbuild/linux-mips64el': 0.24.0
|
||||
'@esbuild/linux-ppc64': 0.24.0
|
||||
'@esbuild/linux-riscv64': 0.24.0
|
||||
'@esbuild/linux-s390x': 0.24.0
|
||||
'@esbuild/linux-x64': 0.24.0
|
||||
'@esbuild/netbsd-x64': 0.24.0
|
||||
'@esbuild/openbsd-arm64': 0.24.0
|
||||
'@esbuild/openbsd-x64': 0.24.0
|
||||
'@esbuild/sunos-x64': 0.24.0
|
||||
'@esbuild/win32-arm64': 0.24.0
|
||||
'@esbuild/win32-ia32': 0.24.0
|
||||
'@esbuild/win32-x64': 0.24.0
|
||||
dev: true
|
||||
|
||||
/escalade@3.2.0:
|
||||
resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
|
||||
engines: {node: '>=6'}
|
||||
@@ -3998,6 +3741,7 @@ packages:
|
||||
/event-target-shim@5.0.1:
|
||||
resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==}
|
||||
engines: {node: '>=6'}
|
||||
dev: false
|
||||
|
||||
/events@3.3.0:
|
||||
resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==}
|
||||
@@ -4329,6 +4073,7 @@ packages:
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- supports-color
|
||||
dev: false
|
||||
|
||||
/graphemer@1.4.0:
|
||||
resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==}
|
||||
@@ -5101,7 +4846,7 @@ packages:
|
||||
resolution: {integrity: sha512-tdGKxZgiTexSv97/igC2m8Y6FljgwvwHW/Zy3ql3Jx6MPKrPKaBDLhV7rz8uuLjcDPw6Pxa2PVsnWwen59MmnQ==}
|
||||
dependencies:
|
||||
'@deno/shim-deno': 0.16.1
|
||||
dev: true
|
||||
dev: false
|
||||
|
||||
/object-assign@4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
FROM oven/bun:1.1.38-alpine
|
||||
FROM node:22-alpine
|
||||
|
||||
COPY . ./
|
||||
|
||||
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=1 \
|
||||
CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:8000/health || exit 1
|
||||
|
||||
CMD ["bun", "dist/server.js"]
|
||||
CMD ["npm", "start"]
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
import esbuild from "esbuild";
|
||||
import copyStaticFiles from "esbuild-copy-static-files";
|
||||
|
||||
esbuild
|
||||
.build({
|
||||
entryPoints: ["./src/bot/index.ts"], // Точка входа
|
||||
outdir: "./dist", // Папка выхода
|
||||
format: "esm", // Формат (ESM)
|
||||
bundle: true, // Сборка в один файл
|
||||
sourcemap: true, // Карты кода
|
||||
platform: "node", // Платформа (Node.js)
|
||||
target: ["node20"], // Целевая версия Node.js
|
||||
external: ["canvas"], // Исключить модуль canvas
|
||||
plugins: [
|
||||
copyStaticFiles({
|
||||
src: "./src/assets", // Папка с вашими статическими файлами
|
||||
dest: "./dist/assets", // Куда копировать
|
||||
}),
|
||||
],
|
||||
})
|
||||
.then(() => console.log("Build complete!"))
|
||||
.catch((err) => {
|
||||
console.error("Build failed:", err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -38,6 +38,7 @@
|
||||
"start": "node --import=extensionless/register dist/bot/index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@grammyjs/conversations": "^1.2.0",
|
||||
"@hereconnect/constants": "workspace:^",
|
||||
"@hereconnect/couchdb-changes-stream": "workspace:^",
|
||||
"@hereconnect/lib-service-health-checkserver": "workspace:^",
|
||||
@@ -57,7 +58,6 @@
|
||||
"svgo": "^3.3.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@grammyjs/conversations": "^1.2.0",
|
||||
"@grammyjs/types": "^3.17.0",
|
||||
"@hereconnect/types": "workspace:^",
|
||||
"@types/bun": "^1.1.14",
|
||||
@@ -68,8 +68,6 @@
|
||||
"@types/pouchdb-upsert": "^2.2.9",
|
||||
"@typescript-eslint/eslint-plugin": "^8.18.0",
|
||||
"@typescript-eslint/parser": "^8.18.0",
|
||||
"esbuild": "^0.24.0",
|
||||
"esbuild-copy-static-files": "^0.1.0",
|
||||
"eslint": "^9.16.0",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.7.2"
|
||||
|
||||
@@ -50,7 +50,7 @@ interface CreateQRCodeOptions {
|
||||
userUuid: string;
|
||||
name: string;
|
||||
placement: QRCodeDocument["placement"];
|
||||
actions: string[];
|
||||
actions: QRCodeDocument["actions"];
|
||||
messageDeliveryMethod?: QRCodeDocument["messageDeliveryMethod"];
|
||||
browser_uuid?: string;
|
||||
telegram_id?: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { MyContext } from "@/types/myContext";
|
||||
import { getQRCodesByUser } from "@/api/qrCodes";
|
||||
import { buildManageKeyboard } from "@/bot/utils/keyboards";
|
||||
import { MyContext } from "../../types/myContext";
|
||||
import { getQRCodesByUser } from "../../api/qrCodes";
|
||||
import { buildManageKeyboard } from "../../bot/utils/keyboards";
|
||||
|
||||
/**
|
||||
* Обработка команды /manage с выводом подменю
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import { Bot } from "grammy";
|
||||
import { MyContext } from "../../types/myContext";
|
||||
import { bot } from "old_bot"; // Ваш кастомный контекст
|
||||
import { MyContext } from "../../types/myContext"; // Ваш кастомный контекст
|
||||
|
||||
/**
|
||||
* Устанавливает команды для бота.
|
||||
* @param bot - Экземпляр бота.
|
||||
*/
|
||||
export async function setupCommands(bot: Bot<MyContext>): Promise<void> {
|
||||
// Настройка команд для английского языка (по умолчанию)
|
||||
@@ -32,6 +30,4 @@ export async function setupCommands(bot: Bot<MyContext>): Promise<void> {
|
||||
],
|
||||
{ language_code: "ru" },
|
||||
);
|
||||
|
||||
console.log("Команды успешно установлены.");
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
} from "../utils/keyboards";
|
||||
import { createQRCode } from "../../api/qrCodes";
|
||||
import { generateQRCodeImage } from "../../services/qrGenerator";
|
||||
import { selectMultipleActions } from "./selectMultipleActions";
|
||||
|
||||
// Тип разговора (конверсии)
|
||||
type MyConversation = Conversation<MyContext>;
|
||||
@@ -67,34 +68,25 @@ export async function newQRCodeConversation(
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Выбор действий, доступных при сканировании
|
||||
await ctx.reply(
|
||||
"Выберите одно или несколько действий, которые будут доступны при сканировании этого QR-кода:",
|
||||
{
|
||||
reply_markup: {
|
||||
inline_keyboard: buildActionsKeyboard([
|
||||
{ action: "sendMessage", label: "Отправить сообщение" },
|
||||
{ action: "viewContactInfo", label: "Посмотреть контактные данные" },
|
||||
]),
|
||||
},
|
||||
},
|
||||
// 3. Выбор действий
|
||||
const availableActions = [
|
||||
{ action: "sendMessage", label: "📩 Отправить сообщение" },
|
||||
{ action: "viewContactInfo", label: "📞 Посмотреть контактные данные" },
|
||||
] as const;
|
||||
|
||||
const chosenActions = await selectMultipleActions(
|
||||
conversation,
|
||||
ctx,
|
||||
availableActions,
|
||||
);
|
||||
|
||||
const actionsMsg = await conversation.waitFor("callback_query:data");
|
||||
const chosenAction = actionsMsg.update.callback_query?.data;
|
||||
if (!chosenAction) {
|
||||
await ctx.reply("Вы не выбрали действие. Попробуйте снова /new.");
|
||||
if (chosenActions.length === 0) {
|
||||
await ctx.reply("Вы не выбрали ни одного действия. Попробуйте снова /new.");
|
||||
return;
|
||||
}
|
||||
|
||||
// Подтверждаем выбор
|
||||
await actionsMsg.answerCallbackQuery({ text: "Действие выбрано!" });
|
||||
|
||||
// Пока для MVP можно выбрать только одно действие, в будущем можно расширить
|
||||
const chosenActions = [chosenAction];
|
||||
|
||||
// 4. Создание документа в БД
|
||||
const { url, uri } = await createQRCode({
|
||||
const { url } = await createQRCode({
|
||||
userUuid,
|
||||
name,
|
||||
placement: typedPlacement,
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
import { MyContext } from "../../types/myContext";
|
||||
import { Conversation } from "@grammyjs/conversations";
|
||||
|
||||
// Тип разговора
|
||||
type MyConversation = Conversation<MyContext>;
|
||||
|
||||
interface Action {
|
||||
readonly action: string;
|
||||
readonly label: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Обработчик выбора нескольких действий
|
||||
* @param conversation - Инстанс Conversation
|
||||
* @param ctx - Контекст
|
||||
* @param availableActions - Список доступных действий
|
||||
* @returns Список выбранных действий
|
||||
*/
|
||||
export async function selectMultipleActions<T extends readonly Action[]>(
|
||||
conversation: MyConversation,
|
||||
ctx: MyContext,
|
||||
availableActions: T,
|
||||
): Promise<T[number]["action"][]> {
|
||||
try {
|
||||
if (!Array.isArray(availableActions) || availableActions.length === 0) {
|
||||
throw new Error("Список доступных действий пуст или не определён.");
|
||||
}
|
||||
|
||||
const selectedActions = new Set<T[number]["action"]>();
|
||||
|
||||
const updateKeyboard = () => {
|
||||
return availableActions.map(({ action, label }) => [
|
||||
{
|
||||
text: `${selectedActions.has(action) ? "✔️ " : ""}${label}`,
|
||||
callback_data: `action:${action}`,
|
||||
},
|
||||
]);
|
||||
};
|
||||
|
||||
// Отправляем начальное сообщение
|
||||
const replyMessage = await ctx.reply(
|
||||
"Выберите одно или несколько действий, которые будут доступны при сканировании этого QR-кода. Нажмите 'Готово', когда закончите выбор:",
|
||||
{
|
||||
reply_markup: {
|
||||
inline_keyboard: [
|
||||
...updateKeyboard(),
|
||||
[{ text: "Готово", callback_data: "action:done" }],
|
||||
],
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
while (true) {
|
||||
let actionChoice;
|
||||
try {
|
||||
actionChoice = await conversation.waitFor("callback_query:data");
|
||||
} catch (err) {
|
||||
console.error("Ошибка ожидания callback_query:", err);
|
||||
await ctx.reply(
|
||||
"Произошла ошибка при ожидании вашего выбора. Попробуйте снова.",
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
const choice = actionChoice.update.callback_query?.data;
|
||||
|
||||
if (!choice || !choice.startsWith("action:")) {
|
||||
// Игнорируем callback_data, которые не относятся к текущему этапу
|
||||
console.warn(`Игнорируем callback_data: ${choice}`);
|
||||
await actionChoice.answerCallbackQuery({
|
||||
text: "Неизвестное действие.",
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
const action = choice.replace("action:", "");
|
||||
|
||||
if (action === "done") {
|
||||
await actionChoice.answerCallbackQuery({ text: "Выбор завершён!" });
|
||||
break;
|
||||
}
|
||||
|
||||
// Проверка: является ли выбор валидным
|
||||
const validChoice = availableActions.find((a) => a.action === action);
|
||||
if (!validChoice) {
|
||||
console.error(`Недопустимое действие: ${action}`);
|
||||
await actionChoice.answerCallbackQuery({
|
||||
text: "Неверный выбор. Попробуйте снова.",
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// Добавляем или убираем действие
|
||||
if (selectedActions.has(action as T[number]["action"])) {
|
||||
selectedActions.delete(action as T[number]["action"]);
|
||||
} else {
|
||||
selectedActions.add(action as T[number]["action"]);
|
||||
}
|
||||
|
||||
await actionChoice.answerCallbackQuery({
|
||||
text: `Вы ${
|
||||
selectedActions.has(action as T[number]["action"])
|
||||
? "добавили"
|
||||
: "убрали"
|
||||
} действие.`,
|
||||
});
|
||||
|
||||
// Перерисовываем клавиатуру
|
||||
try {
|
||||
await actionChoice.editMessageReplyMarkup({
|
||||
reply_markup: {
|
||||
inline_keyboard: [
|
||||
...updateKeyboard(),
|
||||
[{ text: "Готово", callback_data: "action:done" }],
|
||||
],
|
||||
},
|
||||
});
|
||||
} catch (err) {
|
||||
console.error("Ошибка обновления клавиатуры:", err);
|
||||
await ctx.reply(
|
||||
"Произошла ошибка при обновлении выбора. Попробуйте снова.",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Array.from(selectedActions);
|
||||
} catch (err) {
|
||||
console.error("Общая ошибка в selectMultipleActions:", err);
|
||||
await ctx.reply(
|
||||
"Произошла непредвиденная ошибка. Попробуйте снова или обратитесь в поддержку.",
|
||||
);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Bot, session } from "grammy";
|
||||
import { conversations, createConversation } from "@grammyjs/conversations";
|
||||
import { MyContext } from "@/types/myContext";
|
||||
import { env } from "@/config/env";
|
||||
import { startHealthServer } from "@hereconnect/lib-service-health-checkserver";
|
||||
import { MyContext } from "../types/myContext";
|
||||
import { env } from "../config/env";
|
||||
import { CouchDBStorageAdapter } from "./storageAdapters/CouchDBStorageAdapter";
|
||||
import { loadUserMiddleware } from "./middleware/loadUser";
|
||||
import { tgBotSessionsDb } from "@/dbs";
|
||||
import { tgBotSessionsDb } from "../dbs";
|
||||
import { setupCommands } from "./commands/setupCommands";
|
||||
import { startCommand } from "./commands/start";
|
||||
import { helpCommand } from "./commands/help";
|
||||
@@ -13,12 +14,21 @@ import { manageCommand } from "./commands/manage";
|
||||
import { callbackQueryHandler } from "./callbackHandlers";
|
||||
import { newQRCodeConversation } from "./conversations/newQRCodeConversation";
|
||||
|
||||
const abortController = new AbortController();
|
||||
|
||||
const storage = new CouchDBStorageAdapter(tgBotSessionsDb, {
|
||||
softDelete: true,
|
||||
type: "tg_bot_session",
|
||||
});
|
||||
|
||||
// Инициализируем бота с нужным типом контекста
|
||||
const bot = new Bot<MyContext>(env.TELEGRAM_BOT_TOKEN);
|
||||
const bot = new Bot<MyContext>(env.TELEGRAM_BOT_TOKEN, {
|
||||
client: {
|
||||
baseFetchConfig: {
|
||||
signal: abortController.signal,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Подключаем сессии. По необходимости определите initial state для сессии
|
||||
bot.use(session({ storage, initial: () => ({}) }));
|
||||
@@ -44,7 +54,10 @@ bot.on("callback_query:data", callbackQueryHandler);
|
||||
await setupCommands(bot);
|
||||
|
||||
// Запуск бота
|
||||
bot.start();
|
||||
await bot.start();
|
||||
|
||||
await startHealthServer(abortController);
|
||||
|
||||
console.log("Бот запущен!");
|
||||
})();
|
||||
|
||||
|
||||
@@ -6,7 +6,12 @@ if (!process.env.READ_BASE_URL) {
|
||||
throw new Error("Необходимо указать READ_BASE_URL в переменных окружения.");
|
||||
}
|
||||
|
||||
if (!process.env.API_URL) {
|
||||
throw new Error("Environment variable API_URL is not set");
|
||||
}
|
||||
|
||||
export const env = {
|
||||
TELEGRAM_BOT_TOKEN: process.env.BOT_TOKEN,
|
||||
READ_BASE_URL: process.env.READ_BASE_URL,
|
||||
API_URL: process.env.API_URL,
|
||||
} as const;
|
||||
|
||||
+15
-17
@@ -12,45 +12,46 @@ import type {
|
||||
} from "@hereconnect/types";
|
||||
|
||||
import type { TelegramWebhookDesignDocument } from "@hereconnect/tg-bot-webhook-ddoc";
|
||||
import { CouchDBSessionDocument } from "@/bot/storageAdapters/CouchDBStorageAdapter";
|
||||
import type { SessionData } from "@/types/myContext";
|
||||
import { CouchDBSessionDocument } from "./bot/storageAdapters/CouchDBStorageAdapter";
|
||||
import type { SessionData } from "./types/myContext";
|
||||
import { env } from "./config/env";
|
||||
// import type { TgUpdateDocument } from "./types";
|
||||
|
||||
if (!process.env.API_URL) {
|
||||
if (!env.API_URL) {
|
||||
throw new Error("Environment variable API_URL is not set");
|
||||
}
|
||||
|
||||
export const TG_BOT_DB_NAME = "tg_bot";
|
||||
export const TG_BOT_DB_URL = `${process.env.API_URL}/${TG_BOT_DB_NAME}`;
|
||||
export const TG_BOT_DB_URL = `${env.API_URL}/${TG_BOT_DB_NAME}`;
|
||||
|
||||
export const messagesDb = new PouchDB<MessageDocument>(
|
||||
`${process.env.API_URL}/messages`,
|
||||
`${env.API_URL}/messages`,
|
||||
{
|
||||
skip_setup: true,
|
||||
},
|
||||
);
|
||||
|
||||
export const serverSettingsDb = new PouchDB<MessageDeliveryMethodWebPushVapid>(
|
||||
`${process.env.API_URL}/server_settings`,
|
||||
`${env.API_URL}/server_settings`,
|
||||
{
|
||||
skip_setup: true,
|
||||
},
|
||||
);
|
||||
|
||||
export const publicSettingsDb = new PouchDB<PublicSettingsDocument>(
|
||||
`${process.env.API_URL}/public_settings`,
|
||||
`${env.API_URL}/public_settings`,
|
||||
{
|
||||
skip_setup: true,
|
||||
},
|
||||
);
|
||||
|
||||
export const qrDb = new PouchDB<QRCodeDocument>(`${process.env.API_URL}/qr`, {
|
||||
export const qrDb = new PouchDB<QRCodeDocument>(`${env.API_URL}/qr`, {
|
||||
skip_setup: true,
|
||||
});
|
||||
|
||||
export const webPushSubscriptionsDb = new PouchDB<
|
||||
WebPushSubscriptionDocument<PushSubscription>
|
||||
>(`${process.env.API_URL}/web_push_subscriptions`, {
|
||||
>(`${env.API_URL}/web_push_subscriptions`, {
|
||||
skip_setup: true,
|
||||
});
|
||||
|
||||
@@ -63,25 +64,22 @@ export const tgBotDesignDocumentsDb =
|
||||
export const serviceSeqTrackerDb = tgBotDb as ServiceSeqTrackerDatabase;
|
||||
|
||||
export const tgBotSessionsDb = new PouchDB<CouchDBSessionDocument<SessionData>>(
|
||||
`${process.env.API_URL}/tg_bot_sessions`,
|
||||
`${env.API_URL}/tg_bot_sessions`,
|
||||
{
|
||||
skip_setup: true,
|
||||
},
|
||||
);
|
||||
|
||||
export const userChatSettingsDb = new PouchDB<UserChatSettingsDocument>(
|
||||
`${process.env.API_URL}/user_chat_settings`,
|
||||
`${env.API_URL}/user_chat_settings`,
|
||||
{
|
||||
skip_setup: true,
|
||||
},
|
||||
);
|
||||
|
||||
export const usersDb = new PouchDB<UserDocument>(
|
||||
`${process.env.API_URL}/_users`,
|
||||
{
|
||||
skip_setup: true,
|
||||
},
|
||||
);
|
||||
export const usersDb = new PouchDB<UserDocument>(`${env.API_URL}/_users`, {
|
||||
skip_setup: true,
|
||||
});
|
||||
|
||||
export const checkDatabases = async () => {
|
||||
const entries = await Promise.all(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import QRCodeStyling from "qr-code-styling";
|
||||
import { SvgProcessor } from "@/utils/images/svg/SvgProcessor";
|
||||
import { SvgProcessor } from "../utils/images/svg/SvgProcessor";
|
||||
import fs from "fs/promises";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
|
||||
@@ -10,10 +10,7 @@
|
||||
"skipLibCheck": true, // Пропуск проверки типов в библиотечных файлах
|
||||
"declaration": true, // Генерация `.d.ts` файлов
|
||||
"sourceMap": true, // Генерация `.map` файлов
|
||||
"paths": {
|
||||
"@/*": ["./src/*"] // Настройка алиасов (сопоставление путей)
|
||||
}
|
||||
},
|
||||
"include": ["src"], // Указываем папку с исходниками
|
||||
"exclude": ["node_modules", "dist"] // Исключаем ненужные директории
|
||||
"exclude": ["node_modules", "dist", "old"] // Исключаем ненужные директории
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user