Skip to content

Rename IncomingFile.webUrl to contentUrl - #773

Merged
Corina (corinagum) merged 2 commits into
mainfrom
cg/rename-content-url
Aug 27, 2026
Merged

Rename IncomingFile.webUrl to contentUrl#773
Corina (corinagum) merged 2 commits into
mainfrom
cg/rename-content-url

Conversation

@corinagum

Copy link
Copy Markdown
Collaborator

Renames the public IncomingFile.webUrl property to contentUrl.

This is not a breaking change

The property has never been published. webUrl arrived with #712 ("Receive files in personal scope") on 2026-08-13, and no release has been cut since. Verified rather than assumed:

  • npm dist-tags: latest is 2.0.15, next is 2.1.0-preview.3. There is no stable 2.1.0.
  • I downloaded and unpacked the @microsoft/teams.apps@2.1.0-preview.3 tarball. It contains zero occurrences of webUrl and no files/ output in dist at all. The whole ctx.files feature postdates it.
  • git tag --contains on Feature: Receive files in personal scope #712 is empty, and release/v2.1 does not contain packages/apps/src/files/ at all.

So there are no consumers to break, in any published form. This is also the last cheap moment: once 2.1 ships from main, the name is locked.

Why

The value arrives on the wire as the attachment's contentUrl, and Attachment.contentUrl already exposes it publicly in this same SDK. That left the same value reachable under two different public names depending on which door you came through:

activity.attachments[0].contentUrl   // public
ctx.files[0].webUrl                  // public, same value, different name

Upstream doesn't call it a "web URL" either. APX sources it from fileInfo.ObjectUrl and writes it into the Bot Framework attachment's ContentUrl slot, so webUrl was a name this SDK invented at the boundary. The mapping comment in files-accessor.ts was the only thing holding the two vocabularies together, and it's now unnecessary: the value is a straight pass-through.

The one real objection, and how it's handled

contentUrl sits next to downloadUrl, and it is the one that does not return content. That's a genuine footgun, but it already exists on Attachment.contentUrl regardless of what we do here, and it's a docs problem rather than a design problem. Two public names for one value is the design problem. So the docstring now states the trap directly:

Browsable URL to the file in OneDrive/SharePoint, as sent on the attachment's contentUrl. Not fetchable for bytes despite the name; those come from downloadUrl.

Cross-SDK

Matching PRs go up for teams.py (web_urlcontent_url) and teams.net (WebUrlContentUrl). The feature is unreleased in all three, so all three can move together. Published docs in teams-sdk are updated separately.

Validation

30 suites / 585 tests pass; build and lint clean.

The value arrives on the wire as the attachment's `contentUrl`, and
`Attachment.contentUrl` already exposes it publicly, so the same value had
two public names depending on which door a developer came through.

Renaming now is free: the files feature has never been published. The
`2.1.0-preview.3` package on npm contains no `files/` output and no
`webUrl` at all.

Also documents the trap the name invites: this URL is browsable, not
fetchable. Bytes come from `downloadUrl`.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7d326e8a-aeb4-4481-bc0a-58d2a012584e

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR renames the public IIncomingFile/IncomingFile property that surfaces an attachment’s browsable link from webUrl to contentUrl, aligning the files API with the wire shape (Attachment.contentUrl) and existing SDK vocabulary.

Changes:

  • Renamed IIncomingFile.webUrlcontentUrl and updated the IncomingFile implementation/constructor init shape accordingly.
  • Updated FilesAccessor mapping to populate contentUrl from the attachment.
  • Updated unit tests to assert against contentUrl.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.

File Description
packages/apps/src/files/types.ts Renames IIncomingFile property to contentUrl and updates its JSDoc.
packages/apps/src/files/incoming-file.ts Renames init/class fields from webUrl to contentUrl in IncomingFile.
packages/apps/src/files/files-accessor.ts Updates the attachment-to-IncomingFile mapping to set contentUrl.
packages/apps/src/files/files-accessor.spec.ts Updates expectations to validate the renamed contentUrl field.
Suppressed comments (1)

packages/apps/src/files/incoming-file.ts:41

  • IncomingFile.contentUrl is a new public field but currently lacks a doc comment, which makes it easy to confuse with the byte-fetching URL. Adding a brief JSDoc here keeps class-level IntelliSense clear even when users interact with IncomingFile directly instead of the IIncomingFile interface.
  readonly source: FileSource;
  readonly contentUrl?: string;
  readonly raw?: unknown;

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/apps/src/files/types.ts
Comment thread packages/apps/src/files/incoming-file.ts
The docstring told callers bytes come from `downloadUrl`, but that member
is private on `IncomingFile` and absent from `IIncomingFile`, so the
`{@link}` was broken and the guidance named something a consumer cannot
reach. Points at `download()` and `stream()` instead.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7d326e8a-aeb4-4481-bc0a-58d2a012584e
Corina (corinagum) added a commit to microsoft/teams.py that referenced this pull request Aug 27, 2026
Renames the public `IncomingFile.web_url` property to `content_url`.

## This is not a breaking change

**The property has never been published.** `web_url` arrived with the
"Receive files in personal scope" work and no release has been cut
since, so there are no consumers to break in any published form.

This is also the last cheap moment: once the files feature ships, the
name is locked.

## Why

The value arrives on the wire as the attachment's `content_url`, and
`Attachment.content_url` **already exposes it publicly** in this same
SDK. That left the same value reachable under two different public names
depending on which door you came through:

```python
activity.attachments[0].content_url   # public
ctx.files[0].web_url                  # public, same value, different name
```

Upstream doesn't call it a "web URL" either. APX sources it from
`fileInfo.ObjectUrl` and writes it into the Bot Framework attachment's
`ContentUrl` slot, so `web_url` was a name this SDK invented at the
boundary. The mapping comment in `files_accessor.py` was the only thing
holding the two vocabularies together, and it's now unnecessary: the
value is a straight pass-through.

## The one real objection, and how it's handled

`content_url` sits next to `download_url`, and it is the one that does
**not** return content. That's a genuine footgun, but it already exists
on `Attachment.content_url` regardless of what we do here, and it's a
docs problem rather than a design problem. Two public names for one
value is the design problem. So the docstring now states the trap
directly:

> Browsable URL to the file in OneDrive/SharePoint, as sent on the
attachment's `content_url`. Not fetchable for bytes despite the name;
those come from `download_url`.

## Cross-SDK

Companion to microsoft/teams.ts#773 (`webUrl` → `contentUrl`), with a
matching PR for `teams.net` (`WebUrl` → `ContentUrl`). The feature is
unreleased in all three, so all three can move together. Published docs
in `teams-sdk` are updated separately.

## Validation

598 tests pass; `poe check` clean.

---------

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot-Session: 7d326e8a-aeb4-4481-bc0a-58d2a012584e
@corinagum
Corina (corinagum) added this pull request to the merge queue Aug 27, 2026
Merged via the queue into main with commit 4d0602a Aug 27, 2026
8 checks passed
@corinagum
Corina (corinagum) deleted the cg/rename-content-url branch August 27, 2026 20:39
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