def send_reviews_ready_email(user_id, app_ids_countries): user = User.objects.get(pk=user_id) app_ids = [app_id for app_id, _ in app_ids_countries] apps_by_id = dict((a.id, a) for a in AppStoreApp.objects.filter(id__in=app_ids)) apps = [] for app_id, country in app_ids_countries: app = apps_by_id[app_id] appstore_app_info.decorate_app(app, country) apps.append(app) messsage = emails.create_reviews_ready_email(user, apps) emails.send_all([messsage])
def send_reviews_ready_email(user_id, app_ids_countries): user = User.objects.get(pk=user_id) app_ids = [app_id for app_id, _ in app_ids_countries] apps_by_id = dict( (a.id, a) for a in AppStoreApp.objects.filter(id__in=app_ids)) apps = [] for app_id, country in app_ids_countries: app = apps_by_id[app_id] appstore_app_info.decorate_app(app, country) apps.append(app) messsage = emails.create_reviews_ready_email(user, apps) emails.send_all([messsage])
def send_welcome_email(user_id): user = User.get_cached(user_id) if not user: # Deleted, rollbacked transaction, etc. return unsubscribe_url = generate_user_unsubscribe_url(user, 'unsubscribed_from_email') verify_url = None if user.flags.has_unverified_email: verify_url = verification_url_for_user_email(user, user.email) email = emails.create_welcome_email(user, verify_url, unsubscribe_url) emails.send_all([email])
def _maybe_notify_subscriptions_for_app_id(app_id, country): app = AppStoreApp.objects.get(pk=app_id) appstore_app_info.decorate_app(app, country) interested_parties = AppStoreAppInterest.objects.filter(app_id=app.id, country=country, enabled=True).values_list('user_id', flat=True) subs = AppStoreReviewSubscription.objects.filter(user__in=interested_parties, enabled=True).select_related('user') # Restrict subs to unfiltered or filtered just for this app. subs = subs.filter(Q(filter_app_id__isnull=True) | Q(filter_app_id=app_id)) if subs.count() > 100: logging.warn('Optimize subscription sending for app: %s (%s - %s)', app.id, app.itunes_id, app.bundle_id) email_messages = [] notifications = [] for sub in subs: reviews = AppStoreReview.objects.filter(app=app, initial_ingestion=False, create_time__gt=(sub.last_notification_time or sub.create_time), country=country) if sub.filter_good: reviews = reviews.filter(rating__gte=4) if sub.filter_very_good: reviews = reviews.filter(rating=5) reviews_stats = reviews.aggregate(max_create_time=Max('create_time'), count=Count('id')) reviews_count = reviews_stats['count'] reviews_max_create_time = reviews_stats['max_create_time'] if not reviews_count: continue reviews = list(reviews.order_by('-rating', '-create_time')[:10]) n = AppStoreReviewNotification(app=app, user=sub.user) n.reviews_count = reviews_count if sub.email or sub.my_email: created_user = None if sub.my_email: email = sub.user.email else: created_user = sub.user email = sub.email unsub_url = unsubscribe_url_for_subscription(sub) email_messages.append( emails.create_review_email(email, app, reviews_count, reviews, unsub_url, created_user=created_user)) n.email = email if sub.my_email: n.my_email = True elif sub.slack_channel_name or sub.slack_url: slack_json = slack_review_json(app, reviews_count, reviews) slack.post_message_to_slack_subscription(sub, slack_json) if sub.slack_url: n.slack_webhook = True else: n.slack_channel_name = sub.slack_channel_name elif sub.twitter_connection: # For now, just pick first one for auto-tweeting. tweet_review_for_user.delay(sub.user_id, sub.twitter_connection.handle, reviews[0].id) n.twitter_handle = sub.twitter_connection.handle else: continue logging.error('WTF? unknown sub: %s', sub.id) # NOTE: This is not now() because now() might be different from max(create_time) of this batch, # and we use create_time as the filter for the next notification time. sub.last_notification_time = reviews_max_create_time sub.save(update_fields=['last_notification_time']) notifications.append(n) if email_messages: emails.send_all(email_messages) if notifications: AppStoreReviewNotification.objects.bulk_create(notifications)
def send_new_subscription_email(sub, apps): unsubscribe_url = unsubscribe_url_for_subscription(sub) message = emails.create_reviews_subscription_email(sub.user, sub.email, apps, unsubscribe_url) emails.send_all([message])
def send_latest_report_for_user_subs(user_id, requested_date): user = User.objects.get(pk=user_id) vendor = get_chosen_vendor_for_user(user) if not vendor: logging.info('No chosen vendor for user: %s', user.id) return status = report_status_for_vendor_date(vendor, requested_date) if status != REPORT_STATUS_AVAILABLE: logging.info('No report for user: %s', user.id) return # Do this atomically because we might be competing with another worker process. with transaction.atomic(): last_report_date_matches = Q(latest_report_date__isnull=True) | Q( latest_report_date__lt=requested_date) subs = list( AppStoreSalesReportSubscription.objects.select_for_update().filter( last_report_date_matches, user=user, enabled=True)) if not subs: return # Update subscriptions so we don't notify them again. AppStoreSalesReportSubscription.objects.filter( id__in=[s.id for s in subs]).update(latest_report_date=requested_date) app_metrics, total_metrics = get_sales_metrics(vendor, requested_date) if not app_metrics: logging.warn('No metrics for vendor id %s subscriptions (date: %s)', vendor.id, requested_date) return notifications = [] email_messages = [] for s in subs: n = AppStoreSalesReportNotification(user=s.user) if s.slack_channel_name or s.slack_url: message_dict = slack_sales_report_dict(app_metrics, total_metrics, requested_date) slack.post_message_to_slack_subscription(s, message_dict) if s.slack_url: n.slack_webhook = True else: n.slack_channel_name = s.slack_channel_name elif s.my_email or s.email: created_user = None if s.my_email: email = s.user.email else: created_user = s.user email = s.email unsub_url = unsubscribe_url_for_subscription(s) message = emails.create_sales_report_email( user, email, app_metrics, total_metrics, requested_date, unsub_url, created_user=created_user) email_messages.append(message) if s.my_email: n.my_email = True n.email = email else: logging.warn( 'Unsupported notification type for itunes notification: %s', s.id) notifications.append(n) if email_messages: emails.send_all(email_messages) if notifications: AppStoreSalesReportNotification.objects.bulk_create(notifications)
def send_latest_report_for_user_subs(user_id, requested_date): user = User.objects.get(pk=user_id) vendor = get_chosen_vendor_for_user(user) if not vendor: logging.info('No chosen vendor for user: %s', user.id) return status = report_status_for_vendor_date(vendor, requested_date) if status != REPORT_STATUS_AVAILABLE: logging.info('No report for user: %s', user.id) return # Do this atomically because we might be competing with another worker process. with transaction.atomic(): last_report_date_matches = Q(latest_report_date__isnull=True) | Q(latest_report_date__lt=requested_date) subs = list(AppStoreSalesReportSubscription.objects.select_for_update().filter(last_report_date_matches, user=user, enabled=True)) if not subs: return # Update subscriptions so we don't notify them again. AppStoreSalesReportSubscription.objects.filter(id__in=[s.id for s in subs]).update(latest_report_date=requested_date) app_metrics, total_metrics = get_sales_metrics(vendor, requested_date) if not app_metrics: logging.warn('No metrics for vendor id %s subscriptions (date: %s)', vendor.id, requested_date) return notifications = [] email_messages = [] for s in subs: n = AppStoreSalesReportNotification(user=s.user) if s.slack_channel_name or s.slack_url: message_dict = slack_sales_report_dict(app_metrics, total_metrics, requested_date) slack.post_message_to_slack_subscription(s, message_dict) if s.slack_url: n.slack_webhook = True else: n.slack_channel_name = s.slack_channel_name elif s.my_email or s.email: created_user = None if s.my_email: email = s.user.email else: created_user = s.user email = s.email unsub_url = unsubscribe_url_for_subscription(s) message = emails.create_sales_report_email(user, email, app_metrics, total_metrics, requested_date, unsub_url, created_user=created_user) email_messages.append(message) if s.my_email: n.my_email = True n.email = email else: logging.warn('Unsupported notification type for itunes notification: %s', s.id) notifications.append(n) if email_messages: emails.send_all(email_messages) if notifications: AppStoreSalesReportNotification.objects.bulk_create(notifications)