Skip to content

Forward the original source from restricted chats#309

Open
starius wants to merge 2 commits into
AyuGram:devfrom
starius:opt-ayu-forward
Open

Forward the original source from restricted chats#309
starius wants to merge 2 commits into
AyuGram:devfrom
starius:opt-ayu-forward

Conversation

@starius

@starius starius commented Mar 24, 2026

Copy link
Copy Markdown

When forwarding from a chat with forwarding restrictions, prefer native forwarding from the forwardable original source message. This avoids Ayu re-upload where the source channel already allows forwarding, automating the manual open-original-and-forward workflow when possible.

What was done and how:

  • Added forward source resolution in Ayu forward logic by reading original sender/id from forwarded message metadata and validating that the original channel allows forwarding.
  • Updated Ayu fallback decisions to skip full/manual fallback when such a source is resolvable, while preserving existing fallback for deleted messages, TTL media, and genuinely non-forwardable sources.
  • Updated both forwarding send paths (ApiWrap and ShareBox) to send MTProto forwards with resolved source peer/message id.
  • Updated multi-item full-Ayu checks to evaluate all selected items, not only the first one.

@ZavaruKitsu

Copy link
Copy Markdown
Member

Too many broad changes. AyuForward already has chunking, so you should've just reused that, e.g. in intelligentForward replace const auto items = draft.items; with const auto items = resolveForwardSources(draft.items); + a few changes in isAyuForwardNeeded and isFullAyuForwardNeeded

Also, from what I've tested, it only works if the peer has already been resolved (e.g. opened manually at least once before app restart, or if you've already joined the source unrestricted channel).

@psyhhhh

This comment was marked as off-topic.

starius added 2 commits April 10, 2026 22:51
Resolve restricted forwards back to their original channel posts inside
AyuForward's existing chunking flow.

When a restricted forwarded message still points to an addressable original
channel post, resolve that source item and plain-forward it. Fall back to
full Ayu forward when the source is not a channel post, when the original
channel is no longer accessible, when the source channel itself forbids
forwarding, or when the original post can no longer be resolved.

Remember source posts that were already confirmed missing in the current
session so later forwarding decisions use the same fallback immediately.
Make the full-Ayu checks in ApiWrap and ShareBox consider the whole
selection so mixed batches still follow AyuForward's chunking rules.
Show the "Plain forwarding is not allowed" label only when an item
actually requires a full Ayu fallback.

Restricted chats can still plain-forward messages whose original source
channel post is resolvable, so the menu should reflect the resolved
forwarding mode instead of the chat-level no-forwards flag. Use
isFullAyuForwardNeeded(item) for that label so source-rerouted messages
stop showing the warning while full-Ayu-only messages still do.
@starius

starius commented Apr 11, 2026

Copy link
Copy Markdown
Author

@ZavaruKitsu I reworked it. Now the change stays focused in ayu_forward.cpp with very small changes apiwrap.cpp and share_box.cpp.

I fixed the bugs that you found and tested all the scenarios manually (see the list below).

I also removed "Plain forwarding is not allowed" from messages which are likely to be forwarded directly. I did it in another commit. Since some of them may still fallback to Ayu forward technique, this fact is memorized and used next time if the same message is opened again in context menu.

Ayu Forward Manual Test Checklist

Use a normal destination chat where you can verify whether the result was a plain forward or an Ayu-style fallback. When useful, repeat a case after app restart to check session-state behavior.

Forwarding Behavior

  1. Restricted chat, original source is a public channel post, source post still exists. Forward the message. Expected: plain forward succeeds through the original source post, not Ayu fallback.

  2. Restricted chat, original source is a private channel post, you are still a member of that source channel, and the source post still exists. Forward the message. Expected: plain forward succeeds through the original source post.

  3. Restricted chat, original source is a private channel post, you were a member earlier so the source may still be cached, then you leave the source channel without restarting the app. Forward the message again. Expected: it should go directly to Ayu fallback, with no stuck forwarding 0/1 state and no hanging unsent item.

  4. Repeat the previous “left private source channel” case after app restart. Expected: it should still use Ayu fallback immediately.

  5. Restricted chat, original source is a channel you can access, but you have not manually opened that source channel in the current app session after restart. Forward the message. Expected: source resolution should still work and plain forward should succeed.

  6. Restricted chat, original source post has been deleted, but you still have access to the source channel. Try forwarding the message once. Expected: forwarding should use Ayu fallback.

  7. After the previous deleted-source test, reopen the context menu on the same message in the same session. Expected: the UI should now treat it as full-Ayu-only and show Plain forwarding is not allowed.

  8. Restricted chat, original source channel itself does not allow forwarding. Forward the message. Expected: Ayu fallback is used.

  9. Restricted chat, forwarded copy points to an original user instead of a channel post. Forward the message. Expected: Ayu fallback is used, because there is no reusable original channel post to plain-forward.

  10. Restricted chat, message is deleted, unsupported TTL, or has self-destructing media. Forward the message. Expected: Ayu fallback is used.

  11. Unrestricted chat message with no restricted-source routing involved. Forward the message. Expected: behavior is unchanged from normal forwarding.

Mixed Selections

  1. Select multiple messages where one is source-reroutable and another is full-Ayu-only, with the reroutable item first. Forward the selection. Expected: the batch should still work correctly, following AyuForward chunking instead of forcing the whole batch into one mode.

  2. Repeat the previous mixed-selection case with the full-Ayu-only item first. Expected: same result; order should not break the decision.

  3. Mixed selection where one item has a deleted original source post already learned as missing in the current session and another item is still source-reroutable. Forward the selection. Expected: the deleted-source item should stay on Ayu fallback while reroutable items can still use plain forwarding as allowed by chunking.

Context Menu Label

  1. Open the context menu on a restricted-chat message that is source-reroutable. Expected: Plain forwarding is not allowed is not shown.

  2. Open the context menu on a message that truly requires full Ayu fallback, such as a user-origin message, a no-forwards source, TTL content, or an inaccessible private source channel. Expected: Plain forwarding is not allowed is shown.

  3. For a deleted original source post, open the context menu before any new forwarding attempt in the current session, then forward once, then reopen the menu. Expected: before discovery the label may still be absent, but after the app has confirmed the source post is missing, the label should appear for that message in the same session.

Other Flows

  1. Forward through the share box to multiple destinations using a reroutable restricted-chat message. Expected: behavior matches the direct forward flow.

  2. Forward to a forum topic or as a reply using a reroutable restricted-chat message. Expected: topic or reply targeting still works correctly.

  3. Repeat a few successful reroutable cases after app restart to confirm there is no bad cached state left behind from earlier failed resolutions or fallbacks.

I checked all of these manually.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants