mirror of
https://github.com/therealaleph/MasterHttpRelayVPN-RUST.git
synced 2026-05-17 21:24:48 +03:00
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>
This commit is contained in:
@@ -339,24 +339,51 @@ def files_channel_post_link(chat_id: str, message_id: int) -> str:
|
|||||||
def post_main_channel_pointer(
|
def post_main_channel_pointer(
|
||||||
bot_token: str,
|
bot_token: str,
|
||||||
main_chat_id: str,
|
main_chat_id: str,
|
||||||
files_channel_link: str,
|
files_channel_post_link: str,
|
||||||
version: str,
|
version: str,
|
||||||
hashtag: str,
|
hashtag: str,
|
||||||
|
channel_username_link: str = "",
|
||||||
|
channel_invite_link: str = "",
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Post a short cross-link to the main announcement channel pointing
|
"""Post a short cross-link to the main announcement channel pointing
|
||||||
at the anchor post in the files channel. Replaces the previous
|
at the anchor post in the files channel. Replaces the previous
|
||||||
behaviour of posting the universal APK + full changelog directly
|
behaviour of posting the universal APK + full changelog directly
|
||||||
to the main channel — the main channel becomes a discovery surface
|
to the main channel — the main channel becomes a discovery surface
|
||||||
while the files channel hosts the actual artifacts.
|
while the files channel hosts the actual artifacts.
|
||||||
|
|
||||||
|
Includes channel-join links (public username + invite hash) at the
|
||||||
|
bottom so recipients who aren't yet members can subscribe before
|
||||||
|
clicking through to the specific release post.
|
||||||
"""
|
"""
|
||||||
text = (
|
parts = [
|
||||||
f"<b>📦 mhrv-rs v{html_escape(version)} منتشر شد</b>\n"
|
f"<b>📦 mhrv-rs v{html_escape(version)} منتشر شد</b>",
|
||||||
f"\nبرای دانلود فایلها (Android، Windows، macOS، Linux و ...) "
|
"",
|
||||||
f"به کانال فایلها مراجعه کنید:\n"
|
f"برای دانلود فایلها (Android، Windows، macOS، Linux و ...) "
|
||||||
f"\n👉 <a href=\"{html_escape(files_channel_link)}\">"
|
f"به کانال فایلها مراجعه کنید:",
|
||||||
f"v{html_escape(version)} — همه فایلها + SHA-256</a>\n"
|
"",
|
||||||
f"\n{hashtag}"
|
f"👉 <a href=\"{html_escape(files_channel_post_link)}\">"
|
||||||
)
|
f"v{html_escape(version)} — همه فایلها + SHA-256</a>",
|
||||||
|
]
|
||||||
|
# Channel-join links. Two forms handle different states of the
|
||||||
|
# files channel: the `t.me/<username>` form works for public
|
||||||
|
# channels and is the prettier link; the `t.me/+<hash>` invite
|
||||||
|
# link works regardless of whether the channel is public, and is
|
||||||
|
# the only path in for private/restricted channels. Showing both
|
||||||
|
# is forgiving — recipients click whichever works for them.
|
||||||
|
if channel_username_link or channel_invite_link:
|
||||||
|
parts.append("")
|
||||||
|
parts.append("لینک کانال:")
|
||||||
|
if channel_username_link:
|
||||||
|
# Render as plain URL (not HTML <a>) so the text shows the
|
||||||
|
# link itself — useful when users share the message via
|
||||||
|
# screenshot or copy-paste outside Telegram, which would
|
||||||
|
# strip the <a href> wrapper.
|
||||||
|
parts.append(html_escape(channel_username_link))
|
||||||
|
if channel_invite_link:
|
||||||
|
parts.append(f"و یا: {html_escape(channel_invite_link)}")
|
||||||
|
parts.append("")
|
||||||
|
parts.append(hashtag)
|
||||||
|
text = "\n".join(parts)
|
||||||
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
|
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
|
||||||
data = urllib.parse.urlencode({
|
data = urllib.parse.urlencode({
|
||||||
"chat_id": main_chat_id,
|
"chat_id": main_chat_id,
|
||||||
@@ -472,11 +499,30 @@ def main() -> int:
|
|||||||
main_chat_id = os.environ.get("MAIN_CHAT_ID", "").strip()
|
main_chat_id = os.environ.get("MAIN_CHAT_ID", "").strip()
|
||||||
if main_chat_id and announce_msg_id is not None:
|
if main_chat_id and announce_msg_id is not None:
|
||||||
link = files_channel_post_link(chat_id, announce_msg_id)
|
link = files_channel_post_link(chat_id, announce_msg_id)
|
||||||
|
# Optional channel-join links rendered alongside the cross-link.
|
||||||
|
# `FILES_CHANNEL_USERNAME` is the public-username form (clean
|
||||||
|
# `t.me/<name>` URL — clickable for everyone). `FILES_CHANNEL_INVITE`
|
||||||
|
# is the `t.me/+<hash>` invite link, the only join path for
|
||||||
|
# private channels. Either or both can be set; both render in
|
||||||
|
# the body as separate lines.
|
||||||
|
username = os.environ.get("FILES_CHANNEL_USERNAME", "").strip().lstrip("@")
|
||||||
|
username_link = f"https://t.me/{username}" if username else ""
|
||||||
|
invite_link = os.environ.get("FILES_CHANNEL_INVITE", "").strip()
|
||||||
print()
|
print()
|
||||||
print(f"posting cross-link to main channel:")
|
print(f"posting cross-link to main channel:")
|
||||||
print(f" link: {link}")
|
print(f" post link: {link}")
|
||||||
|
if username_link:
|
||||||
|
print(f" channel username link: {username_link}")
|
||||||
|
if invite_link:
|
||||||
|
print(f" channel invite link: {invite_link}")
|
||||||
ok = post_main_channel_pointer(
|
ok = post_main_channel_pointer(
|
||||||
bot_token, main_chat_id, link, args.version, args.hashtag
|
bot_token,
|
||||||
|
main_chat_id,
|
||||||
|
link,
|
||||||
|
args.version,
|
||||||
|
args.hashtag,
|
||||||
|
channel_username_link=username_link,
|
||||||
|
channel_invite_link=invite_link,
|
||||||
)
|
)
|
||||||
if not ok:
|
if not ok:
|
||||||
failures += 1
|
failures += 1
|
||||||
|
|||||||
@@ -110,12 +110,22 @@ jobs:
|
|||||||
# APK + full changelog. Sourced from the same secret the
|
# APK + full changelog. Sourced from the same secret the
|
||||||
# legacy `telegram` job in release.yml used.
|
# legacy `telegram` job in release.yml used.
|
||||||
MAIN_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
|
MAIN_CHAT_ID: ${{ secrets.TELEGRAM_CHAT_ID }}
|
||||||
# Optional: if the files channel later gets a public username,
|
# Public-username form of the files channel link. Used for
|
||||||
# set the repo variable `FILES_CHANNEL_USERNAME` (without the
|
# both (a) the post-link in the main-channel cross-post — so
|
||||||
# `@`) so the cross-link uses the prettier `t.me/<name>/<msg>`
|
# `t.me/<name>/<msg>` works for everyone, not just members
|
||||||
# form instead of `t.me/c/<id>/<msg>` (which only resolves for
|
# via `t.me/c/<id>/<msg>` — and (b) one of the two
|
||||||
# channel members).
|
# channel-join links rendered at the bottom of the cross-post.
|
||||||
FILES_CHANNEL_USERNAME: ${{ vars.FILES_CHANNEL_USERNAME }}
|
# Defaults to `mhrv_rs` (current public username); override via
|
||||||
|
# repo variable if the channel is renamed.
|
||||||
|
FILES_CHANNEL_USERNAME: ${{ vars.FILES_CHANNEL_USERNAME || 'mhrv_rs' }}
|
||||||
|
# `t.me/+<hash>` invite link for the files channel. Rendered
|
||||||
|
# as the second channel-join option in the main-channel
|
||||||
|
# cross-post — the only join path that works for users coming
|
||||||
|
# from outside Telegram search (private/restricted channels)
|
||||||
|
# or whose Telegram client doesn't resolve usernames cleanly.
|
||||||
|
# Override via repo variable if the channel's invite hash is
|
||||||
|
# rotated.
|
||||||
|
FILES_CHANNEL_INVITE: ${{ vars.FILES_CHANNEL_INVITE || 'https://t.me/+R1OyoHX2boA1ZDgx' }}
|
||||||
run: |
|
run: |
|
||||||
if [ -z "${BOT_TOKEN:-}" ]; then
|
if [ -z "${BOT_TOKEN:-}" ]; then
|
||||||
echo "::error::TELEGRAM_BOT_TOKEN not set; can't publish"
|
echo "::error::TELEGRAM_BOT_TOKEN not set; can't publish"
|
||||||
|
|||||||
Reference in New Issue
Block a user