65.9K
CodeProject 正在变化。 阅读更多。
Home

使用无服务器 Python 构建 Microsoft Teams 应用(第二部分):使用 Python 和 Azure Functions 构建频道和组选项卡

2022 年 1 月 19 日

CPOL

8分钟阅读

viewsIcon

4325

downloadIcon

68

在本文中,我们将探讨如何使用 Python 和 Azure Functions 构建频道和群组选项卡以及带有自适应卡片的选项卡。

在本系列的第一篇文章中,我们分步学习了如何在 Python 中为 Microsoft Teams 构建个人选项卡应用,并由无服务器 Azure Functions 提供支持。在本系列三篇文章中的第二篇文章中,我们将使用 Python 和 Azure Functions 创建频道和群组选项卡应用。幸运的是,我们可以重用大部分代码,并且学习曲线将逐渐减小。

Microsoft Teams 频道和群组应用向用户显示一个页面,其中包含有关该频道或群组的信息。这种类型的 Teams 应用使用户能够组织他们的日历、项目管理工作表、文件等,并查看团队或频道成员共享的其他信息。

我们基于现有的 C# 示例构建了这个新应用,该示例说明了如何实现一个 带有 SSO 身份验证的频道和群组选项卡

您可以从第一篇文章中提供的代码开始,通过遵循本教程分步实现频道和群组选项卡应用。或者,您可以从 GitHub 下载源代码并跳转到配置步骤来启动并运行该应用。要继续学习,您应该了解 Python 并拥有一个免费的 Azure 帐户。我们将向您展示如何完成其余工作。

检查应用程序架构

与我们在本系列第一篇文章中开发的个人选项卡应用一样,我们正在使用 Python 和 Flask 构建一个无服务器应用来控制应用程序流程并呈现 Teams 内的 HTML 内容。 

当无服务器函数首次加载时,它们会从磁盘读取 HTML 模板并将其缓存在变量中,以便快速呈现网页 HTML。

应用的结构与第一篇文章相同。但是,这次我们添加了一个新的 az-function-configuration HTTP 触发器,以便在有人将应用添加到频道或群组时为 Teams 选项卡提供一个配置页面。

此应用程序仅由五个 Azure Functions 组成get-user-access-tokenindexauth-startauth-end 和 configuration。我们借用了第一个项目中的函数,除了 configuration,我们将在本教程中进行构建。

在 Azure 上注册应用程序

在向 Teams 发送访问请求之前,我们必须在 Azure Active Directory (AAD) 应用注册门户中注册一个新的应用程序,并创建一个供应用用于向 Azure 进行身份验证的密钥。我们在第一篇文章中已经为一个个人选项卡进行了应用注册,并且这两个应用程序非常相似。但是,这次我们想创建一个频道选项卡应用,因此我们必须进行新的注册。请按照以下步骤设置新的应用注册。

首先,请遵循 Teams 选项卡 SSO 身份验证 README 中此过程的说明。您可以使用相同的步骤将您的 Teams Python 应用程序与 Azure AD 注册。但是,这次我们创建的应用注册名为 channel-tab-sso-function-app

接下来,在 Azure 门户应用注册中更改重定向 URI链接,使其指向您的函数应用网站(例如,*.azurewebsites.net)。此外,请勾选隐式授予混合流选项。

另外,请确保在公开 API 选项卡中,应用程序 ID URI 指向 /api/az-function-auth-end

重用现有个人选项卡应用的现有代码

现在让我们重用我们在第一篇文章中创建的个人选项卡代码来构建我们频道选项卡应用的很大一部分。

首先,在 \ChannelTabSSO 文件夹中创建一个新文件夹来包含您的新 Python 项目。然后,在终端中打开新文件夹,键入以下命令在所选文件夹中打开 VS Code。

\ChannelTabSSO>code .

然后,像这样将静态文件从旧的 PersonalTabSSO 项目复制到新的 ChannelTabSSO 项目。

ChannelTabSSO 
    +-- static 
          +-- js 
            +-- auth.js 
    +-- templates 
          |-- base.html 
          |-- index.html 
          |-- auth_start.html 
          +-- auth_end.html

接下来,将 ssoAuthHelper.pycacheHelper.py 文件从 PersonalTabSSO 文件夹复制到 ChannelTabSSO

ChannelTabSSO
    |-- ssoAuthHelper.py
    +-- cacheHelper.py

然后,将 PersonalTabSSO 文件夹中的 az-functions-* 文件夹及其包含的文件复制到 ChannelTabSSO

ChannelTabSSO
    |-- az-function-auth-end/
    |-- az-function-auth-start/
    |-- az-function-index/
    +-- az-function-get-user-access-token/

这种复制粘贴的工作是频道选项卡应用中最困难的部分。完成后,VS Code 将显示您的项目如下。

添加配置页面文件

频道选项卡应用与个人选项卡应用略有不同。Microsoft 设计了频道或群组选项卡应用,以弹出配置页面,提供选项并收集用户的信息,然后根据用户的响应设置内容页面的 contentUrl

正如 Microsoft 的创建配置页面文档所示,配置页面是一个特殊的内容页面,用于控制用户在应用中可以执行的操作。请按照以下步骤实现配置页面。

首先,在 static 下创建一个新的 images 文件夹,然后从源存储库图像文件夹下载图像并将其添加到 images 文件夹。

ChannelTabSSO 
    +-- static 
          +-- images
                |-- IconGray.png
                |-- IconRed.png
                +-- TeamsIcon.png.png

现在,在 templates 文件夹中创建 configuration.html 文件,内容如下。

{% extends "base.html" %}
{% block title %}Python Configuration Page{% endblock %}
{% block content %}
  <h1>Python Configuration Channel Tab SSO Authentication</h1>
  <div id="divError" style="display: none"></div>
  <button onclick="requestConsent()" id="consent" style="display:none;">Authenticate</button>
  <div id="divGraphProfile" style="display: none"></div>
 
  <button onclick="(document.getElementById('icon').src = '/static/images/IconGray.png'); colorClickGray()">Select Gray</button>
  <img id="icon" src="https://raw.githubusercontent.com/marcelooliveira/PythonTeamsApps/main/ChannelTabSSO/static/images/TeamsIcon.png" alt="icon" style="width:100px" />
  <button onclick="(document.getElementById('icon').src = '/static/images/IconRed.png'); colorClickRed()">Select Red</button>
{% endblock %}
{% block scripts %}
<script>
  microsoftTeams.initialize();
  let saveGray = () => {
      microsoftTeams.settings.registerOnSaveHandler((saveEvent) => {
          microsoftTeams.settings.setSettings({
              websiteUrl: window.location.origin ,
              contentUrl: window.location.origin + "/api/az-function-index",
              entityId: "Python Channel Configure",
              suggestedDisplayName: "Python Channel Configure - Grey Settings"
          });
          saveEvent.notifySuccess();
      });
  }
  let saveRed = () => {
      microsoftTeams.settings.registerOnSaveHandler((saveEvent) => {
          microsoftTeams.settings.setSettings({
              websiteUrl: window.location.origin ,
              contentUrl: window.location.origin + "/api/az-function-index",
              entityId: "Python Channel Configure",
              suggestedDisplayName: "Python Channel Configure - Red Settings"
          });
          saveEvent.notifySuccess();
      });
  }
 
let icon = document.getElementById("icon");
  const colorClickGray = () => {
      microsoftTeams.settings.setValidityState(true);
      saveGray()
  }
 
  const colorClickRed = () => {
      microsoftTeams.settings.setValidityState(true);
      saveRed();
  }
</script>
 
{% endblock %}

请注意,配置页面与索引内容页面略有不同。稍后,我们将讨论配置页面如何工作以及 Teams 在将频道选项卡应用添加到频道或群组时如何向用户显示它。

创建 az-function-configuration Azure 函数

我们已经从第一个个人选项卡应用复制了四个 Azure 函数。但是,我们仍然必须创建一个 Azure 函数作为 HTTP 触发器并渲染我们的配置页面。

首先,单击 Azure 选项卡,然后单击创建新项目图标。

接下来,选择 ChannelTabSSO 作为您的本地函数项目文件夹

然后,选择 Python 作为您的函数应用语言

接下来,选择 HTTP 触发器作为 Azure函数模板。

将其命名为 az-function-configuration

然后,将函数设置为匿名,以便任何人都可以访问其端点而无需传递代码参数。

\az-function-configuration 文件夹中的 __init__.py 文件内容替换为以下代码。

import azure.functions as func 
from flask import Flask
import sys
from cacheHelper import CacheHelper
 
app = Flask(__name__)
 
this = sys.modules[__name__]
this.cacheHelper = None
 
def main(req: func.HttpRequest, context: func.Context) -> func.HttpResponse:
    if this.cacheHelper is None:
        this.cacheHelper = CacheHelper(context.function_directory)
    return func.WsgiMiddleware(app).handle(req, context)
 
@app.route("/api/az-function-configuration")
def index():
    return this.cacheHelper.render_cached_page(app, "configuration.html")

上面的代码将对 /api/az-function-configuration 端点的调用重新路由到 Python 代码,并使用 Flask 引擎进行渲染。

应用程序设置和配置

与第一篇文章一样,我们更改了一些配置,以便我们的频道选项卡应用可以在我们的开发机器和云中运行。

首先,修改 requirements.txt 以确保它包含以下行。

azure-functions
requests
flask==2.0.2
msal

然后,在项目根文件夹处打开终端并安装要求。

pip install -r requirements.txt

接下来,单击 Azure 选项卡,选择您的函数应用,然后单击下载远程设置

然后,打开 local.settings.json 文件。然后,添加您在 Azure 门户上创建的应用注册的配置。在这种情况下,我们使用 channel-tab-sso-function-app 的设置。

local.settings.json 文件中包含以下配置:InstanceTenantIdClientIdAppSecretAuthUrlCacheEnabled

{ 
  "IsEncrypted": false, 
  "Values": { 
    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=personaltabssofunctionap;AccountKey=*************************************;EndpointSuffix=core.windows.net", 
    "FUNCTIONS_WORKER_RUNTIME": "python", 
    "FUNCTIONS_EXTENSION_VERSION": "~4", 
    "WEBSITE_CONTENTAZUREFILECONNECTIONSTRING": "DefaultEndpointsProtocol=https;AccountName=personaltabssofunctionap;AccountKey=********************************************;EndpointSuffix=core.windows.net", 
    "WEBSITE_CONTENTSHARE": "personal-tab-sso-function-app45e3c0", 
    "APPINSIGHTS_INSTRUMENTATIONKEY": "********-****-****-****-************", 
    "Instance": "https://login.microsoftonline.com/", 
    "TenantId": "********-****-****-****-************", 
    "ClientId": "********-****-****-****-************", 
    "AppSecret": "***************************************************************", 
    "AuthUrl": "/oauth2/v2.0/token", 
    "CacheEnabled": "false" 
  } 
}

Azure 选项卡上,单击上传本地设置。此命令将您的本地配置发送到云中的函数应用。

最后,按 F5 在调试模式下运行项目。

观察我们现在拥有五个工作的 Azure 函数。

  • az-function-auth-end: [GET,POST] https://:7071/api/az-function-auth-end
  • az-function-auth-start: [GET,POST] https://:7071/api/az-function-auth-start
  • az-function-configuration: [GET,POST] https://:7071/api/az-function-configuration
  • az-function-get-user-access-token: [GET,POST] https://:7071/api/az-function-get-user-access-token
  • az-function-index: [GET,POST] https://:7071/api/az-function-index

现在,单击本地项目文件夹中的Functions文件夹,然后单击部署到函数应用图标。此操作会将您的 Python 函数上传到 Azure。

最后,在 Azure 中选择您的函数应用进行部署。

 

将频道选项卡应用添加到团队

我们将通过上传包含清单的 .zip 文件来安装频道选项卡应用,就像个人选项卡应用一样。首先,单击应用选项卡,然后单击上传自定义应用链接。

然后,选择 manifest.zip 文件。

此时,您已安装了新应用。但是,与个人选项卡应用不同,用户无法立即打开频道选项卡应用。相反,用户只有在有人将应用添加到团队后才能打开频道和群组选项卡。让我们探讨一下这个过程。

首先,单击应用选项卡上的应用,然后单击添加到团队按钮。

然后,选择您想添加应用的团队。

将应用添加到团队后,应用将显示我们之前创建的配置页面。

这个页面是一个很好的地方,可以定义参数、行为和外观,以自定义您的团队或频道将如何使用您的新 Python 应用。虽然我们的示例配置页面只有一些占位符按钮来选择颜色,但它暗示了实际的可能性。

在团队中使用频道选项卡应用

在我们将频道选项卡应用添加到团队后,用户可以在团队界面中看到一个新的配置选项卡。

现在 Teams 将我们的用户重定向到索引页面。但是,与个人选项卡应用一样,频道选项卡应用在用户使用之前必须先请求并获得授权。这是我们从原始个人选项卡项目复制的相同的索引内容页面,其中包含身份验证按钮。

Teams 请求用户在使用前同意您的应用。

现在您的团队用户可以享受带有 SSO 身份验证的频道选项卡了。您的应用程序在此处显示的内容取决于您的应用程序以及您在配置页面上定义的选项。

后续步骤

在本系列的第二部分中,我们介绍了如何将 Microsoft Teams 与 Azure 无服务器函数和 SSO 身份验证集成以创建频道选项卡应用。我们讨论了如何使用 Python 和 Visual Studio Code,在 Azure 云中托管一个最小化的工作频道选项卡应用项目。

我们从第一个个人选项卡应用创建了一个新的频道选项卡应用,工作量很小。Flask 和 Jinja 使用 HTML 和 JavaScript 代码生成新的配置网页。再次,Python 代码作为我们 Azure 无服务器函数的驱动力闪耀。

您现在拥有一个可用的频道选项卡应用程序,您可以将其作为脚手架,使用您的 Python 编程技能来开发专业的 Microsoft Teams 应用。

注册 Azure 免费试用版,以创建和运行您自己的基于 Python 的 Teams 应用,或者继续本系列的第三部分,了解如何构建带有自适应卡片的选项卡

要了解更多关于如何为个人、您的团队、您的组织或所有 Microsoft Teams 用户构建应用的信息,请查看为 Microsoft Teams 开发应用

© . All rights reserved.