是否可以从 azure 函数中为 EventGrid 生成 TriggerUrl?

Is it possible to generate TriggerUrl for EventGrid from within the azure function?

我的 azure 函数解决方案中有一个 EventGrid 触发器。

我想在 URL 上使用函数 key/code 生成触发器 URL,以便从函数本身内部订阅事件网格主题。但是到目前为止,我找不到获取函数资源 ID 或获取实际代码的方法。可能吗?

我相信您可以使用 Web Apps - List Function Secrets REST API 获取您知道其 resourceId 的函数的触发器 URL。作为参考,这里是 API 根据文档

调用
POST https://management.azure.com/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Web/sites/{name}/functions/{functionName}/listsecrets?api-version=2016-08-01

另请注意,进行此调用时最好使用 Managed Identity

当为该功能启用 MSI 时,我可以获得应用程序的 resourceId 并向 ARM 请求令牌。

    public async Task<JToken> ListHostKeys()
    {
        var handler = new JwtSecurityTokenHandler();
        var jsonToken = handler.ReadToken(this.httpClient.DefaultRequestHeaders.Authorization.Parameter) as JwtSecurityToken;
        var resourceId=jsonToken.Claims.FirstOrDefault(c => c.Type == "xms_mirid")?.Value;
        var rsp = await httpClient.PostAsync($"https://management.azure.com{resourceId}/host/default/listKeys?api-version=2018-11-01", new StringContent(""));
        return JToken.Parse(await rsp.Content.ReadAsStringAsync());
    }

    builder.Services.AddHttpClient<ArmClient>((sp, http) =>
        {
            try
            {
                var tokenProvider = new AzureServiceTokenProvider();

                var accessToken = tokenProvider.GetAccessTokenAsync("https://management.azure.com/").GetAwaiter().GetResult();

                http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", accessToken);
            }
            catch (Exception)
            {

            }
        });

然后在需要回调时 url 我可以执行以下操作:

    private async Task<IOBoardCollection> CreateIOBoardCollectionAsync(JToken unit)
    {
        //Create the collection on io-board.com


            var code = "";
            try
            {
                if (Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME").Contains("azurewebsites"))
                {
                    var keys = await armClient.ListHostKeys();
                    logger.LogInformation("Running on azure wbsites {keys}", keys?.ToString().Substring(10));
                    code = keys.SelectToken("$.systemKeys.eventgrid_extension").ToString();

                }
            }
            catch (Exception ex)
            {
                logger.LogError(ex, "Failed to get code");
            }
            var metadata = unit.ToObject<TrackUnitProperties>();
            metadata.EntityKey = context.EntityKey;

            return await IOBoardClient.CreateCollectionAsync(
                IOBoardClient.SubscriptionId, metadata,
                $"https://{Environment.GetEnvironmentVariable("WEBSITE_HOSTNAME") ?? "io-board.eu.ngrok.io"}/runtime/webhooks/EventGrid?functionName=EventGridTrigger&code={code}");



    }