Linkvorschau mit Smartchips

Auf dieser Seite wird beschrieben, wie Sie ein Google Workspace-Add-on erstellen, mit dem Nutzer von Google Docs, Sheets und Präsentationen Links von einem Drittanbieterdienst in der Vorschau ansehen können.

Ein Google Workspace-Add‑on kann die Links Ihres Dienstes erkennen und Nutzer auffordern, eine Vorschau aufzurufen. Sie können ein Add-on so konfigurieren, dass mehrere URL-Muster in der Vorschau angezeigt werden, z. B. Links zu Supportanfragen, Vertriebsleads und Mitarbeiterprofilen.

So rufen Nutzer eine Linkvorschau auf

Um Links in der Vorschau anzusehen, interagieren Nutzer mit Smartchips und Karten.

Nutzer sieht sich eine Karte in der Vorschau an

Wenn Nutzer eine URL in ein Dokument oder eine Tabelle eingeben oder einfügen, werden sie in Google Docs oder Google Sheets aufgefordert, den Link durch einen Smartchip zu ersetzen. Der Smart-Chip enthält ein Symbol und einen kurzen Titel oder eine kurze Beschreibung des Inhalts des Links. Wenn der Nutzer den Mauszeiger auf den Chip bewegt, wird eine Karte mit einer Vorschau mit weiteren Informationen zur Datei oder zum Link angezeigt.

Im folgenden Video sehen Sie, wie ein Nutzer einen Link in einen Smartchip umwandelt und eine Karte in der Vorschau ansieht:

So sehen Nutzer eine Vorschau von Links in Google Präsentationen

Smart Chips von Drittanbietern werden für Linkvorschauen in Google-Präsentationen nicht unterstützt. Wenn Nutzer eine URL in eine Präsentation eingeben oder einfügen, werden sie in Google Präsentationen aufgefordert, den Link durch seinen Titel als verlinkten Text anstelle eines Chips zu ersetzen. Wenn der Nutzer den Mauszeiger auf den Linktitel bewegt, wird eine Karte mit einer Vorschau der Informationen zum Link angezeigt.

Die folgende Abbildung zeigt, wie eine Linkvorschau in Google Präsentationen gerendert wird:

Beispiel für eine Linkvorschau in Google-Präsentationen

Vorbereitung

Apps Script

Node.js

Python

Java

Optional: Authentifizierung für einen Drittanbieterdienst einrichten

Wenn Ihr Add-on eine Verbindung zu einem Dienst herstellt, für den eine Autorisierung erforderlich ist, müssen sich Nutzer beim Dienst authentifizieren, um Links in der Vorschau anzusehen. Wenn Nutzer also zum ersten Mal einen Link aus Ihrem Dienst in eine Datei in Google Docs, Google Sheets oder Google Präsentationen einfügen, muss Ihr Add-on den Autorisierungsablauf aufrufen.

Informationen zum Einrichten eines OAuth-Dienstes oder einer benutzerdefinierten Autorisierungsaufforderung finden Sie unter Add-on mit einem Drittanbieterdienst verbinden.

In diesem Abschnitt wird beschrieben, wie Sie Linkvorschauen für Ihr Add-on einrichten. Dazu sind die folgenden Schritte erforderlich:

  1. Linkvorschauen im Manifest Ihres Add-ons konfigurieren
  2. Smartchip- und Kartenoberfläche für Ihre Links erstellen

Linkvorschauen konfigurieren

Geben Sie zum Konfigurieren von Linkvorschauen die folgenden Abschnitte und Felder im Manifest Ihres Add-ons an:

  1. Fügen Sie im Abschnitt addOns das Feld docs hinzu, um Docs zu erweitern, das Feld sheets, um Sheets zu erweitern, und das Feld slides, um Präsentationen zu erweitern.
  2. Implementieren Sie in jedem Feld den linkPreviewTriggers-Trigger, der eine runFunction enthält. Sie definieren diese Funktion im folgenden Abschnitt Smartchip und Karte erstellen.

    Informationen dazu, welche Felder Sie im linkPreviewTriggers-Trigger angeben können, finden Sie in der Referenzdokumentation zu Apps Script-Manifesten oder Bereitstellungsressourcen für andere Laufzeiten.

  3. Fügen Sie im Feld oauthScopes den Bereich https://www.googleapis.com/auth/workspace.linkpreview hinzu, damit Nutzer das Add-on autorisieren können, Links in ihrem Namen in der Vorschau anzusehen.

Ein Beispiel finden Sie im Abschnitt oauthScopes und addons des folgenden Manifests, in dem Linkvorschauen für einen Supportanfrage-Dienst konfiguriert werden.

{
  "oauthScopes": [
    "https://www.googleapis.com/auth/workspace.linkpreview"
  ],
  "addOns": {
    "common": {
      "name": "Preview support cases",
      "logoUrl": "https://www.example.com/images/company-logo.png",
      "layoutProperties": {
        "primaryColor": "#dd4b39"
      }
    },
    "docs": {
      "linkPreviewTriggers": [
        {
          "runFunction": "caseLinkPreview",
          "patterns": [
            {
              "hostPattern": "example.com",
              "pathPrefix": "support/cases"
            },
            {
              "hostPattern": "*.example.com",
              "pathPrefix": "cases"
            },
            {
              "hostPattern": "cases.example.com"
            }
          ],
          "labelText": "Support case",
          "logoUrl": "https://www.example.com/images/support-icon.png",
          "localizedLabelText": {
            "es": "Caso de soporte"
          }
        }
      ]
    },
    "sheets": {
      "linkPreviewTriggers": [
        {
          "runFunction": "caseLinkPreview",
          "patterns": [
            {
              "hostPattern": "example.com",
              "pathPrefix": "support/cases"
            },
            {
              "hostPattern": "*.example.com",
              "pathPrefix": "cases"
            },
            {
              "hostPattern": "cases.example.com"
            }
          ],
          "labelText": "Support case",
          "logoUrl": "https://www.example.com/images/support-icon.png",
          "localizedLabelText": {
            "es": "Caso de soporte"
          }
        }
      ]
    },
    "slides": {
      "linkPreviewTriggers": [
        {
          "runFunction": "caseLinkPreview",
          "patterns": [
            {
              "hostPattern": "example.com",
              "pathPrefix": "support/cases"
            },
            {
              "hostPattern": "*.example.com",
              "pathPrefix": "cases"
            },
            {
              "hostPattern": "cases.example.com"
            }
          ],
          "labelText": "Support case",
          "logoUrl": "https://www.example.com/images/support-icon.png",
          "localizedLabelText": {
            "es": "Caso de soporte"
          }
        }
      ]
    }
  }
}

Im Beispiel werden mit dem Google Workspace-Add‑on Links für den Supportanfrage-Dienst eines Unternehmens in der Vorschau angezeigt. Das Add-on gibt drei URL-Muster für die Vorschau von Links an. Wenn ein Link mit einem der URL-Muster übereinstimmt, erstellt und zeigt die Callback-Funktion caseLinkPreview eine Karte und einen Smart-Chip in Docs, Sheets oder Präsentationen an und ersetzt die URL durch den Linktitel.

Smartchip und Karte erstellen

Wenn Sie einen Smartchip und eine Karte für einen Link zurückgeben möchten, müssen Sie alle Funktionen implementieren, die Sie im linkPreviewTriggers-Objekt angegeben haben.

Wenn ein Nutzer mit einem Link interagiert, der einem angegebenen URL-Muster entspricht, wird der linkPreviewTriggers-Trigger ausgelöst und die zugehörige Callback-Funktion übergibt das Ereignisobjekt EDITOR_NAME.matchedUrl.url als Argument. Sie verwenden die Nutzlast dieses Ereignisobjekts, um den Smart-Chip und die Karte für die Linkvorschau zu erstellen.

Wenn ein Nutzer beispielsweise den Link https://www.example.com/cases/123456 in Google Docs als Vorschau ansieht, wird die folgende Ereignis-Payload zurückgegeben:

JSON

{
  "docs": {
    "matchedUrl": {
        "url": "https://www.example.com/support/cases/123456"
    }
  }
}

Zum Erstellen der Kartenoberfläche verwenden Sie Widgets, um Informationen zum Link anzuzeigen. Sie können auch Aktionen erstellen, mit denen Nutzer den Link öffnen oder seinen Inhalt ändern können. Eine Liste der verfügbaren Widgets und Aktionen finden Sie unter Unterstützte Komponenten für Vorschaukarten.

So erstellen Sie den Smartchip und die Karte für eine Linkvorschau:

  1. Implementieren Sie die Funktion, die Sie im Abschnitt linkPreviewTriggers des Manifests Ihres Add-ons angegeben haben:
    1. Die Funktion muss ein Ereignisobjekt mit EDITOR_NAME.matchedUrl.url als Argument akzeptieren und ein einzelnes Card-Objekt zurückgeben.
    2. Wenn für Ihren Dienst eine Autorisierung erforderlich ist, muss die Funktion auch den Autorisierungsablauf aufrufen.
  2. Implementieren Sie für jede Vorschaukarte alle Callback-Funktionen, die die Widget-Interaktivität für die Benutzeroberfläche ermöglichen. Wenn Sie beispielsweise eine Schaltfläche mit dem Text „Link aufrufen“ einfügen, können Sie eine Aktion erstellen, die eine Callback-Funktion angibt, mit der der Link in einem neuen Fenster geöffnet wird. Weitere Informationen zu Widget-Interaktionen

Mit dem folgenden Code wird die Callback-Funktion caseLinkPreview für Docs erstellt:

Apps Script

apps-script/3p-resources/3p-resources.gs
/**
* Entry point for a support case link preview.
*
* @param {!Object} event The event object.
* @return {!Card} The resulting preview link card.
*/
function caseLinkPreview(event) {

  // If the event object URL matches a specified pattern for support case links.
  if (event.docs.matchedUrl.url) {

    // Uses the event object to parse the URL and identify the case details.
    const caseDetails = parseQuery(event.docs.matchedUrl.url);

    // Builds a preview card with the case name, and description
    const caseHeader = CardService.newCardHeader()
      .setTitle(`Case ${caseDetails["name"][0]}`);
    const caseDescription = CardService.newTextParagraph()
      .setText(caseDetails["description"][0]);

    // Returns the card.
    // Uses the text from the card's header for the title of the smart chip.
    return CardService.newCardBuilder()
      .setHeader(caseHeader)
      .addSection(CardService.newCardSection().addWidget(caseDescription))
      .build();
  }
}

/**
* Extracts the URL parameters from the given URL.
*
* @param {!string} url The URL to parse.
* @return {!Map} A map with the extracted URL parameters.
*/
function parseQuery(url) {
  const query = url.split("?")[1];
  if (query) {
    return query.split("&")
    .reduce(function(o, e) {
      var temp = e.split("=");
      var key = temp[0].trim();
      var value = temp[1].trim();
      value = isNaN(value) ? value : Number(value);
      if (o[key]) {
        o[key].push(value);
      } else {
        o[key] = [value];
      }
      return o;
    }, {});
  }
  return null;
}

Node.js

node/3p-resources/index.js
/**
 * 
 * A support case link preview.
 *
 * @param {!URL} url The event object.
 * @return {!Card} The resulting preview link card.
 */
function caseLinkPreview(url) {
  // Builds a preview card with the case name, and description
  // Uses the text from the card's header for the title of the smart chip.
  // Parses the URL and identify the case details.
  const name = `Case ${url.searchParams.get("name")}`;
  return {
    action: {
      linkPreview: {
        title: name,
        previewCard: {
          header: {
            title: name
          },
          sections: [{
            widgets: [{
              textParagraph: {
                text: url.searchParams.get("description")
              }
            }]
          }]
        }
      }
    }
  };
}

Python

python/3p-resources/create_link_preview/main.py
def case_link_preview(url):
    """A support case link preview.
    Args:
      url: A matching URL.
    Returns:
      The resulting preview link card.
    """

    # Parses the URL and identify the case details.
    query_string = parse_qs(url.query)
    name = f'Case {query_string["name"][0]}'
    # Uses the text from the card's header for the title of the smart chip.
    return {
        "action": {
            "linkPreview": {
                "title": name,
                "previewCard": {
                    "header": {
                        "title": name
                    },
                    "sections": [{
                        "widgets": [{
                            "textParagraph": {
                                "text": query_string["description"][0]
                            }
                        }]
                    }],
                }
            }
        }
    }

Java

java/3p-resources/src/main/java/CreateLinkPreview.java
/**
 * A support case link preview.
 *
 * @param url A matching URL.
 * @return The resulting preview link card.
 */
JsonObject caseLinkPreview(URL url) throws UnsupportedEncodingException {
  // Parses the URL and identify the case details.
  Map<String, String> caseDetails = new HashMap<String, String>();
  for (String pair : url.getQuery().split("&")) {
      caseDetails.put(URLDecoder.decode(pair.split("=")[0], "UTF-8"), URLDecoder.decode(pair.split("=")[1], "UTF-8"));
  }

  // Builds a preview card with the case name, and description
  // Uses the text from the card's header for the title of the smart chip.
  JsonObject cardHeader = new JsonObject();
  String caseName = String.format("Case %s", caseDetails.get("name"));
  cardHeader.add("title", new JsonPrimitive(caseName));

  JsonObject textParagraph = new JsonObject();
  textParagraph.add("text", new JsonPrimitive(caseDetails.get("description")));

  JsonObject widget = new JsonObject();
  widget.add("textParagraph", textParagraph);

  JsonArray widgets = new JsonArray();
  widgets.add(widget);

  JsonObject section = new JsonObject();
  section.add("widgets", widgets);

  JsonArray sections = new JsonArray();
  sections.add(section);

  JsonObject previewCard = new JsonObject();
  previewCard.add("header", cardHeader);
  previewCard.add("sections", sections);

  JsonObject linkPreview = new JsonObject();
  linkPreview.add("title", new JsonPrimitive(caseName));
  linkPreview.add("previewCard", previewCard);

  JsonObject action = new JsonObject();
  action.add("linkPreview", linkPreview);

  JsonObject renderActions = new JsonObject();
  renderActions.add("action", action);

  return renderActions;
}

Unterstützte Komponenten für Vorschaukarten

Google Workspace-Add-ons unterstützen die folgenden Widgets und Aktionen für Linkvorschaukarten:

Apps Script

Feld „Kartenservice“ Typ
TextParagraph Widget
DecoratedText Widget
Image Widget
IconImage Widget
ButtonSet Widget
TextButton Widget
ImageButton Widget
Grid Widget
Divider Widget
OpenLink Aktion
Navigation Aktion
: Nur die Methode updateCard wird unterstützt.

JSON

Feld „Karte“ (google.apps.card.v1) Typ
TextParagraph Widget
DecoratedText Widget
Image Widget
Icon Widget
ButtonList Widget
Button Widget
Grid Widget
Divider Widget
OpenLink Aktion
Navigation Aktion
: Nur die Methode updateCard wird unterstützt.

Vollständiges Beispiel: Supportfall-Add-on

Im folgenden Beispiel wird ein Google Workspace-Add-on verwendet, mit dem Links zu den Supportfällen eines Unternehmens in Google Docs in der Vorschau angezeigt werden.

Das Beispiel führt Folgendes aus:

  • Vorschau-Links zu Supportanfragen, z. B. https://www.example.com/support/cases/1234. Auf dem Smart-Chip wird ein Supportsymbol angezeigt und die Vorschaukarte enthält die Fall-ID und eine Beschreibung.
  • Wenn die Sprache des Nutzers auf Spanisch eingestellt ist, wird labelText des Smart-Chips ins Spanische übersetzt.

Manifest

Apps Script

apps-script/3p-resources/appsscript.json
{
  "timeZone": "America/New_York",
  "exceptionLogging": "STACKDRIVER",
  "runtimeVersion": "V8",
  "oauthScopes": [
    "https://www.googleapis.com/auth/workspace.linkpreview",
    "https://www.googleapis.com/auth/workspace.linkcreate"
  ],
  "addOns": {
    "common": {
      "name": "Manage support cases",
      "logoUrl": "https://developers.google.com/workspace/add-ons/images/support-icon.png",
      "layoutProperties": {
        "primaryColor": "#dd4b39"
      }
    },
    "docs": {
      "linkPreviewTriggers": [
        {
          "runFunction": "caseLinkPreview",
          "patterns": [
            {
              "hostPattern": "example.com",
              "pathPrefix": "support/cases"
            },
            {
              "hostPattern": "*.example.com",
              "pathPrefix": "cases"
            },
            {
              "hostPattern": "cases.example.com"
            }
          ],
          "labelText": "Support case",
          "localizedLabelText": {
            "es": "Caso de soporte"
          },
          "logoUrl": "https://developers.google.com/workspace/add-ons/images/support-icon.png"
        }
      ],
      "createActionTriggers": [
        {
          "id": "createCase",
          "labelText": "Create support case",
          "localizedLabelText": {
            "es": "Crear caso de soporte"
          },
          "runFunction": "createCaseInputCard",
          "logoUrl": "https://developers.google.com/workspace/add-ons/images/support-icon.png"
        }
      ]
    }
  }
}

JSON

{
  "oauthScopes": [
    "https://www.googleapis.com/auth/workspace.linkpreview"
  ],
  "addOns": {
    "common": {
      "name": "Preview support cases",
      "logoUrl": "https://developers.google.com/workspace/add-ons/images/support-icon.png",
      "layoutProperties": {
        "primaryColor": "#dd4b39"
      }
    },
    "docs": {
      "linkPreviewTriggers": [
        {
          "runFunction": "URL",
          "patterns": [
            {
              "hostPattern": "example.com",
              "pathPrefix": "support/cases"
            },
            {
              "hostPattern": "*.example.com",
              "pathPrefix": "cases"
            },
            {
              "hostPattern": "cases.example.com"
            }
          ],
          "labelText": "Support case",
          "localizedLabelText": {
            "es": "Caso de soporte"
          },
          "logoUrl": "https://developers.google.com/workspace/add-ons/images/support-icon.png"
        }
      ]
    }
  }
}

Code

Apps Script

apps-script/3p-resources/3p-resources.gs
/**
* Entry point for a support case link preview.
*
* @param {!Object} event The event object.
* @return {!Card} The resulting preview link card.
*/
function caseLinkPreview(event) {

  // If the event object URL matches a specified pattern for support case links.
  if (event.docs.matchedUrl.url) {

    // Uses the event object to parse the URL and identify the case details.
    const caseDetails = parseQuery(event.docs.matchedUrl.url);

    // Builds a preview card with the case name, and description
    const caseHeader = CardService.newCardHeader()
      .setTitle(`Case ${caseDetails["name"][0]}`);
    const caseDescription = CardService.newTextParagraph()
      .setText(caseDetails["description"][0]);

    // Returns the card.
    // Uses the text from the card's header for the title of the smart chip.
    return CardService.newCardBuilder()
      .setHeader(caseHeader)
      .addSection(CardService.newCardSection().addWidget(caseDescription))
      .build();
  }
}

/**
* Extracts the URL parameters from the given URL.
*
* @param {!string} url The URL to parse.
* @return {!Map} A map with the extracted URL parameters.
*/
function parseQuery(url) {
  const query = url.split("?")[1];
  if (query) {
    return query.split("&")
    .reduce(function(o, e) {
      var temp = e.split("=");
      var key = temp[0].trim();
      var value = temp[1].trim();
      value = isNaN(value) ? value : Number(value);
      if (o[key]) {
        o[key].push(value);
      } else {
        o[key] = [value];
      }
      return o;
    }, {});
  }
  return null;
}

Node.js

node/3p-resources/index.js
/**
 * Responds to any HTTP request related to link previews.
 *
 * @param {Object} req An HTTP request context.
 * @param {Object} res An HTTP response context.
 */
exports.createLinkPreview = (req, res) => {
  const event = req.body;
  if (event.docs.matchedUrl.url) {
    const url = event.docs.matchedUrl.url;
    const parsedUrl = new URL(url);
    // If the event object URL matches a specified pattern for preview links.
    if (parsedUrl.hostname === 'example.com') {
      if (parsedUrl.pathname.startsWith('/support/cases/')) {
        return res.json(caseLinkPreview(parsedUrl));
      }
    }
  }
};


/**
 * 
 * A support case link preview.
 *
 * @param {!URL} url The event object.
 * @return {!Card} The resulting preview link card.
 */
function caseLinkPreview(url) {
  // Builds a preview card with the case name, and description
  // Uses the text from the card's header for the title of the smart chip.
  // Parses the URL and identify the case details.
  const name = `Case ${url.searchParams.get("name")}`;
  return {
    action: {
      linkPreview: {
        title: name,
        previewCard: {
          header: {
            title: name
          },
          sections: [{
            widgets: [{
              textParagraph: {
                text: url.searchParams.get("description")
              }
            }]
          }]
        }
      }
    }
  };
}

Python

python/3p-resources/create_link_preview/main.py
from typing import Any, Mapping
from urllib.parse import urlparse, parse_qs

import flask
import functions_framework


@functions_framework.http
def create_link_preview(req: flask.Request):
    """Responds to any HTTP request related to link previews.
    Args:
      req: An HTTP request context.
    Returns:
      An HTTP response context.
    """
    event = req.get_json(silent=True)
    if event["docs"]["matchedUrl"]["url"]:
        url = event["docs"]["matchedUrl"]["url"]
        parsed_url = urlparse(url)
        # If the event object URL matches a specified pattern for preview links.
        if parsed_url.hostname == "example.com":
            if parsed_url.path.startswith("/support/cases/"):
                return case_link_preview(parsed_url)

    return {}




def case_link_preview(url):
    """A support case link preview.
    Args:
      url: A matching URL.
    Returns:
      The resulting preview link card.
    """

    # Parses the URL and identify the case details.
    query_string = parse_qs(url.query)
    name = f'Case {query_string["name"][0]}'
    # Uses the text from the card's header for the title of the smart chip.
    return {
        "action": {
            "linkPreview": {
                "title": name,
                "previewCard": {
                    "header": {
                        "title": name
                    },
                    "sections": [{
                        "widgets": [{
                            "textParagraph": {
                                "text": query_string["description"][0]
                            }
                        }]
                    }],
                }
            }
        }
    }

Java

java/3p-resources/src/main/java/CreateLinkPreview.java
import com.google.cloud.functions.HttpFunction;
import com.google.cloud.functions.HttpRequest;
import com.google.cloud.functions.HttpResponse;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;

import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;

public class CreateLinkPreview implements HttpFunction {
  private static final Gson gson = new Gson();

  /**
   * Responds to any HTTP request related to link previews.
   *
   * @param request An HTTP request context.
   * @param response An HTTP response context.
   */
  @Override
  public void service(HttpRequest request, HttpResponse response) throws Exception {
    JsonObject event = gson.fromJson(request.getReader(), JsonObject.class);
    String url = event.getAsJsonObject("docs")
        .getAsJsonObject("matchedUrl")
        .get("url")
        .getAsString();
    URL parsedURL = new URL(url);
    // If the event object URL matches a specified pattern for preview links.
    if ("example.com".equals(parsedURL.getHost())) {
      if (parsedURL.getPath().startsWith("/support/cases/")) {
        response.getWriter().write(gson.toJson(caseLinkPreview(parsedURL)));
        return;
      }
    }

    response.getWriter().write("{}");
  }


  /**
   * A support case link preview.
   *
   * @param url A matching URL.
   * @return The resulting preview link card.
   */
  JsonObject caseLinkPreview(URL url) throws UnsupportedEncodingException {
    // Parses the URL and identify the case details.
    Map<String, String> caseDetails = new HashMap<String, String>();
    for (String pair : url.getQuery().split("&")) {
        caseDetails.put(URLDecoder.decode(pair.split("=")[0], "UTF-8"), URLDecoder.decode(pair.split("=")[1], "UTF-8"));
    }

    // Builds a preview card with the case name, and description
    // Uses the text from the card's header for the title of the smart chip.
    JsonObject cardHeader = new JsonObject();
    String caseName = String.format("Case %s", caseDetails.get("name"));
    cardHeader.add("title", new JsonPrimitive(caseName));

    JsonObject textParagraph = new JsonObject();
    textParagraph.add("text", new JsonPrimitive(caseDetails.get("description")));

    JsonObject widget = new JsonObject();
    widget.add("textParagraph", textParagraph);

    JsonArray widgets = new JsonArray();
    widgets.add(widget);

    JsonObject section = new JsonObject();
    section.add("widgets", widgets);

    JsonArray sections = new JsonArray();
    sections.add(section);

    JsonObject previewCard = new JsonObject();
    previewCard.add("header", cardHeader);
    previewCard.add("sections", sections);

    JsonObject linkPreview = new JsonObject();
    linkPreview.add("title", new JsonPrimitive(caseName));
    linkPreview.add("previewCard", previewCard);

    JsonObject action = new JsonObject();
    action.add("linkPreview", linkPreview);

    JsonObject renderActions = new JsonObject();
    renderActions.add("action", action);

    return renderActions;
  }

}