def submit_message(self, phone, message):
        """
        Submits the message for phone to the email gateway.

        Returns true in case of success

        In case of a failure an exception is raised
        """
        if self.smsgateway:
            identifier = self.smsgateway.option_dict.get("SMTPIDENTIFIER")
            recipient = self.smsgateway.option_dict.get("MAILTO").format(
                otp=message, phone=phone)
            subject = self.smsgateway.option_dict.get(
                "SUBJECT", "{phone}").format(otp=message, phone=phone)
            body = self.smsgateway.option_dict.get("BODY",
                                                   "{otp}").format(otp=message,
                                                                   phone=phone)
        else:
            identifier = self.config.get("IDENTIFIER")
            server = self.config.get("MAILSERVER")
            sender = self.config.get("MAILSENDER")
            recipient = self.config.get("MAILTO")
            subject = self.config.get("SUBJECT", PHONE_TAG)
            body = self.config.get("BODY", MSG_TAG)

            if not (server and recipient and sender) and not (identifier and \
                    recipient):
                log.error("incomplete config: %s. MAILTO and (IDENTIFIER or "
                          "MAILSERVER and MAILSENDER) needed" % self.config)
                raise SMSError(-1, "Incomplete SMS config.")

            log.debug("submitting message {0!r} to {1!s}".format(body, phone))
            recipient = string.replace(recipient, PHONE_TAG, phone)
            subject = string.replace(subject, PHONE_TAG, phone)
            subject = string.replace(subject, MSG_TAG, message)
            body = string.replace(body, PHONE_TAG, phone)
            body = string.replace(body, MSG_TAG, message)

        if identifier:
            r = send_email_identifier(identifier, recipient, subject, body)
        else:
            username = self.config.get("MAILUSER")
            password = self.config.get("MAILPASSWORD")
            r = send_email_data(server, subject, body, sender, recipient,
                                username, password)
        if not r:
            raise SMSError(500, "Failed to deliver SMS to SMTP Gateway.")

        return True
    def submit_message(self, phone, message):
        """
        send a message to a phone using an external script

        :param phone: the phone number
        :param message: the message to submit to the phone
        :return:
        """
        log.debug("submitting message {0!s} to {1!s}".format(message, phone))
        if not self.smsgateway:
            # this should not happen. We now always use sms gateway definitions.
            log.warning("Missing smsgateway definition!")
            raise SMSError(-1, "Missing smsgateway definition!")

        script = self.smsgateway.option_dict.get("script")
        background = self.smsgateway.option_dict.get("background")

        script_name = self.script_directory + "/" + script
        proc_args = [script_name]
        proc_args.append(phone)

        # As the message can contain blanks... it is passed via stdin
        rcode = 0
        try:
            log.info("Starting script {script!r}.".format(script=script_name))
            p = subprocess.Popen(proc_args,
                                 cwd=self.script_directory,
                                 universal_newlines=True,
                                 stdin=subprocess.PIPE)
            p.communicate(message)
            if background == SCRIPT_WAIT:
                rcode = p.wait()
        except Exception as e:
            log.warning("Failed to execute script {0!r}: {1!r}".format(
                script_name, e))
            log.warning(traceback.format_exc())
            if background == SCRIPT_WAIT:
                raise SMSError(-1, "Failed to start script for sending SMS.")

        if rcode:
            log.warning(
                "Script {script!r} failed to execute with error code {error!r}"
                .format(script=script_name, error=rcode))
            raise SMSError(-1, "Error during execution of the script.")
        else:
            log.info("SMS delivered to {0!s}.".format(phone))

        return True
    def submit_message(self, phone, message):
        if self.smsgateway:
            username = self.smsgateway.option_dict.get("USERNAME")
            password = self.smsgateway.option_dict.get("PASSWORD")
            proxy = self.smsgateway.option_dict.get("PROXY")
        else:
            username = self.config.get("USERNAME")
            password = self.config.get("PASSWORD")
            proxy = self.config.get('PROXY')
        proxies = None
        if proxy:
            protocol = proxy.split(":")[0]
            proxies = {protocol: proxy}

        r = requests.post(URL,
                          data=REQUEST_XML %
                          (phone.strip().strip("+"), message),
                          headers={'content-type': 'text/xml'},
                          auth=(username, password),
                          proxies=proxies)

        log.debug("SMS submitted: {0!s}".format(r.status_code))
        log.debug("response content: {0!s}".format(r.text))

        if r.status_code != 200:
            raise SMSError(r.status_code, "SMS could not be "
                           "sent: %s" % r.status_code)
        return True
Exemple #4
0
    def test_00_SMSError(self):
        err = SMSError(100, "Some Error")
        text = "{0!r}".format(err)
        self.assertTrue(text == "SMSError(error_id=100, description='Some "
                                "Error')", text)

        text = "{0!s}".format(err)
        self.assertTrue(text == "Some Error", text)
Exemple #5
0
    def test_00_SMSError(self):
        err = SMSError(100, "Some Error")
        text = "%r" % err
        self.assertTrue(
            text == "SMSError(error_id=100, description='Some "
            "Error')", text)

        text = "%s" % err
        self.assertTrue(text == "Some Error", text)
    def _check_success(self, response):
        """
        Check the success according to the reply
        1. if RETURN_SUCCESS is defined
        2. if RETURN_FAIL is defined
        :response reply: A response object.
        """
        reply = response.text
        ret = False
        if self.smsgateway:
            return_success = self.smsgateway.option_dict.get("RETURN_SUCCESS")
            return_fail = self.smsgateway.option_dict.get("RETURN_FAIL")
        else:
            return_success = self.config.get("RETURN_SUCCESS")
            return_fail = self.config.get("RETURN_FAIL")

        if return_success:
            if return_success in reply:
                log.debug("sending sms success")
                ret = True
            else:
                log.warning("failed to send sms. Reply %s does not match "
                            "the RETURN_SUCCESS definition" % reply)
                raise SMSError(
                    response.status_code,
                    "We received a none success reply from the "
                    "SMS Gateway: {0!s} ({1!s})".format(reply, return_success))

        elif return_fail:
            if return_fail in reply:
                log.warning("sending sms failed. %s was not found "
                            "in %s" % (return_fail, reply))
                raise SMSError(
                    response.status_code,
                    "We received the predefined error from the "
                    "SMS Gateway.")
            else:
                log.debug("sending sms success")
                ret = True
        else:
            ret = True
        return ret
    def submit_message(self, phone, message):
        """
        send a message to a phone via an smpp protocol to smsc

        :param phone: the phone number
        :param message: the message to submit to the phone
        :return:
        """
        if not import_successful:  # pragma: no cover
            log.error("smpplib can not be found!")
            raise SMSError(404, "smpplib can not be found!")

        log.debug("submitting message {0!s} to {1!s}".format(message, phone))
        if not self.smsgateway:
            # this should not happen. We now always use sms gateway definitions.
            log.warning("Missing smsgateway definition!")
            raise SMSError(-1, "Missing smsgateway definition!")

        smsc_host = self.smsgateway.option_dict.get("SMSC_HOST")
        smsc_port = self.smsgateway.option_dict.get("SMSC_PORT")
        sys_id = self.smsgateway.option_dict.get("SYSTEM_ID")
        passwd = self.smsgateway.option_dict.get("PASSWORD")
        s_addr_ton = parse_int(self.smsgateway.option_dict.get("S_ADDR_TON"))
        s_addr_npi = parse_int(self.smsgateway.option_dict.get("S_ADDR_NPI"))
        s_addr = self.smsgateway.option_dict.get("S_ADDR")
        d_addr_ton = parse_int(self.smsgateway.option_dict.get("D_ADDR_TON"))
        d_addr_npi = parse_int(self.smsgateway.option_dict.get("D_ADDR_NPI"))

        if not smsc_host:
            log.warning("Can not submit message. SMSC_HOST is missing.")
            raise SMSError(-1,
                           "No SMSC_HOST specified in the provider config.")

        if not smsc_port:
            log.warning("Can not submit message. SMSC_PORT is missing.")
            raise SMSError(-1,
                           "No SMSC_PORT specified in the provider config.")

        # Initialize the SMPP Client
        client = None
        error_message = None
        try:
            client = smpplib.client.Client(smsc_host, smsc_port)
            client.connect()
            r = client.bind_transmitter(system_id=sys_id, password=passwd)
            log.debug("bind_transmitter returns {0!r}".format(r))
            r = client.send_message(source_addr_ton=s_addr_ton,
                                    source_addr_npi=s_addr_npi,
                                    source_addr=s_addr,
                                    dest_addr_ton=d_addr_ton,
                                    dest_addr_npi=d_addr_npi,
                                    destination_addr=phone,
                                    short_message=message)
            log.debug("send_message returns {0!r}".format(r))

        except Exception as err:
            error_message = "{0!r}".format(err)
            log.warning("Failed to send message: {0!r}".format(error_message))
            log.debug("{0!s}".format(traceback.format_exc()))

        finally:
            if client:
                client.disconnect()

        if error_message:
            raise SMSError(
                error_message, "SMS could not be "
                "sent: {0!r}".format(error_message))
        return True
    def submit_message(self, phone, message):
        """
        send a message to a phone via an http sms gateway

        :param phone: the phone number
        :param message: the message to submit to the phone
        :return:
        """
        log.debug("submitting message {0!r} to {1!s}".format(message, phone))
        parameter = {}
        regexp = self.smsgateway.option_dict.get("REGEXP", "")
        if regexp != "":
            phone = re.sub(regexp, "", phone)
        if self.smsgateway:
            url = self.smsgateway.option_dict.get("URL")
            method = self.smsgateway.option_dict.get("HTTP_METHOD", "GET")
            username = self.smsgateway.option_dict.get("USERNAME")
            password = self.smsgateway.option_dict.get("PASSWORD")
            ssl_verify = self.smsgateway.option_dict.get("CHECK_SSL",
                                                         "yes") == "yes"
            # FIXME: The Proxy option is deprecated and will be removed a version > 2.21
            proxy = self.smsgateway.option_dict.get("PROXY")
            http_proxy = self.smsgateway.option_dict.get('HTTP_PROXY')
            https_proxy = self.smsgateway.option_dict.get('HTTPS_PROXY')
            timeout = self.smsgateway.option_dict.get("TIMEOUT") or 3
            for k, v in self.smsgateway.option_dict.iteritems():
                if k not in self.parameters().get("parameters"):
                    # This is an additional option
                    parameter[k] = v.format(otp=message, phone=phone)
        else:
            url = self.config.get('URL')
            method = self.config.get('HTTP_Method', 'GET')
            username = self.config.get('USERNAME')
            password = self.config.get('PASSWORD')
            ssl_verify = self.config.get('CHECK_SSL', True)
            # FIXME: The Proxy option is deprecated and will be removed a version > 2.21
            proxy = self.config.get('PROXY')
            http_proxy = self.config.get('HTTP_PROXY')
            https_proxy = self.config.get('HTTPS_PROXY')
            parameter = self._get_parameters(message, phone)
            timeout = self.config.get("TIMEOUT") or 3

        if url is None:
            log.warning("can not submit message. URL is missing.")
            raise SMSError(-1, "No URL specified in the provider config.")
        basic_auth = None

        # there might be the basic authentication in the request url
        # like http://user:passw@hostname:port/path
        if password is None and username is None:
            parsed_url = urlparse(url)
            if "@" in parsed_url[1]:
                puser, server = parsed_url[1].split('@')
                username, password = puser.split(':')

        if username and password is not None:
            basic_auth = (username, password)

        proxies = {}
        if http_proxy:
            proxies["http"] = http_proxy
        if https_proxy:
            proxies["https"] = https_proxy
        if not proxies and proxy:
            # No new proxy config but only the old one.
            protocol = proxy.split(":")[0]
            proxies = {protocol: proxy}

        # url, parameter, username, password, method
        requestor = requests.get
        params = parameter
        data = {}
        if method == "POST":
            requestor = requests.post
            params = {}
            data = parameter

        log.debug("issuing request with parameters %s and method %s and "
                  "authentication %s to url %s." %
                  (parameter, method, basic_auth, url))
        r = requestor(url,
                      params=params,
                      data=data,
                      verify=ssl_verify,
                      auth=basic_auth,
                      timeout=float(timeout),
                      proxies=proxies)
        log.debug(
            "queued SMS on the HTTP gateway. status code returned: {0!s}".
            format(r.status_code))

        # We assume, that all gateways return with HTTP Status Code 200,
        # 201 or 202
        if r.status_code not in [200, 201, 202]:
            raise SMSError(r.status_code, "SMS could not be "
                           "sent: %s" % r.status_code)
        success = self._check_success(r)
        return success
Exemple #9
0
    def submit_message(self, phone, message):
        """
        send a message to a phone via an smpp protocol to smsc

        :param phone: the phone number
        :param message: the message to submit to the phone
        :return:
        """
        log.debug("submitting message {0!s} to {1!s}".format(message, phone))
        parameter = {}
        if self.smsgateway:
            smsc_host = self.smsgateway.option_dict.get("SMSC_HOST")
            smsc_port = self.smsgateway.option_dict.get("SMSC_PORT")
            sys_id = self.smsgateway.option_dict.get("SYSTEM_ID")
            passwd = self.smsgateway.option_dict.get("PASSWORD")
            s_addr_ton = int(self.smsgateway.option_dict.get("S_ADDR_TON"), 16)
            s_addr_npi = int(self.smsgateway.option_dict.get("S_ADDR_NPI"), 16)
            s_addr = self.smsgateway.option_dict.get("S_ADDR")
            d_addr_ton = int(self.smsgateway.option_dict.get("D_ADDR_TON"), 16)
            d_addr_npi = int(self.smsgateway.option_dict.get("D_ADDR_NPI"), 16)

        else:
            smsc_host = self.config.get('SMSC_HOST')
            smsc_port = self.config.get('SMSC_PORT')
            sys_id = self.config.get('SYSTEM_ID')
            passwd = self.config.get('PASSWORD')
            s_addr_ton = int(self.config.get('S_ADDR_TON'), 16)
            s_addr_npi = int(self.config.get('S_ADDR_NPI'), 16)
            s_addr = self.config.get('S_ADDR')
            d_addr_ton = int(self.config.get('D_ADDR_TON'), 16)
            d_addr_npi = int(self.config.get('D_ADDR_NPI'), 16)

        if smsc_host is None:
            log.warning("can not submit message. SMSC_HOST is missing.")
            raise SMSError(-1,
                           "No SMSC_HOST specified in the provider config.")
        else:
            if smsc_port is None:
                log.warning("can not submit message. SMSC_PORT is missing.")
                raise SMSError(
                    -1, "No SMSC_PORT specified in the provider config.")

        #SMPP Part
        client = None
        error_message = None
        try:
            client = smpplib.client.Client(smsc_host.encode("ascii"),
                                           smsc_port.encode("ascii"))
            client.connect()
            client.bind_transmitter(system_id=sys_id.encode("ascii"),
                                    password=passwd.encode("ascii"))
            client.send_message(
                source_addr_ton=s_addr_ton,
                source_addr_npi=s_addr_npi,
                source_addr=s_addr.encode("ascii"),
                dest_addr_ton=d_addr_ton,
                dest_addr_npi=d_addr_npi,
                destination_addr=phone.strip().strip("+").encode("ascii"),
                short_message=message.encode("ascii"))
        except KeyError as inst:
            error_message = inst.args[0]
        except:
            error_message = "Bad connection string"
        finally:
            if client:
                client.disconnect()

        if error_message is not None:
            raise SMSError(error_message, "SMS could not be "
                           "sent: %s" % error_message)
        return True
    def submit_message(self, phone, message):
        """
        send a message to a phone via an http sms gateway
        :param phone: the phone number
        :param message: the message to submit to the phone
        :return:
        """
        success = False
        url = self.config.get('URL')
        if url is None:
            log.warning("can not submit message. URL is missing.")
            raise SMSError(-1, "No URL specified in the provider config.")

        log.debug("submitting message {0!s} to {1!s}".format(message, phone))

        method = self.config.get('HTTP_Method', 'GET')
        username = self.config.get('USERNAME')
        password = self.config.get('PASSWORD')
        ssl_verify = self.config.get('CHECK_SSL', True)
        parameter = self._get_parameters(message, phone)
        basic_auth = None

        # there might be the basic authentication in the request url
        # like http://user:passw@hostname:port/path
        if password is None and username is None:
            parsed_url = urlparse(url)
            if "@" in parsed_url[1]:
                puser, server = parsed_url[1].split('@')
                username, password = puser.split(':')

        if username and password is not None:
            basic_auth = (username, password)

        proxy = self.config.get('PROXY')
        proxies = None
        if proxy:
            protocol = proxy.split(":")[0]
            proxies = {protocol: proxy}

        # url, parameter, username, password, method
        requestor = requests.get
        params = parameter
        data = {}
        if method == "POST":
            requestor = requests.post
            params = {}
            data = parameter

        log.debug("issuing request with parameters %s and method %s and "
                  "authentication %s to url %s." %
                  (parameter, method, basic_auth, url))
        r = requestor(url,
                      params=params,
                      data=data,
                      verify=ssl_verify,
                      auth=basic_auth,
                      proxies=proxies)
        log.debug(
            "queued SMS on the HTTP gateway. status code returned: {0!s}".
            format(r.status_code))

        # We assume, that all gateway return with HTTP Status Code 200
        if r.status_code != 200:
            raise SMSError(r.status_code, "SMS could not be "
                           "sent: %s" % r.status_code)
        success = self._check_success(r)
        return success