/// <summary> /// Creates the email content for deals email /// </summary> /// <param name="dealsEmailCargo">Deals Email cargo</param> /// <returns>EmailContent for deals email</returns> private EmailContent PrepareEmail(DealsEmailCargo dealsEmailCargo) { EmailData emailData = _emailContentCreator.GetContent(dealsEmailCargo); bool isTest = (dealsEmailCargo.Hints != null) && dealsEmailCargo.Hints.IsTest; EmailContent emailContent = new EmailContent { From = isTest ? this._emailFromAddressTestAccount : this._emailFromAddress, FromDisplay = this._emailFromDisplay, Subject = emailData.Subject, HtmlBody = emailData.HtmlBody, TextBody = emailData.TextBody, Category = dealsEmailCargo.Campaign }; if (!dealsEmailCargo.Hints.IsTestEmail) { // Saving the email data in the history table UserEmailEntity emailToSend = new UserEmailEntity(dealsEmailCargo.UserId, dealsEmailCargo.LocationId, DateTime.UtcNow, EmailType.WeeklyDeal); emailToSend.SetSerializedPayload(new UserEmailPayload { DealIds = emailData.DealIds }); this._userHistoryStorage.SaveUserEmailEntity(emailToSend); } return(emailContent); }
/// <summary> /// The generate model. /// </summary> /// <param name="emailJob"> /// The email job. /// </param> /// <param name="deals"> /// The deals. /// </param> /// <returns> /// The <see cref="DealsEmailModel"/>. /// </returns> public DealsEmailModel GenerateModel(DealsEmailCargo emailJob, IEnumerable <Deal> deals) { /** * List<MockDealModel> dealsModel = new List<MockDealModel>(); * foreach (Deal deal in deals) * { * var dealModel = new MockDealModel * { * TransactionUrl = deal.TransactionUrl, * BrandString = deal.DealProvider.ProviderBrandingName, * Description = deal.Description, * Discount = deal.DealInfo != null && deal.DealInfo.VoucherDiscountPercent != 0 ? Math.Round(deal.DealInfo.VoucherDiscountPercent, MidpointRounding.AwayFromZero) + "%" : string.Empty, * OriginalPrice = deal.DealInfo != null && deal.DealInfo.VoucherValue != 0 ? "$" + Math.Round(deal.DealInfo.VoucherValue, MidpointRounding.AwayFromZero) : string.Empty, * Price = deal.PriceDisplayString, * LargeImageUrl = string.Format("https://az389013.vo.msecnd.net/{0}?size=10", deal.Id), * MediumImageUrl = string.Format("https://az389013.vo.msecnd.net/{0}?size=4", deal.Id), * Remaining = this.GetRemainingStr(deal.EndTime), * StoreName = deal.Business != null ? deal.Business.Name : string.Empty, * Title = deal.Title * }; * dealsModel.Add(dealModel); * } * * var model = * new DealsEmailModel * { * TopDeal = dealsModel.First(), * RestDeals = dealsModel.Skip(1).Take(3) * }; * return model; **/ return(null); }
/// <summary> /// The get deals. /// </summary> /// <param name="emailJob"> /// The email job. /// </param> /// <param name="dealsToExclude"> /// The deals to exclude. /// </param> /// <returns> /// The <see cref="IEnumerable"/>. /// </returns> public IEnumerable <Deal> GetDeals(DealsEmailCargo emailJob, IEnumerable <Guid> dealsToExclude) { Random rnd = new Random(); int numberOfDeals = 5; List <Deal> deals = new List <Deal>(); for (int i = 0; i < numberOfDeals; i++) { Deal deal = new Deal(); deal.Title = rnd.Next(25, 75) + "% Off For $" + rnd.Next(100, 500); deal.Description = "This is the deal description" + Guid.NewGuid(); deal.TransactionUrl = @"http://www.yelp.com/seattle"; deal.ImageUrl = @"http://a.abcnews.com/images/Technology/ht_microsoft_cc_120823_wg.jpg"; deals.Add(deal); } return(deals); }
/// <summary> /// The get deals. /// </summary> /// <param name="user"> /// The user. /// </param> /// <param name="subscription"> /// The subscription. /// </param> /// <returns> /// The <see cref="IEnumerable{Deal}"/>. /// </returns> public IEnumerable <Deal> GetDeals(DealsEmailCargo emailJob, IEnumerable <Guid> dealsToExclude) { throw new NotImplementedException(); /** * DealsLocation location; * DealsSelectionConditions dealsSelectionConditions = this.defaultDealsSelectionConditions; * if (this.dealsLocations.TryGetValue(subscription.LocationId, out location)) * { * dealsSelectionConditions = location.Conditions; * } * * var refinements = new Refinements(); * * if (user.Info != null && * user.Info.Preferences != null * && user.Info.Preferences.Categories != null * && user.Info.Preferences.Categories.Any()) * { * refinements.Categories = user.Info.Preferences.Categories.Select(elem => string.Format("lomo:{0}", elem)); * } * * if (dealsSelectionConditions.ProvidersWhitelist != null && dealsSelectionConditions.ProvidersWhitelist.Any()) * { * refinements.Sources = dealsSelectionConditions.ProvidersWhitelist; * } * * Task<IEnumerable<Deal>> getDealsTask; * if (location != null) * { * getDealsTask = this.dealsClient.GetNearbyDeals(new Coordinates { Latitude = location.Latitude, Longitude = location.Longitude }, location.Radius, 5, refinements); * } * else * { * getDealsTask = this.dealsClient.GetOnlineDeals(5, refinements); * } * * getDealsTask.Wait(TimeSpan.FromSeconds(20)); * return getDealsTask.Result; **/ //TODO - reimplement if needed }
/// <summary> /// Handles the Deals email job /// </summary> /// <param name="emailCargo">Deals email cargo</param> public void Handle(EmailCargo emailCargo) { DealsEmailCargo dealsEmailCargo = emailCargo as DealsEmailCargo; if (dealsEmailCargo != null) { EmailContent emailContent = PrepareEmail(dealsEmailCargo); bool isTest = (dealsEmailCargo.Hints != null) && dealsEmailCargo.Hints.IsTest; SendEmailRequest request = new SendEmailRequest { Content = emailContent, ToList = new List <string> { dealsEmailCargo.EmailAddress }, IsTest = isTest }; // Send the email this._userServicesClient.SendEmail(dealsEmailCargo.Id, request, null); } }
private static void CreateTestEmailCargo(DealsContract dealsContract, Tuple <string, string> tuple) { Log.Verbose("Creating test email cargo"); List <Guid> dealGuids = null; if (dealsContract.Deals != null && dealsContract.Deals.Any()) { dealGuids = dealsContract.Deals.Select(dealId => new Guid(dealId)).ToList(); } User user = _usersDal.GetUserByUserId(new Guid(_testUserId)); if (!dealsContract.Location.StartsWith("us:postal:")) { dealsContract.Location = string.Format("{0}:{1}", "us:postal", dealsContract.Location); } foreach (string email in _lstTestEmailAddress) { DealsEmailCargo dealsEmailCargo = new DealsEmailCargo { Id = user.Id, UserId = user.Id, EmailAddress = email, Campaign = tuple.Item2, Hints = new EmailJobHints { IsTest = false, IncludeDeals = true, IsTestEmail = true }, LocationId = dealsContract.Location, UnsubscribeUrl = _usersDal.GetUnsubscribeUrlInfo(user.Id).UnsubscribeUrl, DealIds = dealGuids, IsCloDeal = true, Subject = dealsContract.Subject }; dealsEmailCargo.EmailRenderingServiceAddress = string.Format(tuple.Item1, dealsEmailCargo.Campaign); _emailJobsQueue.Enqueue(dealsEmailCargo); Log.Verbose("Enqueued Deals test email cargo : {0} ", dealsEmailCargo.ToString()); } }
/// <summary> /// The get content. /// </summary> /// <param name="emailCargo"> /// The email Job. /// </param> /// <returns> /// The <see cref="EmailContent"/>. /// </returns> /// <exception cref="TemplateRenderException"> /// error while rendering the template /// </exception> public EmailData GetContent(object emailCargo) { EmailData emailData = null; DealsEmailCargo dealsEmailCargo = emailCargo as DealsEmailCargo; if (dealsEmailCargo != null) { string locationId = dealsEmailCargo.LocationId; bool isSendTimeWindowValid = true; IEnumerable <UserEmailEntity> emailHistoryEntities = null; //If this is not a test email, check the history to make sure we are not sending the email to the same user within the sendtime window. if (!dealsEmailCargo.Hints.IsTestEmail) { emailHistoryEntities = this.userHistoryStorage.GetUserEmailEntities(dealsEmailCargo.UserId, mailHistoryLookback).ToList(); isSendTimeWindowValid = this.IsSendTimeWindowValid(emailHistoryEntities.FirstOrDefault(elem => elem.LocationId == locationId), dealsEmailCargo); } if (isSendTimeWindowValid) { IEnumerable <Guid> dealsToExclude = null; //if dealids are not included the cargo, we have to select random deals. Need to check in the history to make sure we are excluding deals that have //already been sent in the past few weeks (based on the mail history lookback settings) if (emailHistoryEntities != null && dealsEmailCargo.DealIds == null) { dealsToExclude = this.GetDealsToExclude(emailHistoryEntities); } EmailRenderingClient <DailyDealsContract> emailRenderingClient = new EmailRenderingClient <DailyDealsContract> { EmailRenderingServiceUrl = dealsEmailCargo.EmailRenderingServiceAddress }; IEnumerable <Deal> deals = null; if (dealsEmailCargo.Hints != null && dealsEmailCargo.Hints.IncludeDeals) { deals = this.dealsSelector.GetDeals(emailCargo as DealsEmailCargo, dealsToExclude).ToList(); } if (deals != null && deals.Any()) { DealsTemplateData dailyDealsTemplateData = new DealsTemplateData { EmailAddress = dealsEmailCargo.EmailAddress, UnsubscribeUrl = dealsEmailCargo.UnsubscribeUrl, LocationId = locationId, Deals = deals, DealEmailType = dealsEmailCargo.DealIds != null && dealsEmailCargo.DealIds.Any() ? DealEmailType.TrendingDeal : DealEmailType.WeeklyDeal }; var model = this.templateModelCreator.GenerateModel(dailyDealsTemplateData); emailData = new EmailData { Subject = !string.IsNullOrEmpty(dealsEmailCargo.Subject) ? dealsEmailCargo.Subject : this.RenderSubject(model), HtmlBody = emailRenderingClient.RenderHtml(model), TextBody = string.Empty, DealIds = deals.Select(elem => new Guid(elem.Id)).ToList() }; } else { int dealsCount = deals != null?deals.Count() : 0; throw new ModelContentException(string.Format("Number of deals is: {0}. This is insufficient for email model creation", dealsCount)); } } } return(emailData); }
private static void CreateEmailCargo(DealsContract dealsContract, Tuple <string, string> tuple) { Log.Verbose("Creating clo email cargo"); string accessToken = GetAnalyticsAccessToken(); Log.Verbose("got analytics access token"); object continuationContext = null; bool hasMore = true; List <Guid> dealGuids = null; if (dealsContract.Deals != null && dealsContract.Deals.Any()) { dealGuids = dealsContract.Deals.Select(dealId => new Guid(dealId)).ToList(); } while (hasMore) { try { EmailsSubscriptionsBatchResponse response = _usersDal.GetNextEmailSubscriptionsBatch(10000, true, continuationContext, SubscriptionType.WeeklyDeals); { if (response.EmailSubscriptions != null) { foreach (EmailSubscription emailSubscription in response.EmailSubscriptions) { if (emailSubscription.LocationId.Contains("us:postal:")) { Tuple <bool, string> cloRegionInfo = CloHelper.IsCloRegion(emailSubscription.LocationId); if (cloRegionInfo.Item1) { User user = _usersDal.GetUserByUserId(emailSubscription.UserId); if (!string.IsNullOrEmpty(user.MsId)) { Tuple <DateTime?, DateTime?> cloInfo = GetCloInfo(user.Id, accessToken); if (cloInfo.Item1 != null) { DealsEmailCargo dealsEmailCargo = new DealsEmailCargo { Id = user.Id, UserId = user.Id, EmailAddress = user.Email, Campaign = tuple.Item2, Hints = new EmailJobHints { IsTest = false, IncludeDeals = true }, LocationId = emailSubscription.LocationId, UnsubscribeUrl = _usersDal.GetUnsubscribeUrlInfo(user.Id).UnsubscribeUrl, DealIds = dealGuids, IsCloDeal = true, Subject = dealsContract.Subject }; dealsEmailCargo.EmailRenderingServiceAddress = string.Format(tuple.Item1, dealsEmailCargo.Campaign); _emailJobsQueue.Enqueue(dealsEmailCargo); } } } } } } } hasMore = response.HasMore; continuationContext = response.ContinuationContext; } catch (Exception exception) { Log.Error(exception.Message); } } }
/// <summary> /// The get deals. /// </summary> /// <param name="emailJob"> /// The email job. /// </param> /// <param name="dealsToExclude">deals to exclude</param> /// <returns> /// the list of deals /// </returns> /// <exception cref="ApplicationException">location id is wrong </exception> public IEnumerable <Deal> GetDeals(DealsEmailCargo emailJob, IEnumerable <Guid> dealsToExclude) { var refinements = new Refinements(); if (emailJob.Categories != null && emailJob.Categories.Any()) { refinements.Categories = emailJob.Categories.Select(elem => string.Format("lomo:{0}", elem)); } refinements.ResultsPerBusiness = 1; string locationId = emailJob.LocationId; Users.Dal.DataModel.Location location = Users.Dal.DataModel.Location.Parse(locationId); Task <IEnumerable <Deal> > getDealsTask; if (location.CountryCode != "us") { Log.Error(string.Format("Location Id isn't in us. Location Id={0}", locationId)); } refinements.Market = string.Format("en-{0}", location.CountryCode); string dealFlight = emailJob.IsCloDeal ? CloFlight : NonCloFlight; //Construct the flight name of the form <<DealFlight (whether to get clo or prepaid only deals)>>,<<campaign name (for tracking in analytics)?>> if (!string.IsNullOrEmpty(emailJob.Campaign)) { refinements.Flights = string.Format("{0},{1}", dealFlight, emailJob.Campaign); } else { refinements.Flights = dealFlight; } List <Deal> selectedDeals; if (emailJob.DealIds != null && emailJob.DealIds.Any()) { getDealsTask = this.dealsClient.GetDealsById(emailJob.DealIds.ToList(), refinements: refinements); //If we are selecting specific deals to send in the email, do not do any further actions like excluding previously sent deals selectedDeals = getDealsTask.Result.ToList(); } else { if (location.Type == LocationType.Postal || location.Type == LocationType.City) { string regionCode = string.Format("{0} {1} {2}", location.CountryCode, location.AdminDistrict, location.Value); getDealsTask = this.dealsClient.GetDealsByRegion(regionCode, null, null, DealsCount, refinements, emailJob.Anid); } else if (location.Type == LocationType.National) { getDealsTask = this.dealsClient.GetOnlineDeals(DealsCount, refinements); } else { throw new ApplicationException( string.Format( "Location Id not supported. Only postal, national or city location type are allowed in this phase. Location Id={0}", locationId)); } var returnedDeals = getDealsTask.Result.ToList(); HashSet <string> dealsToExcludeHash = new HashSet <string>(); if (dealsToExclude != null && dealsToExclude.Any()) { foreach (var dealGuid in dealsToExclude) { dealsToExcludeHash.Add(dealGuid.ToString().ToLowerInvariant()); } } selectedDeals = this.SelectDeals(6, dealsToExcludeHash, returnedDeals); } return(selectedDeals); }