0
votes

I have a Timer Functions (beta version/v2) with that uses the Graph Api. but I get the following error.

I get now this error:

2018-10-10T08:52:34.019 [Error] Microsoft.Azure.WebJobs.Host: Error indexing method 'Functions.TimerTriggerMeetingRoom'. Microsoft.Azure.WebJobs.Host: Unable to resolve binding parameter 'headers'. Binding expressions must map to either a value provided by the trigger or a property of the value the trigger is bound to, or must be a system binding expression (e.g. sys.randguid, sys.utcnow, etc.).

This is my "run.csx" code:

#r "Newtonsoft.Json"
#r "System.Configuration"
#r "System.Data"


using System.Net; 
using System.Net.Http; 
using System.Net.Http.Headers; 
using System.Text;
using System;
using System.Globalization;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;

using System.Configuration;

using System.Threading.Tasks;

public static async Task Run(TimerInfo myTimer, string graphToken, ILogger log)
{
    var currentTime = DateTime.UtcNow;
    var ramsey = new List<Ramsey>();

    log.LogInformation("C# HTTP trigger function processed a request.");

    HttpClient client = new HttpClient();
    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", graphToken);
    var json = await client.GetStringAsync("https://graph.microsoft.com/v1.0/me/");


    log.LogInformation("C# HTTP trigger function processed a request.");
    JObject jResults = JObject.Parse(json);
    //log.LogInformation(jResults.ToString());
    var result= jResults["value"];
    log.LogInformation("value: "+result.ToString());

     return new HttpResponseMessage(HttpStatusCode.OK) 
    {
        Content = new StringContent(json, Encoding.UTF8, "application/json") 
    };
}


public class Ramsey
{
    public string subject { get; set; }
}

"Function.json":

{
  "bindings": [
    {
      "name": "myTimer",
      "type": "timerTrigger",
      "direction": "in",
      "schedule": "0 */15 * * * *"
    },
    {
      "name": "$return",
      "type": "http",
      "direction": "out"
    },
    {
      "type": "token",
      "name": "graphToken",
      "resource": "https://graph.microsoft.com",
      "identity": "UserFromRequest",
      "direction": "in"
    }
  ]
}

This is instead my "functions.proj" file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.Mobile.Client" Version="2.0.0"/>
    <PackageReference Include="MySql.Data" Version="7.0.7-m61"/>
  </ItemGroup>
</Project>

Please let me know. Thank you in advance

1
You can review the following link for reference: docs.microsoft.com/en-us/azure/azure-functions/…Yuki
Hi, from the Azure Timer Functions how do I get access to Microsoft Graph (graph.microsoft.com) in order to get information regarding the calendar of the user?Filippo

1 Answers

2
votes

The key problem here is the use of "identity": "UserFromRequest" with a timer trigger. That identity mode is only supported with an HttpTrigger, as it pulls the request information from the HTTP request.

For timer driven scenarios, the two best options for identity are clientCredentials or userFromId. clientCredentials is probably not what you want in this case, as you are accessing Graph resources, and the service principal of your function application probably doesn't have anything interesting in the graph.

To use the userFromId identity mode, you need to do the following:

  1. Specify the principal id for the user by adding "userId":"<principalId>" to your function.json
  2. Make sure the user specified above is logged into the function application. This can be accomplished by having the user either directly login themselves at https://<function-app-name>.azurewebsites.net/.auth/login/aad or by having a client make a POST request to the above URL, with the below body (NOTE: all tokens have an audience of the function application):

{ "id_token": "<idToken>", "access_token": "<accessToken>", "refresh_token": "<refreshToken>" }