diff --git a/.github/workflows/sync-cloud-run-env.yml b/.github/workflows/sync-cloud-run-env.yml index a32534f..b674883 100644 --- a/.github/workflows/sync-cloud-run-env.yml +++ b/.github/workflows/sync-cloud-run-env.yml @@ -75,6 +75,12 @@ jobs: CRISIS_ALERT_PUSH_PRIORITY: ${{ vars.CRISIS_ALERT_PUSH_PRIORITY }} CRISIS_ALERT_PUSH_TAGS: ${{ vars.CRISIS_ALERT_PUSH_TAGS }} CRISIS_ALERT_PUSH_BODY_MAX_CHARS: ${{ vars.CRISIS_ALERT_PUSH_BODY_MAX_CHARS }} + CRISIS_ALERT_TELEGRAM_CHAT_IDS: ${{ vars.CRISIS_ALERT_TELEGRAM_CHAT_IDS }} + CRISIS_ALERT_TELEGRAM_BOT_TOKEN_SECRET_NAME: ${{ vars.CRISIS_ALERT_TELEGRAM_BOT_TOKEN_SECRET_NAME }} + CRISIS_ALERT_TELEGRAM_API_BASE_URL: ${{ vars.CRISIS_ALERT_TELEGRAM_API_BASE_URL }} + CRISIS_ALERT_TELEGRAM_PARSE_MODE: ${{ vars.CRISIS_ALERT_TELEGRAM_PARSE_MODE }} + CRISIS_ALERT_TELEGRAM_DISABLE_WEB_PAGE_PREVIEW: ${{ vars.CRISIS_ALERT_TELEGRAM_DISABLE_WEB_PAGE_PREVIEW }} + CRISIS_ALERT_TELEGRAM_BODY_MAX_CHARS: ${{ vars.CRISIS_ALERT_TELEGRAM_BODY_MAX_CHARS }} # Optional strategy overrides; leave unset to inherit the UsEquityStrategies profile defaults. INCOME_THRESHOLD_USD: ${{ vars.INCOME_THRESHOLD_USD }} QQQI_INCOME_RATIO: ${{ vars.QQQI_INCOME_RATIO }} @@ -87,6 +93,7 @@ jobs: CRISIS_ALERT_SMS_AUTH_TOKEN: ${{ secrets.CRISIS_ALERT_SMS_AUTH_TOKEN }} CRISIS_ALERT_PUSH_APP_TOKEN: ${{ secrets.CRISIS_ALERT_PUSH_APP_TOKEN }} CRISIS_ALERT_PUSH_ACCESS_TOKEN: ${{ secrets.CRISIS_ALERT_PUSH_ACCESS_TOKEN }} + CRISIS_ALERT_TELEGRAM_BOT_TOKEN: ${{ secrets.CRISIS_ALERT_TELEGRAM_BOT_TOKEN }} steps: - name: Check whether env sync is enabled id: config @@ -397,6 +404,17 @@ jobs: remove_secret_vars+=("CRISIS_ALERT_PUSH_ACCESS_TOKEN") fi + if [ -n "${CRISIS_ALERT_TELEGRAM_BOT_TOKEN_SECRET_NAME:-}" ]; then + secret_pairs+=("CRISIS_ALERT_TELEGRAM_BOT_TOKEN=${CRISIS_ALERT_TELEGRAM_BOT_TOKEN_SECRET_NAME}:latest") + remove_env_vars+=("CRISIS_ALERT_TELEGRAM_BOT_TOKEN") + elif [ -n "${CRISIS_ALERT_TELEGRAM_BOT_TOKEN:-}" ]; then + env_pairs+=("CRISIS_ALERT_TELEGRAM_BOT_TOKEN=${CRISIS_ALERT_TELEGRAM_BOT_TOKEN}") + remove_secret_vars+=("CRISIS_ALERT_TELEGRAM_BOT_TOKEN") + else + remove_env_vars+=("CRISIS_ALERT_TELEGRAM_BOT_TOKEN") + remove_secret_vars+=("CRISIS_ALERT_TELEGRAM_BOT_TOKEN") + fi + secret_pairs+=("LONGPORT_APP_KEY=${LONGPORT_APP_KEY_SECRET_NAME}:latest") remove_env_vars+=("LONGPORT_APP_KEY") @@ -571,6 +589,36 @@ jobs: remove_env_vars+=("CRISIS_ALERT_PUSH_BODY_MAX_CHARS") fi + if [ -n "${CRISIS_ALERT_TELEGRAM_CHAT_IDS:-}" ]; then + env_pairs+=("CRISIS_ALERT_TELEGRAM_CHAT_IDS=${CRISIS_ALERT_TELEGRAM_CHAT_IDS}") + else + remove_env_vars+=("CRISIS_ALERT_TELEGRAM_CHAT_IDS") + fi + + if [ -n "${CRISIS_ALERT_TELEGRAM_API_BASE_URL:-}" ]; then + env_pairs+=("CRISIS_ALERT_TELEGRAM_API_BASE_URL=${CRISIS_ALERT_TELEGRAM_API_BASE_URL}") + else + remove_env_vars+=("CRISIS_ALERT_TELEGRAM_API_BASE_URL") + fi + + if [ -n "${CRISIS_ALERT_TELEGRAM_PARSE_MODE:-}" ]; then + env_pairs+=("CRISIS_ALERT_TELEGRAM_PARSE_MODE=${CRISIS_ALERT_TELEGRAM_PARSE_MODE}") + else + remove_env_vars+=("CRISIS_ALERT_TELEGRAM_PARSE_MODE") + fi + + if [ -n "${CRISIS_ALERT_TELEGRAM_DISABLE_WEB_PAGE_PREVIEW:-}" ]; then + env_pairs+=("CRISIS_ALERT_TELEGRAM_DISABLE_WEB_PAGE_PREVIEW=${CRISIS_ALERT_TELEGRAM_DISABLE_WEB_PAGE_PREVIEW}") + else + remove_env_vars+=("CRISIS_ALERT_TELEGRAM_DISABLE_WEB_PAGE_PREVIEW") + fi + + if [ -n "${CRISIS_ALERT_TELEGRAM_BODY_MAX_CHARS:-}" ]; then + env_pairs+=("CRISIS_ALERT_TELEGRAM_BODY_MAX_CHARS=${CRISIS_ALERT_TELEGRAM_BODY_MAX_CHARS}") + else + remove_env_vars+=("CRISIS_ALERT_TELEGRAM_BODY_MAX_CHARS") + fi + if [ -n "${LONGBRIDGE_DRY_RUN_ONLY:-}" ]; then env_pairs+=("LONGBRIDGE_DRY_RUN_ONLY=${LONGBRIDGE_DRY_RUN_ONLY}") else diff --git a/README.md b/README.md index c79425a..b18fa03 100644 --- a/README.md +++ b/README.md @@ -70,13 +70,15 @@ Telegram notifications include structured execution and heartbeat messages, with | `LONGBRIDGE_DRY_RUN_ONLY` | No | Set to `true` to keep the selected deployment in dry-run mode. | | `LONGBRIDGE_DEBUG_POSITION_SNAPSHOT` | No | Set to `true` to log raw LongBridge position quantity and available quantity for troubleshooting. | | `LONGBRIDGE_STRATEGY_PLUGIN_MOUNTS_JSON` | No | Optional LongBridge-side strategy plugin mount JSON. The plugin artifact controls mode; platform config must not set `mode`. | -| `CRISIS_ALERT_CHANNELS` | No | Optional crisis alert channel list: `email`, `sms`, and/or `push`. | +| `CRISIS_ALERT_CHANNELS` | No | Optional crisis alert channel list: `email`, `sms`, `push`, and/or `telegram`. | | `CRISIS_ALERT_EMAIL_RECIPIENTS` | No | Comma/semicolon/newline-separated email-form recipients. Use a normal mailbox for email-only delivery, or a Google Voice-associated mailbox/address to also trigger Google Voice prompts. | | `CRISIS_ALERT_EMAIL_SENDER_EMAIL` | No | Sender email address used for crisis alert email. Gmail is the default transport, but the sender naming is provider-neutral. | | `CRISIS_ALERT_EMAIL_SENDER_PASSWORD` | No | Sender SMTP password or app password. For Cloud Run, prefer `CRISIS_ALERT_EMAIL_SENDER_PASSWORD_SECRET_NAME` in env sync. | | `CRISIS_ALERT_EMAIL_SMTP_HOST` | No | Optional SMTP host override. Defaults to Gmail SMTP when unset. | | `CRISIS_ALERT_EMAIL_SMTP_PORT` | No | Optional SMTP port override. Defaults to `465` when unset. | | `CRISIS_ALERT_EMAIL_SMTP_SECURITY` | No | Optional SMTP security override: `ssl`, `starttls`, or `none`. Defaults to `ssl` when unset. | +| `CRISIS_ALERT_TELEGRAM_CHAT_IDS` | No | Dedicated crisis-alert Telegram chat IDs. Separate from the strategy-cycle Telegram chat. | +| `CRISIS_ALERT_TELEGRAM_BOT_TOKEN` | No | Dedicated crisis-alert Telegram bot token. For Cloud Run, prefer `CRISIS_ALERT_TELEGRAM_BOT_TOKEN_SECRET_NAME` in env sync. | | `LONGBRIDGE_MIN_RESERVED_CASH_USD` | No | Platform-level minimum cash reserve in USD. Defaults to `0`; the effective reserve is the max of this floor, `LONGBRIDGE_RESERVED_CASH_RATIO * total equity`, and any strategy-provided reserve. | | `LONGBRIDGE_RESERVED_CASH_RATIO` | No | Platform-level minimum cash reserve ratio in `[0,1]`. Defaults to `0`; it can raise but not lower a strategy-provided reserve. | | `LONGBRIDGE_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD` | No | Safe-haven/cash-sweep target values below this USD amount are kept as cash instead of buying BOXX/BIL. Default `1000`. | @@ -241,13 +243,15 @@ Telegram 通知包含结构化的调仓和心跳消息,支持中英文切换 | `LONGBRIDGE_DRY_RUN_ONLY` | 否 | 设为 `true` 时,该部署保持 dry-run。 | | `LONGBRIDGE_DEBUG_POSITION_SNAPSHOT` | 否 | 设为 `true` 时输出 LongBridge 原始持仓数量和可卖数量,便于排查。 | | `LONGBRIDGE_STRATEGY_PLUGIN_MOUNTS_JSON` | 否 | 可选的 LongBridge 侧策略插件挂载 JSON。插件 artifact 自带模式;平台配置不要设置 `mode`。 | -| `CRISIS_ALERT_CHANNELS` | 否 | 可选危机告警通道列表:`email`、`sms` 和/或 `push`。 | +| `CRISIS_ALERT_CHANNELS` | 否 | 可选危机告警通道列表:`email`、`sms`、`push` 和/或 `telegram`。 | | `CRISIS_ALERT_EMAIL_RECIPIENTS` | 否 | 通知收件邮箱。普通邮箱只收邮件;关联 Google Voice 的邮箱/地址会额外触发 Google Voice 提醒。支持逗号、分号或换行分隔。 | | `CRISIS_ALERT_EMAIL_SENDER_EMAIL` | 否 | 通知发送方邮箱。默认传输走 Gmail SMTP,但命名不绑定 Gmail。 | | `CRISIS_ALERT_EMAIL_SENDER_PASSWORD` | 否 | 发送方 SMTP 密码或 app password。Cloud Run env sync 建议配置 `CRISIS_ALERT_EMAIL_SENDER_PASSWORD_SECRET_NAME`。 | | `CRISIS_ALERT_EMAIL_SMTP_HOST` | 否 | 可选 SMTP host 覆盖。不设置时默认 Gmail SMTP。 | | `CRISIS_ALERT_EMAIL_SMTP_PORT` | 否 | 可选 SMTP port 覆盖。不设置时默认 `465`。 | | `CRISIS_ALERT_EMAIL_SMTP_SECURITY` | 否 | 可选 SMTP 加密方式:`ssl`、`starttls` 或 `none`。不设置时默认 `ssl`。 | +| `CRISIS_ALERT_TELEGRAM_CHAT_IDS` | 否 | 危机告警专用 Telegram chat ID,和常规策略周期 Telegram 分开。 | +| `CRISIS_ALERT_TELEGRAM_BOT_TOKEN` | 否 | 危机告警专用 Telegram bot token。Cloud Run env sync 建议配置 `CRISIS_ALERT_TELEGRAM_BOT_TOKEN_SECRET_NAME`。 | | `LONGBRIDGE_MIN_RESERVED_CASH_USD` | 否 | 平台级最低预留现金 USD。默认 `0`;实际预留取该下限、`LONGBRIDGE_RESERVED_CASH_RATIO * 总资产` 和策略预留中的最大值。 | | `LONGBRIDGE_RESERVED_CASH_RATIO` | 否 | 平台级最低预留现金比例,取值 `[0,1]`。默认 `0`;只会抬高,不会降低策略预留。 | | `LONGBRIDGE_SAFE_HAVEN_CASH_SUBSTITUTE_THRESHOLD_USD` | 否 | `BOXX`/`BIL` 等避险现金替代标的目标金额低于该 USD 门槛时保留现金,不买入。默认 `1000`。 | diff --git a/requirements.txt b/requirements.txt index c310078..3198c1c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ flask gunicorn -quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@2fdb7c35edf2f39c1592a7dd9319b7516276fabf -us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@b626ee3e42feabbf6cd427af6faf5655ca6cd76f +quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@b520bcaa216e36b94ce60c8c6a13f982de826830 +us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@df91828c8b521516c85512e136e724064b6b9dac pandas requests pytz diff --git a/runtime_config_support.py b/runtime_config_support.py index af6e525..47912bc 100644 --- a/runtime_config_support.py +++ b/runtime_config_support.py @@ -78,6 +78,12 @@ class PlatformRuntimeSettings: crisis_alert_push_priority: str | None = None crisis_alert_push_tags: str | None = None crisis_alert_push_body_max_chars: str | None = None + crisis_alert_telegram_chat_ids: tuple[str, ...] = () + crisis_alert_telegram_bot_token: str | None = None + crisis_alert_telegram_api_base_url: str | None = None + crisis_alert_telegram_parse_mode: str | None = None + crisis_alert_telegram_disable_web_page_preview: str | None = None + crisis_alert_telegram_body_max_chars: str | None = None runtime_target: RuntimeTarget | None = None @@ -208,6 +214,24 @@ def load_platform_runtime_settings( crisis_alert_push_body_max_chars=_first_non_empty( os.getenv("CRISIS_ALERT_PUSH_BODY_MAX_CHARS") ), + crisis_alert_telegram_chat_ids=_split_env_list( + os.getenv("CRISIS_ALERT_TELEGRAM_CHAT_IDS") + ), + crisis_alert_telegram_bot_token=_first_non_empty( + os.getenv("CRISIS_ALERT_TELEGRAM_BOT_TOKEN") + ), + crisis_alert_telegram_api_base_url=_first_non_empty( + os.getenv("CRISIS_ALERT_TELEGRAM_API_BASE_URL") + ), + crisis_alert_telegram_parse_mode=_first_non_empty( + os.getenv("CRISIS_ALERT_TELEGRAM_PARSE_MODE") + ), + crisis_alert_telegram_disable_web_page_preview=_first_non_empty( + os.getenv("CRISIS_ALERT_TELEGRAM_DISABLE_WEB_PAGE_PREVIEW") + ), + crisis_alert_telegram_body_max_chars=_first_non_empty( + os.getenv("CRISIS_ALERT_TELEGRAM_BODY_MAX_CHARS") + ), runtime_target=runtime_target, ) diff --git a/tests/test_runtime_config_support.py b/tests/test_runtime_config_support.py index f6eaf69..90414dd 100644 --- a/tests/test_runtime_config_support.py +++ b/tests/test_runtime_config_support.py @@ -143,6 +143,12 @@ def test_load_platform_runtime_settings_uses_defaults_with_explicit_strategy_pro self.assertIsNone(settings.crisis_alert_push_priority) self.assertIsNone(settings.crisis_alert_push_tags) self.assertIsNone(settings.crisis_alert_push_body_max_chars) + self.assertEqual(settings.crisis_alert_telegram_chat_ids, ()) + self.assertIsNone(settings.crisis_alert_telegram_bot_token) + self.assertIsNone(settings.crisis_alert_telegram_api_base_url) + self.assertIsNone(settings.crisis_alert_telegram_parse_mode) + self.assertIsNone(settings.crisis_alert_telegram_disable_web_page_preview) + self.assertIsNone(settings.crisis_alert_telegram_body_max_chars) def test_load_platform_runtime_settings_prefers_runtime_target_json(self): with patch.dict( @@ -345,7 +351,7 @@ def test_crisis_alert_channels_and_push_config_are_loaded_from_env(self): os.environ, { "RUNTIME_TARGET_JSON": runtime_target_json(SAMPLE_STRATEGY_PROFILE), - "CRISIS_ALERT_CHANNELS": "email;push", + "CRISIS_ALERT_CHANNELS": "email;push;telegram", "CRISIS_ALERT_PUSH_RECIPIENTS": "risk-topic; backup-topic", "CRISIS_ALERT_PUSH_PROVIDER": "ntfy", "CRISIS_ALERT_PUSH_APP_TOKEN": "app-token", @@ -355,12 +361,18 @@ def test_crisis_alert_channels_and_push_config_are_loaded_from_env(self): "CRISIS_ALERT_PUSH_PRIORITY": "5", "CRISIS_ALERT_PUSH_TAGS": "warning", "CRISIS_ALERT_PUSH_BODY_MAX_CHARS": "300", + "CRISIS_ALERT_TELEGRAM_CHAT_IDS": "12345; @risk_channel", + "CRISIS_ALERT_TELEGRAM_BOT_TOKEN": "telegram-token", + "CRISIS_ALERT_TELEGRAM_API_BASE_URL": "https://telegram.example.test", + "CRISIS_ALERT_TELEGRAM_PARSE_MODE": "HTML", + "CRISIS_ALERT_TELEGRAM_DISABLE_WEB_PAGE_PREVIEW": "false", + "CRISIS_ALERT_TELEGRAM_BODY_MAX_CHARS": "900", }, clear=True, ): settings = load_platform_runtime_settings(project_id_resolver=lambda: "project-1") - self.assertEqual(settings.crisis_alert_channels, ("email", "push")) + self.assertEqual(settings.crisis_alert_channels, ("email", "push", "telegram")) self.assertEqual(settings.crisis_alert_push_recipients, ("risk-topic", "backup-topic")) self.assertEqual(settings.crisis_alert_push_provider, "ntfy") self.assertEqual(settings.crisis_alert_push_app_token, "app-token") @@ -370,6 +382,15 @@ def test_crisis_alert_channels_and_push_config_are_loaded_from_env(self): self.assertEqual(settings.crisis_alert_push_priority, "5") self.assertEqual(settings.crisis_alert_push_tags, "warning") self.assertEqual(settings.crisis_alert_push_body_max_chars, "300") + self.assertEqual(settings.crisis_alert_telegram_chat_ids, ("12345", "@risk_channel")) + self.assertEqual(settings.crisis_alert_telegram_bot_token, "telegram-token") + self.assertEqual( + settings.crisis_alert_telegram_api_base_url, + "https://telegram.example.test", + ) + self.assertEqual(settings.crisis_alert_telegram_parse_mode, "HTML") + self.assertEqual(settings.crisis_alert_telegram_disable_web_page_preview, "false") + self.assertEqual(settings.crisis_alert_telegram_body_max_chars, "900") def test_income_layer_overrides_are_loaded_from_env(self): with patch.dict( diff --git a/tests/test_sync_cloud_run_env_workflow.sh b/tests/test_sync_cloud_run_env_workflow.sh index 2ae48d4..d75e84c 100644 --- a/tests/test_sync_cloud_run_env_workflow.sh +++ b/tests/test_sync_cloud_run_env_workflow.sh @@ -40,6 +40,7 @@ grep -Fq 'CRISIS_ALERT_EMAIL_SENDER_PASSWORD: ${{ secrets.CRISIS_ALERT_EMAIL_SEN grep -Fq 'CRISIS_ALERT_SMS_AUTH_TOKEN: ${{ secrets.CRISIS_ALERT_SMS_AUTH_TOKEN }}' "$workflow_file" grep -Fq 'CRISIS_ALERT_PUSH_APP_TOKEN: ${{ secrets.CRISIS_ALERT_PUSH_APP_TOKEN }}' "$workflow_file" grep -Fq 'CRISIS_ALERT_PUSH_ACCESS_TOKEN: ${{ secrets.CRISIS_ALERT_PUSH_ACCESS_TOKEN }}' "$workflow_file" +grep -Fq 'CRISIS_ALERT_TELEGRAM_BOT_TOKEN: ${{ secrets.CRISIS_ALERT_TELEGRAM_BOT_TOKEN }}' "$workflow_file" grep -Fq 'TELEGRAM_TOKEN_SECRET_NAME: ${{ vars.TELEGRAM_TOKEN_SECRET_NAME }}' "$workflow_file" grep -Fq 'LONGPORT_APP_KEY_SECRET_NAME: ${{ vars.LONGPORT_APP_KEY_SECRET_NAME }}' "$workflow_file" grep -Fq 'LONGPORT_APP_SECRET_SECRET_NAME: ${{ vars.LONGPORT_APP_SECRET_SECRET_NAME }}' "$workflow_file" @@ -75,6 +76,8 @@ grep -Fq 'CRISIS_ALERT_PUSH_DEVICE: ${{ vars.CRISIS_ALERT_PUSH_DEVICE }}' "$work grep -Fq 'CRISIS_ALERT_PUSH_PRIORITY: ${{ vars.CRISIS_ALERT_PUSH_PRIORITY }}' "$workflow_file" grep -Fq 'CRISIS_ALERT_PUSH_TAGS: ${{ vars.CRISIS_ALERT_PUSH_TAGS }}' "$workflow_file" grep -Fq 'CRISIS_ALERT_PUSH_BODY_MAX_CHARS: ${{ vars.CRISIS_ALERT_PUSH_BODY_MAX_CHARS }}' "$workflow_file" +grep -Fq 'CRISIS_ALERT_TELEGRAM_CHAT_IDS: ${{ vars.CRISIS_ALERT_TELEGRAM_CHAT_IDS }}' "$workflow_file" +grep -Fq 'CRISIS_ALERT_TELEGRAM_BOT_TOKEN_SECRET_NAME: ${{ vars.CRISIS_ALERT_TELEGRAM_BOT_TOKEN_SECRET_NAME }}' "$workflow_file" grep -Fq 'INCOME_THRESHOLD_USD: ${{ vars.INCOME_THRESHOLD_USD }}' "$workflow_file" grep -Fq 'QQQI_INCOME_RATIO: ${{ vars.QQQI_INCOME_RATIO }}' "$workflow_file" grep -Fq 'LONGBRIDGE_DRY_RUN_ONLY: ${{ vars.LONGBRIDGE_DRY_RUN_ONLY }}' "$workflow_file" @@ -107,6 +110,7 @@ grep -Fq 'secret_pairs+=("CRISIS_ALERT_EMAIL_SENDER_PASSWORD=${CRISIS_ALERT_EMAI grep -Fq 'secret_pairs+=("CRISIS_ALERT_SMS_AUTH_TOKEN=${CRISIS_ALERT_SMS_AUTH_TOKEN_SECRET_NAME}:latest")' "$workflow_file" grep -Fq 'secret_pairs+=("CRISIS_ALERT_PUSH_APP_TOKEN=${CRISIS_ALERT_PUSH_APP_TOKEN_SECRET_NAME}:latest")' "$workflow_file" grep -Fq 'secret_pairs+=("CRISIS_ALERT_PUSH_ACCESS_TOKEN=${CRISIS_ALERT_PUSH_ACCESS_TOKEN_SECRET_NAME}:latest")' "$workflow_file" +grep -Fq 'secret_pairs+=("CRISIS_ALERT_TELEGRAM_BOT_TOKEN=${CRISIS_ALERT_TELEGRAM_BOT_TOKEN_SECRET_NAME}:latest")' "$workflow_file" grep -Fq 'secret_pairs+=("LONGPORT_APP_KEY=${LONGPORT_APP_KEY_SECRET_NAME}:latest")' "$workflow_file" grep -Fq 'secret_pairs+=("LONGPORT_APP_SECRET=${LONGPORT_APP_SECRET_SECRET_NAME}:latest")' "$workflow_file" grep -Fq 'LONGPORT_SECRET_NAME=${LONGPORT_SECRET_NAME}' "$workflow_file" @@ -142,6 +146,8 @@ grep -Fq 'CRISIS_ALERT_PUSH_DEVICE=${CRISIS_ALERT_PUSH_DEVICE}' "$workflow_file" grep -Fq 'CRISIS_ALERT_PUSH_PRIORITY=${CRISIS_ALERT_PUSH_PRIORITY}' "$workflow_file" grep -Fq 'CRISIS_ALERT_PUSH_TAGS=${CRISIS_ALERT_PUSH_TAGS}' "$workflow_file" grep -Fq 'CRISIS_ALERT_PUSH_BODY_MAX_CHARS=${CRISIS_ALERT_PUSH_BODY_MAX_CHARS}' "$workflow_file" +grep -Fq 'CRISIS_ALERT_TELEGRAM_CHAT_IDS=${CRISIS_ALERT_TELEGRAM_CHAT_IDS}' "$workflow_file" +grep -Fq 'CRISIS_ALERT_TELEGRAM_BODY_MAX_CHARS=${CRISIS_ALERT_TELEGRAM_BODY_MAX_CHARS}' "$workflow_file" grep -Fq 'remove_env_vars+=("CRISIS_ALERT_EMAIL_RECIPIENTS")' "$workflow_file" grep -Fq 'remove_env_vars+=("CRISIS_ALERT_EMAIL_SENDER_EMAIL")' "$workflow_file" grep -Fq 'remove_env_vars+=("CRISIS_ALERT_EMAIL_SENDER_PASSWORD")' "$workflow_file" @@ -165,6 +171,8 @@ grep -Fq 'remove_env_vars+=("CRISIS_ALERT_PUSH_DEVICE")' "$workflow_file" grep -Fq 'remove_env_vars+=("CRISIS_ALERT_PUSH_PRIORITY")' "$workflow_file" grep -Fq 'remove_env_vars+=("CRISIS_ALERT_PUSH_TAGS")' "$workflow_file" grep -Fq 'remove_env_vars+=("CRISIS_ALERT_PUSH_BODY_MAX_CHARS")' "$workflow_file" +grep -Fq 'remove_env_vars+=("CRISIS_ALERT_TELEGRAM_BOT_TOKEN")' "$workflow_file" +grep -Fq 'remove_env_vars+=("CRISIS_ALERT_TELEGRAM_CHAT_IDS")' "$workflow_file" grep -Fq '"CRISIS_ALERT_GOOGLE_VOICE_TO"' "$workflow_file" grep -Fq '"CRISIS_ALERT_GOOGLE_VOICE_GATEWAY"' "$workflow_file" grep -Fq '"CRISIS_ALERT_GOOGLE_VOICE_GMAIL_USER"' "$workflow_file"