# PlayFab

Sample PlayFab Azure Cloud Function and legacy Cloud Scripts.

These are server-side PlayFab samples that POST a recorded purchase to the Nexus attributions endpoint. The Azure functions section covers the Azure Cloud Functions runtime and the legacy functions section covers PlayFab's older Cloud Script runtime, each with its own Microsoft quick-start.

## Azure functions

### Prerequisites

1. [Nexus Support-a-Creator getting started guide](/api-quick-start-guide/)
2. [PlayFab Azure Cloud Functions Quick Start Guide](https://docs.microsoft.com/en-us/gaming/playfab/features/automation/cloudscript-af/quickstart)

### Sample Azure cloud function

```csharp
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Threading.Tasks;

namespace MyPlayFabProject.Functions
{
    public static class PushToNexus
    {
        [FunctionName("PushToNexus")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req,
            ILogger log)
        {
            var request = await req.ReadAsStringAsync();
            
            PlayerPlayStreamFunctionExecutionContext<dynamic> context = JsonConvert.DeserializeObject<PlayerPlayStreamFunctionExecutionContext<dynamic>>(request);
            dynamic args = context.FunctionArgument;

            Activity.Current?.AddBaggage("PlayFabId", context.PlayerProfile.PlayerId);

            if (context.PlayStreamEventEnvelope == null || context.PlayStreamEventEnvelope.EventData == null)
            {
                log.LogError("Error: PlayStreamEventEnvelope or EventData was null");
                return new StatusCodeResult(500);
            }

            var purchaseEvent = JsonConvert.DeserializeObject<PlayerRealmoneyPurchase>(context.PlayStreamEventEnvelope.EventData);

            var customTags = (purchaseEvent.CustomTags as JObject).ToObject<NexusCustomTags>();

            var description = customTags.Description;
            var nexusCreatorId = customTags.NexusCreatorId;
            var playerName = customTags.PlayerName;
            var transactionAmount = purchaseEvent.OrderTotal;
            var transactionCurrency = purchaseEvent.TransactionCurrency;
            var transactionDate = DateTime.UtcNow.ToString("o");
            var transactionId = purchaseEvent.TransactionId;

            if (string.IsNullOrEmpty(nexusCreatorId))
            {
                log.LogDebug("Request did not contain nexusCreatorId");
                return new OkResult();
            }

            if (transactionCurrency.ToString().Length == 0)
            {
                log.LogError("Could not find transactionCurrency");
                return new BadRequestResult();
            }

            if (transactionAmount == 0)
            {
                log.LogError("Could not find transactionAmount");
                return new BadRequestResult();
            }

            if (string.IsNullOrEmpty(transactionId))
            {
                log.LogError("Could not find transactionId");
                return new BadRequestResult();
            }

            var contentBody = new Dictionary<string, object>(){
                { "creatorId", nexusCreatorId },
                { "playerName", playerName },
                { "currency", transactionCurrency.ToString() },
                { "description", description },
                { "subtotal", transactionAmount },
                { "transactionId", transactionId },
                { "transactionDate", transactionDate },
            };
            
            var content = JsonConvert.SerializeObject(contentBody);
            var url = "https://api.nexus.gg/v1/attributions/transactions";
            
            using (var client = new WebClient())
            {
                client.Headers.Add(HttpRequestHeader.ContentType, "application/json");
                client.Headers.Add("X-SHARED-SECRET", "nexus_sk_your_key_here");
                
                var responseString = client.UploadString(new Uri(url), "POST", content);
                log.LogDebug("responseString: " + JsonConvert.SerializeObject(responseString));
            }

            return new OkResult();
        }
    }
}
```

<ApiMethod method="POST" path="/attributions/transactions" />

<LinkCard title="View full reference" description="Parameters, responses, and status codes." href="/api/operations/creatorattribution/" />

## Legacy functions

### Prerequisites

1. [Nexus Support-a-Creator getting started guide](/api-quick-start-guide/)
2. [PlayFab Legacy Functions Quick Start Guide](https://docs.microsoft.com/en-us/gaming/playfab/features/automation/cloudscript/quickstart)

### Sample legacy script

```javascript
handlers.pushToNexus = function (args, context) {
    var description = context.playStreamEvent.CustomTags.description;
    var nexusCreatorId = context.playStreamEvent.CustomTags.nexusCreatorId;
    var playerName = context.playStreamEvent.CustomTags.playerName;
    var transactionCurrency = context.playStreamEvent.TransactionCurrency;
    var transactionAmount = context.playStreamEvent.OrderTotal;
    var transactionId = context.playStreamEvent.TransactionId;
    var transactionDate = new Date().toISOString();

    if (nexusCreatorId == null || nexusCreatorId.length == 0) {
        log.debug('Could not find nexusCreatorId');
        return;
    }

    if (transactionCurrency == null || transactionCurrency.length == 0) {
        log.debug('Could not find transactionCurrency');
        return;
    }

    if (transactionAmount == null || transactionAmount.length == 0) {
        log.debug('Could not find transactionAmount');
        return;
    }

    if (transactionId == null || transactionId.length == 0) {
        log.debug('Could not find transactionId');
        return;
    }

    var contentBody = {
        creatorId: nexusCreatorId,
        playerName: playerName,
        currency: transactionCurrency,
        description: description,
        subtotal: transactionAmount,
        transactionId: transactionId,
        transactionDate: transactionDate,
    };
    var contentType = "application/json";
    var headers = {
        'X-SHARED-SECRET': 'nexus_sk_your_key_here'
    };
    var url = "https://api.nexus.gg/v1/attributions/transactions";

    var responseString = http.request(url, "POST", JSON.stringify(contentBody), contentType, headers);
    log.debug('responseString: ' + responseString);
}
```

<ApiMethod method="POST" path="/attributions/transactions" />

<LinkCard title="View full reference" description="Parameters, responses, and status codes." href="/api/operations/creatorattribution/" />
