Skip to content

feat/bug: add custom feedback form & fix pydantic valid error on MessageUpdateActivity#349

Merged
lilyydu merged 8 commits intomainfrom
lilyydu/bugs
Apr 3, 2026
Merged

feat/bug: add custom feedback form & fix pydantic valid error on MessageUpdateActivity#349
lilyydu merged 8 commits intomainfrom
lilyydu/bugs

Conversation

@lilyydu
Copy link
Copy Markdown
Collaborator

@lilyydu lilyydu commented Apr 2, 2026

resolves: #326 and #347

  • added default empty string for text in MessageUpdateActivity (otherwise throws pydantic error)
  • added support for custom feedback form (through ChannelData.feedback_loop).

Custom Feedback Context:
Learn Doc

  • previously we had a flag called enable_feedback_loop which only enables the default feedback form
  • now, we have a param called feedback_loop that can either be default or custom.
  • however, the service doesn't accept both at once. Hence I normalized enable_feedback_loop into feedback_loop. whenever enable_feedback_loop is set to True, it'll set feedback_loop to default and itself back to None.
image

Example Usage:

@app.on_message
async def on_message(ctx: ActivityContext[MessageActivity]):
    if ctx.activity.text == "feedback default":
    # This is the legacy approach that normalizes. Recommended to use `feedback_loop` instead.
        await ctx.send(
            MessageActivityInput(text="Rate this response!").with_channel_data(ChannelData(feedback_loop_enabled=True))
        )
    elif ctx.activity.text == "feedback custom":
        await ctx.send(
            MessageActivityInput(text="Rate this response!").add_feedback(
                mode="custom"
            )  # triggers message/fetchTask invoke
        )


@app.on_message_fetch_task
async def on_feedback_fetch_task(ctx: ActivityContext[MessageFetchTaskInvokeActivity]):
    card = AdaptiveCard.model_validate(
        {
            "type": "AdaptiveCard",
            "version": "1.4",
            "body": [
                {"type": "TextBlock", "text": "Tell us more about your feedback:"},
                {
                    "type": "Input.Text",
                    "id": "feedbackText",
                    "placeholder": "Enter your feedback here...",
                    "isMultiline": True,
                },
            ],
            "actions": [
                {"type": "Action.Submit", "title": "Submit"},
            ],
        }
    )
    return TaskModuleInvokeResponse(
        task=TaskModuleContinueResponse(
            value=CardTaskModuleTaskInfo(
                title="Feedback",
                card=card_attachment(AdaptiveCardAttachment(content=card)),
            )
        )
    )

Copilot AI review requested due to automatic review settings April 2, 2026 22:31
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds SDK support for Teams “custom feedback form” flows (message/fetchTask) and fixes a Pydantic validation failure when messageUpdate activities omit text (e.g., attachment-only updates).

Changes:

  • Add MessageFetchTaskInvokeActivity + apps routing hooks (on_message_fetch_task) for custom feedback task modules.
  • Introduce ChannelData.feedback_loop / FeedbackLoop and update Activity.add_feedback() to support "default" vs "custom".
  • Default MessageUpdateActivity.text to "" and add unit tests to prevent regressions.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
packages/apps/src/microsoft_teams/apps/routing/generated_handlers.py Adds generated handler registration method for message.fetch-task.
packages/apps/src/microsoft_teams/apps/routing/activity_route_configs.py Registers new route config for message/fetchTask invokes returning a task module response.
packages/api/tests/unit/test_message_activities.py Adds tests ensuring MessageUpdateActivity.text defaults to empty string and inbound parsing succeeds without text.
packages/api/tests/unit/test_activity.py Updates feedback tests for new feedback_loop model and adds custom-mode assertion.
packages/api/src/microsoft_teams/api/models/channel_data/feedback_loop.py New FeedbackLoop model representing feedback configuration.
packages/api/src/microsoft_teams/api/models/channel_data/channel_data.py Adds feedback_loop field and normalization logic for legacy feedback_loop_enabled.
packages/api/src/microsoft_teams/api/models/channel_data/init.py Exports FeedbackLoop from the channel_data package.
packages/api/src/microsoft_teams/api/models/activity.py Extends add_feedback() to support "default" vs "custom" via feedback_loop.
packages/api/src/microsoft_teams/api/activities/message/message_update.py Defaults MessageUpdateActivity.text to "" to avoid validation errors.
packages/api/src/microsoft_teams/api/activities/invoke/message/fetch_task.py New invoke activity model for message/fetchTask.
packages/api/src/microsoft_teams/api/activities/invoke/message/init.py Re-exports newly added message invoke models.
packages/api/src/microsoft_teams/api/activities/invoke/init.py Adds MessageFetchTaskInvokeActivity to the invoke tagged union.

lilyydu and others added 4 commits April 2, 2026 15:39
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@corinagum
Copy link
Copy Markdown
Contributor

corinagum commented Apr 3, 2026

image

Do you happen to know why learn docs specify Bot Framework SDK here? Seems odd...

Oh I guess they just meant using the Bot Framework SDK. The placement is just a little weird because it's modifying the data object. Please disregard.

Would we be able to get Ricky's help to update the docs with Teams SDK info?

Copy link
Copy Markdown
Contributor

@corinagum corinagum left a comment

Choose a reason for hiding this comment

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

lgtm!
Do you know if there's a plan to deprecate feedbackLoopEnabled? Do we want to plan to deprecate it for simplicity?

@lilyydu
Copy link
Copy Markdown
Collaborator Author

lilyydu commented Apr 3, 2026

image ~Do you happen to know why learn docs specify Bot Framework SDK here? Seems odd...~

Oh I guess they just meant using the Bot Framework SDK. The placement is just a little weird because it's modifying the data object. Please disregard.

Would we be able to get Ricky's help to update the docs with Teams SDK info?

yep! We should be able to get Ricky to help us update

lgtm! Do you know if there's a plan to deprecate feedbackLoopEnabled? Do we want to plan to deprecate it for simplicity?

afaik from the docs it seems to be in public developer preview still! Once it's officially GA'd, I think we can begin the effort to deprecate

Copy link
Copy Markdown
Collaborator

@heyitsaamir heyitsaamir left a comment

Choose a reason for hiding this comment

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

Can we show an example?

@lilyydu lilyydu merged commit 3ece4ba into main Apr 3, 2026
7 checks passed
@lilyydu lilyydu deleted the lilyydu/bugs branch April 3, 2026 22:01
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.

[Bug]: message/fetchTask is missing when using custom feedback forms

4 participants