Skip to content

Commit 0d54c5c

Browse files
therealalephclaude
andcommitted
ci(telegram): use public mhrv_rs link in main-channel post + add invite
Two related changes to the main-channel cross-post (one message per release that points at the files channel): 1. Post-link now uses the public-username form `t.me/mhrv_rs/<msg_id>` instead of the private `t.me/c/<chat_id>/<msg_id>`. The latter only resolves for channel members; the former works for everyone, so recipients seeing the main-channel announcement can click through to a specific release post even if they're not yet subscribed. Wired via the existing `FILES_CHANNEL_USERNAME` workflow env var, now defaulting to `mhrv_rs` (the channel's public username) if the `vars.FILES_CHANNEL_USERNAME` repo variable is unset. Override per repo if the channel is renamed. 2. Channel-join links rendered in the body of the main-channel post, below the post-link: لینک کانال: https://t.me/mhrv_rs و یا: https://t.me/+R1OyoHX2boA1ZDgx Two forms cover the cases where one or the other is filtered: - `t.me/mhrv_rs` — public username form, prettier, surfaces in Telegram search - `t.me/+<hash>` — invite link, the only join path that works for private/restricted channels and for users whose client doesn't resolve public usernames cleanly Wired via new `FILES_CHANNEL_INVITE` env var, defaulting to the current invite hash; override via `vars.FILES_CHANNEL_INVITE` if rotated. Per user request — not running this against v1.8.0 retroactively, just wiring it up for the next release. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 0669b93 commit 0d54c5c

2 files changed

Lines changed: 73 additions & 17 deletions

File tree

.github/scripts/telegram_publish_files.py

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -339,24 +339,51 @@ def files_channel_post_link(chat_id: str, message_id: int) -> str:
339339
def post_main_channel_pointer(
340340
bot_token: str,
341341
main_chat_id: str,
342-
files_channel_link: str,
342+
files_channel_post_link: str,
343343
version: str,
344344
hashtag: str,
345+
channel_username_link: str = "",
346+
channel_invite_link: str = "",
345347
) -> bool:
346348
"""Post a short cross-link to the main announcement channel pointing
347349
at the anchor post in the files channel. Replaces the previous
348350
behaviour of posting the universal APK + full changelog directly
349351
to the main channel — the main channel becomes a discovery surface
350352
while the files channel hosts the actual artifacts.
353+
354+
Includes channel-join links (public username + invite hash) at the
355+
bottom so recipients who aren't yet members can subscribe before
356+
clicking through to the specific release post.
351357
"""
352-
text = (
353-
f"<b>📦 mhrv-rs v{html_escape(version)} منتشر شد</b>\n"
354-
f"\nبرای دانلود فایل‌ها (Android، Windows، macOS، Linux و ...) "
355-
f"به کانال فایل‌ها مراجعه کنید:\n"
356-
f"\n👉 <a href=\"{html_escape(files_channel_link)}\">"
357-
f"v{html_escape(version)} — همه فایل‌ها + SHA-256</a>\n"
358-
f"\n{hashtag}"
359-
)
358+
parts = [
359+
f"<b>📦 mhrv-rs v{html_escape(version)} منتشر شد</b>",
360+
"",
361+
f"برای دانلود فایل‌ها (Android، Windows، macOS، Linux و ...) "
362+
f"به کانال فایل‌ها مراجعه کنید:",
363+
"",
364+
f"👉 <a href=\"{html_escape(files_channel_post_link)}\">"
365+
f"v{html_escape(version)} — همه فایل‌ها + SHA-256</a>",
366+
]
367+
# Channel-join links. Two forms handle different states of the
368+
# files channel: the `t.me/<username>` form works for public
369+
# channels and is the prettier link; the `t.me/+<hash>` invite
370+
# link works regardless of whether the channel is public, and is
371+
# the only path in for private/restricted channels. Showing both
372+
# is forgiving — recipients click whichever works for them.
373+
if channel_username_link or channel_invite_link:
374+
parts.append("")
375+
parts.append("لینک کانال:")
376+
if channel_username_link:
377+
# Render as plain URL (not HTML <a>) so the text shows the
378+
# link itself — useful when users share the message via
379+
# screenshot or copy-paste outside Telegram, which would
380+
# strip the <a href> wrapper.
381+
parts.append(html_escape(channel_username_link))
382+
if channel_invite_link:
383+
parts.append(f"و یا: {html_escape(channel_invite_link)}")
384+
parts.append("")
385+
parts.append(hashtag)
386+
text = "\n".join(parts)
360387
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
361388
data = urllib.parse.urlencode({
362389
"chat_id": main_chat_id,
@@ -472,11 +499,30 @@ def main() -> int:
472499
main_chat_id = os.environ.get("MAIN_CHAT_ID", "").strip()
473500
if main_chat_id and announce_msg_id is not None:
474501
link = files_channel_post_link(chat_id, announce_msg_id)
502+
# Optional channel-join links rendered alongside the cross-link.
503+
# `FILES_CHANNEL_USERNAME` is the public-username form (clean
504+
# `t.me/<name>` URL — clickable for everyone). `FILES_CHANNEL_INVITE`
505+
# is the `t.me/+<hash>` invite link, the only join path for
506+
# private channels. Either or both can be set; both render in
507+
# the body as separate lines.
508+
username = os.environ.get("FILES_CHANNEL_USERNAME", "").strip().lstrip("@")
509+
username_link = f"https://t.me/{username}" if username else ""
510+
invite_link = os.environ.get("FILES_CHANNEL_INVITE", "").strip()
475511
print()
476512
print(f"posting cross-link to main channel:")
477-
print(f" link: {link}")
513+
print(f" post link: {link}")
514+
if username_link:
515+
print(f" channel username link: {username_link}")
516+
if invite_link:
517+
print(f" channel invite link: {invite_link}")
478518
ok = post_main_channel_pointer(
479-
bot_token, main_chat_id, link, args.version, args.hashtag
519+
bot_token,
520+
main_chat_id,
521+
link,
522+
args.version,
523+
args.hashtag,
524+
channel_username_link=username_link,
525+
channel_invite_link=invite_link,
480526
)
481527
if not ok:
482528
failures += 1

.github/workflows/telegram-publish-files.yml

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,22 @@ jobs:
110110
# APK + full changelog. Sourced from the same secret the
111111
# legacy `telegram` job in release.yml used.
112112
MAIN_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
113-
# Optional: if the files channel later gets a public username,
114-
# set the repo variable `FILES_CHANNEL_USERNAME` (without the
115-
# `@`) so the cross-link uses the prettier `t.me/<name>/<msg>`
116-
# form instead of `t.me/c/<id>/<msg>` (which only resolves for
117-
# channel members).
118-
FILES_CHANNEL_USERNAME: ${{ vars.FILES_CHANNEL_USERNAME }}
113+
# Public-username form of the files channel link. Used for
114+
# both (a) the post-link in the main-channel cross-post — so
115+
# `t.me/<name>/<msg>` works for everyone, not just members
116+
# via `t.me/c/<id>/<msg>` — and (b) one of the two
117+
# channel-join links rendered at the bottom of the cross-post.
118+
# Defaults to `mhrv_rs` (current public username); override via
119+
# repo variable if the channel is renamed.
120+
FILES_CHANNEL_USERNAME: ${{ vars.FILES_CHANNEL_USERNAME || 'mhrv_rs' }}
121+
# `t.me/+<hash>` invite link for the files channel. Rendered
122+
# as the second channel-join option in the main-channel
123+
# cross-post — the only join path that works for users coming
124+
# from outside Telegram search (private/restricted channels)
125+
# or whose Telegram client doesn't resolve usernames cleanly.
126+
# Override via repo variable if the channel's invite hash is
127+
# rotated.
128+
FILES_CHANNEL_INVITE: ${{ vars.FILES_CHANNEL_INVITE || 'https://t.me/+R1OyoHX2boA1ZDgx' }}
119129
run: |
120130
if [ -z "${BOT_TOKEN:-}" ]; then
121131
echo "::error::TELEGRAM_BOT_TOKEN not set; can't publish"

0 commit comments

Comments
 (0)