question

Kim Strasser avatar image
Kim Strasser asked

Are Azure functions better than CloudScript POST methods?

Is it better to make the API call UpdateUserTitleDisplayName in Azure functions instead of the normal cloud script? Why would it be better?

I always check the DesiredDisplayname in cloud script before I call UpdateUserTitleDisplayName. For example, I don't want to allow certain characters in the display name, therefore I always need to check the DesiredDisplayname before updating it.

I call UpdateUserTitleDisplayName like this in the normal cloud script:

function UpdateUserTitleDisplayNameFromCloudScript(DesiredDisplayname, PlayFabId)
{
    var contentBodyTemp = {
        "DisplayName": DesiredDisplayname,
        "PlayFabId": PlayFabId
    };
    
    let url = "https://E5E2C.playfabapi.com/Admin/UpdateUserTitleDisplayName";
    let method = "POST";
    let contentBody = `{"PlayFabId": "${PlayFabId}", "DisplayName": "${DesiredDisplayname}"}`;
    let contentType = "application/json";
    let headers = { "X-SecretKey": "..." };
    let responseString = http.request(url, method, contentBody, contentType, headers);
    let responseJSONObj = JSON.parse(responseString);
    return (responseJSONObj);
}

How can I make the same call in Azure functions?

https://docs.microsoft.com/en-us/azure/azure-functions/functions-create-first-function-vs-code?pivots=programming-language-csharp

I have already created a new function(from the quickstart tutorial) in Visual Studio Code, but I don't know how to make a PlayFab API call in Azure function. How can I call UpdateUserTitleDisplayName in Azure functions?

Can I delete the entire code from the quickstart tutorial in HttpExample.cs and replace it with a UpdateUserTitleDisplayName API call?

CloudScript
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Sarah Zhang avatar image
Sarah Zhang answered

>> Is it better to make the API call UpdateUserTitleDisplayName in Azure functions instead of the normal cloud script? Why would it be better?

As our documentation -- https://docs.microsoft.com/en-us/gaming/playfab/features/automation/cloudscript-af/ said, basing CloudScript on Azure Functions brings a few key improvements, please check the first section for detailed information.

For your case, it would be better to use AzureFunctions to make the API call UpdateUserTitleDisplayName. A major improvement is that it can use C# PlayFab Admin SDK.

>> How can I call UpdateUserTitleDisplayName in Azure functions?Can I delete the entire code from the quickstart tutorial in HttpExample.cs and replace it with a UpdateUserTitleDisplayName API call?

After you follow through our quick start -- https://docs.microsoft.com/en-us/gaming/playfab/features/automation/cloudscript-af/quickstart. You also need to check the code of Azure Functions Example and the CloudScript Plugins for the reference of writing the custom CloudScript using Azure Functions. Specially, you need to follow the comment in the Handlers.cs to upload the local.settings.json file if you want to use this example.

After you set up the full environment, the possible sample code of calling UpdateUserTitleDisplayName would be something like this.

using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using PlayFab;
using PlayFab.AdminModels;
using PlayFab.Plugins.CloudScript;
using System.Net.Http;
using System.Net.Http.Headers;

namespace PlayFab.FunctionExample
{
    public static class Handlers
    {
        [FunctionName("MakeAPICall")]
        public static async Task<dynamic> MakeApiCall(
            [HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequestMessage req, ILogger log)
        {
            /* Create the function execution's context through the request */
            var context = await FunctionContext<dynamic>.Create(req);
            var args = context.FunctionArgument;

            /* Create the request object through the SDK models */
            var request = new UpdateUserTitleDisplayNameRequest();
            request.PlayFabId = context.CallerEntityProfile.Lineage.MasterPlayerAccountId;
            request.DisplayName = "Sidney";
            /* Use the ApiSettings and AuthenticationContext provided to the function as context for making API calls. */
            var adminApi = new PlayFabAdminInstanceAPI(context.ApiSettings, context.AuthenticationContext);
         
            /* The PlayFabServerAPI SDK methods provide means of making HTTP request to the PlayFab Main Server without any 
             * extra code needed to issue the HTTP requests. */
            return await adminApi.UpdateUserTitleDisplayNameAsync(request);
        }
        
    }
    
}

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Kim Strasser avatar image Kim Strasser commented ·

How can I get the desired display name from the client code in my Azure function? For example, if the player enters the display name "Sidney" in the client code, how can I get this string value in my Azure function?

var result = await PlayFabCloudScriptAPI.ExecuteFunctionAsync(new ExecuteFunctionRequest()
{
    Entity = new PlayFab.CloudScriptModels.EntityKey()
    {
        Id = entityid,
        Type = entitytype,
    },
    FunctionName = "Playfabfunctions",
    FunctionParameter = new Dictionary<string, object>() { { "Sidney", "Displayname" } },
    GeneratePlayStreamEvent = true
});
 
if (result.Error != null)
{
 
}
else
{
    if (result.Result.FunctionResultTooLarge ?? false)
    {
        Console.WriteLine("This can happen if you exceed the limit that can be returned from an Azure Function, See PlayFab Limits Page for details.");
    }
 
    Console.WriteLine("The " + result.Result.FunctionName + "function took " + result.Result.ExecutionTimeMilliseconds.ToString() + " to complete.");
    Console.WriteLine(result.Result.FunctionResult.ToString());
}

How can I get the display name here in my Azure function?

request.DisplayName = 
0 Likes 0 ·
Kim Strasser avatar image
Kim Strasser answered

It's not working. I get this error message in the client code: "Invocation of cloud script function Playfabfunctions failed"

What is wrong with my function?

Client code:

var result = await PlayFabCloudScriptAPI.ExecuteFunctionAsync(new ExecuteFunctionRequest()
{
    Entity = new PlayFab.CloudScriptModels.EntityKey()
    {
        Id = entityid,
        Type = entitytype,
    },
    FunctionName = "Playfabfunctions",
    FunctionParameter = new Dictionary<string, object>() { { "inputValue", "Test" } },
    GeneratePlayStreamEvent = true
});

if (result.Error != null)
{

}
else
{
    if (result.Result.FunctionResultTooLarge ?? false)
    {
        Console.WriteLine("This can happen if you exceed the limit that can be returned from an Azure Function, See PlayFab Limits Page for details.");
    }

    Console.WriteLine("The " + result.Result.FunctionName + "function took " + result.Result.ExecutionTimeMilliseconds.ToString() + " to complete.");
    Console.WriteLine(result.Result.FunctionResult.ToString());
}

Azure function:

namespace My.Functions
{
   public static class Playfabfunctions
   {
        [FunctionName("Playfabfunctions")]
        public static async Task<dynamic> MakeApiCall(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequestMessage req, ILogger log)
        {
            /* Create the function execution's context through the request */
            var context = await FunctionContext<dynamic>.Create(req);
            var args = context.FunctionArgument;
 
            /* Create the request object through the SDK models */
            var request = new UpdateUserTitleDisplayNameRequest();
            request.PlayFabId = context.CallerEntityProfile.Lineage.MasterPlayerAccountId;
            request.DisplayName = "Sidney";
            /* Use the ApiSettings and AuthenticationContext provided to the function as context for making API calls. */
            var adminApi = new PlayFabAdminInstanceAPI(context.ApiSettings, context.AuthenticationContext);
         
            /* The PlayFabServerAPI SDK methods provide means of making HTTP request to the PlayFab Main Server without any 
             * extra code needed to issue the HTTP requests. */
            return await adminApi.UpdateUserTitleDisplayNameAsync(request);
        }
    }
}

I have chosen "Authorization level: Anonymous" when I created my Azure project in Visual Studio Code. And I have added "PLAYFAB_DEV_SECRET_KEY": "...", and "PLAYFAB_TITLE_ID": "..." to my local.settings.json file.

In addition, I selected the Register Function button in my PlayFab account and I have created the following cloud script function:

Trigger type: HTTP

Function name: Playfabfunctions

Function URL: https://playfabfunctionapp.azurewebsites.net/api/Playfabfunctions

What is wrong with my function?

1 comment
10 |1200

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Sarah Zhang avatar image Sarah Zhang commented ·

As the comment said, In the remote version of your app, these values can either be uploaded on the App through the portal by uploading the same local.settings.json file. Could you try to set the environment variable in the portal? Like the following image shows. Or you can upload the settings as this doc -- https://docs.microsoft.com/en-us/azure/azure-functions/functions-develop-vs-code?tabs=csharp#publish-application-settings said.

0 Likes 0 ·
azureportal.png (108.5 KiB)

Write an Answer

Hint: Notify or tag a user in this post by typing @username.

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.