Manifests para complementos do Google Workspace

Um complemento usa um arquivo de manifesto para configurar determinados detalhes sobre o app e a operação dele.

Esta documentação aborda os detalhes da configuração de um manifesto para um complemento do Google Workspace.

Estrutura do manifesto para complementos do Google Workspace

Os complementos do Google Workspace usam o arquivo de manifesto para definir vários aspectos da aparência e do comportamento.

As propriedades do manifesto para complementos do Google Workspace são organizadas na seção addOns.

  • Para informações sobre arquivos de manifesto do Google Apps Script, consulte Estrutura do manifesto.

  • Para informações sobre arquivos de manifesto de complementos criados com endpoints HTTP, consulte projects.deployments.

Manifestos do Google Chat

Se o complemento do Google Workspace estender o Google Chat, configure um app do Google Chat ativando e configurando a API Google Chat no console do Google Cloud.

As configurações comuns de configuração do manifesto (incluindo addons.common) são ignoradas no Chat. Use a API Chat para configurar as seguintes configurações do Chat:

Se você criou o complemento no Apps Script, adicione ou atualize os seguintes objetos no manifesto:

Para configurar as configurações do Chat para um complemento, consulte Configurar um app do Google Chat.

Exemplo de configuração de manifesto de complemento do Google Workspace

Os exemplos a seguir mostram a parte de um manifesto que define um complemento do Google Workspace, incluindo estes aspectos:

  • addOns.common define o nome, o logotipo, as cores e outras configurações gerais do complemento.

  • O manifesto define uma página inicial comum, mas também define páginas iniciais específicas do Google Agenda, Google Drive, Google Docs, Google Planilhas e Google Apresentações. O Gmail usa a página inicial padrão.

  • As configurações de manifesto de exemplo ativam o seguinte:

    • Acionadores eventOpen e eventUpdated do Google Agenda.

    • (Somente Apps Script) Duas soluções de conferência do Google Agenda .

    • Duas ações universais.

    • Um onItemsSelectedTrigger do Drive.

    • Uma ação de escrever do Gmail e um acionador contextual.

    • Um objeto linkPreviewTriggers do Documentos. Consulte Visualizar links com ícones inteligentes.

    • Um objeto createActionTriggers do Documentos. Consulte Criar recursos de terceiros no menu "@".

    • Interfaces específicas de arquivos para Documentos, Planilhas e Apresentações.

    • Uma opção sidePanelUri e addOnOrigins do Google Meet.

    • (Somente HTTP) Dois HttpOptions para enviar um cabeçalho de autorização e oferecer suporte à permissão granular.

  • O campo oauthScopes define os escopos de autorização do projeto.

  • (Somente Apps Script) O urlFetchWhitelist garante que os endpoints buscados correspondam aos prefixos de URL HTTPS especificados. Consulte URLs permitidos.

Os links nos exemplos redirecionam para descrições de campo na referência de manifesto para complementos do Google Workspace do Apps Script e HTTP.

Os manifestos incluem outros componentes. Os campos em addOns estão diretamente relacionados aos complementos do Google Workspace. Este exemplo mostra apenas uma parte de um arquivo de manifesto completo e não é funcional por conta própria.

Apps Script

{
  "addOns": {
    "calendar": {
      "createSettingsUrlFunction": "getConferenceSettingsPageUrl",
      "conferenceSolution": [{
        "id": "my-video-conf",
        "logoUrl": "https://lh3.googleusercontent.com/...",
        "name": "My Video Conference",
        "onCreateFunction": "onCreateMyVideoConference"
      }, {
        "id": "my-streamed-conf",
        "logoUrl": "https://lh3.googleusercontent.com/...",
        "name": "My Streamed Conference",
        "onCreateFunction": "onCreateMyStreamedConference"
      }],
      "currentEventAccess": "READ_WRITE",
      "eventOpenTrigger": {
        "runFunction": "onCalendarEventOpen"
      },
      "eventUpdateTrigger": {
        "runFunction": "onCalendarEventUpdate"
      },
      "eventAttachmentTrigger": {
        "label": "My Event Attachment",
        "runFunction": "onCalendarEventAddAttachment"
      },
      "homepageTrigger": {
        "runFunction": "onCalendarHomePageOpen",
        "enabled": true
      }
    },
    "common": {
      "homepageTrigger": {
        "runFunction": "onDefaultHomePageOpen",
        "enabled": true
      },
      "layoutProperties": {
        "primaryColor": "#ff392b",
        "secondaryColor": "#d68617"
      },
      "logoUrl": "https://ssl.gstatic.com/docs/script/images/logo/script-64.png",
      "name": "Demo Google Workspace add-on",
      "openLinkUrlPrefixes": [
        "https://mail.google.com/",
        "https://script.google.com/a/google.com/d/",
        "https://drive.google.com/a/google.com/file/d/",
        "https://www.example.com/"
      ],
      "universalActions": [{
        "label": "Open settings",
        "runFunction": "getSettingsCard"
      }, {
        "label": "Open Help URL",
        "openLink": "https://www.example.com/help"
      }],
      "useLocaleFromApp": true
    },
    "drive": {
      "homepageTrigger": {
        "runFunction": "onDriveHomePageOpen",
        "enabled": true
      },
      "onItemsSelectedTrigger": {
        "runFunction": "onDriveItemsSelected"
      }
    },
    "gmail": {
      "composeTrigger": {
        "selectActions": [
          {
            "text": "Add images to email",
            "runFunction": "getInsertImageComposeCards"
          }
        ],
        "draftAccess": "METADATA"
      },
      "contextualTriggers": [
        {
          "unconditional": {},
          "onTriggerFunction": "onGmailMessageOpen"
        }
      ]
    },
    "docs": {
      "homepageTrigger": {
        "runFunction": "onEditorsHomepage"
      },
      "onFileScopeGrantedTrigger": {
        "runFunction": "onFileScopeGrantedEditors"
      },
      "linkPreviewTriggers": [
        {
        "runFunction": "onLinkPreview",
        "patterns": [
            {
              "hostPattern": "example.com",
              "pathPrefix": "example-path"
            }
        ],
        "labelText": "Link preview",
        "localizedLabelText": {
          "es": "Link preview localized in Spanish"
        },
        "logoUrl": "https://www.example.com/images/smart-chip-icon.png"
        }
      ],
      "createActionTriggers": [
        {
          "id": "exampleId",
          "labelText": "Example label text",
          "localizedLabelText": {
            "es": "Label text localized in Spanish"
          },
          "runFunction": "exampleFunction",
          "logoUrl": "https://www.example.com/images/case.png"
        }
      ]
    },
    "sheets": {
      "homepageTrigger": {
        "runFunction": "onEditorsHomepage"
      },
      "onFileScopeGrantedTrigger": {
        "runFunction": "onFileScopeGrantedEditors"
      }
    },
    "slides": {
      "homepageTrigger": {
        "runFunction": "onEditorsHomepage"
      },
      "onFileScopeGrantedTrigger": {
        "runFunction": "onFileScopeGrantedEditors"
      }
    },
    "meet": {
      "homepageTrigger",
      "Web": [
        {
          "sidePanelUrl": "https://myownpersonaldomain.com/sidePanelUrl",
          "supportsScreenSharing": true,
          "addOnOrigins": [
            "https://www.myownpersonaldomain.com",
            "https://www.myownpersonaldomain.com:443"
          ],
          "logoUrl": "https://myownpersonaldomain.com/logoUrl",
          "darkModeLogoUrl": "https://myownpersonaldomain.com/darkModeLogoUrl"
        }
    },
  },
  "oauthScopes": [
    "https://www.googleapis.com/auth/calendar.addons.execute",
    "https://www.googleapis.com/auth/calendar.addons.current.event.read",
    "https://www.googleapis.com/auth/calendar.addons.current.event.write",
    "https://www.googleapis.com/auth/drive.addons.metadata.readonly",
    "https://www.googleapis.com/auth/gmail.addons.current.action.compose",
    "https://www.googleapis.com/auth/gmail.addons.current.message.metadata",
    "https://www.googleapis.com/auth/userinfo.email",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/script.locale",
    "https://www.googleapis.com/auth/script.scriptapp",
    "https://www.googleapis.com/auth/drive.file",
    "https://www.googleapis.com/auth/documents.currentonly",
    "https://www.googleapis.com/auth/spreadsheets.currentonly",
    "https://www.googleapis.com/auth/presentations.currentonly",
    "https://www.googleapis.com/auth/workspace.linkpreview"
  ],
  "urlFetchWhitelist": [
    "https://www.example.com/myendpoint/"
  ]
}

HTTP

{
  "addOns": {
    "calendar": {
      "currentEventAccess": "READ_WRITE",
      "eventOpenTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onCalendarEventOpen"
      },
      "eventUpdateTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onCalendarEventUpdate"
      },
      "eventAttachmentTrigger": {
        "label": "My Event Attachment",
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onCalendarEventAddAttachment"
      },
      "homepageTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onCalendarHomePageOpen",
        "enabled": true
      }
    },
    "common": {
      "homepageTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onDefaultHomePageOpen",
        "enabled": true
      },
      "layoutProperties": {
        "primaryColor": "#ff392b",
        "secondaryColor": "#d68617"
      },
      "logoUrl": "https://ssl.gstatic.com/docs/script/images/logo/script-64.png",
      "name": "Demo Google Workspace add-on",
      "openLinkUrlPrefixes": [
        "https://mail.google.com/",
        "https://script.google.com/a/google.com/d/",
        "https://drive.google.com/a/google.com/file/d/",
        "https://www.example.com/"
      ],
      "universalActions": [{
        "label": "Open settings",
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=getSettingsCard"
      }, {
        "label": "Open Help URL",
        "openLink": "https://www.example.com/help"
      }],
      "useLocaleFromApp": true
    },
    "drive": {
      "homepageTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onDriveHomePageOpen",
        "enabled": true
      },
      "onItemsSelectedTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onDriveItemsSelected"
      }
    },
    "gmail": {
      "composeTrigger": {
        "actions": [
          {
            "label": "Add images to email",
            "runFunction": "https://myownpersonaldomain.com/mypage?trigger=getInsertImageComposeCards"
          }
        ],
        "draftAccess": "METADATA"
      },
      "contextualTriggers": [
        {
          "unconditional": {},
          "onTriggerFunction": "https://myownpersonaldomain.com/mypage?trigger=onGmailMessageOpen"
        }
      ]
    },
    "docs": {
      "homepageTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onEditorsHomepage"
      },
      "onFileScopeGrantedTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onFileScopeGrantedEditors"
      },
      "linkPreviewTriggers": [
        {
          "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onLinkPreview",
          "patterns": [
              {
                "hostPattern": "example.com",
                "pathPrefix": "example-path"
              }
          ],
          "labelText": "Link preview",
          "localizedLabelText": {
            "es": "Link preview localized in Spanish"
          },
          "logoUrl": "https://www.example.com/images/smart-chip-icon.png"
        }
      ],
      "createActionTriggers": [
        {
          "id": "exampleId",
          "labelText": "Example label text",
          "localizedLabelText": {
            "es": "Label text localized in Spanish"
          },
          "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onCreateAction",
          "logoUrl": "https://www.example.com/images/case.png"
        }
      ]
    },
    "sheets": {
      "homepageTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onEditorsHomepage"
      },
      "onFileScopeGrantedTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onFileScopeGrantedEditors"
      }
    },
    "slides": {
      "homepageTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onEditorsHomepage"
      },
      "onFileScopeGrantedTrigger": {
        "runFunction": "https://myownpersonaldomain.com/mypage?trigger=onFileScopeGrantedEditors"
      }
    },
    "meet": {
      "homepageTrigger",
      "Web": [
        {
          "sidePanelUrl": "https://myownpersonaldomain.com/sidePanelUrl",
          "supportsScreenSharing": true,
          "addOnOrigins": [
            "https://www.myownpersonaldomain.com",
            "https://www.myownpersonaldomain.com:443"
          ],
          "logoUrl": "https://myownpersonaldomain.com/meetWebLogoUrl",
          "darkModeLogoUrl": "https://myownpersonaldomain.com/darkModeLogoUrl"
        }
      ]
    },
    "httpOptions": {
      "authorizationHeader": "SYSTEM_ID_TOKEN",
      "granularOauthPermissionSupport": "OPT_IN"
    }
  },
  "oauthScopes": [
    "https://www.googleapis.com/auth/calendar.addons.execute",
    "https://www.googleapis.com/auth/calendar.addons.current.event.read",
    "https://www.googleapis.com/auth/calendar.addons.current.event.write",
    "https://www.googleapis.com/auth/drive.addons.metadata.readonly",
    "https://www.googleapis.com/auth/gmail.addons.current.action.compose",
    "https://www.googleapis.com/auth/gmail.addons.current.message.metadata",
    "https://www.googleapis.com/auth/userinfo.email",
    "https://www.googleapis.com/auth/script.external_request",
    "https://www.googleapis.com/auth/script.locale",
    "https://www.googleapis.com/auth/script.scriptapp",
    "https://www.googleapis.com/auth/drive.file",
    "https://www.googleapis.com/auth/documents.currentonly",
    "https://www.googleapis.com/auth/spreadsheets.currentonly",
    "https://www.googleapis.com/auth/presentations.currentonly",
    "https://www.googleapis.com/auth/workspace.linkpreview"
  ]
}

URLs permitidos

Você usa listas de permissões para designar URLs específicos que são pré-aprovados para acesso pelo script ou complemento. As listas de permissões ajudam a proteger os dados do usuário. Quando você define uma lista de permissões, os projetos de script não podem acessar URLs que não foram adicionados à lista.

Esse campo é opcional ao instalar uma implantação de teste, mas é obrigatório ao criar uma implantação versionada.

Você usa listas de permissões quando o script ou complemento realiza as seguintes ações:

  • Recupera ou busca informações de um local externo (como endpoints HTTPS ) usando o serviço UrlFetch do Apps Script. Para permitir URLs para busca, inclua o urlFetchWhitelist campo no arquivo de manifesto.
  • Abre ou mostra um URL em resposta a uma ação do usuário. Isso é obrigatório para complementos do Google Workspace que abrem ou mostram URLs externos ao Google. Para permitir URLs para abertura, inclua o addOns.common.openLinkUrlPrefixes campo no seu arquivo de manifesto.

Como adicionar prefixos à lista de permissões

Ao especificar listas de permissões no arquivo de manifesto (incluindo o campo addOns.common.openLinkUrlPrefixes ou urlFetchWhitelist), você precisa incluir uma lista de prefixos de URL. Os prefixos adicionados ao manifesto precisam atender aos seguintes requisitos:

  • Cada prefixo precisa ser um URL válido.
  • Cada prefixo precisa usar https://, não http://.
  • Cada prefixo precisa ter um domínio completo.
  • Cada prefixo precisa ter um caminho não vazio. Por exemplo, https://www.google.com/ é válido, mas https://www.google.com não é.
  • Você pode usar caracteres curinga para corresponder a prefixos de subdomínio de URL.
  • Um único * caractere curinga pode ser usado no addOns.common.openLinkUrlPrefixes campo para corresponder a todos os links, mas isso não é recomendado, porque pode expor os dados de um usuário a riscos e prolongar o processo de revisão do complemento. Use um caractere curinga apenas se a funcionalidade do complemento exigir.

Ao determinar se um URL corresponde a um prefixo na lista de permissões, as seguintes regras se aplicam:

  • A correspondência de caminho diferencia maiúsculas de minúsculas.
  • Se o prefixo for idêntico ao URL, ele será uma correspondência.
  • Se o URL for o mesmo ou um filho do prefixo, ele será uma correspondência.

Por exemplo, o prefixo https://example.com/foo corresponde aos seguintes URLs:

  • https://example.com/foo
  • https://example.com/foo/
  • https://example.com/foo/bar
  • https://example.com/foo?bar
  • https://example.com/foo#bar

Como usar caracteres curinga

Você pode usar um único caractere curinga (*) para corresponder a um subdomínio para os campos urlFetchWhitelist e addOns.common.openLinkUrlPrefixes. Não é possível usar mais de um caractere curinga para corresponder a vários subdomínios, e o caractere curinga precisa representar o prefixo principal do URL.

Por exemplo, o prefixo https://*.example.com/foo corresponde aos seguintes URLs:

  • https://subdomain.example.com/foo
  • https://any.number.of.subdomains.example.com/foo

O prefixo https://*.example.com/foo não corresponde aos seguintes URLs:

  • https://subdomain.example.com/bar (incompatibilidade de sufixo)
  • https://example.com/foo (pelo menos um subdomínio precisa estar presente)

Algumas das regras de prefixo são aplicadas quando você tenta salvar o manifesto. Por exemplo, os seguintes prefixos causam um erro se estiverem presentes no manifesto quando você tentar salvar:

  • https://*.*.example.com/foo (vários caracteres curinga são proibidos)
  • https://subdomain.*.example.com/foo (os caracteres curinga precisam ser usados como um prefixo principal)