0

I have list of items which also contains button. I am binding that list via Json . Now I want to trigger goal when some user click on that button.

  • I cannot apply goal on page because I want to trigger goal on button click

  • I tried to use sc_trk but because on click it is redirecting to some other domain, then it is also not working.

  • I tried to call web api on button click but when I am fetching goal item from DB using GetItem method, it is returning null.

Below is my code :

public static bool TriggerGoal(Sitecore.Data.ID goalId)
        {
            if (!Tracker.IsActive)
            {
                Tracker.StartTracking();
            }

            if (Sitecore.Analytics.Tracker.IsActive && Sitecore.Analytics.Tracker.Current.CurrentPage != null)
            {
                Sitecore.Data.Items.Item goalItem = Sitecore.Context.Database.GetItem(goalId); // Getting null value
                if (goalItem != null)
                {
                    var goalTrigger = Sitecore.Analytics.Tracker.MarketingDefinitions.Goals[goalItem.ID.ToGuid()];
                    var goalEventData = Sitecore.Analytics.Tracker.Current.CurrentPage.RegisterGoal(goalTrigger);
                    goalEventData.Data = goalItem["Name"];
                    goalEventData.ItemId = goalItem.ID.ToGuid();
                    goalEventData.DataKey = goalItem.Paths.Path;
                    goalEventData.Text = "Goal for Logic";
                    Sitecore.Analytics.Tracker.Current.Interaction.AcceptModifications();
                }
            }
            return true;
        }
 [HttpGet]
        public IHttpActionResult Get([FromUri] UrlModel model)
        {
TriggerGoal(someguid);
}

Can any one suggest me better approach?

9
  • The web API method is one which you can use to with javascript for this...OOTB it does not support for the button click. I guess if you can share your code for the web API, we can check why you are getting null for goal item. Commented Sep 26, 2019 at 17:35
  • What is the Sitecore version you are using? Commented Sep 26, 2019 at 19:19
  • I am using Sitecore 9.0.2 Commented Sep 27, 2019 at 5:00
  • Can you try to use the following to trigger the goal upon the button click: var goalDefinition = Sitecore.Analytics.Tracker.MarketingDefinitions.Goals[goalId]; Sitecore.Analytics.Tracker.Current.CurrentPage.RegisterGoal(goalDefinition); Commented Sep 27, 2019 at 12:47
  • I have added code Commented Sep 27, 2019 at 13:27

1 Answer 1

3

Sitecore 9.x

When you call the API, you must remember to include security so that the cookies go with the request. Mainly the analytics cookie.

In the code below the GetPageForApi(), if requested, will get the page before the Api call. This is since the API is a page request. Without using previous page, the goal would be on the API call itself.

The Api

[HttpGet]
[SkipAnalyticsTrackingApi]
public ActionResult TriggerIAmWithoutEmailGoal()
{
    var response = new BaseResponseDTO<TriggerGoalResponseModel>();
    try
    {
        this.eventRepository.TriggerGoalOnce(PageContent.Constants.Goals.IamWithoutEmail, true);

        response.Data = new TriggerGoalResponseModel()
        {
            Result = true,
        };

        return new JsonNet(response);
    }
    catch (System.Exception ex)
    {
        // log your error

        response.Error = ex.Message;
        return new JsonNet(response);
    }
}

The attribute

public class SkipAnalyticsTrackingApiAttribute : ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        Tracker.Current?.CurrentPage?.Cancel();
    }
}

The repo

private readonly IDefinitionManager<IGoalDefinition> goalDefinitionManager;

// The goalDefinitionManager is injected by DI
public EventRepository(IDefinitionManager<IGoalDefinition> goalDefinitionManager)
{
    this.goalDefinitionManager = goalDefinitionManager;
}

public void TriggerGoal(ID goalId, bool fromApi = false, int engagementValue = 0)
{
    var goalDefinition = this.goalDefinitionManager.Get(goalId.Guid, CultureInfo.InvariantCulture);
    if (goalDefinition == null)
    {
        Log.Warn($"Cannot find goal: {goalId}", this);
        return;
    }

    Log.Info($"Goal Triggered: Contact: {Tracker.Current.Contact.ContactId} : {goalId}", this);

    var page = fromApi ? GetPageForApi() : Tracker.Current.CurrentPage;

    page.RegisterGoal(goalDefinition);
}

public void TriggerGoalOnce(ID goalId,bool fromApi = false)
{
    if (IfGoalAlreadyExists(goalId)) return;

    TriggerGoal(goalId, fromApi);
}

public bool IfGoalAlreadyExists(ID goalId)
{
    if (Tracker.Current?.Session == null) return false;

    var goalsTriggered = Tracker.Current?.Session?.Interaction?.Pages?.SelectMany(x => x.PageEvents).Where(x => x.IsGoal).ToList();

    var behaviorCache = Tracker.Current.Session.Contact.KeyBehaviorCache.Goals.Any(x => x.Id == goalId.ToGuid());
    var pages = goalsTriggered?.Any(x => x.PageEventDefinitionId == goalId.ToGuid()) ?? false;

    return behaviorCache || pages;
}

private IPageContext GetPageForApi()
{
    if (Tracker.Current.Session.Interaction.PreviousPage == null)
        return Tracker.Current.CurrentPage;

    return Tracker.Current.Session.Interaction.PreviousPage;
}

Sitecore 8.2

The API and Attribute are the same as above. But the way to trigger the goal is on the tracker in 8.2.

The repo

public void TriggerGoal(ID goalPath, bool fromApi = false)
{
    if (Tracker.IsActive && Tracker.Current?.CurrentPage != null)
    {
        // Trigger a goal
        var goalItem = Sitecore.Context.Database.GetItem(goalPath); // Goal item

        if (goalItem != null)
        {
            var goal = new PageEventItem(goalItem); // Wrapper for goal
            var page = fromApi ? Tracker.Current.Session.Interaction.PreviousPage : Tracker.Current.CurrentPage;

            if (page == null)
            {
                errorService.LogError(new Exception($"Page is null. Cannnot fire goal. Goal ID {goalPath.Guid}, fromApi = {fromApi}"), this);
                return;
            }


            var pageEventsRow = page.Register(goal); // Goal rtecord to be stored
            pageEventsRow.Data = goalItem["Description"];
            Tracker.Current.Interaction.AcceptModifications();
            Log.Info($"Goal Triggered: Contact: {Tracker.Current.Contact.ContactId} : {goalPath} / {goalItem.Name}", this);
            return;
        }
    }
}

public void TriggerGoalOnce(ID goalId, bool fromApi)
{
    if (IfGoalAlreadyExists(goalId)) return;

    TriggerGoal(goalId, fromApi);
}

public bool IfGoalAlreadyExists(ID goalId)
{
    var goalsTriggered = Tracker.Current.Session.Interaction.Pages.SelectMany(x => x.PageEvents).Where(x => x.IsGoal).ToList();
    return goalsTriggered.Any(x => x.PageEventDefinitionId == goalId.ToGuid());
}
1
  • Thanks for the detail explanation. My problem is that I am getting item when I am passing Home page id then it is returning me item, but when I am passing GoalID then it is giving me null value Commented Oct 1, 2019 at 11:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.