def delete_campaigns(data, token, expected_status=(200,)): """ This method sends a DELETE request to Push Campaign API to delete multiple campaigns. :type data: dict :type token: string :type expected_status: tuple[int] :rtype dict """ response = send_request('delete', PushCampaignApiUrl.CAMPAIGNS, token, data=data) logger.info('tests : delete_campaigns: %s', response.content) print('tests : delete_campaigns: %s', response.content) assert response.status_code in expected_status return response.json()
def get_campaign(campaign_id, token, expected_status=(200,)): """ Get a push campaign from API given by campaign id. :type campaign_id: int | long :type token: string :type expected_status: tuple[int] :rtype dict """ response = send_request('get', PushCampaignApiUrl.CAMPAIGN % campaign_id, token) logger.info('tests : get_campaign: %s', response.content) print('tests : get_campaign: %s', response.content) assert response.status_code in expected_status return response.json()
def unschedule_campaign(campaign_id, token, expected_status=(200,)): """ This method sends a DELETE request to Push Campaign API to unschedule a push campaign. :type campaign_id: int | long :type token: string :type expected_status: tuple[int] :rtype dict """ response = send_request('delete', PushCampaignApiUrl.SCHEDULE % campaign_id, token) logger.info('tests : unschedule_campaign: %s', response.content) print('tests : unschedule_campaign: %s', response.content) assert response.status_code in expected_status return response.json()
def reschedule_campaign(campaign_id, data, token, expected_status=(200,)): """ This method sends a PUT request to Push Campaign API to reschedule a push campaign with given schedule data. :type campaign_id: int | long :type data: dict :type token: string :type expected_status: tuple[int] :rtype dict """ response = send_request('put', PushCampaignApiUrl.SCHEDULE % campaign_id, token, data) logger.info('tests: reschedule_campaign: %s', response.content) print('tests: reschedule_campaign: %s', response.content) assert response.status_code in expected_status return response.json()
def send_campaign(campaign_id, token, expected_status=(200,)): """ This method sends a POST request to Push Campaign API to send a campaign to associated candidates. :type campaign_id: int | long :type token: string :type expected_status: tuple[int] :rtype dict """ url = PushCampaignApiUrl.SEND % campaign_id response = send_request('post', url, token) logger.info('tests : send_campaign: %s', response.content) print('tests : send_campaign: %s', response.content) assert response.status_code in expected_status return response.json()
def delete_campaign(campaign_id, token, expected_status=(200,)): """ This method sends a DELETE request to Push Campaign API to delete a campaign given by campaign_id. :type campaign_id: int | long :type token: string :type expected_status: tuple[int] :rtype dict """ response = send_request('delete', PushCampaignApiUrl.CAMPAIGN % campaign_id, token) logger.info('tests : delete_campaign: %s', response.content) print('tests : delete_campaign: %s', response.content) assert response.status_code in expected_status return response.json()
def get_campaigns(token, page=DEFAULT_PAGE, per_page=DEFAULT_PAGE_SIZE, expected_status=(200,)): """ Get campaign of a specific user. Default page number is 1 and per_page (page size) is 10 :type page: int | long :type per_page: int | long :type token: string :type expected_status: tuple[int] """ query = '?page=%s&per_page=%s' % (page, per_page) response = send_request('get', PushCampaignApiUrl.CAMPAIGNS + query, token) logger.info('tests : get_campaigns: %s', response.content) print('tests : get_campaigns: %s', response.content) assert response.status_code in expected_status return response.json()
def create_campaign(data, token, expected_status=(201,)): """ Send a POST request to Push Campaign API with campaign data to create a new Push Campaign. :type data: dict :type token: string :type expected_status: tuple[int] :rtype dict """ response = send_request('post', PushCampaignApiUrl.CAMPAIGNS, token, data) logger.info('tests : create_campaign: %s', response.content) print('tests : create_campaign: %s', response.content) assert response.status_code in expected_status headers = response.headers response = response.json() response['headers'] = headers return response
def get_blasts(campaign_id, token, page=DEFAULT_PAGE, per_page=DEFAULT_PAGE_SIZE, expected_status=(200,), count=None): """ This method sends a GET request to Push Campaign API to get a list of blasts associated with a campaign given by campaign_id. :type campaign_id: int | long :type token: string :type page: int | long :type per_page: int | long :type expected_status: tuple[int] :type count: int | None :rtype dict """ query = '?page=%s&per_page=%s' % (page, per_page) response = send_request('get', PushCampaignApiUrl.BLASTS % campaign_id + query, token) logger.info('tests : get_blasts: %s', response.content) print('tests : get_blasts: %s', response.content) assert response.status_code in expected_status response = response.json() if count: assert len(response['blasts']) == count return response
def send_campaign_to_candidate(self, candidate_and_device_ids): """ This method sends campaign to a single candidate. It gets the devices associated with the candidate and sends this campaign to all devices using OneSignal's RESTful API. Destination url is first converted to something like http://127.0.0.1:8012/redirect/1 which is then signed http://127.0.0.1:8012/v1/redirect/1052?valid_until=1453990099.0 # &auth_user=no_user&extra=&signature=cWQ43J%2BkYetfmE2KmR85%2BLmvuIw%3D This URL is sent to candidate in push notification and when user clicks on notification he is redirected to our url redirection endpoint, which after updating campaign stats, redirected to original url given for campaign owner. :param candidate_and_device_ids: list of tuple and each tuple contains id of candidate and list of candidate device ids :return: True | None """ with app.app_context(): candidate_id, device_ids = candidate_and_device_ids candidate = Candidate.get_by_id(candidate_id) self.campaign = PushCampaign.get_by_id(self.campaign_id) assert isinstance(candidate, Candidate), \ 'candidate should be instance of Candidate Model' logger.info('Going to send campaign to candidate (id = %s)' % candidate.id) # A device is actually candidate's desktop, android or iOS machine where # candidate will receive push notifications. Device id is given by OneSignal. if not device_ids: logger.error('Candidate has not subscribed for push notification. candidate_id: %s,' 'campaign_id: %s' % (candidate_id, self.campaign_id)) else: try: destination_url = self.campaign.url url_conversion_id = self.create_or_update_url_conversion( destination_url=destination_url, source_url='') redirect_url = PushCampaignApiUrl.REDIRECT % url_conversion_id # expiry duration is of one year expiry_time = datetime.datetime.now() + relativedelta(years=+1) signed_url = CampaignUtils.sign_redirect_url(redirect_url, expiry_time) if CampaignUtils.IS_DEV: # update the 'source_url' in "url_conversion" record. # Source URL should not be saved in database. But we have tests written # for Redirection endpoint. That's why in case of DEV, # I am saving source URL here. self.create_or_update_url_conversion(url_conversion_id=url_conversion_id, source_url=signed_url) one_signal_client = OneSignalSdk(app_id=ONE_SIGNAL_APP_ID, user_auth_key=ONE_SIGNAL_REST_API_KEY) response = one_signal_client.create_notification(self.campaign.body_text, heading=self.campaign.name, url=signed_url, player_ids=device_ids) if response.ok: campaign_send = PushCampaignSend(blast_id=self.campaign_blast_id, candidate_id=candidate.id ) PushCampaignSend.save(campaign_send) push_url_conversion = PushCampaignSendUrlConversion( url_conversion_id=url_conversion_id, send_id=campaign_send.id ) PushCampaignSendUrlConversion.save(push_url_conversion) return True else: response = response.json() errors = response['errors'] logger.error('Error while sending push notification to candidate (id: %s),' 'Errors: %s' % (candidate_id, errors)) UrlConversion.delete(url_conversion_id) except Exception: logger.exception('Unable to send push campaign (id: %s) to candidate (id: %s)' % (self.campaign.id, candidate.id))
""" Run Celery Worker For Celery to run from command line, script runs as separate process with celery command Usage: open terminal cd to talent-flask-services directory Run the following command to start celery worker: $ celery -A push_campaign_service.push_campaign_app.celery_app worker --concurrency=4 --loglevel=info """ # Service Specific from push_campaign_service.common.talent_celery import CELERY_WORKER_ARGS from push_campaign_service.push_campaign_app import celery_app, logger, app from push_campaign_service.common.talent_config_manager import TalentConfigKeys from push_campaign_service.common.campaign_services.campaign_utils import CampaignUtils try: logger.info("Celery worker has been started successfully for:%s" % app.name) celery_app.start(argv=CELERY_WORKER_ARGS + [CampaignUtils.PUSH] + ['-n', CampaignUtils.PUSH]) except Exception as e: logger.exception( "Couldn't start Celery worker for push_campaign_service in " "%s environment." % (app.config[TalentConfigKeys.ENV_KEY]))