Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a command to find users dropped by follow-up campaigns. #919

Closed
wants to merge 1 commit into from

Conversation

toolness
Copy link
Collaborator

@toolness toolness commented Nov 6, 2019

Note: this PR isn't intended for merging, I'm going to just run it locally and then close this PR to ensure that the code is recorded somewhere.

This adds a command that outputs a CSV of RapidPro contacts who never received follow-up campaign SMS messages due to the situation described in #902.

@toolness toolness closed this Nov 6, 2019
@toolness toolness deleted the find-dropped-campaigns branch November 6, 2019 23:12
@toolness
Copy link
Collaborator Author

Relatedly, here's a command to follow up with dropped users:

import datetime
from django.conf import settings
from django.core.management.base import CommandError, BaseCommand
from temba_client.v2 import TembaClient
from temba_client.utils import parse_iso8601, format_iso8601

from rapidpro.rapidpro_util import get_group, get_field


class Command(BaseCommand):
    def add_arguments(self, parser):
        parser.add_argument('--dry-run', help="don't actually update records",
                            action='store_true')
        parser.add_argument('--only-contact-uuid', help="limit migration to one contact UUID")

    def follow_up_with_contacts(
        self, client: TembaClient, group_name: str, field_key: str,
        only_contact_uuid: str, dry_run: bool, date_diff: datetime.timedelta
    ):
        group = get_group(client, group_name)
        assert get_field(client, field_key) is not None
        now = format_iso8601(datetime.datetime.now())
        prefix = "[DRY RUN] " if dry_run else ""
        print(f"{prefix}Finding contacts in RapidPro group '{group_name}' whose {field_key} "
              f"exceeds their creation date by {date_diff} and replacing it with "
              f"{now}.")
        kwargs = {'group': group}
        if only_contact_uuid:
            kwargs['uuid'] = only_contact_uuid
        contacts = client.get_contacts(**kwargs).iterfetches(retry_on_rate_exceed=True)
        for contact_batch in contacts:
            for contact in contact_batch:
                field_value = parse_iso8601(contact.fields[field_key])
                assert isinstance(field_value, datetime.datetime)
                assert isinstance(contact.created_on, datetime.datetime)
                if field_value - contact.created_on > date_diff:
                    update = {field_key: now}
                    print(f"{prefix}Updating {repr(contact.name)} fields {update}")
                    if not dry_run:
                        client.update_contact(contact, fields={
                            **contact.fields,
                            **update
                        })

    def handle(self, *args, **options):
        if not settings.RAPIDPRO_API_TOKEN:
            raise CommandError("RAPIDPRO_API_TOKEN must be configured.")
        client = TembaClient(settings.RAPIDPRO_HOSTNAME, settings.RAPIDPRO_API_TOKEN)
        only_contact_uuid: str = options['only_contact_uuid'] or ""
        dry_run: bool = options['dry_run']

        self.follow_up_with_contacts(
            client,
            'DHCR Requested Rental History',
            'date_of_dhcr_req_rental_history',
            only_contact_uuid,
            dry_run,
            datetime.timedelta(days=19)
        )

@toolness toolness added the code snippet Temporary code that we only need to run once and don't need to merge for long-term use. label Feb 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code snippet Temporary code that we only need to run once and don't need to merge for long-term use.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant