/// <summary> /// Gets the variation name assigned for the user for the campaign /// </summary> /// <param name="campaignKey">Campaign key to uniquely identify a server-side campaign.</param> /// <param name="userId">User ID which uniquely identifies each user.</param> /// <param name="options">Dictionary for passing extra parameters to activate</param> /// <returns> /// If variation is assigned then variation name, or Null in case of user not becoming part /// </returns> public string GetVariation(string campaignKey, string userId, Dictionary <string, dynamic> options = null) { if (options == null) { options = new Dictionary <string, dynamic>(); } Dictionary <string, dynamic> customVariables = options.ContainsKey("customVariables") ? options["customVariables"] : null; Dictionary <string, dynamic> variationTargetingVariables = options.ContainsKey("variationTargetingVariables") ? options["variationTargetingVariables"] : null; if (this._validator.GetVariation(campaignKey, userId, options)) { var campaign = this._campaignAllocator.GetCampaign(this._settings, campaignKey); if (campaign == null || campaign.Status != Constants.CampaignStatus.RUNNING) { LogErrorMessage.CampaignNotRunning(typeof(IVWOClient).FullName, campaignKey, nameof(GetVariation)); return(null); } if (campaign.Type == Constants.CampaignTypes.FEATURE_ROLLOUT) { LogErrorMessage.InvalidApi(typeof(IVWOClient).FullName, userId, campaignKey, campaign.Type, nameof(GetVariation)); return(null); } var assignedVariation = this.AllocateVariation(campaignKey, userId, campaign, customVariables, variationTargetingVariables, apiName: nameof(GetVariation)); if (assignedVariation.Variation != null) { return(assignedVariation.Variation.Name); } return(assignedVariation.Variation?.Name); } return(null); }
/// <summary> /// Activates a server-side A/B test for a specified user for a server-side running campaign. /// </summary> /// <param name="campaignKey">Campaign key to uniquely identify a server-side campaign.</param> /// <param name="userId">User ID which uniquely identifies each user.</param> /// <param name="options">Dictionary for passing extra parameters to activate</param> /// <returns> /// The name of the variation in which the user is bucketed, or null if the user doesn't qualify to become a part of the campaign. /// </returns> public string Activate(string campaignKey, string userId, Dictionary <string, dynamic> options = null) { if (options == null) { options = new Dictionary <string, dynamic>(); } Dictionary <string, dynamic> customVariables = options.ContainsKey("customVariables") ? options["customVariables"] : null; Dictionary <string, dynamic> variationTargetingVariables = options.ContainsKey("variationTargetingVariables") ? options["variationTargetingVariables"] : null; if (this._validator.Activate(campaignKey, userId, options)) { var campaign = this._campaignAllocator.GetCampaign(this._settings, campaignKey); if (campaign == null || campaign.Status != Constants.CampaignStatus.RUNNING) { LogErrorMessage.CampaignNotRunning(typeof(IVWOClient).FullName, campaignKey, nameof(Activate)); return(null); } if (campaign.Type != Constants.CampaignTypes.VISUAL_AB) { LogErrorMessage.InvalidApi(typeof(IVWOClient).FullName, userId, campaignKey, campaign.Type, nameof(Activate)); return(null); } var assignedVariation = this.AllocateVariation(campaignKey, userId, campaign, customVariables, variationTargetingVariables, apiName: nameof(Activate)); if (assignedVariation.Variation != null) { var trackUserRequest = ServerSideVerb.TrackUser(this._settings.AccountId, assignedVariation.Campaign.Id, assignedVariation.Variation.Id, userId, this._isDevelopmentMode); trackUserRequest.ExecuteAsync(); return(assignedVariation.Variation.Name); } } return(null); }
public async Task <byte[]> ExecuteAsync(ApiRequest apiRequest) { if (apiRequest == null) { return(null); } HttpRequestMessage httpRequestMessage = new HttpRequestMessage(apiRequest.Method.GetHttpMethod(), apiRequest.Uri.ToString()); HttpResponseMessage httpResponseMessage = null; try { httpResponseMessage = await _httpClient.SendAsync(httpRequestMessage); if (httpResponseMessage.IsSuccessStatusCode) { var response = await httpResponseMessage.Content.ReadAsByteArrayAsync(); LogInfoMessage.ImpressionSuccess(file, apiRequest.Uri.ToString()); return(response); } LogErrorMessage.ImpressionFailed(file, apiRequest.Uri?.ToString()); } catch (Exception exception) { LogErrorMessage.ImpressionFailed(file, apiRequest.Uri?.ToString()); } finally { } return(null); }
public dynamic getTypeCastedFeatureValue(dynamic value, string variableType) { try { if (value.GetType().Name == Constants.DotnetVariableTypes.VALUES[variableType]) { return(value); } if (variableType == Constants.VariableTypes.STRING) { return(Convert.ToString(value)); } if (variableType == Constants.VariableTypes.INTEGER) { return(Convert.ToInt32(value)); } if (variableType == Constants.VariableTypes.DOUBLE) { return(Convert.ToDouble(value)); } if (variableType == Constants.VariableTypes.BOOLEAN) { return(Convert.ToBoolean(value)); } return(value); } catch { LogErrorMessage.UnableToTypeCast(typeof(IVWOClient).FullName, value, variableType, value.GetType().Name); return(null); } }
/// <summary> /// Tracks a conversion event for a particular user for a running server-side campaign. /// </summary> /// <param name="userId">User ID which uniquely identifies each user.</param> /// <param name="goalIdentifier">The Goal key to uniquely identify a goal of a server-side campaign.</param> /// <param name="options">Dictionary for passing extra parameters to activate</param> /// <returns> /// A boolean value based on whether the impression was made to the VWO server. /// True, if an impression event is successfully being made to the VWO server for report generation. /// False, If userId provided is not part of campaign or when unexpected error comes and no impression call is made to the VWO server. /// </returns> public Dictionary <string, bool> Track(string userId, string goalIdentifier, Dictionary <string, dynamic> options = null) { if (options == null) { options = new Dictionary <string, dynamic>(); } string goalTypeToTrack = options.ContainsKey("goalTypeToTrack") ? options["goalTypeToTrack"] : null; bool shouldTrackReturningUser = options.ContainsKey("shouldTrackReturningUser") ? options["shouldTrackReturningUser"] : this._shouldTrackReturningUser; goalTypeToTrack = !string.IsNullOrEmpty(goalTypeToTrack) ? goalTypeToTrack : this._goalTypeToTrack != null ? this._goalTypeToTrack : Constants.GoalTypes.ALL; Dictionary <string, bool> result = new Dictionary <string, bool>(); bool campaignFound = false; foreach (BucketedCampaign campaign in this._settings.Campaigns) { foreach (KeyValuePair <string, Goal> goal in campaign.Goals) { if (goal.Key != null && goalIdentifier == goal.Value.Identifier && (goalTypeToTrack == Constants.GoalTypes.ALL || goalTypeToTrack == goal.Value.Type)) { campaignFound = true; result[campaign.Key] = this.Track(campaign.Key, userId, goalIdentifier, options); } } } if (!campaignFound) { LogErrorMessage.NoCampaignForGoalFound(file, goalIdentifier); return(null); } return(result); }
/// <summary> /// Returns the feature variable corresponding to the variableKey passed. It typecasts the value to the corresponding value type found in settings_file /// </summary> /// <param name="campaignKey">Campaign key to uniquely identify a server-side campaign.</param> /// <param name="variableKey">Campaign key to uniquely identify a server-side campaign.</param> /// <param name="userId">User ID which uniquely identifies each user.</param> /// <param name="options">Dictionary for passing extra parameters to activate</param> /// <returns> /// The name of the variation in which the user is bucketed, or null if the user doesn't qualify to become a part of the campaign. /// </returns> public dynamic GetFeatureVariableValue(string campaignKey, string variableKey, string userId, Dictionary <string, dynamic> options = null) { if (options == null) { options = new Dictionary <string, dynamic>(); } Dictionary <string, dynamic> customVariables = options.ContainsKey("customVariables") ? options["customVariables"] : null; Dictionary <string, dynamic> variationTargetingVariables = options.ContainsKey("variationTargetingVariables") ? options["variationTargetingVariables"] : null; var variables = new List <Dictionary <string, dynamic> >(); var variable = new Dictionary <string, dynamic>(); if (this._validator.GetFeatureVariableValue(campaignKey, variableKey, userId, options)) { var campaign = this._campaignAllocator.GetCampaign(this._settings, campaignKey); if (campaign == null || campaign.Status != Constants.CampaignStatus.RUNNING) { LogErrorMessage.CampaignNotRunning(typeof(IVWOClient).FullName, campaignKey, nameof(GetFeatureVariableValue)); return(null); } if (campaign.Type == Constants.CampaignTypes.VISUAL_AB) { LogErrorMessage.InvalidApi(typeof(IVWOClient).FullName, userId, campaignKey, campaign.Type, nameof(GetFeatureVariableValue)); return(null); } var assignedVariation = this.AllocateVariation(campaignKey, userId, campaign, customVariables, variationTargetingVariables, apiName: nameof(GetFeatureVariableValue)); if (campaign.Type == Constants.CampaignTypes.FEATURE_ROLLOUT) { variables = campaign.Variables; } else if (campaign.Type == Constants.CampaignTypes.FEATURE_TEST) { if (!assignedVariation.Variation.IsFeatureEnabled) { LogInfoMessage.FeatureNotEnabledForUser(typeof(IVWOClient).FullName, campaignKey, userId, nameof(GetFeatureVariableValue)); assignedVariation = this.GetControlVariation(campaign, campaign.Variations.Find(1, (new VariationAllocator()).GetVariationId)); } else { LogInfoMessage.FeatureEnabledForUser(typeof(IVWOClient).FullName, campaignKey, userId, nameof(GetFeatureVariableValue)); } variables = assignedVariation.Variation.Variables; } variable = this.GetVariable(variables, variableKey); if (variable == null || variable.Count == 0) { LogErrorMessage.VariableNotFound(typeof(IVWOClient).FullName, variableKey, campaignKey, campaign.Type, userId, nameof(GetFeatureVariableValue)); return(null); } else { LogInfoMessage.VariableFound(typeof(IVWOClient).FullName, variableKey, campaignKey, campaign.Type, variable["value"].ToString(), userId, nameof(GetFeatureVariableValue)); } return(this._segmentEvaluator.getTypeCastedFeatureValue(variable["value"], variable["type"])); } return(null); }
private static bool ValidateWithLog(Func <bool> validationFunc, string parameterName, string apiName) { bool validationResult = validationFunc.Invoke(); if (validationResult == false) { LogErrorMessage.ApiMissingParams(file, apiName, parameterName); } return(validationResult); }
public AccountSettings ProcessAndBucket(Settings settings) { try { var campaigns = Process(settings.Campaigns); return(new AccountSettings(settings.SdkKey, campaigns, settings.AccountId, settings.Version)); } catch (Exception exception) { } LogErrorMessage.ProjectConfigCorrupted(file); return(null); }
/// <summary> /// Identifies whether the user becomes a part of feature rollout/test or not. /// </summary> /// <param name="campaignKey">Campaign key to uniquely identify a server-side campaign.</param> /// <param name="userId">User ID which uniquely identifies each user.</param> /// <param name="options">Dictionary for passing extra parameters to activate</param> /// <returns> /// /// A boolean value based on whether the impression was made to the VWO server. /// True, if an impression event is successfully being made to the VWO server for report generation. /// False, If userId provided is not part of campaign or when unexpected error comes and no impression call is made to the VWO server. /// </returns> public bool IsFeatureEnabled(string campaignKey, string userId, Dictionary <string, dynamic> options = null) { if (options == null) { options = new Dictionary <string, dynamic>(); } Dictionary <string, dynamic> customVariables = options.ContainsKey("customVariables") ? options["customVariables"] : null; Dictionary <string, dynamic> variationTargetingVariables = options.ContainsKey("variationTargetingVariables") ? options["variationTargetingVariables"] : null; if (this._validator.IsFeatureEnabled(campaignKey, userId, options)) { var campaign = this._campaignAllocator.GetCampaign(this._settings, campaignKey); if (campaign == null || campaign.Status != Constants.CampaignStatus.RUNNING) { LogErrorMessage.CampaignNotRunning(typeof(IVWOClient).FullName, campaignKey, nameof(IsFeatureEnabled)); return(false); } if (campaign.Type == Constants.CampaignTypes.VISUAL_AB) { LogErrorMessage.InvalidApi(typeof(IVWOClient).FullName, userId, campaignKey, campaign.Type, nameof(IsFeatureEnabled)); return(false); } var assignedVariation = this.AllocateVariation(campaignKey, userId, campaign, customVariables, variationTargetingVariables, apiName: nameof(IsFeatureEnabled)); if (campaign.Type == Constants.CampaignTypes.FEATURE_TEST) { if (assignedVariation.Variation != null) { var trackUserRequest = ServerSideVerb.TrackUser(this._settings.AccountId, assignedVariation.Campaign.Id, assignedVariation.Variation.Id, userId, this._isDevelopmentMode); trackUserRequest.ExecuteAsync(); var result = assignedVariation.Variation.IsFeatureEnabled; if (result) { LogInfoMessage.FeatureEnabledForUser(typeof(IVWOClient).FullName, campaignKey, userId, nameof(IsFeatureEnabled)); } else { LogInfoMessage.FeatureNotEnabledForUser(typeof(IVWOClient).FullName, campaignKey, userId, nameof(IsFeatureEnabled)); } return(result); } return(false); } return(true); } else { return(false); } }
/// <summary> /// Calls Get within try to suppress any Exception from outside of SDK application. /// </summary> /// <param name="userId"></param> /// <returns></returns> private UserStorageMap TryGetUserMap(string userId, string campaignKey) { try { LogInfoMessage.LookingUpUserStorageService(file, userId, campaignKey); return(this._userStorageService.Get(userId, campaignKey)); } catch (Exception ex) { LogErrorMessage.GetUserStorageServiceFailed(file, userId, campaignKey); } return(null); }
internal void SetUserMap(string userId, string campaignKey, string variationName, string goalIdentifier = null) { if (this._userStorageService == null) { LogDebugMessage.NoUserStorageServiceSet(file); return; } try { this._userStorageService.Set(new UserStorageMap(userId, campaignKey, variationName, goalIdentifier)); LogInfoMessage.SavingDataUserStorageService(file, userId); return; } catch (Exception ex) { LogErrorMessage.SetUserStorageServiceFailed(file, userId); } }
internal void SaveUserMap(string userId, string campaignTestKey, string variationName) { if (this._userProfileService == null) { LogDebugMessage.NoUserProfileServiceSave(file); return; } try { LogInfoMessage.SavingDataUserProfileService(file, userId); this._userProfileService.Save(new UserProfileMap(userId, campaignTestKey, variationName)); return; } catch (Exception ex) { LogErrorMessage.SaveUserProfileServiceFailed(file, userId); } }
/// <summary> /// If variation is assigned, allocate the goal using goalIdentifier. /// </summary> /// <param name="campaignKey"></param> /// <param name="userId"></param> /// <param name="goalIdentifier"></param> /// <param name="campaign"></param> /// <param name="customVariables"></param> /// <param name="variationTargetingVariables"></param> /// <param name="apiName"></param> /// <returns> /// If Variation is allocated and goal with given identifier is found, return UserAssignedInfo with valid information, otherwise, Empty UserAssignedInfo object. /// </returns> private UserAllocationInfo AllocateVariation(string campaignKey, string userId, BucketedCampaign campaign, Dictionary <string, dynamic> customVariables, Dictionary <string, dynamic> variationTargetingVariables, string goalIdentifier, string apiName) { var userAllocationInfo = this.AllocateVariation(campaignKey, userId, campaign, customVariables, variationTargetingVariables, apiName); if (userAllocationInfo.Variation != null) { if (userAllocationInfo.Campaign.Goals.TryGetValue(goalIdentifier, out Goal goal)) { userAllocationInfo.Goal = goal; } else { LogErrorMessage.TrackApiGoalNotFound(file, goalIdentifier, campaignKey, userId); } } else { LogErrorMessage.TrackApiVariationNotFound(file, campaignKey, userId); } return(userAllocationInfo); }
/// <summary> /// Makes a call to our server to store the tagValues /// </summary> /// <param name="tagKey">key name of the tag</param> /// <param name="tagValue">value of the tag</param> /// <param name="userId">User ID which uniquely identifies each user.</param> /// <returns> /// A boolean value based on whether the impression was made to the VWO server. /// True, if an impression event is successfully being made to the VWO server for report generation. /// False, If userId provided is not part of campaign or when unexpected error comes and no impression call is made to the VWO server. /// </returns> public bool Push(string tagKey, dynamic tagValue, string userId) { if (this._validator.Push(tagKey, tagValue, userId)) { if ((int)tagKey.Length > (Constants.PushApi.TAG_KEY_LENGTH)) { LogErrorMessage.TagKeyLengthExceeded(typeof(IVWOClient).FullName, tagKey, userId, nameof(Push)); return(false); } if ((int)tagValue.Length > (Constants.PushApi.TAG_VALUE_LENGTH)) { LogErrorMessage.TagValueLengthExceeded(typeof(IVWOClient).FullName, tagValue, userId, nameof(Push)); return(false); } var pushRequest = ServerSideVerb.PushTags(this._settings, tagKey, tagValue, userId, this._isDevelopmentMode); pushRequest.ExecuteAsync(); return(true); } return(false); }
/// <summary> /// Calls Get within try to suppress any Exception from outside of SDK application. /// </summary> /// <param name="userId"></param> /// <param name="campaignKey"></param> /// <param name="userStorageData"></param> /// <returns></returns> private UserStorageMap TryGetUserMap(string userId, string campaignKey, Dictionary <string, dynamic> userStorageData = null) { try { LogInfoMessage.LookingUpUserStorageService(file, userId, campaignKey); if (userStorageData != null) { if (userStorageData.ContainsKey("userId") && userStorageData.ContainsKey("campaignKey") && userStorageData.ContainsKey("variationName")) { if (string.IsNullOrEmpty(userStorageData["userId"]) == false && string.IsNullOrEmpty(userStorageData["campaignKey"]) == false && string.IsNullOrEmpty(userStorageData["variationName"]) == false) { string jsonString = JsonConvert.SerializeObject(userStorageData); var allValue = JsonConvert.DeserializeObject <UserStorageMap>(jsonString); LogInfoMessage.ReturnUserStorageData(file, userStorageData["userId"], userStorageData["campaignKey"]); return(allValue); } else { return(this._userStorageService.Get(userId, campaignKey)); } } else { return(this._userStorageService.Get(userId, campaignKey)); } } else { return(this._userStorageService.Get(userId, campaignKey)); } } catch (Exception ex) { LogErrorMessage.GetUserStorageServiceFailed(file, userId, campaignKey); } return(null); }
/// <summary> /// Send Post network call to VWO servers. /// </summary> /// <returns>Boolean value specifying flush was successful or not.</returns> private async Task <bool> sendPostCall() { string PayLoad = HttpRequestBuilder.GetJsonString(this.batchQueue); var ApiRequest = ServerSideVerb.EventBatching(this.accountId, this.isDevelopmentMode, this.apikey); HttpClient httpClient = new HttpClient(); httpClient.DefaultRequestHeaders.Accept.Clear(); httpClient.DefaultRequestHeaders.Add("Authorization", this.apikey); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); var data = new StringContent(PayLoad, Encoding.UTF8, "application/json"); try { HttpResponseMessage response = await httpClient.PostAsync(ApiRequest.Uri, data); response.EnsureSuccessStatusCode(); if (response.StatusCode == System.Net.HttpStatusCode.OK && response.StatusCode < System.Net.HttpStatusCode.Ambiguous) { if (flushCallback != null) { flushCallback.onFlush(null, PayLoad); } LogInfoMessage.ImpressionSuccess(file, ApiRequest.logUri?.ToString()); return(true); } else if (response.StatusCode == System.Net.HttpStatusCode.RequestEntityTooLarge) { if (flushCallback != null) { flushCallback.onFlush("Payload size too large", PayLoad); } LogDebugMessage.BatchEventLimitExceeded(file, ApiRequest.logUri?.ToString(), this.accountId.ToString(), eventsPerRequest.ToString()); LogErrorMessage.ImpressionFailed(file, ApiRequest.logUri?.ToString()); return(false); } else if (response.StatusCode == System.Net.HttpStatusCode.BadRequest) { if (flushCallback != null) { flushCallback.onFlush("Account id not found, no request app id found, or invalid API key", PayLoad); } LogErrorMessage.BulkNotProcessed(file); LogErrorMessage.ImpressionFailed(file, ApiRequest.logUri?.ToString()); return(false); } else { LogErrorMessage.BulkNotProcessed(file); LogErrorMessage.ImpressionFailed(file, ApiRequest.logUri?.ToString()); if (flushCallback != null) { flushCallback.onFlush("Invalid call", PayLoad); } return(false); } } catch (HttpRequestException ex) { LogErrorMessage.BulkNotProcessed(file); LogErrorMessage.UnableToDisplayHttpRequest(file, ex.StackTrace); if (flushCallback != null) { flushCallback.onFlush("HttpRequest Exception", PayLoad); } return(false); } }
/// <summary> /// Tracks a conversion event for a particular user for a running server-side campaign. /// </summary> /// <param name="campaignKey">Campaign key to uniquely identify a server-side campaign.</param> /// <param name="userId">User ID which uniquely identifies each user.</param> /// <param name="goalIdentifier">The Goal key to uniquely identify a goal of a server-side campaign.</param> /// <param name="options">Dictionary for passing extra parameters to activate</param> /// <returns> /// A boolean value based on whether the impression was made to the VWO server. /// True, if an impression event is successfully being made to the VWO server for report generation. /// False, If userId provided is not part of campaign or when unexpected error comes and no impression call is made to the VWO server. /// </returns> public bool Track(string campaignKey, string userId, string goalIdentifier, Dictionary <string, dynamic> options = null) { if (options == null) { options = new Dictionary <string, dynamic>(); } string revenueValue = options.ContainsKey("revenueValue") ? options["revenueValue"].ToString() : null; Dictionary <string, dynamic> customVariables = options.ContainsKey("customVariables") ? options["customVariables"] : null; Dictionary <string, dynamic> variationTargetingVariables = options.ContainsKey("variationTargetingVariables") ? options["variationTargetingVariables"] : null; string goalTypeToTrack = options.ContainsKey("goalTypeToTrack") ? options["goalTypeToTrack"] : null; bool shouldTrackReturningUser = options.ContainsKey("shouldTrackReturningUser") ? options["shouldTrackReturningUser"] : this._shouldTrackReturningUser; if (this._validator.Track(campaignKey, userId, goalIdentifier, revenueValue, options)) { goalTypeToTrack = !string.IsNullOrEmpty(goalTypeToTrack) ? goalTypeToTrack : this._goalTypeToTrack != null ? this._goalTypeToTrack : Constants.GoalTypes.ALL; var campaign = this._campaignAllocator.GetCampaign(this._settings, campaignKey); if (campaign == null || campaign.Status != Constants.CampaignStatus.RUNNING) { LogErrorMessage.CampaignNotRunning(typeof(IVWOClient).FullName, campaignKey, nameof(Track)); return(false); } if (campaign.Type == Constants.CampaignTypes.FEATURE_ROLLOUT) { LogErrorMessage.InvalidApi(typeof(IVWOClient).FullName, userId, campaignKey, campaign.Type, nameof(Track)); return(false); } var assignedVariation = this.AllocateVariation(campaignKey, userId, campaign, customVariables, variationTargetingVariables, goalIdentifier: goalIdentifier, apiName: nameof(Track)); var variationName = assignedVariation.Variation?.Name; var selectedGoalIdentifier = assignedVariation.Goal?.Identifier; if (string.IsNullOrEmpty(variationName) == false) { if (string.IsNullOrEmpty(selectedGoalIdentifier) == false) { if (goalTypeToTrack != assignedVariation.Goal.Type && goalTypeToTrack != Constants.GoalTypes.ALL) { return(false); } if (!this.isGoalTriggerRequired(campaignKey, userId, goalIdentifier, variationName, shouldTrackReturningUser)) { return(false); } bool sendImpression = true; if (assignedVariation.Goal.IsRevenueType() && string.IsNullOrEmpty(revenueValue)) { sendImpression = false; LogErrorMessage.TrackApiRevenueNotPassedForRevenueGoal(file, goalIdentifier, campaignKey, userId); } else if (assignedVariation.Goal.IsRevenueType() == false) { revenueValue = null; } if (sendImpression) { var trackGoalRequest = ServerSideVerb.TrackGoal(this._settings.AccountId, assignedVariation.Campaign.Id, assignedVariation.Variation.Id, userId, assignedVariation.Goal.Id, revenueValue, this._isDevelopmentMode); trackGoalRequest.ExecuteAsync(); return(true); } } else { LogErrorMessage.TrackApiGoalNotFound(file, goalIdentifier, campaignKey, userId); } } } return(false); }