Enviar y recibir imágenes en línea

Una imagen en línea forma parte del mensaje y se representa directamente en una conversación de Microsoft Teams en lugar de aparecer como documentos almacenados en la pestaña Compartido de la conversación. Teams representa cada imagen como datos adjuntos de actividad con un tipo MIME de imagen y una dirección URL hospedada o URI de datos base64.

Use el SDK de Teams para descargar las imágenes que los usuarios pegan en los mensajes y para enviar imágenes desde direcciones URL hospedadas o bytes en memoria. Para los documentos almacenados en OneDrive o SharePoint, vea Enviar y recibir archivos.

Nota:

En GCC High, DoD y Teams operado por 21Vianet, los agentes pueden usar datos adjuntos de imagen en base64 para incluir una imagen en un mensaje aunque no se admitan flujos de trabajo de archivos de documento.

Experiencia del usuario

Comprenda cómo aparecen y se comportan las imágenes en línea para que pueda seleccionar la presentación adecuada para el contenido visual. Los usuarios pueden:

  • Ver una imagen que envía un agente con un texto de mensaje y una imagen en base64 colocadas dentro del texto con formato del mensaje.
  • Pegar una imagen que se representa en su posición en un mensaje compuesto.
  • Interactuar con una imagen incluida en una tarjeta adaptable.

Usa un archivo adjunto hospedado para una imagen independiente, contenido HTML/XML base64 para una ubicación exacta o una tarjeta adaptativa cuando la imagen pertenezca a contenido interactivo.

Experiencia del desarrollador

Elija una representación de imagen en función de dónde se almacenan los bytes y cómo debe aparecer la imagen. Las siguientes opciones coinciden con el orden de implementación de este artículo:

Requisito Enfoque recomendado
Recibir una imagen pegada en un mensaje Inspeccionar datos adjuntos de actividad y usar el cliente HTTP del SDK autenticado
Enviar una imagen junto al texto del mensaje Datos adjuntos de imagen con una dirección URL hospedada o un URI de datos en base64
Colocar una imagen dentro del texto con formato Imagen base64 en contenido HTML/XML
Agregar una imagen a contenido interactivo Elemento de tarjeta Image adaptativa

La colección de datos adjuntos de actividad contiene la carga de imágenes y cualquier información de diseño HTML. Las imágenes en línea no se exponen a través del descriptor de acceso de archivos del SDK de Teams.

Operación Chat personal Chat de grupo Canal Requisito
Recibir imágenes en línea Compatible a través de datos adjuntos de actividad Usar datos adjuntos de actividad Usar datos adjuntos de actividad Descarga con el cliente HTTP SDK autenticado de la aplicación.
Enviar imágenes alineadas Compatible Compatible Compatible No se requiere ningún permiso de Graph ni inicio de sesión de usuario.

Trabajar con imágenes alineadas

Use imágenes en línea cuando los usuarios o agentes necesiten que el contenido visual se represente directamente en una conversación en lugar de como un documento almacenado. Use datos adjuntos de actividad autenticada para recibir imágenes y datos adjuntos de imagen o contenido HTML/XML para enviarlos.

Recibir imágenes en línea

Una imagen en línea no se expone a través del descriptor de acceso de archivos SDK de Teams. Normalmente, un mensaje entrante incluye datos image/* adjuntos con la dirección URL de descarga autenticada y datos text/html adjuntos que conservan la posición de la imagen.

Use el image/* archivo adjunto como fuente canónica. No uses la <img src> dirección URL del archivo adjunto HTML para descargar la imagen.

using Microsoft.Extensions.DependencyInjection;
using Microsoft.Teams.Apps.Clients;
using Microsoft.Teams.Apps.Schema;

HttpClient imageClient = app.Services
    .GetRequiredService<IHttpClientFactory>()
    .CreateClient(nameof(ApiClient));

teams.OnMessage(async (context, cancellationToken) =>
{
    TeamsAttachment? image =
        context.Activity.Attachments?.FirstOrDefault(
            attachment =>
                attachment.ContentType is not null &&
                attachment.ContentType.Value.StartsWith(
                    "image/",
                    StringComparison.OrdinalIgnoreCase) &&
                attachment.ContentUrl is not null);

    if (image?.ContentUrl is not Uri contentUrl)
    {
        return;
    }

    using HttpResponseMessage response =
        await imageClient.GetAsync(
            contentUrl,
            HttpCompletionOption.ResponseHeadersRead,
            cancellationToken);

    response.EnsureSuccessStatusCode();

    byte[] bytes =
        await response.Content.ReadAsByteArrayAsync(
            cancellationToken);

    // Process the image bytes.
});

API y valores clave:

  • nameof(ApiClient): selecciona el cliente SDK con autenticación de plataforma.
  • ContentType: Coincidir con un image/* tipo MIME sin distinguir mayúsculas de minúsculas.
  • ContentUrl: usa la dirección URL de descarga de la imagen autenticada canónica.
  • ResponseHeadersRead: comienza primero a procesar sin almacenar en búfer el contenido de la respuesta.
  • EnsureSuccessStatusCode: Producir un error explícito cuando la recuperación de la imagen no se realice correctamente.
app.on('message', async ({ activity }) => {
  const image = activity.attachments?.find(
    (attachment) =>
      attachment.contentType?.toLowerCase().startsWith('image/') &&
      attachment.contentUrl
  );

  if (image?.contentUrl) {
    const response = await app.api.http.get<ArrayBuffer>(
      image.contentUrl,
      { responseType: 'arraybuffer' }
    );
    const bytes = Buffer.from(response.data);

    // Process the image bytes.
  }
});

API y valores clave:

  • activity.attachments: buscar todos los datos adjuntos de los mensajes entrantes.
  • contentType: Coincidir con un image/* tipo MIME sin distinguir mayúsculas de minúsculas.
  • contentUrl: usa la dirección URL de descarga de la imagen autenticada canónica.
  • app.api.http: Descargar bytes con el cliente autenticado del SDK.
  • responseType: Configurar arraybuffer para recibir contenido de imagen binario.
@app.on_message
async def handle_message(ctx: ActivityContext[MessageActivity]) -> None:
    image = next(
        (
            attachment
            for attachment in (ctx.activity.attachments or [])
            if attachment.content_type
            and attachment.content_type.lower().startswith("image/")
            and attachment.content_url
        ),
        None,
    )

    if image and image.content_url:
        response = await app.api.http.get(image.content_url)
        image_bytes = response.content

        # Process the image bytes.

API y valores clave:

  • ctx.activity.attachments: buscar todos los datos adjuntos de los mensajes entrantes.
  • content_type: Coincidir con un image/* tipo MIME sin distinguir mayúsculas de minúsculas.
  • content_url: usa la dirección URL de descarga de la imagen autenticada canónica.
  • app.api.http: Descargar bytes con el cliente autenticado del SDK.
  • response.content: acceda al contenido de la imagen binaria descargada.

Procese los bytes directamente cuando sea posible. Conviértalos a base64 solo cuando una API descendente lo requiera y conserve el tipo MIME real de los datos adjuntos.

Enviar una imagen alineada

Una imagen saliente en línea usa un tipo MIME de imagen y ContentType una dirección URL HTTPS accesible o un URI de datos base64 en ContentUrl. El envío no carga la imagen en OneDrive o SharePoint y no requiere permiso de Graph ni inicio de sesión de usuario.

Elija una dirección URL hospedada para imágenes disponibles externamente o datos en base64 para imágenes pequeñas en poder de la aplicación y, a continuación, cree los datos adjuntos correspondientes para el mensaje saliente. Teams admite imágenes en línea con los siguientes límites:

Límite Valor
Dimensiones máximas 1024 x 1024 píxeles
Tamaño máximo de la imagen 1 MB
Formatos compatibles PNG, JPEG y GIF
GIF animado No se admite
Validación de SDK No realizado

Advertencia

La API de envío puede aceptar una imagen fuera de las dimensiones, el tamaño o el formato admitidos, pero no se puede representar en el cliente de Teams.

Enviar una imagen desde una URL hospedada

Use una dirección URL hospedada cuando la imagen ya esté disponible a través de un punto de conexión HTTPS público o sea demasiado grande para insertarla de forma eficaz. Agregue la dirección URL accesible y el tipo MIME coincidente a los datos adjuntos de imagen.

TeamsAttachment image = TeamsAttachment.CreateBuilder()
    .WithContentType(new AttachmentContentType("image/png"))
    .WithContentUrl(new Uri("https://contoso.com/charts/weekly.png"))
    .WithName("weekly.png")
    .Build();

await context.SendAsync(
    new MessageActivityInput()
        .WithText("Here is the latest chart:")
        .AddAttachment(image),
    cancellationToken);

Propiedades y valores clave:

  • ContentType: establezca el tipo MIME que coincida con los bytes de imagen hospedada.
  • ContentUrl: establece una dirección URL de imagen HTTPS accesible públicamente.
  • Name: agregue un nombre para mostrar opcional para la imagen.
  • AddAttachment: adjunta la imagen al mensaje saliente.
app.on('message', async ({ send }) => {
  await send(
    new MessageActivityInput('Here is the latest chart:')
      .addAttachments({
        contentType: 'image/png',
        contentUrl: 'https://contoso.com/charts/weekly.png',
        name: 'weekly.png'
      })
  );
});

Propiedades y valores clave:

  • contentType: establezca el tipo MIME que coincida con los bytes de imagen hospedada.
  • contentUrl: establece una dirección URL de imagen HTTPS accesible públicamente.
  • name: agregue un nombre para mostrar opcional para la imagen.
  • addAttachments: adjunta la imagen al mensaje saliente.
@app.on_message
async def handle_message(ctx: ActivityContext[MessageActivity]) -> None:
    await ctx.send(
        MessageActivityInput(text="Here is the latest chart:").add_attachments(
            Attachment(
                content_type="image/png",
                content_url="https://contoso.com/charts/weekly.png",
                name="weekly.png",
            )
        )
    )

Propiedades y valores clave:

  • content_type: establezca el tipo MIME que coincida con los bytes de imagen hospedada.
  • content_url: establece una dirección URL de imagen HTTPS accesible públicamente.
  • name: agregue un nombre para mostrar opcional para la imagen.
  • add_attachments: adjunta la imagen al mensaje saliente.

El cliente de Teams debe poder acceder a la dirección URL sin credenciales de agente. Prefiera este enfoque para imágenes que no son pequeñas.

Enviar bytes de imagen como base64

Use un URI de datos base64 cuando los bytes de imagen solo existan en la aplicación, como para un icono, una miniatura o un gráfico generados. Codifique los bytes, conserve el tipo MIME correcto y adjunte el URI de datos resultante al mensaje.

byte[] bytes = await File.ReadAllBytesAsync(
    "./charts/weekly.png",
    cancellationToken);

string dataUri =
    $"data:image/png;base64,{Convert.ToBase64String(bytes)}";

TeamsAttachment image = TeamsAttachment.CreateBuilder()
    .WithContentType(new AttachmentContentType("image/png"))
    .WithContentUrl(new Uri(dataUri))
    .WithName("weekly.png")
    .Build();

await context.SendAsync(
    new MessageActivityInput()
        .WithText("Here is the latest chart:")
        .AddAttachment(image),
    cancellationToken);

Propiedades y valores clave:

  • dataUri: prefijo base64 bytes con el tipo MIME coincidente.
  • ContentType: hacer coincidir el URI de datos y el formato de imagen real.
  • ContentUrl: Ajuste el URI de datos completo en Uri.
  • Name: agrega un nombre de archivo opcional que coincida con el formato de imagen.
app.on('message', async ({ send }) => {
  const bytes = await readFile('./charts/weekly.png');

  await send(
    new MessageActivityInput('Here is the latest chart:')
      .addAttachments({
        contentType: 'image/png',
        contentUrl: `data:image/png;base64,${bytes.toString('base64')}`,
        name: 'weekly.png'
      })
  );
});

Propiedades y valores clave:

  • contentUrl: prefijo base64 bytes con el tipo MIME coincidente.
  • contentType: hacer coincidir el URI de datos y el formato de imagen real.
  • bytes.toString('base64'): codifica los bytes de imagen para el URI de datos.
  • name: agrega un nombre de archivo opcional que coincida con el formato de imagen.
@app.on_message
async def handle_message(ctx: ActivityContext[MessageActivity]) -> None:
    encoded = b64encode(
        Path("./charts/weekly.png").read_bytes()
    ).decode("ascii")

    await ctx.send(
        MessageActivityInput(text="Here is the latest chart:").add_attachments(
            Attachment(
                content_type="image/png",
                content_url=f"data:image/png;base64,{encoded}",
                name="weekly.png",
            )
        )
    )

Propiedades y valores clave:

  • content_url: prefijo base64 bytes con el tipo MIME coincidente.
  • content_type: hacer coincidir el URI de datos y el formato de imagen real.
  • b64encode: codifica los bytes de imagen para el URI de datos.
  • name: agrega un nombre de archivo opcional que coincida con el formato de imagen.

Base64 aumenta el tamaño de la carga útil en aproximadamente un tercio. Úselo para imágenes generadas pequeñas y use una dirección URL hospedada para imágenes más grandes.

Colocar una imagen en el texto de un mensaje

Use contenido HTML/XML para controlar la ubicación y las dimensiones de las imágenes:

string encoded = Convert.ToBase64String(
    await File.ReadAllBytesAsync(
        "./charts/weekly.png",
        cancellationToken));

await context.SendAsync(
    new MessageActivityInput()
        .WithText(
            $"<div>Revenue is up." +
            $"<img src=\"data:image/png;base64,{encoded}\"/>" +
            $"Questions?</div>")
        .WithTextFormat(TextFormats.Xml),
    cancellationToken);

Propiedades y valores clave:

  • src: use un URI de datos base64 para las imágenes incrustadas.
  • TextFormats.Xml: habilitar elementos HTML en el cuerpo del mensaje.
  • height y width: Agregue dimensiones opcionales al elemento de imagen.
app.on('message', async ({ send }) => {
  const bytes = await readFile('./charts/weekly.png');
  const encoded = bytes.toString('base64');

  await send(
    new MessageActivityInput(
      `<div>Revenue is up.` +
      `<img src="data:image/png;base64,${encoded}"/>` +
      `Questions?</div>`
    ).withTextFormat('xml')
  );
});

Propiedades y valores clave:

  • src: use un URI de datos base64 para las imágenes incrustadas.
  • withTextFormat('xml'): habilita los elementos HTML en el cuerpo del mensaje.
  • height y width: Agregue dimensiones opcionales al elemento de imagen.
@app.on_message
async def send_positioned_image(
    ctx: ActivityContext[MessageActivity],
) -> None:
    encoded = base64.b64encode(
        Path("./charts/weekly.png").read_bytes()
    ).decode("ascii")

    await ctx.send(
        MessageActivityInput(
            text=(
                '<div>Revenue is up.'
                f'<img src="data:image/png;base64,{encoded}"/>'
                'Questions?</div>'
            )
        ).with_text_format("xml")
    )

Propiedades y valores clave:

  • src: use un URI de datos base64 para las imágenes incrustadas.
  • with_text_format("xml"): habilita los elementos HTML en el cuerpo del mensaje.
  • height y width: Agregue dimensiones opcionales al elemento de imagen.

Un HTTPS <img src> no se carga ni se reescribe. En su lugar, use datos adjuntos de imagen hospedada. Cada imagen insertada cuenta para la carga del mensaje y, si supera el límite, se puede rechazar todo el mensaje.

Para varias imágenes independientes, agregue cada archivo adjunto y seleccione un diseño compatible, como lista o carrusel. Para una imagen dentro de contenido interactivo, usa un elemento de tarjeta Image adaptable. En el caso de respuestas transmitidas, agregue datos adjuntos solo al mensaje final porque las actividades de escritura intermedias no llevan datos adjuntos.

Controlar los errores

Controle los errores de recuperación por separado de los errores de validación y representación de imágenes para que los usuarios reciban una respuesta accionable.

Código de estado Código de error Descripción Acción del desarrollador
HTTP 4xx Error al solicitar imagen autenticada La plataforma rechazó la solicitud de la URL de imagen entrante. Use el cliente HTTP del SDK autenticado, conserve el estado de respuesta y compruebe que la aplicación puede acceder a los datos adjuntos del mensaje.
HTTP 5xx Servicio de imágenes no disponible Teams o el servicio de datos adjuntos no pudieron completar la descarga. Conserve el error original y vuelva a intentarlo según las instrucciones del servicio.
No aplicable Datos adjuntos de imagen no válidos Los datos adjuntos no tienen ningún tipo MIME de imagen ni dirección URL de contenido. Omita los datos adjuntos e inspeccione los datos adjuntos de actividad restantes.
No aplicable Imagen hospedada no disponible El cliente de Teams no puede acceder a una dirección URL de imagen hospedada sin las credenciales del agente. Use una dirección URL HTTPS accesible públicamente o envíe una imagen en base64.
No aplicable Error al procesar la imagen El tipo, formato, tamaño o dimensiones MIME no se admiten. Haga coincidir el tipo MIME con los bytes y valide la imagen antes de enviarla.
No aplicable Carga de mensaje rechazada El contenido de la imagen en base64 hace que el mensaje supere su límite de carga. Reduzca el tamaño de la imagen o use una dirección URL hospedada.

Instrucciones de diseño y procedimientos recomendados

Aplique estas instrucciones para crear experiencias de imagen en línea confiables y accesibles. Revíselas antes de procesar o enviar contenido de imagen.

  • Indique a los usuarios qué imagen recibió o generó el agente y qué hizo con el contenido.
  • Use el cliente HTTP del SDK autenticado para las direcciones URL de imagen entrantes.
  • Buscar en todos los datos adjuntos en lugar de asumir que el primer adjunto es una imagen.
  • Usa el image/* archivo adjunto como fuente de descarga canónica, no la dirección URL HTML <img src> .
  • Conservar y validar el tipo MIME de imagen real.
  • Mantenga las imágenes en base64 pequeñas y prefiera las direcciones URL hospedadas para las imágenes más grandes.
  • Asegúrese de que las direcciones URL de imagen hospedadas sean accesibles sin credenciales de agente.
  • Valide el tamaño, las dimensiones y el formato de la imagen antes de enviarla.
  • Agregar texto alternativo significativo cuando la imagen forme parte de una tarjeta adaptable.
  • Use HTML/XML solo cuando se requiera una ubicación o dimensiones exactas de la imagen.
  • Agregue datos adjuntos al mensaje final transmitido porque las actividades de escritura intermedias no llevan datos adjuntos.
  • No registre bytes de imagen ni URL de datos adjuntos autenticados.
  • Propagar la cancelación y conservar los errores HTTP para los diagnósticos.

Vea también

Use estos recursos para explorar las API de imagen del SDK de Teams relacionadas, el control de archivos, las tarjetas y la guía de mensajería.