コード例 #1
0
def send_sms(domain, contact, phone_number, text, metadata=None):
    """
    Sends an outbound SMS. Returns false if it fails.
    """
    if phone_number is None:
        return False
    if isinstance(phone_number, int) or isinstance(phone_number, long):
        phone_number = str(phone_number)
    phone_number = clean_phone_number(phone_number)

    msg = SMSLog(domain=domain,
                 phone_number=phone_number,
                 direction=OUTGOING,
                 date=datetime.utcnow(),
                 backend_id=None,
                 text=text)
    if contact:
        msg.couch_recipient = contact._id
        msg.couch_recipient_doc_type = contact.doc_type
    add_msg_tags(msg, metadata)

    def onerror():
        logging.exception("Problem sending SMS to %s" % phone_number)

    return queue_outgoing_sms(msg, onerror=onerror)
コード例 #2
0
def send_sms_to_verified_number(verified_number, text, metadata=None):
    """
    Sends an sms using the given verified phone number entry.
    
    verified_number The VerifiedNumber entry to use when sending.
    text            The text of the message to send.
    
    return  True on success, False on failure
    """
    backend = verified_number.backend
    msg = SMSLog(couch_recipient_doc_type=verified_number.owner_doc_type,
                 couch_recipient=verified_number.owner_id,
                 phone_number="+" + str(verified_number.phone_number),
                 direction=OUTGOING,
                 date=datetime.utcnow(),
                 domain=verified_number.domain,
                 backend_id=backend._id,
                 text=text)
    add_msg_tags(msg, metadata)

    def onerror():
        logging.exception("Exception while sending SMS to VerifiedNumber id " +
                          verified_number._id)

    return queue_outgoing_sms(msg, onerror=onerror)
コード例 #3
0
ファイル: views.py プロジェクト: tsinkala/commcare-hq
def post(request, domain):
    # TODO: Figure out if this is being used anywhere and remove it if not
    """
    We assume sms sent to HQ will come in the form
    http://hqurl.com?username=%(username)s&password=%(password)s&id=%(phone_number)s&text=%(message)s
    """
    text = request.REQUEST.get('text', '')
    to = request.REQUEST.get('id', '')
    username = request.REQUEST.get('username', '')
    # ah, plaintext passwords....
    # this seems to be the most common API that a lot of SMS gateways expose
    password = request.REQUEST.get('password', '')
    if not text or not to or not username or not password:
        error_msg = 'ERROR missing parameters. Received: %(1)s, %(2)s, %(3)s, %(4)s' % \
                     ( text, to, username, password )
        logging.error(error_msg)
        return HttpResponseBadRequest(error_msg)
    user = authenticate(username=username, password=password)
    if user is None or not user.is_active:
        return HttpResponseBadRequest("Authentication fail")
    msg = SMSLog(
        domain=domain,
        # TODO: how to map phone numbers to recipients, when phone numbers are shared?
        #couch_recipient=id,
        phone_number=to,
        direction=INCOMING,
        date=datetime.now(),
        text=text)
    msg.save()
    return HttpResponse('OK')
コード例 #4
0
ファイル: migration.py プロジェクト: ekush/commcare-hq
    def testFRISMSLogSync(self):
        prev_couch_count = self.getSMSLogCount()
        prev_sql_count = self.getSMSCount()

        # Test Create
        smslog = SMSLog()
        self.setRandomSMSLogValues(smslog)
        smslog.save()

        sleep(1)
        smslog = FRISMSLog.get(smslog._id)
        self.setRandomFRISMSLogValues(smslog)
        smslog.save()

        sleep(1)
        self.assertEqual(self.getSMSLogCount(), prev_couch_count + 1)
        self.assertEqual(self.getSMSCount(), prev_sql_count + 1)

        sms = SMS.objects.get(couch_id=smslog._id)
        self.checkFieldValues(smslog, sms, FRISMSLog._migration_get_fields())
        self.assertTrue(FRISMSLog.get_db().get_rev(
            smslog._id).startswith('2-'))

        # Test Update
        self.setRandomSMSLogValues(smslog)
        self.setRandomFRISMSLogValues(smslog)
        smslog.save()

        sleep(1)
        self.assertEqual(self.getSMSLogCount(), prev_couch_count + 1)
        self.assertEqual(self.getSMSCount(), prev_sql_count + 1)
        sms = SMS.objects.get(couch_id=smslog._id)
        self.checkFieldValues(smslog, sms, FRISMSLog._migration_get_fields())
        self.assertTrue(SMSLog.get_db().get_rev(smslog._id).startswith('3-'))
コード例 #5
0
 def _get_fake_sms(self, text):
     msg = SMSLog(domain=self.domain,
                  phone_number='+16175555454',
                  direction=OUTGOING,
                  date=datetime.utcnow(),
                  backend_id=self.mobile_backend.get_id,
                  text=text)
     msg.save()
     return msg
コード例 #6
0
ファイル: api.py プロジェクト: tsinkala/commcare-hq
def send_sms_with_backend(domain, phone_number, text, backend_id):
    msg = SMSLog(domain=domain,
                 phone_number=phone_number,
                 direction=OUTGOING,
                 date=datetime.utcnow(),
                 text=text)

    def onerror():
        logging.exception("Exception while sending SMS to %s with backend %s" %
                          (phone_number, backend_id))

    return send_message_via_backend(msg,
                                    MobileBackend.load(backend_id),
                                    onerror=onerror)
コード例 #7
0
ファイル: utils.py プロジェクト: ekush/commcare-hq
def send_test_message(verified_number, text, metadata=None):
    msg = SMSLog(couch_recipient_doc_type=verified_number.owner_doc_type,
                 couch_recipient=verified_number.owner_id,
                 phone_number="+" + str(verified_number.phone_number),
                 direction=OUTGOING,
                 date=datetime.utcnow(),
                 domain=verified_number.domain,
                 text=text,
                 processed=True,
                 datetime_to_process=datetime.utcnow(),
                 queued_timestamp=datetime.utcnow())
    msg.save()
    add_msg_tags(msg, metadata)
    return True
コード例 #8
0
ファイル: api.py プロジェクト: ekush/commcare-hq
def send_sms_with_backend(domain,
                          phone_number,
                          text,
                          backend_id,
                          metadata=None):
    phone_number = clean_phone_number(phone_number)
    msg = SMSLog(domain=domain,
                 phone_number=phone_number,
                 direction=OUTGOING,
                 date=datetime.utcnow(),
                 backend_id=backend_id,
                 text=text)
    add_msg_tags(msg, metadata)

    return queue_outgoing_sms(msg)
コード例 #9
0
ファイル: util.py プロジェクト: tsinkala/commcare-hq
def q_and_a(testcase,
            answer,
            expected_response,
            domain=DOMAIN,
            contact_id=CONTACT_ID,
            print_output=True):

    responses = get_responses(
        SMSLog(couch_recipient=contact_id, domain=domain, text=answer))
    [answer_back] = responses
    testcase.assertEqual(expected_response, answer_back,
                         "Response to '%s' expected '%s' but was '%s'" % \
                         (answer, expected_response, answer_back))
    if print_output:
        print "%s -> %s" % (answer, answer_back)
コード例 #10
0
ファイル: api.py プロジェクト: ekush/commcare-hq
def incoming(phone_number,
             text,
             backend_api,
             timestamp=None,
             domain_scope=None,
             backend_message_id=None,
             delay=True,
             backend_attributes=None,
             raw_text=None):
    """
    entry point for incoming sms

    phone_number - originating phone number
    text - message content
    backend_api - backend API ID of receiving sms backend
    timestamp - message received timestamp; defaults to now (UTC)
    domain_scope - if present, only messages from phone numbers that can be
      definitively linked to this domain will be processed; others will be
      dropped (useful to provide security when simulating incoming sms)
    """
    # Log message in message log
    if text is None:
        text = ""
    phone_number = clean_phone_number(phone_number)
    msg = SMSLog(
        phone_number=phone_number,
        direction=INCOMING,
        date=timestamp or datetime.utcnow(),
        text=text,
        domain_scope=domain_scope,
        backend_api=backend_api,
        backend_message_id=backend_message_id,
        raw_text=raw_text,
    )
    if backend_attributes:
        for k, v in backend_attributes.items():
            setattr(msg, k, v)
    if settings.SMS_QUEUE_ENABLED:
        msg.processed = False
        msg.datetime_to_process = datetime.utcnow()
        msg.queued_timestamp = msg.datetime_to_process
        msg.save()
        enqueue_directly(msg)
    else:
        msg.processed = True
        msg.save()
        process_incoming(msg, delay=delay)
    return msg
コード例 #11
0
ファイル: generator.py プロジェクト: ekush/commcare-hq
def arbitrary_messages_by_backend_and_direction(backend_ids,
                                                phone_number=None,
                                                domain=None,
                                                directions=DIRECTIONS):
    phone_number = phone_number or TEST_NUMBER
    domain = domain or TEST_DOMAIN
    messages = []
    for api_id, instance_id in backend_ids.items():
        for direction in directions:
            sms_log = SMSLog(direction=direction,
                             phone_number=phone_number,
                             domain=domain,
                             backend_api=api_id,
                             backend_id=instance_id,
                             text=arbitrary_message(),
                             date=datetime.datetime.utcnow())
            sms_log.save()
            messages.append(sms_log)
    return messages
コード例 #12
0
def send_sms_with_backend(domain,
                          phone_number,
                          text,
                          backend_id,
                          metadata=None):
    phone_number = clean_phone_number(phone_number)
    msg = SMSLog(domain=domain,
                 phone_number=phone_number,
                 direction=OUTGOING,
                 date=datetime.utcnow(),
                 backend_id=backend_id,
                 text=text)
    add_msg_tags(msg, metadata)

    def onerror():
        logging.exception("Exception while sending SMS to %s with backend %s" %
                          (phone_number, backend_id))

    return queue_outgoing_sms(msg, onerror=onerror)
コード例 #13
0
ファイル: api.py プロジェクト: tsinkala/commcare-hq
def send_sms(domain, id, phone_number, text):
    """
    Sends an outbound SMS. Returns false if it fails.
    """
    if phone_number is None:
        return False
    if isinstance(phone_number, int) or isinstance(phone_number, long):
        phone_number = str(phone_number)
    logging.debug('Sending message: %s' % text)
    phone_number = clean_phone_number(phone_number)

    msg = SMSLog(domain=domain,
                 couch_recipient=id,
                 couch_recipient_doc_type="CouchUser",
                 phone_number=phone_number,
                 direction=OUTGOING,
                 date=datetime.utcnow(),
                 text=text)

    def onerror():
        logging.exception("Problem sending SMS to %s" % phone_number)

    return send_message_via_backend(msg, onerror=onerror)
コード例 #14
0
ファイル: api.py プロジェクト: tsinkala/commcare-hq
def incoming(phone_number,
             text,
             backend_api,
             timestamp=None,
             domain_scope=None,
             delay=True):
    """
    entry point for incoming sms

    phone_number - originating phone number
    text - message content
    backend_api - backend ID of receiving sms backend
    timestamp - message received timestamp; defaults to now (UTC)
    domain_scope - if present, only messages from phone numbers that can be
      definitively linked to this domain will be processed; others will be
      dropped (useful to provide security when simulating incoming sms)
    """
    phone_number = clean_phone_number(phone_number)
    v = VerifiedNumber.by_phone(phone_number, include_pending=True)
    if domain_scope:
        # only process messages for phones known to be associated with this domain
        if v is None or v.domain != domain_scope:
            raise RuntimeError(
                'attempted to simulate incoming sms from phone number not verified with this domain'
            )

    # Log message in message log
    msg = SMSLog(phone_number=phone_number,
                 direction=INCOMING,
                 date=timestamp or datetime.utcnow(),
                 text=text,
                 backend_api=backend_api)
    if v is not None and v.verified:
        msg.couch_recipient_doc_type = v.owner_doc_type
        msg.couch_recipient = v.owner_id
        msg.domain = v.domain
    msg.save()

    create_billable_for_sms(msg, backend_api, delay=delay)

    if v is not None and v.verified:
        for h in settings.SMS_HANDLERS:
            try:
                handler = to_function(h)
            except:
                logging.exception('error loading sms handler: %s' % h)
                continue

            try:
                was_handled = handler(v, text)
            except:
                logging.exception(
                    'unhandled error in sms handler %s for message [%s]' %
                    (h, text))
                was_handled = False

            if was_handled:
                break
    else:
        if not process_sms_registration(msg):
            import verify
            verify.process_verification(phone_number, text)

    return msg