Skip to content

Add Adaptive Cards support for interactive bot elements #16505

@cbcoutinho

Description

@cbcoutinho

Summary

This issue proposes adding support for Adaptive Cards to enable rich, interactive bot experiences in Nextcloud Talk. This will allow bots to create sophisticated forms, buttons, layouts, and data displays beyond simple text messages and reactions.

I've created a PR that introduces Adaptive Cards as a POC in #16506, with example cards showcasing some of the functionality.

Problem Statement

Currently, Nextcloud Talk bots are limited to:

  • Sending/receiving text messages
  • Adding/removing emoji reactions
  • Creating polls

This restricts bots from providing interactive experiences like:

  • Form-based data collection (feedback, registrations, settings)
  • Multi-step workflows with dynamic branching
  • Quick action buttons (confirmations, menu selections)
  • Rich content displays (tables, formatted layouts, images)
  • Date/time selection interfaces

Proposed Solution

Adopt Adaptive Cards as the standard for interactive bot elements. Adaptive Cards is an open-source, platform-agnostic framework with:

  • JSON-based declarative schema
  • Industry adoption (Microsoft Teams, Outlook, Webex)
  • Rich ecosystem (visual designer, SDKs, samples)
  • Comprehensive element library (20+ elements, 6 input types)
  • Built-in accessibility support

Full details in ADR 0001

Phase 1 & 2 Implementation (This PR)

Phase 1: Basic Card Rendering

Frontend:

  • Integration of adaptivecards npm package
  • AdaptiveCardRenderer.vue component wrapping the SDK
  • Support for core elements: TextBlock, Image, Container, ColumnSet
  • Support for basic inputs: Input.Text, Input.ChoiceSet, Input.Toggle
  • Support for actions: Action.Submit, Action.OpenUrl

Backend:

  • New adaptivecards capability in capabilities endpoint
  • Extended bot message schema to support card objects
  • Cards embedded in bot messages via parameters.object.type: "adaptivecard"

Bot Message Format:

{
    "message": "Please fill out this form",
    "parameters": {
        "object": {
            "type": "adaptivecard",
            "id": "card-abc123",
            "card": {
                "type": "AdaptiveCard",
                "version": "1.5",
                "body": [
                    {
                        "type": "TextBlock",
                        "text": "What's your feedback?",
                        "weight": "Bolder"
                    },
                    {
                        "type": "Input.Text",
                        "id": "feedback",
                        "isMultiline": true,
                        "placeholder": "Enter your feedback..."
                    }
                ],
                "actions": [
                    {
                        "type": "Action.Submit",
                        "title": "Submit"
                    }
                ]
            }
        }
    }
}

Phase 2: Action Handling

User Interactions:

  • Intercept Action.Submit in renderer
  • Collect all Input.* values from the card
  • Send webhook to bot with Activity Streams 2.0 payload

Webhook Payload (on submit):

{
    "type": "adaptivecard_submit",
    "actor": {
        "id": "users/alice",
        "name": "Alice"
    },
    "target": {
        "id": "12345",
        "name": "Project Discussion"
    },
    "card": {
        "id": "card-abc123",
        "values": {
            "feedback": "Great feature!"
        },
        "data": {}
    }
}

Security:

  • Action.OpenUrl with domain whitelisting
  • URL confirmation dialogs for external links
  • SSRF protection (blocks javascript:, data: URIs)
  • Server-side input validation and sanitization
  • XSS prevention with content escaping

Backwards Compatibility:

  • Feature gated by adaptivecards capability
  • Older clients show fallback: "🤖 Bot Name sent an interactive card (view in updated client)"
  • Includes deeplink to web UI

Example Use Cases

1. Meeting Scheduler Bot

{
    "type": "AdaptiveCard",
    "version": "1.5",
    "body": [
        {
            "type": "TextBlock",
            "text": "📅 Schedule Your 1:1 Meeting",
            "size": "Large",
            "weight": "Bolder"
        },
        {
            "type": "Input.Date",
            "id": "date",
            "label": "Preferred date"
        },
        {
            "type": "Input.Time",
            "id": "time",
            "label": "Preferred time"
        }
    ],
    "actions": [
        {
            "type": "Action.Submit",
            "title": "Schedule"
        }
    ]
}

2. Incident Response Bot

{
    "type": "AdaptiveCard",
    "version": "1.5",
    "body": [
        {
            "type": "TextBlock",
            "text": "🚨 Production Alert",
            "color": "Attention",
            "weight": "Bolder"
        },
        {
            "type": "FactSet",
            "facts": [
                {"title": "Service", "value": "API Gateway"},
                {"title": "Severity", "value": "High"},
                {"title": "Error Rate", "value": "23%"}
            ]
        },
        {
            "type": "Input.ChoiceSet",
            "id": "action",
            "label": "Response",
            "choices": [
                {"title": "Acknowledge", "value": "ack"},
                {"title": "Escalate", "value": "escalate"},
                {"title": "Resolve", "value": "resolve"}
            ]
        }
    ],
    "actions": [
        {
            "type": "Action.Submit",
            "title": "Submit"
        }
    ]
}

Future Phases (Not in This PR)

Phase 3: Card Updates & Nextcloud Extensions

  • Bot API for updating cards: PUT /ocs/v2.php/apps/spreed/api/v1/bot/{token}/card/{cardId}
  • Real-time card updates via WebSocket
  • Custom Nextcloud actions: x-nextcloud.startCall, x-nextcloud.shareFile, etc.
  • Collaborative mode (show live responses like polls)

Phase 4: Advanced Features

  • Action.Execute for custom verbs
  • Action.ToggleVisibility
  • Data binding with ${variable} expressions
  • Conditional rendering with $when rules
  • Full Adaptive Cards 1.5 spec compliance

Benefits

  1. Rich Interactive Experiences - Forms, buttons, layouts, data displays
  2. Developer Familiarity - Reuse knowledge from Teams/Outlook bot development
  3. Excellent Tooling - Visual designer, extensive samples, documentation
  4. Future-Proof - Ongoing spec development by community
  5. Cross-Platform Potential - Portable across federated instances
  6. Reduced Maintenance - Spec evolution handled by Adaptive Cards community
  7. Accessibility - Built-in ARIA support
  8. Faster Development - ~13 weeks total vs. 16+ weeks for proprietary solution

Trade-offs

  • Bundle Size: ~150KB added (adaptivecards package, minified)
  • External Dependency: Relies on Microsoft-maintained open standard
  • Learning Curve: Team and bot developers learn new schema
  • Limited Customization: Styling constrained by SDK (ensures consistency)

Testing

The implementation includes:

  • Unit tests for AdaptiveCardRenderer component
  • Integration tests for bot message handling
  • Security tests for URL validation and XSS prevention
  • Example cards in docs/adaptive-cards-examples.md

Documentation

  • ADR 0001: Full architectural decision with evaluation criteria
  • Bot Documentation: Updated docs/bots.md with Adaptive Cards usage
  • Examples: Comprehensive examples in docs/adaptive-cards-examples.md

References

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions