Kartlara etkileşimli kullanıcı arayüzü öğeleri ekleyin

Bu sayfada, kullanıcıların Google Chat uygulamanızla etkileşim kurabilmesi (ör. bir düğmeyi tıklayarak veya bilgi göndererek) için kartlara widget'ların ve kullanıcı arayüzü öğelerinin nasıl ekleneceği açıklanmaktadır.

Chat uygulamaları, etkileşimli kartlar oluşturmak için aşağıdaki Chat arayüzlerini kullanabilir:

  • Bir veya daha fazla kart içeren mesajlar.
  • Ana sayfalar: Chat uygulamasıyla doğrudan mesajlarda Ana Sayfa sekmesinden görüntülenen bir karttır.
  • Mesajlardan ve ana sayfalardan yeni bir pencerede açılan kartlar olan iletişim kutuları.

Kullanıcılar kartlarla etkileşim kurduğunda Chat uygulamaları, aldıkları verileri kullanarak işlem yapabilir ve buna göre yanıt verebilir. Ayrıntılı bilgi için Google Chat kullanıcılarından bilgi toplama ve işleme başlıklı makaleyi inceleyin.


Chat uygulamaları için mesajlaşma ve kullanıcı arayüzleri tasarlamak ve önizlemek üzere Kart Oluşturucu'yu kullanın:

Kart Oluşturucu'yu açın

Ön koşullar

Kullanıcı etkileşimlerini alacak ve bunlara yanıt verecek şekilde yapılandırılmış bir Google Chat uygulaması. Etkileşimli bir Chat uygulaması oluşturmak için kullanmak istediğiniz uygulama mimarisine göre aşağıdaki hızlı başlangıç kılavuzlarından birini tamamlayın:

Düğme ekleme

ButtonList widget'ı bir dizi düğme gösterir. Düğmelerde metin, simge veya hem metin hem simge gösterilebilir. Her Button, kullanıcılar düğmeyi tıkladığında gerçekleşen bir OnClick işlemi destekler. Örneğin:

  • Kullanıcılara ek bilgi sağlamak için köprüyü OpenLink ile açın.
  • API çağırma gibi özel bir işlevi çalıştıran bir action çalıştırın.

Erişilebilirlik için düğmeler alternatif metni destekler.

Özel işlev çalıştıran bir düğme ekleme

Aşağıda, iki düğmeli bir ButtonList widget'ından oluşan bir kart gösterilmektedir. Bir düğme, Google Chat geliştirici belgelerini yeni bir sekmede açar. Diğer düğme, goToView() adlı özel bir işlevi çalıştırır ve viewType="BIRD EYE VIEW" parametresini iletir.

Materyal Tasarım stiline sahip bir düğme ekleme

Aşağıda, farklı Materyal Tasarım düğme stillerinde bir düğme grubu gösterilmektedir.

Materyal Tasarım stilini uygulamak için "color" özelliğini eklemeyin.

Özel renkli bir düğme ve devre dışı bırakılmış bir düğme ekleyin

"disabled": "true" ayarını yaparak kullanıcıların bir düğmeyi tıklamasını engelleyebilirsiniz.

Aşağıda, iki düğmeli bir ButtonList widget'ından oluşan bir kart gösterilmektedir. Düğmelerden biri, düğmenin arka plan rengini özelleştirmek için Color alanını kullanır. Diğer düğme, Disabled alanıyla devre dışı bırakılır. Bu, kullanıcının düğmeyi tıklamasını ve işlevi yürütmesini engeller.

Simge içeren bir düğme ekleme

Aşağıda, iki simge Button widget'ı içeren bir ButtonList widget'ından oluşan kart gösterilmektedir. Düğmelerden biri, Google Chat'in yerleşik e-posta simgesini görüntülemek için knownIcon alanını kullanır. Diğer düğme, özel simge widget'ı göstermek için iconUrl alanını kullanır.

Simge ve metin içeren bir düğme ekleme

Aşağıda, kullanıcıdan e-posta göndermesini isteyen bir ButtonList widget'ından oluşan bir kart gösterilmektedir. İlk düğmede bir e-posta simgesi, ikinci düğmede ise metin gösterilir. Kullanıcı, sendEmail işlevini çalıştırmak için simgeyi veya metin düğmesini tıklayabilir.

Daraltılabilir bölüm düğmesini özelleştirme

Kart içindeki bölümleri daraltan ve genişleten kontrol düğmesini özelleştirin. Bölümün içeriğini görsel olarak temsil etmek için çeşitli simgeler veya resimler arasından seçim yapın. Böylece kullanıcıların bilgileri anlaması ve bilgilerle etkileşim kurması kolaylaşır.

Taşma menüsü ekleme

Overflow menu, ek seçenekler ve işlemler sunmak için Chat kartlarında kullanılabilir. Kartın arayüzünü karmaşıklaştırmadan daha fazla seçenek eklemenize olanak tanıyarak temiz ve düzenli bir tasarım sağlar.

Çip listesi ekleme

ChipList widget'ı, bilgileri görüntülemek için çok yönlü ve görsel açıdan ilgi çekici bir yöntem sunar. Etiketleri, kategorileri veya diğer alakalı verileri temsil etmek için çip listelerini kullanarak kullanıcıların içeriğinizde gezinmesini ve içeriğinizle etkileşim kurmasını kolaylaştırın.

Kullanıcılardan bilgi toplama

Bu bölümde, metin veya seçimler gibi bilgileri toplayan widget'ları nasıl ekleyebileceğiniz açıklanmaktadır.

Kullanıcıların girişlerini nasıl işleyeceğinizi öğrenmek için Google Chat kullanıcılarından bilgi toplama ve işleme başlıklı makaleyi inceleyin.

Metin toplama

TextInput widget'ı, kullanıcıların metin girebileceği bir alan sağlar. Widget, kullanıcıların tek tip veri girmesine yardımcı olan önerileri ve metin giriş alanında değişiklik olduğunda (ör. kullanıcının metin eklemesi veya silmesi) çalışan, Actions olan değişiklik işlemlerini destekler.

Kullanıcılardan soyut veya bilinmeyen veriler toplamanız gerektiğinde bu TextInput widget'ını kullanın. Kullanıcılardan tanımlı verileri toplamak için bunun yerine SelectionInput widget'ını kullanın.

Aşağıda, TextInput widget'ından oluşan bir kart gösterilmektedir:

Tarih veya saat toplama

DateTimePicker widget'ı, kullanıcıların tarih, saat veya hem tarih hem de saat girmesine olanak tanır. Kullanıcılar, tarih ve saat seçmek için seçiciyi de kullanabilir. Kullanıcılar geçersiz bir tarih veya saat girerse seçici, kullanıcıların bilgileri doğru girmesini isteyen bir hata gösterir.

Aşağıda, üç farklı türde DateTimePicker widget'ından oluşan bir kart gösterilmektedir:

Kullanıcıların öğe seçmesine izin verme

SelectionInput widget'ı; onay kutuları, radyo düğmeleri, anahtarlar veya açılır menü gibi seçilebilir öğelerden oluşan bir grup sunar. Kullanıcılardan tanımlanmış ve standartlaştırılmış veriler toplamak için bu widget'ı kullanabilirsiniz. Kullanıcılardan tanımlanmamış veriler toplamak için TextInput widget'ını kullanın.

SelectionInput widget'ı, kullanıcıların tek tip veri girmesine yardımcı olan önerileri ve değişiklik olduğunda gerçekleştirilen işlemleri destekler. Değişiklik olduğunda gerçekleştirilen işlemler, Actions seçim giriş alanında bir değişiklik olduğunda (ör. kullanıcının bir öğeyi seçmesi veya seçimini kaldırması) çalıştırılan işlemlerdir.

Chat uygulamaları, seçilen öğelerin değerini alabilir ve işleyebilir. Form girişleriyle çalışma hakkında ayrıntılı bilgi için Kullanıcılar tarafından girilen bilgileri işleme başlıklı makaleyi inceleyin.

Bu bölümde, SelectionInput widget'ını kullanan kart örnekleri verilmiştir. Örneklerde farklı türde bölüm girişleri kullanılmıştır:

Onay kutusu ekleme

Aşağıda, onay kutularını kullanan bir SelectionInput widget'ı ile kullanıcıdan bir kişinin profesyonel, kişisel veya her ikisi olup olmadığını belirtmesini isteyen bir kart gösterilmektedir:

Radyo düğmesi ekleme

Aşağıda, radyo düğmeleri kullanan bir SelectionInput widget'ı ile kullanıcıdan bir kişinin profesyonel mi yoksa kişisel mi olduğunu belirtmesini isteyen bir kart gösterilmektedir:

Anahtar ekleme

Aşağıda, kullanıcının bir kişinin profesyonel mi, kişisel mi yoksa her ikisi mi olduğunu belirtmesini isteyen ve anahtarları kullanan bir SelectionInput widget'ı içeren kart gösterilmektedir:

Aşağıda, kullanıcının bir kişinin profesyonel mi yoksa kişisel mi olduğunu belirtmesini isteyen bir kart gösterilmektedir. Bu kartta, açılır menü kullanan bir SelectionInput widget'ı yer alır:

Açılır menüleri dinamik olarak doldurma

Google Chat uygulamalarında kullanılabilir.

Açılır menüdeki öğeleri Google Workspace'teki veri kaynaklarından veya harici bir veri kaynağından dinamik olarak doldurabilirsiniz. Dinamik veri kaynaklarını kullanmak için DataSourceConfig nesnelerinden oluşan bir dizi olan dataSourceConfigs alanını belirtirsiniz. Her DataSourceConfig, platformDataSource veya remoteDataSource içerebilir. Şu anda yalnızca bir DataSourceConfig desteklenmektedir.

Google Workspace'teki öğeleri doldurma

Google Workspace kullanıcıları gibi Google Workspace veri kaynaklarındaki öğeleri doldurmak için DataSourceConfig içinde platformDataSource alanını belirtirsiniz. Statik items kullanmanın aksine, bu seçim öğeleri Google Workspace'ten dinamik olarak alındığı için SelectionItem nesnelerini atlarsınız.

Aşağıdaki kodda, Google Workspace kullanıcılarını dolduran bir açılır menü gösterilmektedir:

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "widgets": [
        {
          "selectionInput": {
            "name": "contacts",
            "type": "DROPDOWN",
            "label": "Select contact from organization",
            "dataSourceConfigs": [
              {
                "platformDataSource": {
                  "commonDataSource": "USER"
                },
                "minCharactersTrigger": 1
              }
            ]
          }
        }
      ]
    }
  ]
}
Öğeleri harici bir veri kaynağından doldurma

Öğeleri bir müşteri ilişkileri yönetimi (CRM) sistemi gibi üçüncü taraf veya harici bir veri kaynağından doldurmak için DataSourceConfig içindeki remoteDataSource alanını kullanarak veri kaynağından öğeleri döndüren bir işlev belirtirsiniz.

Aşağıdaki kodda, getCrmLeads işlevini çalıştırarak harici bir kişi grubundan öğeleri dolduran bir açılır menü gösterilmektedir:

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "widgets": [
        {
          "selectionInput": {
            "name": "crm_leads",
            "type": "DROPDOWN",
            "label": "Select CRM Lead",
            "dataSourceConfigs": [
              {
                "remoteDataSource": {
                  "function": "getCrmLeads"
                },
                "minCharactersTrigger": 2
              }
            ],
            "items": [
              {
                "text": "Suggested Lead 1",
                "value": "lead-1"
              }
            ]
          }
        }
      ]
    }
  ]
}

Dinamik veri kaynağına yönelik istekleri azaltmak için kullanıcılar yazmaya başlamadan önce açılır menüde görünen önerilen öğeleri ekleyebilirsiniz. Ayrıca, DataSourceConfig içinde minCharactersTrigger değerini ayarlayarak açılır menüyü, kullanıcıların yazdıklarına göre öğeleri otomatik olarak tamamlayacak şekilde yapılandırabilirsiniz. Kullanıcı en az minCharactersTrigger içinde belirtilen sayıda karakter yazdığında remoteDataSource içinde belirtilen işlev tetiklenir. İşlevinize iletilen olay nesnesi, kullanıcının autocomplete_widget_query anahtarındaki girişini içerir.

Çoklu seçim menüsü ekleme

Aşağıda, kullanıcıdan çoklu seçim menüsünden kişi seçmesini isteyen bir kart gösterilmektedir:

Google Workspace'te aşağıdaki veri kaynaklarından çoklu seçim menüsü için öğeler doldurabilirsiniz:

  • Google Workspace kullanıcıları: Yalnızca aynı Google Workspace kuruluşundaki kullanıcıları doldurabilirsiniz.
  • Chat alanları: Çoklu seçim menüsüne öğe giren kullanıcı, yalnızca Google Workspace kuruluşunda ait olduğu alanları görüntüleyebilir ve seçebilir.

Google Workspace veri kaynaklarını kullanmak için platformDataSource alanını belirtirsiniz. Diğer seçim girişi türlerinden farklı olarak, bu seçim öğeleri Google Workspace'ten dinamik olarak alındığı için SelectionItem nesnelerini atlarsınız.

Aşağıdaki kodda, Google Workspace kullanıcılarının çoklu seçim menüsü gösterilmektedir. Kullanıcıları doldurmak için seçim girişi, commonDataSource değerini USER olarak ayarlar:

JSON

{
  "selectionInput": {
    "name": "contacts",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 5,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "commonDataSource": "USER"
    }
  }
}

Aşağıdaki kodda, Chat alanlarının çoklu seçim menüsü gösterilmektedir. Seçim girişi, alanları doldurmak için hostAppDataSource alanını belirtir. Çoklu seçim menüsü, defaultToCurrentSpace değerini true olarak ayarlar. Bu sayede, mevcut alan menüdeki varsayılan seçim olur:

JSON

{
  "selectionInput": {
    "name": "spaces",
    "type": "MULTI_SELECT",
    "label": "Selected contacts",
    "multiSelectMaxSelectedItems": 3,
    "multiSelectMinQueryLength": 1,
    "platformDataSource": {
      "hostAppDataSource": {
        "chatDataSource": {
          "spaceDataSource": {
            "defaultToCurrentSpace": true
          }
        }
      }
    }
  }
}

Çoklu seçim menüleri, üçüncü taraf veya harici bir veri kaynağından da öğe doldurabilir. Örneğin, bir kullanıcının müşteri ilişkileri yönetimi (CRM) sistemindeki olası satış listesinden seçim yapmasına yardımcı olmak için çoklu seçim menülerini kullanabilirsiniz.

Harici bir veri kaynağı kullanmak için externalDataSource alanını kullanarak veri kaynağından öğe döndüren bir işlev belirtirsiniz.

Harici bir veri kaynağına gönderilen istekleri azaltmak için, kullanıcılar menüye yazmadan önce çoklu seçim menüsünde görünen önerilen öğeleri ekleyebilirsiniz. Örneğin, kullanıcı için son aranan kişileri doldurabilirsiniz. Önerilen öğeleri harici bir veri kaynağından doldurmak için SelectionItem nesnelerini belirtin.

Aşağıdaki kod örneğinde, harici bir veri kaynağından öğeleri sorgulayan ve dolduran çoklu seçim menüsü gösterilmektedir:

Node.js

node/chat/selection-input/index.js
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: FUNCTION_URL },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getSuggestedContact("3")]
}

FUNCTION_URL yerine harici veri kaynağını sorgulayan HTTP uç noktasını yazın.

Python

python/chat/selection-input/main.py
'selectionInput': {
  'name': "contacts",
  'type': "MULTI_SELECT",
  'label': "Selected contacts",
  'multiSelectMaxSelectedItems': 3,
  'multiSelectMinQueryLength': 1,
  'externalDataSource': { 'function': FUNCTION_URL },
  # Suggested items loaded by default.
  # The list is static here but it could be dynamic.
  'items': [get_suggested_contact("3")]
}

FUNCTION_URL yerine harici veri kaynağını sorgulayan HTTP uç noktasını yazın.

Java

java/chat/selection-input/src/main/java/com/google/chat/selectionInput/App.java
.setSelectionInput(new GoogleAppsCardV1SelectionInput()
  .setName("contacts")
  .setType("MULTI_SELECT")
  .setLabel("Selected contacts")
  .setMultiSelectMaxSelectedItems(3)
  .setMultiSelectMinQueryLength(1)
  .setExternalDataSource(new GoogleAppsCardV1Action().setFunction(FUNCTION_URL))
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  .setItems(List.of(getSuggestedContact("3")))))))))));

FUNCTION_URL yerine harici veri kaynağını sorgulayan HTTP uç noktasını yazın.

Apps Komut Dosyası

Bu örnekte, kart JSON'u döndürülerek bir kart mesajı gönderilir. Apps Komut Dosyası kart hizmetini de kullanabilirsiniz.

apps-script/chat/selection-input/selection-input.gs
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: "queryContacts" },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getSuggestedContact("3")]
}

Dinamik bir veri kaynağından önerilen öğeleri doldurma

Harici veri kaynakları için, kullanıcıların çoklu seçim menüsüne veya açılır menüye yazmaya başladığı öğeleri otomatik olarak tamamlayabilir ve önerebilirsiniz. Örneğin, bir kullanıcı ABD'deki şehirleri dolduran bir menü için Atl yazmaya başlarsa Chat uygulamanız, kullanıcı yazmayı bitirmeden önce Atlanta ifadesini otomatik olarak önerebilir. En fazla 100 öğe önerebilirsiniz.

Önerilen öğeleri döndürmek için harici veri kaynağını sorgulayan işlevin aşağıdakileri yapması gerekir:

  1. Kullanıcılar menüye yazdığında Chat uygulamasının aldığı bir olay nesnesini işleyin.
  2. Olay nesnesinden, kullanıcının yazdığı değeri alın. Bu değer, event.commonEventObject.parameters["autocomplete_widget_query"] alanında gösterilir.
  3. Kullanıcıya önerilecek bir veya daha fazla SelectionItems almak için kullanıcı giriş değerini kullanarak veri kaynağını sorgulayın.
  4. modifyCard nesnesiyle RenderActions işlemini döndürerek önerilen öğeleri döndürün.

Aşağıdaki kod örneğinde, bir Chat uygulamasının karttaki çoklu seçim menüsünde öğeleri dinamik olarak nasıl önerdiği gösterilmektedir. Kullanıcı menüye bir şey yazdığında widget'ın externalDataSource alanında sağlanan işlev veya uç nokta, harici bir veri kaynağını sorgular ve kullanıcının seçebileceği öğeler önerir:

Node.js

node/chat/selection-input/index.js
/**
 * Web app that responds to events sent from a Google Chat space.
 *
 * @param {Object} req Request sent from Google Chat space
 * @param {Object} res Response to send back
 */
app.post('/', async (req, res) => {
  // Stores the Google Chat event
  const chatEvent = req.body.chat;

  // Handle user interaction with multiselect.
  if(chatEvent.widgetUpdatedPayload) {
    return res.json(queryContacts(req.body));
  }

  // Replies with a card that contains the multiselect menu.
  return res.json({ hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: FUNCTION_URL },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}});
});

/**
 * Get contact suggestions based on text typed by users.
 *
 * @param {Object} event the event object that contains the user's query
 * @return {Object} suggestions
 */
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a selection item in the menu.
 */
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

FUNCTION_URL yerine harici veri kaynağını sorgulayan HTTP uç noktasını yazın.

Python

python/chat/selection-input/main.py
@app.route('/', methods=['POST'])
def post() -> Mapping[str, Any]:
  """Handle requests from Google Chat

  Returns:
      Mapping[str, Any]: The response
  """
  # Stores the Google Chat event
  chatEvent = request.get_json().get('chat')

  # Handle user interaction with multiselect.
  if chatEvent.get('widgetUpdatedPayload') is not None:
    return json.jsonify(query_contacts(request.get_json()))

  # Replies with a card that contains the multiselect menu.
  return json.jsonify({ 'hostAppDataAction': { 'chatDataAction': { 'createMessageAction': {
    'message': { 'cardsV2': [{
      'cardId': "contactSelector",
      'card': { 'sections':[{ 'widgets': [{
        'selectionInput': {
          'name': "contacts",
          'type': "MULTI_SELECT",
          'label': "Selected contacts",
          'multiSelectMaxSelectedItems': 3,
          'multiSelectMinQueryLength': 1,
          'externalDataSource': { 'function': FUNCTION_URL },
          # Suggested items loaded by default.
          # The list is static here but it could be dynamic.
          'items': [get_suggested_contact("3")]
        }
      }]}]}
    }]}
  }}}})


def query_contacts(event: dict) -> dict:
  """Get contact suggestions based on text typed by users.

  Args:
      event (Mapping[str, Any]): The event object that contains the user's query

  Returns:
      Mapping[str, Any]: The response with contact suggestions.
  """
  query = event.get("commonEventObject").get("parameters").get("autocomplete_widget_query")
  return { 'action': { 'modifyOperations': [{ 'updateWidget': { 'selectionInputWidgetSuggestions': { 'suggestions': list(
    filter(lambda e: query is None or query in e["text"], [
      # The list is static here but it could be dynamic.
      get_suggested_contact("1"), get_suggested_contact("2"), get_suggested_contact("3"), get_suggested_contact("4"), get_suggested_contact("5")
    # Only return items based on the query from the user
    ])
  )}}}]}}


def get_suggested_contact(id: str) -> dict:
  """Generate a suggested contact given an ID.

  Args:
      id (str): The ID of the contact to return.

  Returns:
      Mapping[str, Any]: The contact formatted as a selection item in the menu.
  """
  return {
    'value': id,
    'startIconUri': "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    'text': "Contact " + id
  }

FUNCTION_URL yerine harici veri kaynağını sorgulayan HTTP uç noktasını yazın.

Java

java/chat/selection-input/src/main/java/com/google/chat/selectionInput/App.java
@SpringBootApplication
@RestController
// Web app that responds to events sent from a Google Chat space.
public class App {
  private static final String FUNCTION_URL = "your-function-url";

  public static void main(String[] args) {
    SpringApplication.run(App.class, args);
  }

  /**
   * Handle requests from Google Chat
   * 
   * @param event the event object sent by Google Chat
   * @return The response to be sent back to Google Chat
   */
  @PostMapping("/")
  @ResponseBody
  public GenericJson onEvent(@RequestBody JsonNode event) throws Exception {
    // Stores the Google Chat event
    JsonNode chatEvent = event.at("/chat");

    // Handle user interaction with multiselect.
    if (!chatEvent.at("/widgetUpdatedPayload").isEmpty()) {
      return queryContacts(event);
    }

    // Replies with a card that contains the multiselect menu.
    Message message = new Message().setCardsV2(List.of(new CardWithId()
      .setCardId("contactSelector")
      .setCard(new GoogleAppsCardV1Card()
        .setSections(List.of(new GoogleAppsCardV1Section().setWidgets(List.of(new GoogleAppsCardV1Widget()
          .setSelectionInput(new GoogleAppsCardV1SelectionInput()
            .setName("contacts")
            .setType("MULTI_SELECT")
            .setLabel("Selected contacts")
            .setMultiSelectMaxSelectedItems(3)
            .setMultiSelectMinQueryLength(1)
            .setExternalDataSource(new GoogleAppsCardV1Action().setFunction(FUNCTION_URL))
            // Suggested items loaded by default.
            // The list is static here but it could be dynamic.
            .setItems(List.of(getSuggestedContact("3")))))))))));

    return new GenericJson() {{
      put("hostAppDataAction", new GenericJson() {{
        put("chatDataAction", new GenericJson() {{
          put("createMessageAction", new GenericJson() {{
            put("message", message);
          }});
        }});
      }});
    }};
  }

  /**
   * Get contact suggestions based on text typed by users.
   *
   * @param event the event object that contains the user's query.
   * @return The response with contact suggestions.
   */
  GenericJson queryContacts(JsonNode event) throws Exception {
    String query = event.at("/commonEventObject/parameters/autocomplete_widget_query").asText();
    List<GoogleAppsCardV1SelectionItem> suggestions = List.of(
      // The list is static here but it could be dynamic.
      getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
    // Only return items based on the query from the user
    ).stream().filter(e -> query == null || e.getText().indexOf(query) > -1).toList();

    return new GenericJson() {{
      put("action", new GenericJson() {{
        put("modifyOperations", List.of(new GenericJson() {{
          put("updateWidget", new GenericJson() {{
            put("selectionInputWidgetSuggestions", new GenericJson() {{
              put("suggestions", suggestions);
            }});
          }});
        }}));
      }});
    }};
  }

  /**
   * Generate a suggested contact given an ID.
   * 
   * @param id The ID of the contact to return.
   * @return The contact formatted as a selection item in the menu.
   */
  GoogleAppsCardV1SelectionItem getSuggestedContact(String id) {
    return new GoogleAppsCardV1SelectionItem()
      .setValue(id)
      .setStartIconUri("https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png")
      .setText("Contact " + id);
  }
}

FUNCTION_URL yerine harici veri kaynağını sorgulayan HTTP uç noktasını yazın.

Apps Komut Dosyası

Bu örnek, kart JSON'u döndürerek bir kart mesajı gönderir. Apps Komut Dosyası kart hizmetini de kullanabilirsiniz.

apps-script/chat/selection-input/selection-input.gs
/**
* Responds to a Message trigger in Google Chat.
*
* @param {Object} event the event object from Google Chat
* @return {Object} Response from the Chat app.
*/
function onMessage(event) {
  // Replies with a card that contains the multiselect menu.
  return { hostAppDataAction: { chatDataAction: { createMessageAction: { message: {
    cardsV2: [{
      cardId: "contactSelector",
      card: { sections:[{ widgets: [{
        selectionInput: {
          name: "contacts",
          type: "MULTI_SELECT",
          label: "Selected contacts",
          multiSelectMaxSelectedItems: 3,
          multiSelectMinQueryLength: 1,
          externalDataSource: { function: "queryContacts" },
          // Suggested items loaded by default.
          // The list is static here but it could be dynamic.
          items: [getSuggestedContact("3")]
        }
      }]}]}
    }]
  }}}}};
}

/**
* Get contact suggestions based on text typed by users.
*
* @param {Object} event the event object that contains the user's query
* @return {Object} suggestions
*/
function queryContacts(event) {
  const query = event.commonEventObject.parameters["autocomplete_widget_query"];
  return { action: { modifyOperations: [{ updateWidget: { selectionInputWidgetSuggestions: { suggestions: [
    // The list is static here but it could be dynamic.
    getSuggestedContact("1"), getSuggestedContact("2"), getSuggestedContact("3"), getSuggestedContact("4"), getSuggestedContact("5")
  // Only return items based on the query from the user.
  ].filter(e => !query || e.text.includes(query)) }}}]}};
}

/**
* Generate a suggested contact given an ID.
*
* @param {String} id The ID of the contact to return.
* @return {Object} The contact formatted as a selection item in the menu.
*/
function getSuggestedContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

Kartlara girilen verileri doğrulama

Bu sayfada, bir kartın action ve widget'larına girilen verilerin nasıl doğrulanacağı açıklanmaktadır. Örneğin, bir metin giriş alanına kullanıcı tarafından metin girildiğini veya alanın belirli sayıda karakter içerdiğini doğrulayabilirsiniz.

İşlemler için gerekli widget'ları ayarlama

Kartın action kapsamında, bir işlemin ihtiyaç duyduğu widget'ların adlarını requiredWidgets listesine ekleyin.

Bu işlem çağrıldığında burada listelenen widget'lardan herhangi birinin değeri yoksa form işlemi gönderimi iptal edilir.

Bir işlem için "allWidgetsAreRequired": true ayarlandığında karttaki tüm widget'lar bu işlem için zorunlu olur.

Çoklu seçimde allWidgetsAreRequired işlemi ayarlama

JSON

{
  "sections": [
    {
      "header": "Select contacts",
      "widgets": [
        {
          "selectionInput": {
            "type": "MULTI_SELECT",
            "label": "Selected contacts",
            "name": "contacts",
            "multiSelectMaxSelectedItems": 3,
            "multiSelectMinQueryLength": 1,
            "onChangeAction": {
              "allWidgetsAreRequired": true
            },
            "items": [
              {
                "value": "contact-1",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 1",
                "bottomText": "Contact one description",
                "selected": false
              },
              {
                "value": "contact-2",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 2",
                "bottomText": "Contact two description",
                "selected": false
              },
              {
                "value": "contact-3",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 3",
                "bottomText": "Contact three description",
                "selected": false
              },
              {
                "value": "contact-4",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 4",
                "bottomText": "Contact four description",
                "selected": false
              },
              {
                "value": "contact-5",
                "startIconUri": "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
                "text": "Contact 5",
                "bottomText": "Contact five description",
                "selected": false
              }
            ]
          }
        }
      ]
    }
  ]
}
dateTimePicker'da allWidgetsAreRequired işlemi ayarlama

JSON

{
  "sections": [
    {
      "widgets": [
        {
          "textParagraph": {
            "text": "A datetime picker widget with both date and time:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_date_and_time",
            "label": "meeting",
            "type": "DATE_AND_TIME"
          }
        },
        {
          "textParagraph": {
            "text": "A datetime picker widget with just date:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_date_only",
            "label": "Choose a date",
            "type": "DATE_ONLY",
            "onChangeAction":{
              "allWidgetsAreRequired": true
            }
          }
        },
        {
          "textParagraph": {
            "text": "A datetime picker widget with just time:"
          }
        },
        {
          "divider": {}
        },
        {
          "dateTimePicker": {
            "name": "date_time_picker_time_only",
            "label": "Select a time",
            "type": "TIME_ONLY"
          }
        }
      ]
    }
  ]
}
Açılır menüde allWidgetsAreRequired işlemi ayarlayın

JSON

{
  "sections": [
    {
      "header": "Section Header",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 1,
      "widgets": [
        {
          "selectionInput": {
            "name": "location",
            "label": "Select Color",
            "type": "DROPDOWN",
            "onChangeAction": {
              "allWidgetsAreRequired": true
            },
            "items": [
              {
                "text": "Red",
                "value": "red",
                "selected": false
              },
              {
                "text": "Green",
                "value": "green",
                "selected": false
              },
              {
                "text": "White",
                "value": "white",
                "selected": false
              },
              {
                "text": "Blue",
                "value": "blue",
                "selected": false
              },
              {
                "text": "Black",
                "value": "black",
                "selected": false
              }
            ]
          }
        }
      ]
    }
  ]
}

Metin girişi widget'ı için doğrulama ayarlama

textInput widget'ının doğrulama alanında, bu metin girişi widget'ının karakter sınırlamasını ve giriş türünü belirtebilir.

Metin girişi widget'ı için karakter sınırlaması ayarlama

JSON

{
  "sections": [
    {
      "header": "Tell us about yourself",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 2,
      "widgets": [
        {
          "textInput": {
            "name": "favoriteColor",
            "label": "Favorite color",
            "type": "SINGLE_LINE",
            "validation": {"characterLimit": 15},
            "onChangeAction":{
              "allWidgetsAreRequired": true
            }
          }
        }
      ]
    }
  ]
}
Metin girişi widget'ı için giriş türünü ayarlama

JSON

{
  "sections": [
    {
      "header": "Validate text inputs by input types",
      "collapsible": true,
      "uncollapsibleWidgetsCount": 2,
      "widgets": [
        {
          "textInput": {
            "name": "mailing_address",
            "label": "Please enter a valid email address",
            "type": "SINGLE_LINE",
            "validation": {
              "inputType": "EMAIL"
            },
            "onChangeAction": {
              "allWidgetsAreRequired": true
            }
          }
        },
        {
          "textInput": {
            "name": "validate_integer",
            "label": "Please enter a number",
              "type": "SINGLE_LINE",
            "validation": {
              "inputType": "INTEGER"
            }
          }
        },
        {
          "textInput": {
            "name": "validate_float",
            "label": "Please enter a number with a decimal",
            "type": "SINGLE_LINE",
            "validation": {
              "inputType": "FLOAT"
            }
          }
        }
      ]
    }
  ]
}

Sorun giderme

Bir Google Chat uygulaması veya kartı hata döndürdüğünde Chat arayüzünde "Bir hata oluştu" veya "İsteğiniz işlenemiyor" mesajı gösterilir. Bazen Chat kullanıcı arayüzünde hata mesajı gösterilmez ancak Chat uygulaması veya kartı beklenmedik bir sonuç üretir. Örneğin, kart mesajı görünmeyebilir.

Chat kullanıcı arayüzünde hata mesajı gösterilmeyebilir ancak Chat uygulamaları için hata günlüğü etkinleştirildiğinde hataları düzeltmenize yardımcı olacak açıklayıcı hata mesajları ve günlük verileri kullanılabilir. Hataları görüntüleme, hata ayıklama ve düzeltme konusunda yardım için Google Chat hatalarını giderme ve düzeltme başlıklı makaleyi inceleyin.

Eklenti olmayan Chat uygulamaları: Etkileşimli kartlar ve iletişim kutuları tasarlama

Aşağıdaki belgeler, Google Workspace eklentisi olmayan Chat uygulamaları için geçerlidir. Eklenti olmayan bir Chat uygulamasını taşımak için Google Chat uygulamasını Google Workspace eklentisine dönüştürme başlıklı makaleyi inceleyin.

Aşağıdaki kodda, eklenti olmayan bir Chat uygulamasında kullanıcının harici kişi grubundan öğelerin yer aldığı çoklu seçim menüsü gösterilmektedir. Menüde varsayılan olarak bir kişi gösterilir ve harici veri kaynağından öğeleri alıp doldurmak için getContacts işlevi çalıştırılır:

Node.js

node/selection-input/index.js
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: "getContacts" },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getContact("3")]
}

Python

python/selection-input/main.py
'selectionInput': {
  'name': "contacts",
  'type': "MULTI_SELECT",
  'label': "Selected contacts",
  'multiSelectMaxSelectedItems': 3,
  'multiSelectMinQueryLength': 1,
  'externalDataSource': { 'function': "getContacts" },
  # Suggested items loaded by default.
  # The list is static here but it could be dynamic.
  'items': [get_contact("3")]
}

Java

java/selection-input/src/main/java/com/google/chat/selectionInput/App.java
.setSelectionInput(new GoogleAppsCardV1SelectionInput()
  .setName("contacts")
  .setType("MULTI_SELECT")
  .setLabel("Selected contacts")
  .setMultiSelectMaxSelectedItems(3)
  .setMultiSelectMinQueryLength(1)
  .setExternalDataSource(new GoogleAppsCardV1Action().setFunction("getContacts"))
  .setItems(List.of(getContact("3")))))))))));

Apps Komut Dosyası

apps-script/selection-input/selection-input.gs
selectionInput: {
  name: "contacts",
  type: "MULTI_SELECT",
  label: "Selected contacts",
  multiSelectMaxSelectedItems: 3,
  multiSelectMinQueryLength: 1,
  externalDataSource: { function: "getContacts" },
  // Suggested items loaded by default.
  // The list is static here but it could be dynamic.
  items: [getContact("3")]
}

Eklenti olmayan bir Chat uygulamasındaki öğeleri otomatik olarak tamamlamak için harici veri kaynağını sorgulayan ve kullanıcı çoklu seçim menüsüne her yazdığında öğeleri döndüren bir işlev oluşturun. İşlev şunları yapmalıdır:

  • Kullanıcının menüyle etkileşimini temsil eden bir olay nesnesi iletin.
  • Etkileşim etkinliğinin invokedFunction değerinin, externalDataSource alanındaki işlevle eşleştiğini belirleyin.
  • İşlevler eşleştiğinde harici veri kaynağından önerilen öğeleri döndürün. Kullanıcının yazdıklarına göre öğe önermek için autocomplete_widget_query anahtarının değerini alın. Bu değer, kullanıcının menüye yazdığı değeri temsil eder.

Aşağıdaki kod, harici bir veri kaynağındaki öğeleri otomatik olarak tamamlar. Önceki örneği kullanırsak eklenti olmayan Chat uygulaması, getContacts işlevinin ne zaman tetiklendiğine bağlı olarak öğeler önerir:

Node.js

node/selection-input/index.js
/**
 * Responds to a WIDGET_UPDATE event in Google Chat.
 *
 * @param {Object} event The event object from Chat API.
 * @return {Object} Response from the Chat app.
 */
function onWidgetUpdate(event) {
  if (event.common["invokedFunction"] === "getContacts") {
    const query = event.common.parameters["autocomplete_widget_query"];
    return { actionResponse: {
      type: "UPDATE_WIDGET",
      updatedWidget: { suggestions: { items: [
        // The list is static here but it could be dynamic.
        getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("5")
      // Only return items based on the query from the user
      ].filter(e => !query || e.text.includes(query))}}
    }};
  }
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a suggested item for selectors.
 */
function getContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}

Python

python/selection-input/main.py
def on_widget_update(event: dict) -> dict:
  """Responds to a WIDGET_UPDATE event in Google Chat."""
  if "getContacts" == event.get("common").get("invokedFunction"):
    query = event.get("common").get("parameters").get("autocomplete_widget_query")
    return { 'actionResponse': {
      'type': "UPDATE_WIDGET",
      'updatedWidget': { 'suggestions': { 'items': list(filter(lambda e: query is None or query in e["text"], [
        # The list is static here but it could be dynamic.
        get_contact("1"), get_contact("2"), get_contact("3"), get_contact("4"), get_contact("5")
      # Only return items based on the query from the user
      ]))}}
    }}


def get_contact(id: str) -> dict:
  """Generate a suggested contact given an ID."""
  return {
    'value': id,
    'startIconUri': "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    'text': "Contact " + id
  }

Java

java/selection-input/src/main/java/com/google/chat/selectionInput/App.java
// Responds to a WIDGET_UPDATE event in Google Chat.
Message onWidgetUpdate(JsonNode event) {
  if ("getContacts".equals(event.at("/invokedFunction").asText())) {
    String query = event.at("/common/parameters/autocomplete_widget_query").asText();
    return new Message().setActionResponse(new ActionResponse()
      .setType("UPDATE_WIDGET")
      .setUpdatedWidget(new UpdatedWidget()
        .setSuggestions(new SelectionItems().setItems(List.of(
          // The list is static here but it could be dynamic.
          getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("5")
        // Only return items based on the query from the user
        ).stream().filter(e -> query == null || e.getText().indexOf(query) > -1).toList()))));
  }
  return null;
}

// Generate a suggested contact given an ID.
GoogleAppsCardV1SelectionItem getContact(String id) {
  return new GoogleAppsCardV1SelectionItem()
    .setValue(id)
    .setStartIconUri("https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png")
    .setText("Contact " + id);
}

Apps Komut Dosyası

apps-script/selection-input/selection-input.gs
/**
 * Responds to a WIDGET_UPDATE event in Google Chat.
 *
 * @param {Object} event The event object from Chat API.
 * @return {Object} Response from the Chat app.
 */
function onWidgetUpdate(event) {
  if (event.common["invokedFunction"] === "getContacts") {
    const query = event.common.parameters["autocomplete_widget_query"];
    return { actionResponse: {
      type: "UPDATE_WIDGET",
      updatedWidget: { suggestions: { items: [
        // The list is static here but it could be dynamic.
        getContact("1"), getContact("2"), getContact("3"), getContact("4"), getContact("5")
      // Only return items based on the query from the user
      ].filter(e => !query || e.text.includes(query))}}
    }};
  }
}

/**
 * Generate a suggested contact given an ID.
 *
 * @param {String} id The ID of the contact to return.
 * @return {Object} The contact formatted as a suggested item for selectors.
 */
function getContact(id) {
  return {
    value: id,
    startIconUri: "https://www.gstatic.com/images/branding/product/2x/contacts_48dp.png",
    text: "Contact " + id
  };
}