{"id":47296,"date":"2023-12-10T16:11:00","date_gmt":"2023-06-16T11:23:59","guid":{"rendered":"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/"},"modified":"2024-05-04T12:57:59","modified_gmt":"2024-05-04T04:57:59","slug":"%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5","status":"publish","type":"post","link":"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/","title":{"rendered":"\u6211\u5c1d\u8bd5\u5c06Azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230Teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\u7f16\u3011"},"content":{"rendered":"<h2>\u603b\u7ed3<\/h2>\n<p>\u5c06\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u7684Python\u7a0b\u5e8f\u6ce8\u518c\u5230Azure Functions\u5e76\u81ea\u52a8\u8fd0\u884c\uff0c\u7136\u540e\u5c06\u7ed3\u679c\u4f5c\u4e3aTemas\u516c\u53f8\u4fe1\u606f\u5171\u4eab\u5de5\u5177\u4e2d\u7684\u6e20\u9053POST\uff0c\u5e76\u5e0c\u671b\u80fd\u591f\u5728Azure\u4f7f\u7528\u8d39\u7528\u51cf\u5c11\u7684\u540c\u65f6\uff0c\u63d0\u4f9b\u4e00\u70b9\u5e2e\u52a9\u3002<\/p>\n<h3>\u6267\u884c\u73af\u5883<\/h3>\n<p>macOS Big Sur 11.1<br \/>\npython 3.8.3<br \/>\nAzure CLI 2.28.0<br \/>\nAzure Functions Core Tools 3.0.3785<br \/>\nAzure Function Runtime Version: 3.2.0.0<\/p>\n<p>macOS Big Sur 11.1<br \/>\nPython 3.8.3<br \/>\nAzure CLI 2.28.0<br \/>\nAzure \u51fd\u6570\u6838\u5fc3\u5de5\u5177 3.0.3785<br \/>\nAzure \u51fd\u6570\u8fd0\u884c\u65f6\u7248\u672c\uff1a3.2.0.0<\/p>\n<hr \/>\n<h2>\u4e8b\u524d\u7684\u51c6\u5907<\/h2>\n<h3>\u521b\u5efa\u7528\u4e8e\u6267\u884c\u7a0b\u5e8f\u7684 ServicePrincipal<\/h3>\n<p>\u6839\u636e\u8fd9\u7bc7\u6587\u7ae0\uff0cServicePrincipal\u7684\u5ba2\u6237\u7aef\u5bc6\u94a5\u9ed8\u8ba4\u7684\u6709\u6548\u671f\u662f\u4e00\u5e74\uff0c\u6700\u957f\u53ef\u4ee5\u8bbe\u7f6e\u4e3a\u4e24\u5e74\u3002\u56e0\u6b64\uff0c\u6211\u4eec\u53ef\u4ee5\u901a\u8fc7Azure CLI\u6309\u7167\u4ee5\u4e0b\u6b65\u9aa4\u521b\u5efa\u4e00\u4e2a\u6709\u6548\u671f\u4e3a29\u5e74\u7684ServicePrincipal\uff08\u76ee\u524d\u4e3a\u6b62\uff0c\u5df2\u6210\u529f\u5730\u521b\u5efa\uff09\u3002<\/p>\n<pre class=\"post-pre\"><code>## \u4f7f\u7528\u3059\u308b\u30c6\u30ca\u30f3\u30c8\u306eAzure\u74b0\u5883\u3078\u306e\u30ed\u30b0\u30a4\u30f3\r\n$ az login --tenant &lt;tenant_id&gt;\r\n\r\n## \u6700\u521d\u306f\uff12\u5e74\u3067\u4f5c\u6210\u3057\u307e\u3059\uff08\u30ed\u30fc\u30eb\u5272\u5f53\u306a\u3057\u3067\uff09\r\n$ az ad sp create-for-rbac --name &lt;ServicePrincial\u540d&gt; --skip-assignment --years 2\r\n\r\n## \u4f5c\u6210\u3055\u308c\u305f\u5185\u5bb9\u3092\u53d6\u5f97\u3067\u304d\u308b\u3053\u3068\u3092\u78ba\u8a8d\u3057\u307e\u3059\uff08\u3044\u304d\u306a\u308a29\u5e74\u3067\u4f5c\u6210\u3057\u305f\u5834\u5408\u3001\u53d6\u5f97\u3067\u304d\u307e\u305b\u3093\u3001\u3001\u3001\uff09\r\n$ az ad sp list --display-name &lt;ServicePrincial\u540d&gt;\r\n\r\n## \u305d\u306e\u5f8c\u300129\u5e74\u3067\u518d\u4f5c\u6210\u3057\u307e\u3059\uff08\u30ed\u30fc\u30eb\u5272\u5f53\u306a\u3057\u3067\uff09\r\n$ az ad sp create-for-rbac --name &lt;ServicePrincial\u540d&gt; --skip-assignment --years 29\r\n{\r\n  \"appId\": \"xxxxxxxx-xxxx-4633-8080-xxxxxxxxxxxx\",      --&gt; \u95a2\u6570\u30a2\u30d7\u30ea\u306e\u69cb\u6210\u3067 AZURE_CLIENT_ID \u3068\u3057\u3066\u767b\u9332\r\n  \"displayName\": \"&lt;ServicePrincial\u540d&gt;\",\r\n  \"name\": \"xxxxxxxx-xxxx-4633-8080-xxxxxxxxxxxx\",\r\n  \"password\": \"hogehogehogehogehogehogehogehogege\",     --&gt; \u95a2\u6570\u30a2\u30d7\u30ea\u306e\u69cb\u6210\u3067 AZURE_CLIENT_SECRET \u3068\u3057\u3066\u767b\u9332\r\n  \"tenant\": \"zzzzzzzz-cccc-4645-5757-zzzzzzzzzzzz\"      --&gt; \u95a2\u6570\u30a2\u30d7\u30ea\u306e\u69cb\u6210\u3067 AZURE_TENANT_ID \u3068\u3057\u3066\u767b\u9332\r\n}\r\n\r\n## \u5fc5\u8981\u306a\u30b9\u30b3\u30fc\u30d7\u306b\u5fc5\u8981\u306a\u30ed\u30fc\u30eb\u3092\u5272\u308a\u4e0e\u3048\u307e\u3059\r\n## \u4eca\u56de\u306f\u8907\u6570Subscription\u306e\u5229\u7528\u6599\u91d1\u3092\u53d6\u5f97\u3057\u305f\u3044\u306e\u3067\u3001\u30b9\u30b3\u30fc\u30d7\uff1aSubscription\u3000\u30ed\u30fc\u30eb\uff1aReader \u3068\u3057\u307e\u3059\r\n$ APP_ID=$(az ad sp list --display-name &lt;ServicePrincial\u540d&gt; --query '[].{ID:appId}' --output tsv)\r\n$ az role assignment create --assignee $APP_ID --scope \/subscriptions\/&lt;xxx-SubscriptionID&gt; --role Reader\r\n$ az role assignment create --assignee $APP_ID --scope \/subscriptions\/&lt;yyy-SubscriptionID&gt; --role Reader\r\n$ az role assignment create --assignee $APP_ID --scope \/subscriptions\/&lt;zzz-SubscriptionID&gt; --role Reader\r\n<\/code><\/pre>\n<h3>\u4e3a\u901a\u77e5\u7a0b\u5e8f\u6267\u884c\u7ed3\u679c\u800c\u8fdb\u884c\u7684Teams\u8bbe\u7f6e\u3002<\/h3>\n<p>\u4e3a\u4e86\u5728Teams\u7684\u9891\u9053\u4e2d\u6536\u5230\u6267\u884c\u7ed3\u679c\u7684\u901a\u77e5\uff0c\u8bf7\u6309\u7167\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u7684&#8221;\u4e8b\u524d\u51c6\u5907&#8221;\u6b65\u9aa4\uff0c\u5e76\u8fdb\u884cWebhook\u7684\u8bbe\u7f6e\u3002\u5c06\u751f\u6210\u7684Webhook URL\u590d\u5236\u4e0b\u6765\u3002\u8fd9\u4e2aURL\u5728\u914d\u7f6e\u51fd\u6570\u5e94\u7528\u7a0b\u5e8f\u65f6\u9700\u8981\u6ce8\u518c\u4e3aENDPOINT_TECH\u3002<\/p>\n<h3>\u5728Azure\u4e0a\u521b\u5efa\u6240\u9700\u7684\u9879\u76ee\u3002<\/h3>\n<pre class=\"post-pre\"><code>## \u4f7f\u7528\u30b5\u30d6\u30b9\u30af\u30ea\u30d7\u30b7\u30e7\u30f3\u3092\u5b9a\u7fa9\u3057\u307e\u3059\r\n$ az account set --subscription '&lt;Subscription\u540d&gt;'\r\n\r\n## \u30ea\u30bd\u30fc\u30b9\u30b0\u30eb\u30fc\u30d7\u306e\u4f5c\u6210\r\n$ az group create --resource-group &lt;ResourceGroup\u540d&gt; --location japaneast\r\n\r\n## \u30b9\u30c8\u30ec\u30fc\u30b8\u30a2\u30ab\u30a6\u30f3\u30c8\u306e\u4f5c\u6210\r\naz storage account create --name &lt;StorageAccount\u540d&gt; --resource-group &lt;ResourceGroup\u540d&gt; --location japaneast --sku Standard_LRS\r\n\r\n## Functions\uff08\u95a2\u6570\u30a2\u30d7\u30ea\uff09\u306e\u4f5c\u6210\r\naz functionapp create ---resource-group &lt;ResourceGroup\u540d&gt; --name &lt;Functions\u540d&gt; --storage-account &lt;StorageAccount\u540d&gt; --runtime python --runtime-version 3.7 --consumption-plan-location japaneast --os-type Linux --functions-version 2\r\n\r\n## \u4f5c\u6210\u3057\u305f\u95a2\u6570\u30a2\u30d7\u30ea\u306e\u69cb\u6210\u8a2d\u5b9a\r\n### \u95a2\u6570\u30a2\u30d7\u30ea\u5b9f\u884c\u306e\u305f\u3081\u306e ServicePrincipal \u60c5\u5831\u306e\u5b9a\u7fa9\r\naz functionapp config appsettings set -n &lt;Functions\u540d&gt; -g &lt;ResourceGroup\u540d&gt; \\\r\n    --settings \"AZURE_TENANT_ID=zzzzzzzz-cccc-4645-5757-zzzzzzzzzzzz\"\r\naz functionapp config appsettings set -n &lt;Functions\u540d&gt; -g &lt;ResourceGroup\u540d&gt; \\\r\n    --settings \"AZURE_CLIENT_ID=xxxxxxxx-xxxx-4633-8080-xxxxxxxxxxxx\"\r\naz functionapp config appsettings set -n &lt;Functions\u540d&gt; -g &lt;ResourceGroup\u540d&gt; \\\r\n    --settings \"AZURE_CLIENT_SECRET=hogehogehogehogehogehogehogehogege\"\r\n\r\n### \u95a2\u6570\u30a2\u30d7\u30ea\u306e\u5b9f\u884c\u7d50\u679c\u3092Teams\u306e\u30c1\u30e3\u30cd\u30eb\u306bPOST\uff08Webhook)\u3059\u308b\u305f\u3081\u306e\u5b9a\u7fa9\r\naz functionapp config appsettings set -n &lt;Functions\u540d&gt; -g &lt;ResourceGroup\u540d&gt; \\\r\n    --settings \"ENDPOINT_TECH=https:\/\/nnn.webhook.office.com\/webhookb2\/xxx\/IncomingWebhook\/yyy\/zzz\"\r\n\r\n### \u5b9a\u7fa9\u60c5\u5831\u306e\u78ba\u8a8d\r\naz functionapp config appsettings list -n &lt;Functions\u540d&gt; -g &lt;ResourceGroup\u540d&gt; -o table\r\n<\/code><\/pre>\n<h3>\u521b\u5efa\u672c\u5730\u73af\u5883\u4ee5\u4f9b\u529f\u80fd\u4f7f\u7528<\/h3>\n<pre class=\"post-pre\"><code>## Function\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u306e\u4f5c\u6210\r\n(base)$ mkdir Functions\r\n(base)$ cd Functions\r\n\r\n## \u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u7528\u306ePython\u4eee\u60f3\u74b0\u5883\u306e\u69cb\u7bc9\r\n(base)$ python -m venv .venv\r\n(base)$ source .venv\/bin\/activate\r\n(.venv) (base)$ python --version\r\nPython 3.8.3\r\n\r\n## Function\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306e\u4f5c\u6210\r\n(.venv) (base)$ func init CostSummary --python\r\nWriting requirements.txt\r\nWriting .funcignore\r\nWriting .gitignore\r\nWriting host.json\r\nWriting local.settings.json\r\nWriting \/Users\/ituru\/MyDevelops\/AzureCostManagement\/Functions\/CostSummary\/.vscode\/extensions.json\r\n\r\n## Function\u306e\u4f5c\u6210\r\n(.venv) (base)$ cd CostSummary\r\n(.venv) (base)$ func new                           \r\nSelect a number for template:\r\n1. Azure Blob Storage trigger\r\n2. Azure Cosmos DB trigger\r\n3. Durable Functions activity\r\n4. Durable Functions entity\r\n5. Durable Functions HTTP starter\r\n6. Durable Functions orchestrator\r\n7. Azure Event Grid trigger\r\n8. Azure Event Hub trigger\r\n9. HTTP trigger\r\n10. Kafka output\r\n11. Kafka trigger\r\n12. Azure Queue Storage trigger\r\n13. RabbitMQ trigger\r\n14. Azure Service Bus Queue trigger\r\n15. Azure Service Bus Topic trigger\r\n16. Timer trigger\r\nChoose option: 16\r\nTimer trigger\r\nFunction name: [TimerTrigger] CostSummaryDaily\r\nWriting \/Users\/ituru\/MyDevelops\/AzureCostManagement\/Functions\/CostSummary\/CostSummaryDaily\/readme.md\r\nWriting \/Users\/ituru\/MyDevelops\/AzureCostManagement\/Functions\/CostSummary\/CostSummaryDaily\/__init__.py\r\nWriting \/Users\/ituru\/MyDevelops\/AzureCostManagement\/Functions\/CostSummary\/CostSummaryDaily\/function.json\r\nThe function \"CostSummaryDaily\" was created successfully from the \"Timer trigger\" template.\r\n\r\n## \u30c7\u30a3\u30ec\u30af\u30c8\u30ea\u69cb\u6210\u306e\u78ba\u8a8d\r\n(.venv) (base)$ tree -a      \r\n.\r\n\u251c\u2500\u2500 .funcignore\r\n\u251c\u2500\u2500 .gitignore\r\n\u251c\u2500\u2500 .vscode\r\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 extensions.json\r\n\u251c\u2500\u2500 CostSummaryDaily\r\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 __init__.py\r\n\u2502\u00a0\u00a0 \u251c\u2500\u2500 function.json\r\n\u2502\u00a0\u00a0 \u2514\u2500\u2500 readme.md\r\n\u251c\u2500\u2500 getting_started.md\r\n\u251c\u2500\u2500 host.json\r\n\u251c\u2500\u2500 local.settings.json\r\n\u2514\u2500\u2500 requirements.txt\r\n\r\n2 directories, 10 files\r\n<\/code><\/pre>\n<hr \/>\n<h2>\u5d4c\u5165\u5f0f\u7684Python\u7a0b\u5e8f\u6267\u884c<\/h2>\n<h3>\u6267\u884c\u7a0b\u5e8f<\/h3>\n<pre class=\"post-pre\"><code><span class=\"kn\">import<\/span> <span class=\"nn\">logging<\/span>\r\n<span class=\"kn\">import<\/span> <span class=\"nn\">azure.functions<\/span> <span class=\"k\">as<\/span> <span class=\"n\">func<\/span>\r\n<span class=\"kn\">import<\/span> <span class=\"nn\">os<\/span>\r\n<span class=\"kn\">import<\/span> <span class=\"nn\">time<\/span>\r\n<span class=\"kn\">import<\/span> <span class=\"nn\">json<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"nn\">datetime<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">datetime<\/span><span class=\"p\">,<\/span> <span class=\"n\">timezone<\/span><span class=\"p\">,<\/span> <span class=\"n\">timedelta<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"nn\">azure.identity<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">DefaultAzureCredential<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"nn\">azure.mgmt.resource<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">SubscriptionClient<\/span>\r\n<span class=\"kn\">from<\/span> <span class=\"nn\">azure.mgmt.costmanagement<\/span> <span class=\"kn\">import<\/span> <span class=\"n\">CostManagementClient<\/span>\r\n<span class=\"kn\">import<\/span> <span class=\"nn\">requests<\/span>\r\n<span class=\"kn\">import<\/span> <span class=\"nn\">pandas<\/span> <span class=\"k\">as<\/span> <span class=\"n\">pd<\/span>\r\n\r\n\r\n<span class=\"c1\"># Teams_endpoint = 'Microsoft Teams\u306e \u30c1\u30e3\u30cd\u30eb\u30a8\u30f3\u30c9\u30dd\u30a4\u30f3\u30c8(Webhook)'\r\n<\/span><span class=\"n\">TEAMS_ENDPOINT<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"s\">\"TECH_ALL\"<\/span><span class=\"p\">:<\/span> <span class=\"n\">os<\/span><span class=\"p\">.<\/span><span class=\"n\">environ<\/span><span class=\"p\">[<\/span><span class=\"s\">'ENDPOINT_TECH'<\/span><span class=\"p\">]<\/span>\r\n<span class=\"p\">}<\/span>\r\n\r\n\r\n<span class=\"c1\"># \u63a5\u7d9a\u3057\u3066\u3044\u308b\u30c6\u30ca\u30f3\u30c8\u306e\u30b5\u30d6\u30b9\u30af\u30ea\u30d7\u30b7\u30e7\u30f3\u3092\u64cd\u4f5c\u3059\u308b\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u53d6\u5f97\r\n<\/span><span class=\"k\">def<\/span> <span class=\"nf\">GetSubscriptionObject<\/span><span class=\"p\">():<\/span>\r\n    <span class=\"n\">subscription_client<\/span> <span class=\"o\">=<\/span> <span class=\"n\">SubscriptionClient<\/span><span class=\"p\">(<\/span>\r\n        <span class=\"n\">credential<\/span><span class=\"o\">=<\/span><span class=\"n\">DefaultAzureCredential<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"p\">)<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">subscription_client<\/span>\r\n\r\n\r\n<span class=\"c1\"># CostManagement\u60c5\u5831 \u3092\u64cd\u4f5c\u3059\u308b\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u3092\u53d6\u5f97\r\n<\/span><span class=\"k\">def<\/span> <span class=\"nf\">GetCostManagementObject<\/span><span class=\"p\">():<\/span>\r\n    <span class=\"n\">costmgmt_client<\/span> <span class=\"o\">=<\/span> <span class=\"n\">CostManagementClient<\/span><span class=\"p\">(<\/span>\r\n        <span class=\"n\">credential<\/span><span class=\"o\">=<\/span><span class=\"n\">DefaultAzureCredential<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"p\">)<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">costmgmt_client<\/span>\r\n\r\n\r\n<span class=\"c1\"># \u6307\u5b9a\u3057\u305f Subscription \u306b\u3064\u3044\u3066 CostManagement \u304b\u3089\u30b3\u30b9\u30c8\u3092\u53d6\u5f97\r\n<\/span><span class=\"k\">def<\/span> <span class=\"nf\">GetCostManagement<\/span><span class=\"p\">(<\/span><span class=\"n\">costmgmt_client<\/span><span class=\"p\">,<\/span> <span class=\"n\">subs_id<\/span><span class=\"p\">):<\/span>\r\n\r\n    <span class=\"c1\"># Query costmanagement\r\n<\/span>    <span class=\"n\">SCOPE<\/span> <span class=\"o\">=<\/span> <span class=\"s\">'\/subscriptions\/{}'<\/span><span class=\"p\">.<\/span><span class=\"nb\">format<\/span><span class=\"p\">(<\/span><span class=\"n\">subs_id<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">costmanagement<\/span> <span class=\"o\">=<\/span> <span class=\"n\">costmgmt_client<\/span><span class=\"p\">.<\/span><span class=\"n\">query<\/span><span class=\"p\">.<\/span><span class=\"n\">usage<\/span><span class=\"p\">(<\/span>\r\n        <span class=\"n\">SCOPE<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"p\">{<\/span>\r\n            <span class=\"s\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s\">\"Usage\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"s\">\"timeframe\"<\/span><span class=\"p\">:<\/span> <span class=\"s\">\"MonthToDate\"<\/span><span class=\"p\">,<\/span>\r\n            <span class=\"s\">\"dataset\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n                <span class=\"s\">\"granularity\"<\/span><span class=\"p\">:<\/span> <span class=\"s\">\"None\"<\/span><span class=\"p\">,<\/span>\r\n                <span class=\"s\">\"aggregation\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n                    <span class=\"s\">\"totalCost\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">{<\/span>\r\n                        <span class=\"s\">\"name\"<\/span><span class=\"p\">:<\/span> <span class=\"s\">\"PreTaxCost\"<\/span><span class=\"p\">,<\/span>\r\n                        <span class=\"s\">\"function\"<\/span><span class=\"p\">:<\/span> <span class=\"s\">\"Sum\"<\/span>\r\n                    <span class=\"p\">}<\/span>\r\n                <span class=\"p\">},<\/span>\r\n                <span class=\"s\">\"grouping\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n                    <span class=\"p\">{<\/span>\r\n                        <span class=\"s\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s\">\"Dimension\"<\/span><span class=\"p\">,<\/span>\r\n                        <span class=\"s\">\"name\"<\/span><span class=\"p\">:<\/span> <span class=\"s\">\"ResourceGroup\"<\/span>\r\n                    <span class=\"p\">}<\/span>\r\n                <span class=\"p\">]<\/span>\r\n            <span class=\"p\">}<\/span>\r\n        <span class=\"p\">}<\/span>\r\n    <span class=\"p\">)<\/span>\r\n    <span class=\"k\">return<\/span> <span class=\"n\">costmanagement<\/span>\r\n\r\n\r\n<span class=\"c1\"># \u30b5\u30d6\u30b9\u30af\u30ea\u30d7\u30b7\u30e7\u30f3ID\u3092\u6307\u5b9a\u3057\u30ea\u30bd\u30fc\u30b9\u30b0\u30eb\u30fc\u30d7\u6bce\u306b CostManagement\u60c5\u5831\u3092\u53d6\u5f97\r\n<\/span><span class=\"k\">def<\/span> <span class=\"nf\">GetSubscriptionCsotManagement<\/span><span class=\"p\">(<\/span><span class=\"n\">day0<\/span><span class=\"p\">):<\/span>\r\n\r\n    <span class=\"c1\"># \u30b5\u30d6\u30b9\u30af\u30ea\u30d7\u30b7\u30e7\u30f3\u3092\u64cd\u4f5c\u3059\u308b\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u53d6\u5f97\r\n<\/span>    <span class=\"n\">subscription_list<\/span> <span class=\"o\">=<\/span> <span class=\"n\">GetSubscriptionObject<\/span><span class=\"p\">()<\/span>    \r\n\r\n    <span class=\"c1\"># CostManagement\u3092\u64cd\u4f5c\u3059\u308b\u30aa\u30d6\u30b8\u30a7\u30af\u30c8\u306e\u53d6\u5f97\r\n<\/span>    <span class=\"n\">costmgmt_client<\/span> <span class=\"o\">=<\/span> <span class=\"n\">GetCostManagementObject<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"c1\"># \u53d6\u5f97\u30b3\u30b9\u30c8\u306e \u30ad\u30fc\u3068\u5024\r\n<\/span>    <span class=\"n\">row_key<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"s\">\"Subscription\"<\/span><span class=\"p\">,<\/span> <span class=\"s\">\"UsageCost\"<\/span><span class=\"p\">]<\/span>\r\n    <span class=\"n\">row_value<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[]<\/span>\r\n\r\n    <span class=\"c1\"># \u30b5\u30d6\u30b9\u30af\u30ea\u30d7\u30b7\u30e7\u30f3\u6bce\u306b CostManagement \u304b\u3089\u30b3\u30b9\u30c8\u3092\u53d6\u5f97\r\n<\/span>    <span class=\"k\">for<\/span> <span class=\"n\">n<\/span><span class=\"p\">,<\/span> <span class=\"n\">subs<\/span> <span class=\"ow\">in<\/span> <span class=\"nb\">enumerate<\/span><span class=\"p\">(<\/span><span class=\"n\">subscription_list<\/span><span class=\"p\">.<\/span><span class=\"n\">subscriptions<\/span><span class=\"p\">.<\/span><span class=\"nb\">list<\/span><span class=\"p\">()):<\/span>\r\n        <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"n\">info<\/span><span class=\"p\">(<\/span><span class=\"s\">\"<\/span><span class=\"se\">\\n<\/span><span class=\"s\">\u30b5\u30d6\u30b9\u30af\u30ea\u30d7\u30b7\u30e7\u30f3 \uff1a {}\"<\/span><span class=\"p\">.<\/span><span class=\"nb\">format<\/span><span class=\"p\">(<\/span><span class=\"n\">subs<\/span><span class=\"p\">.<\/span><span class=\"n\">display_name<\/span><span class=\"p\">))<\/span>\r\n        <span class=\"n\">costmanagement<\/span> <span class=\"o\">=<\/span> <span class=\"n\">GetCostManagement<\/span><span class=\"p\">(<\/span><span class=\"n\">costmgmt_client<\/span><span class=\"p\">,<\/span> <span class=\"n\">subs<\/span><span class=\"p\">.<\/span><span class=\"n\">subscription_id<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"c1\"># rows\u30ab\u30e9\u30e0\u30c7\u30fc\u30bf\u3092\u53d6\u5f97\u3057\u3001\u30b3\u30b9\u30c8\u306e\u5408\u8a08\u5024\u306e\u53d6\u5f97\r\n<\/span>        <span class=\"n\">SubTotalCost<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">sum<\/span><span class=\"p\">(<\/span><span class=\"n\">cost<\/span><span class=\"p\">[<\/span><span class=\"mi\">0<\/span><span class=\"p\">]<\/span> <span class=\"k\">for<\/span> <span class=\"n\">cost<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">costmanagement<\/span><span class=\"p\">.<\/span><span class=\"n\">rows<\/span><span class=\"p\">)<\/span>\r\n\r\n        <span class=\"c1\"># \u8868\u793a\u3055\u305b\u308b\u30b3\u30b9\u30c8\u30c7\u30fc\u30bf\u306e\u30ea\u30b9\u30c8\u5316\r\n<\/span>        <span class=\"k\">if<\/span> <span class=\"n\">SubTotalCost<\/span> <span class=\"o\">&gt;<\/span> <span class=\"mi\">0<\/span> <span class=\"p\">:<\/span>   \r\n            <span class=\"n\">val<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"n\">subs<\/span><span class=\"p\">.<\/span><span class=\"n\">display_name<\/span><span class=\"p\">,<\/span> <span class=\"nb\">round<\/span><span class=\"p\">(<\/span><span class=\"n\">SubTotalCost<\/span><span class=\"p\">)]<\/span>\r\n            <span class=\"n\">row_value<\/span><span class=\"p\">.<\/span><span class=\"n\">append<\/span><span class=\"p\">(<\/span><span class=\"n\">val<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"c1\"># \u53d6\u5f97\u3057\u305f\u30b3\u30b9\u30c8\u60c5\u5831\u3092\u8f9e\u66f8\u578b\u306b\u5909\u63db\r\n<\/span>    <span class=\"n\">row_dict<\/span> <span class=\"o\">=<\/span> <span class=\"p\">[<\/span><span class=\"nb\">dict<\/span><span class=\"p\">(<\/span><span class=\"nb\">zip<\/span><span class=\"p\">(<\/span><span class=\"n\">row_key<\/span><span class=\"p\">,<\/span><span class=\"n\">item<\/span><span class=\"p\">))<\/span> <span class=\"k\">for<\/span> <span class=\"n\">item<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">row_value<\/span><span class=\"p\">]<\/span>\r\n\r\n    <span class=\"c1\"># \u30b3\u30b9\u30c8\u3067\u964d\u9806\u30bd\u30fc\u30c8\u3059\u308b\r\n<\/span>    <span class=\"n\">rows<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">sorted<\/span><span class=\"p\">(<\/span><span class=\"n\">row_dict<\/span><span class=\"p\">,<\/span> <span class=\"n\">key<\/span><span class=\"o\">=<\/span><span class=\"k\">lambda<\/span> <span class=\"n\">x<\/span><span class=\"p\">:<\/span><span class=\"n\">x<\/span><span class=\"p\">[<\/span><span class=\"s\">'UsageCost'<\/span><span class=\"p\">],<\/span> <span class=\"n\">reverse<\/span><span class=\"o\">=<\/span><span class=\"bp\">True<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"n\">info<\/span><span class=\"p\">(<\/span><span class=\"n\">rows<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"c1\"># \u53d6\u5f97\u3057\u305f\u30c7\u30fc\u30bf\u3092 DataFrame\u5316\u304b\u3089 markdown \u5f62\u5f0f\u306b\u5909\u63db\r\n<\/span>    <span class=\"n\">df<\/span><span class=\"o\">=<\/span><span class=\"n\">pd<\/span><span class=\"p\">.<\/span><span class=\"n\">DataFrame<\/span><span class=\"p\">(<\/span><span class=\"n\">rows<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">teames_post_str<\/span> <span class=\"o\">=<\/span> <span class=\"n\">df<\/span><span class=\"p\">.<\/span><span class=\"n\">to_markdown<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"c1\"># \u30b3\u30b9\u30c8\u306e\u5408\u8a08\u5024\u306e\u53d6\u5f97\r\n<\/span>    <span class=\"n\">TotalCost<\/span> <span class=\"o\">=<\/span> <span class=\"nb\">sum<\/span><span class=\"p\">(<\/span><span class=\"n\">cost<\/span><span class=\"p\">[<\/span><span class=\"mi\">1<\/span><span class=\"p\">]<\/span> <span class=\"k\">for<\/span> <span class=\"n\">cost<\/span> <span class=\"ow\">in<\/span> <span class=\"n\">row_value<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"n\">info<\/span><span class=\"p\">(<\/span><span class=\"s\">\"<\/span><span class=\"se\">\\n<\/span><span class=\"s\"> \u30b3\u30b9\u30c8\u5408\u8a08: \u00a5{:,}\"<\/span><span class=\"p\">.<\/span><span class=\"nb\">format<\/span><span class=\"p\">(<\/span><span class=\"n\">TotalCost<\/span><span class=\"p\">)<\/span> <span class=\"o\">+<\/span> <span class=\"s\">\"<\/span><span class=\"se\">\\n<\/span><span class=\"s\">\"<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">costmgmt_client<\/span><span class=\"p\">.<\/span><span class=\"n\">close<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"n\">subscription_list<\/span><span class=\"p\">.<\/span><span class=\"n\">close<\/span><span class=\"p\">()<\/span>\r\n\r\n    <span class=\"c1\"># TeamsEndpoint\u3078\u306ePOST\r\n<\/span>    <span class=\"n\">teams_endpoint_post_summary<\/span><span class=\"p\">(<\/span><span class=\"n\">teames_post_str<\/span><span class=\"p\">,<\/span> <span class=\"s\">'{:,}'<\/span><span class=\"p\">.<\/span><span class=\"nb\">format<\/span><span class=\"p\">(<\/span><span class=\"n\">TotalCost<\/span><span class=\"p\">),<\/span> <span class=\"n\">day0<\/span><span class=\"p\">)<\/span>\r\n\r\n\r\n<span class=\"c1\"># TeamsEndpoint\u3078\u306e\u30c7\u30fc\u30bfPOST\uff08\u307e\u3068\u3081\uff09\r\n<\/span><span class=\"k\">def<\/span> <span class=\"nf\">teams_endpoint_post_summary<\/span><span class=\"p\">(<\/span><span class=\"n\">teames_post_str<\/span><span class=\"p\">,<\/span> <span class=\"n\">TotalCost<\/span><span class=\"p\">,<\/span> <span class=\"n\">day0<\/span><span class=\"p\">):<\/span>\r\n    <span class=\"c1\"># Microsoft Teams \u3078\u9001\u4fe1\u3059\u308b\u4e0b\u3054\u3057\u3089\u3048\r\n<\/span>    <span class=\"n\">request<\/span> <span class=\"o\">=<\/span> <span class=\"p\">{<\/span>\r\n        <span class=\"s\">'title'<\/span><span class=\"p\">:<\/span>  <span class=\"s\">'\u3010 Azure : '<\/span> <span class=\"o\">+<\/span> <span class=\"n\">day0<\/span> <span class=\"o\">+<\/span> <span class=\"s\">' \u3011 \u5408\u8a08\uff1a \u00a5 '<\/span> <span class=\"o\">+<\/span> <span class=\"n\">TotalCost<\/span><span class=\"p\">,<\/span>\r\n        <span class=\"s\">'text'<\/span><span class=\"p\">:<\/span> <span class=\"n\">teames_post_str<\/span>\r\n    <span class=\"p\">}<\/span>\r\n\r\n    <span class=\"c1\"># \u74b0\u5883\u5909\u6570\u306e\u78ba\u8a8d\r\n<\/span>    <span class=\"k\">try<\/span> <span class=\"p\">:<\/span>\r\n        <span class=\"n\">endpointurl<\/span> <span class=\"o\">=<\/span> <span class=\"n\">TEAMS_ENDPOINT<\/span><span class=\"p\">[<\/span><span class=\"s\">'TECH_ALL'<\/span><span class=\"p\">]<\/span>    \r\n    <span class=\"k\">except<\/span> <span class=\"nb\">KeyError<\/span> <span class=\"p\">:<\/span>\r\n        <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"n\">info<\/span><span class=\"p\">(<\/span><span class=\"s\">\"<\/span><span class=\"se\">\\n<\/span><span class=\"s\"> ENDPOINT\u306e\u74b0\u5883\u5909\u6570\u304c\u5b9a\u7fa9\u3055\u308c\u3066\u3044\u307e\u305b\u3093\uff01\"<\/span><span class=\"p\">)<\/span>\r\n        <span class=\"k\">return<\/span>\r\n\r\n    <span class=\"c1\"># Microsoft Teams \u3078\u9001\u4fe1\u3059\u308b\r\n<\/span>    <span class=\"n\">response<\/span> <span class=\"o\">=<\/span> <span class=\"n\">requests<\/span><span class=\"p\">.<\/span><span class=\"n\">post<\/span><span class=\"p\">(<\/span><span class=\"n\">endpointurl<\/span><span class=\"p\">,<\/span> <span class=\"n\">json<\/span><span class=\"p\">.<\/span><span class=\"n\">dumps<\/span><span class=\"p\">(<\/span><span class=\"n\">request<\/span><span class=\"p\">))<\/span>\r\n    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"n\">info<\/span><span class=\"p\">(<\/span><span class=\"n\">response<\/span><span class=\"p\">)<\/span>\r\n\r\n\r\n<span class=\"k\">def<\/span> <span class=\"nf\">main<\/span><span class=\"p\">(<\/span><span class=\"n\">mytimer<\/span><span class=\"p\">:<\/span> <span class=\"n\">func<\/span><span class=\"p\">.<\/span><span class=\"n\">TimerRequest<\/span><span class=\"p\">)<\/span> <span class=\"o\">-&gt;<\/span> <span class=\"bp\">None<\/span><span class=\"p\">:<\/span>\r\n    <span class=\"c1\"># \u65e5\u672c\u6642\u9593\u306e\u53d6\u5f97\r\n<\/span>    <span class=\"n\">JST<\/span> <span class=\"o\">=<\/span> <span class=\"n\">timezone<\/span><span class=\"p\">(<\/span><span class=\"n\">timedelta<\/span><span class=\"p\">(<\/span><span class=\"n\">hours<\/span><span class=\"o\">=+<\/span><span class=\"mi\">9<\/span><span class=\"p\">),<\/span> <span class=\"s\">'JST'<\/span><span class=\"p\">)<\/span>\r\n    <span class=\"n\">today<\/span> <span class=\"o\">=<\/span> <span class=\"n\">datetime<\/span><span class=\"p\">.<\/span><span class=\"n\">now<\/span><span class=\"p\">(<\/span><span class=\"n\">JST<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"k\">if<\/span> <span class=\"n\">mytimer<\/span><span class=\"p\">.<\/span><span class=\"n\">past_due<\/span><span class=\"p\">:<\/span>\r\n        <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"n\">info<\/span><span class=\"p\">(<\/span><span class=\"s\">'\u25a0 \u25a0 \u25a0 The timer is past due! \u25a0 \u25a0 \u25a0'<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"n\">info<\/span><span class=\"p\">(<\/span><span class=\"s\">'\u25a0 \u25a0 \u25a0 Python timer trigger function (func-CostSummary) ran at %s \u25a0 \u25a0 \u25a0'<\/span><span class=\"p\">,<\/span> <span class=\"n\">today<\/span><span class=\"p\">)<\/span>\r\n\r\n    <span class=\"n\">start<\/span> <span class=\"o\">=<\/span> <span class=\"n\">time<\/span><span class=\"p\">.<\/span><span class=\"n\">time<\/span><span class=\"p\">()<\/span>\r\n    <span class=\"n\">GetSubscriptionCsotManagement<\/span><span class=\"p\">(<\/span><span class=\"n\">today<\/span><span class=\"p\">.<\/span><span class=\"n\">strftime<\/span><span class=\"p\">(<\/span><span class=\"s\">\"%Y-%m-%d\"<\/span><span class=\"p\">))<\/span>\r\n    <span class=\"n\">generate_time<\/span> <span class=\"o\">=<\/span> <span class=\"n\">time<\/span><span class=\"p\">.<\/span><span class=\"n\">time<\/span><span class=\"p\">()<\/span> <span class=\"o\">-<\/span> <span class=\"n\">start<\/span>\r\n\r\n    <span class=\"n\">logging<\/span><span class=\"p\">.<\/span><span class=\"n\">info<\/span><span class=\"p\">(<\/span><span class=\"s\">\"\u51e6\u7406\u6642\u9593:{0}\"<\/span><span class=\"p\">.<\/span><span class=\"nb\">format<\/span><span class=\"p\">(<\/span><span class=\"n\">generate_time<\/span><span class=\"p\">)<\/span> <span class=\"o\">+<\/span> <span class=\"s\">\" [sec]\"<\/span><span class=\"p\">)<\/span>\r\n<\/code><\/pre>\n<h3>\u5b9a\u4e49\u6240\u9700\u7684Python\u8f6f\u4ef6\u5305\u6765\u6267\u884c<\/h3>\n<pre class=\"post-pre\"><code>azure-functions\r\nazure-identity\r\nazure-mgmt-resource\r\nazure-mgmt-costmanagement\r\ntabulate\r\nrequests\r\npandas\r\n<\/code><\/pre>\n<h3>\u8a2d\u5b9a\u57f7\u884c\u6642\u9593\u8868\uff08\u5b9a\u6642\u89f8\u767c\u5668\uff09\u3002<\/h3>\n<p>\u6bcf\u5929\u5728\u65e5\u672c\u65f6\u95f417:20:00\uff08\u6bcf\u5929\u5728\u534f\u8c03\u4e16\u754c\u65f68:20:00\uff09\u6267\u884c\u3002<\/p>\n<pre class=\"post-pre\"><code><span class=\"p\">{<\/span>\r\n  <span class=\"nl\">\"scriptFile\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"__init__.py\"<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nl\">\"bindings\"<\/span><span class=\"p\">:<\/span> <span class=\"p\">[<\/span>\r\n    <span class=\"p\">{<\/span>\r\n      <span class=\"nl\">\"name\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"mytimer\"<\/span><span class=\"p\">,<\/span>\r\n      <span class=\"nl\">\"type\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"timerTrigger\"<\/span><span class=\"p\">,<\/span>\r\n      <span class=\"nl\">\"direction\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"in\"<\/span><span class=\"p\">,<\/span>\r\n      <span class=\"nl\">\"schedule\"<\/span><span class=\"p\">:<\/span> <span class=\"s2\">\"0 20 8 * * *\"<\/span>\r\n    <span class=\"p\">}<\/span>\r\n  <span class=\"p\">]<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<hr \/>\n<h2>\u672c\u5730\u6d4b\u8bd5<\/h2>\n<h3>\u8fd0\u884c\u7a0b\u5e8f<\/h3>\n<pre class=\"post-pre\"><code>## Python\u30d1\u30c3\u30b1\u30fc\u30b8\u306e\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\r\n(.venv) (base)$ pip install -r requirements.txt\r\n\r\n##  Azure Functions \u69cb\u6210\u60c5\u5831\u306e\u30ed\u30fc\u30ab\u30eb\u306b\u8a2d\u5b9a\r\n(.venv) (base)$ func azure functionapp fetch-app-settings &lt;Functions\u540d&gt;\r\nApp Settings:\r\nLoading FUNCTIONS_WORKER_RUNTIME = *****\r\nLoading FUNCTIONS_EXTENSION_VERSION = *****\r\nLoading AzureWebJobsStorage = *****\r\nLoading WEBSITE_CONTENTAZUREFILECONNECTIONSTRING = *****\r\nLoading WEBSITE_CONTENTSHARE = *****\r\nLoading APPINSIGHTS_INSTRUMENTATIONKEY = *****\r\nLoading AZURE_TENANT_ID = *****\r\nLoading AZURE_CLIENT_ID = *****\r\nLoading AZURE_CLIENT_SECRET = *****\r\nLoading ENDPOINT_TECH = *****\r\n\r\nConnection Strings:\r\n\r\n## \u30ed\u30fc\u30ab\u30eb\u74b0\u5883\u3067\u306e\u5b9f\u884c\r\n(.venv) (base)$ source ..\/.venv\/bin\/activate\r\n(.venv) (base)$ func start --verbose\r\nFound Python version 3.8.3 (python3).\r\n\r\n                  %%%%%%\r\n                 %%%%%%\r\n            @   %%%%%%    @\r\n          @@   %%%%%%      @@\r\n       @@@    %%%%%%%%%%%    @@@\r\n     @@      %%%%%%%%%%        @@\r\n       @@         %%%%       @@\r\n         @@      %%%       @@\r\n           @@    %%      @@\r\n                %%\r\n                %\r\n\r\n\r\nAzure Functions Core Tools\r\nCore Tools Version:       3.0.3785 Commit hash: db6fe71b2f05d09757179d5618a07bba4b28826f  (64-bit)\r\nFunction Runtime Version: 3.2.0.0\r\n         :\r\n        \u7701\u7565\r\n         :\r\n[2021-10-02T03:48:00.398Z] Host started (526ms)\r\n[2021-10-02T03:48:00.398Z] Job host started\r\n[2021-10-02T03:48:04.946Z] Host lock lease acquired by instance ID '000000000000000000000000FFFFFFFF'.\r\n         :\r\n        \u7701\u7565\r\n         :\r\n<\/code><\/pre>\n<hr \/>\n<h2>\u5c06\u5e94\u7528\u7a0b\u5e8f\u90e8\u7f72\u5230Azure<\/h2>\n<h3>\u6267\u884c\u90e8\u7f72<\/h3>\n<pre class=\"post-pre\"><code>(.venv) (base)$ func azure functionapp publish &lt;Functions\u540d&gt;\r\nUploading 7.01 KB [###############################################################################]\r\nRemote build in progress, please wait...\r\n         :\r\n        \u7701\u7565\r\n         :\r\nUploading built content \/home\/site\/artifacts\/functionappartifact.squashfs for linux consumption function app...\r\nResetting all workers for func-costsummary.azurewebsites.net\r\nDeployment successful.\r\nRemote build succeeded!\r\nSyncing triggers...\r\nFunctions in func-CostSummary:\r\n    CostSummaryDaily - [timerTrigger]\r\n<\/code><\/pre>\n<p>\u53ea\u9700\u8981\u5728\u65f6\u95f4\u5230\u8fbe\u65f6\u786e\u8ba4\u6bcf\u5929\u7684Azure\u4f7f\u7528\u8d39\u7528\u901a\u77e5\u662f\u5426\u53d1\u9001\u5230Teams\u6307\u5b9a\u7684\u9891\u9053\u3002<\/p>\n<hr \/>\n<h3>\u603b\u7ed3<\/h3>\n<p>\u867d\u7136\u9047\u5230\u4e86\u5404\u79cd\u95ee\u9898\uff0c\u4f46\u7ec8\u4e8e\u6210\u529f\u5728Azure Functions\u4e0a\u8fd0\u884c\u4e86\u6211\u81ea\u5df1\u5f00\u53d1\u7684Python\u7a0b\u5e8f\u3002Azure Function \u597d\u9ebb\u70e6\uff0c\u6211\u5e0c\u671b\u80fd\u591f\u6709\u50cfAWS\u4e00\u6837\u7b80\u5355\u987a\u7545\u7684\u4f53\u9a8c\u3002<\/p>\n<h3>\u8bf7\u53c2\u8003\u4e0b\u6587<\/h3>\n<p>\u770b\u5230\u4ee5\u4e0b\u7684\u6587\u7ae0\uff0c\u6211\u53d7\u76ca\u532a\u6d45\uff0c\u975e\u5e38\u611f\u8c22\u3002<br \/>\n\u5728Mac\u4e0a\u5b89\u88c5Python3\u5e76\u914d\u7f6e\u73af\u5883\u3010\u6700\u7ec8\u7248\u3011<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u603b\u7ed3 \u5c06\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u7684Python\u7a0b\u5e8f\u6ce8\u518c\u5230Azure Functions\u5e76\u81ea\u52a8\u8fd0\u884c\uff0c\u7136\u540e\u5c06\u7ed3\u679c\u4f5c\u4e3aTemas\u516c [&hellip;]<\/p>\n","protected":false},"author":11,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-47296","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v21.5 (Yoast SEO v21.5) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>\u6211\u5c1d\u8bd5\u5c06Azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230Teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\u7f16\u3011 - Blog - Silicon Cloud<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.silicloud.com\/zh\/blog\/\u6211\u5c1d\u8bd5\u5c06azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\/\" \/>\n<meta property=\"og:locale\" content=\"zh_CN\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"\u6211\u5c1d\u8bd5\u5c06Azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230Teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\u7f16\u3011\" \/>\n<meta property=\"og:description\" content=\"\u603b\u7ed3 \u5c06\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u7684Python\u7a0b\u5e8f\u6ce8\u518c\u5230Azure Functions\u5e76\u81ea\u52a8\u8fd0\u884c\uff0c\u7136\u540e\u5c06\u7ed3\u679c\u4f5c\u4e3aTemas\u516c [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.silicloud.com\/zh\/blog\/\u6211\u5c1d\u8bd5\u5c06azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\/\" \/>\n<meta property=\"og:site_name\" content=\"Blog - Silicon Cloud\" \/>\n<meta property=\"article:published_time\" content=\"2023-06-16T11:23:59+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-05-04T04:57:59+00:00\" \/>\n<meta name=\"author\" content=\"\u65b0, \u97f5\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u4f5c\u8005\" \/>\n\t<meta name=\"twitter:data1\" content=\"\u65b0, \u97f5\" \/>\n\t<meta name=\"twitter:label2\" content=\"\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 \u5206\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/\",\"name\":\"\u6211\u5c1d\u8bd5\u5c06Azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230Teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\u7f16\u3011 - Blog - Silicon Cloud\",\"isPartOf\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\"},\"datePublished\":\"2023-06-16T11:23:59+00:00\",\"dateModified\":\"2024-05-04T04:57:59+00:00\",\"author\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/4ba4019495123db3038fd0809e6959c9\"},\"breadcrumb\":{\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/#breadcrumb\"},\"inLanguage\":\"zh-Hans\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"\u9996\u9875\",\"item\":\"https:\/\/www.silicloud.com\/zh\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"\u6211\u5c1d\u8bd5\u5c06Azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230Teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\u7f16\u3011\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#website\",\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/\",\"name\":\"Blog - Silicon Cloud\",\"description\":\"\",\"inLanguage\":\"zh-Hans\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/4ba4019495123db3038fd0809e6959c9\",\"name\":\"\u65b0, \u97f5\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d484b6c6e4ae82e8a9efea989e1d2af46d9b6ef128101e63b18f559fca0ae627?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d484b6c6e4ae82e8a9efea989e1d2af46d9b6ef128101e63b18f559fca0ae627?s=96&d=mm&r=g\",\"caption\":\"\u65b0, \u97f5\"},\"url\":\"https:\/\/www.silicloud.com\/zh\/blog\/author\/yunxin\/\"},{\"@type\":\"ImageObject\",\"inLanguage\":\"zh-Hans\",\"@id\":\"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/#local-main-organization-logo\",\"url\":\"\",\"contentUrl\":\"\",\"caption\":\"Blog - Silicon Cloud\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\u6211\u5c1d\u8bd5\u5c06Azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230Teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\u7f16\u3011 - Blog - Silicon Cloud","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.silicloud.com\/zh\/blog\/\u6211\u5c1d\u8bd5\u5c06azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\/","og_locale":"zh_CN","og_type":"article","og_title":"\u6211\u5c1d\u8bd5\u5c06Azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230Teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\u7f16\u3011","og_description":"\u603b\u7ed3 \u5c06\u8fd9\u7bc7\u6587\u7ae0\u4e2d\u7684Python\u7a0b\u5e8f\u6ce8\u518c\u5230Azure Functions\u5e76\u81ea\u52a8\u8fd0\u884c\uff0c\u7136\u540e\u5c06\u7ed3\u679c\u4f5c\u4e3aTemas\u516c [&hellip;]","og_url":"https:\/\/www.silicloud.com\/zh\/blog\/\u6211\u5c1d\u8bd5\u5c06azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\/","og_site_name":"Blog - Silicon Cloud","article_published_time":"2023-06-16T11:23:59+00:00","article_modified_time":"2024-05-04T04:57:59+00:00","author":"\u65b0, \u97f5","twitter_card":"summary_large_image","twitter_misc":{"\u4f5c\u8005":"\u65b0, \u97f5","\u9884\u8ba1\u9605\u8bfb\u65f6\u95f4":"6 \u5206"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/","url":"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/","name":"\u6211\u5c1d\u8bd5\u5c06Azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230Teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\u7f16\u3011 - Blog - Silicon Cloud","isPartOf":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website"},"datePublished":"2023-06-16T11:23:59+00:00","dateModified":"2024-05-04T04:57:59+00:00","author":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/4ba4019495123db3038fd0809e6959c9"},"breadcrumb":{"@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/#breadcrumb"},"inLanguage":"zh-Hans","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"\u9996\u9875","item":"https:\/\/www.silicloud.com\/zh\/blog\/"},{"@type":"ListItem","position":2,"name":"\u6211\u5c1d\u8bd5\u5c06Azure\u7684\u4f7f\u7528\u8d39\u7528\u53d1\u5e03\u5230Teams\u7684\u9891\u9053\u4e2d\u3010\u8ba2\u9605-\u65e5\u62a5\u7f16\u3011"}]},{"@type":"WebSite","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#website","url":"https:\/\/www.silicloud.com\/zh\/blog\/","name":"Blog - Silicon Cloud","description":"","inLanguage":"zh-Hans"},{"@type":"Person","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/4ba4019495123db3038fd0809e6959c9","name":"\u65b0, \u97f5","image":{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d484b6c6e4ae82e8a9efea989e1d2af46d9b6ef128101e63b18f559fca0ae627?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d484b6c6e4ae82e8a9efea989e1d2af46d9b6ef128101e63b18f559fca0ae627?s=96&d=mm&r=g","caption":"\u65b0, \u97f5"},"url":"https:\/\/www.silicloud.com\/zh\/blog\/author\/yunxin\/"},{"@type":"ImageObject","inLanguage":"zh-Hans","@id":"https:\/\/www.silicloud.com\/zh\/blog\/%e6%88%91%e5%b0%9d%e8%af%95%e5%b0%86azure%e7%9a%84%e4%bd%bf%e7%94%a8%e8%b4%b9%e7%94%a8%e5%8f%91%e5%b8%83%e5%88%b0teams%e7%9a%84%e9%a2%91%e9%81%93%e4%b8%ad%e3%80%90%e8%ae%a2%e9%98%85-%e6%97%a5%e6%8a%a5\/#local-main-organization-logo","url":"","contentUrl":"","caption":"Blog - Silicon Cloud"}]}},"_links":{"self":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/47296","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/users\/11"}],"replies":[{"embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/comments?post=47296"}],"version-history":[{"count":2,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/47296\/revisions"}],"predecessor-version":[{"id":98456,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/posts\/47296\/revisions\/98456"}],"wp:attachment":[{"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/media?parent=47296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/categories?post=47296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.silicloud.com\/zh\/blog\/wp-json\/wp\/v2\/tags?post=47296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}