Compare commits

..

No commits in common. "75833c7c4b67fdbde0ce14388f3a30c8a8dd1a3b" and "96b923642b9c10dc2ce76f894e989566211c7866" have entirely different histories.

8 changed files with 125 additions and 175 deletions

3
.gitignore vendored
View file

@ -1,3 +0,0 @@
MANIFEST
dist/
__pycache__

View file

@ -1,2 +0,0 @@
include COPYING.txt
include examples.py

View file

@ -1,24 +1,17 @@
THIS IS THIS IS:
A Python 3 wrapper around the SMS gateway from CPSMS <https://www.cpsms.dk/>. A Python wrapper around the SMS gateway from CPSMS <https://www.cpsms.dk/>.
THIS IS NOT THIS IS NOT:
Some sort of magic, free SMS gateway. Some sort of magic, free SMS gateway.
INSTALLATION
cpsms is available from PyPI <https://pypi.python.org/pypi/cpsms>.
Easiest way to install is: `pip install cpsms`.
REQUIREMENTS
You need to have a (paid) account at CPSMS to be able to use their gateway. You need to have a (paid) account at CPSMS to be able to use their gateway.
They sell a fair, no-nonsense product which I'd recommend if you want to be They sell a fair, no-nonsense product which I'd recommend if you want to be
able to send SMS from your code (primarily to Danish phones). able to send SMS from your code (primarily to Danish phones).
HOW TO USE
See a couple of example use cases in example.py that should have come See a couple of example use cases in example.py that should have come
along with this file. Apart from what is shown in examples.py, this also along with this file. Apart from what is shown in examples.py, this also
supports status callback URLs, delayed sending and flash messages. supports status callback URLs, delayed sending and flash messages.
FURTHER INFO
For more info on parameters, take a look at the API documentation found at: For more info on parameters, take a look at the API documentation found at:
<https://www.cpsms.dk/login/index.php?page=dokumentation>. <https://www.cpsms.dk/login/index.php?page=dokumentation>.

108
cpsms.py Normal file
View file

@ -0,0 +1,108 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-'
"""
Copyright 2010, 2011 Mikkel Munch Mortensen <3xm@detfalskested.dk>.
This file is part of SMS Gateway.
SMS Gateway is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
SMS Gateway is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SMS Gateway. If not, see <http://www.gnu.org/licenses/>.
"""
import urllib, getopt
class Gateway():
'''
A Python wrapper around the SMS gateway from CPSMS <https://www.cpsms.dk/>.
Please look at the README for further description.
'''
default_options = {
'recipients' : [],
'message' : '', # Should be a unicode string.
'callback_url' : '',
'timestamp' : '', # For delaying messages. Format: YYYYMMDDHHMM.
'utf8' : 1,
'flash' : 0,
'group' : 0,
'gateway_base_url' : 'https://www.cpsms.dk/sms/?'
}
options = {}
def __init__(self, username, password, sender_name, options = None):
'''
Initialize SMS gateway, with some options.
'''
self.options = self.default_options
if options != None:
self.options.update(options)
self.options['username'] = username
self.options['password'] = password
self.options['from'] = sender_name
def add_recipient(self, number):
'''
Add a number to the list of recipients.
'''
self.options['recipients'].append(number)
def send(self, message = None):
'''
Send the message specified in self.options to all recipients. Optionally, override the message to be sent.
'''
# Decide what to send
if message == None:
message = self.options['message']
# Raise error if message is empty.
if len(message) == 0:
raise ValueError('Message empty.')
# Raise error if message is too long.
if len(message) > 459:
raise ValueError('Message not allowed to be more than 459 characters. Current message is %i characters.' % len(message))
# Raise error if recipients is empty.
if len(self.options['recipients']) == 0:
raise ValueError('No recipients.')
# Construct gateway URL.
options = [
('username', self.options['username']),
('password', self.options['password']),
('message', message.encode('utf-8')),
('from', self.options['from']),
('utf8', self.options['utf8']),
('flash', self.options['flash']),
('group', self.options['group']),
('url', self.options['callback_url']),
]
for r in self.options['recipients']:
options.append(('recipient[]', r))
if self.options['timestamp'] != '':
options.append(('timestamp', self.options['timestamp']))
url = self.options['gateway_base_url'] + urllib.urlencode(options)
# Send SMS.
remote_call = urllib.urlopen(url)
result = remote_call.read()
remote_call.close()
if result.find('<succes>') > -1:
return True, result
else:
return False, result

View file

@ -1,3 +0,0 @@
"""The cpsms package."""
from .cpsms import Gateway

View file

@ -1,131 +0,0 @@
"""
Copyright 2010-2021 Mikkel Munch Mortensen <3xm@detfalskested.dk>.
This file is part of SMS Gateway.
SMS Gateway is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
SMS Gateway is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SMS Gateway. If not, see <http://www.gnu.org/licenses/>.
"""
import base64
import getopt
import json
import re
from urllib import error, parse, request
from typing import Any, Dict, Tuple
class Gateway:
"""
A Python wrapper around the SMS gateway from CPSMS <https://www.cpsms.dk/>.
Please look at the README for further description.
"""
options: Dict[str, Any] = {}
username: str
password: str
gateway_url: str = "https://api.cpsms.dk/v2/send"
@property
def default_options(self) -> Dict[str, Any]:
"""Get some default options to use."""
return {
"to": "",
"message": "",
"from": "",
"timestamp": "", # For delaying messages. Format: Unix timestamp.
"encoding": "UTF-8",
"dlr_url": "",
"flash": False,
"reference": "",
"format": "GSM",
}
def __init__(
self,
username: str,
password: str,
sender_name: str,
options: Dict[str, Any] = None,
gateway_url: str = None,
) -> None:
"""Initialize SMS gateway."""
self.username = username
self.password = password
self.options = self.default_options
self.options["from"] = sender_name
if options is not None:
self.options.update(options)
if gateway_url:
self.gateway_url = gateway_url
def send(self, to: str = None, message: str = None) -> Tuple[bool, str]:
"""
Send a message to a recipient.
Optionally, override the recpient and the message to be sent.
"""
# Raise an error if the sender is not specified.
if not self.options["from"]:
raise ValueError("Sender name cannot be empty.")
# Update message if specified.
if message is not None:
self.options["message"] = message
# Raise error if message is empty.
if not self.options["message"]:
raise ValueError("Message cannot be empty.")
# Raise error if message is too long.
if len(self.options["message"]) > 459:
raise ValueError(
"Message not allowed to be more than 459 characters."
"Current message is %i characters."
% len(self.options["message"])
)
# Update recipient if specified.
if to is not None:
self.options["to"] = to
# Raise error if recipients is empty.
if not self.options["to"]:
raise ValueError("No recipient is set.")
# Raise error if recipient is not a number.
pattern = re.compile("^[0-9]+$")
if pattern.match(self.options["to"]) is None:
raise ValueError(
"Recipient number must be numbers only (no characters, spaces or +)"
)
# Prepare the data to send along.
options = self.options
options["flash"] = int(options["flash"])
data = json.dumps(options).encode()
# Prepare authentication.
auth_header = "{}:{}".format(self.username, self.password)
auth_header = base64.b64encode(auth_header.encode()).decode()
http_request = request.Request(self.gateway_url, data=data)
http_request.add_header(
"Authorization", "Basic {}".format(auth_header)
)
response = request.urlopen(http_request)
return json.loads(response.read().decode())

View file

@ -1,5 +1,8 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-'
""" """
Copyright 2010-2021 Mikkel Munch Mortensen <3xm@detfalskested.dk>. Copyright 2010, 2011 Mikkel Munch Mortensen <3xm@detfalskested.dk>.
This file is part of SMS Gateway. This file is part of SMS Gateway.
@ -19,14 +22,14 @@ along with SMS Gateway. If not, see <http://www.gnu.org/licenses/>.
import cpsms import cpsms
# The easiest way to send a single message.
gateway1 = cpsms.Gateway('username', 'password', 'SMS Test')
gateway1.add_recipient('+4512345678')
print gateway1.send(u'One way of sending a massage.')
# This will send text messages to Bob and Carol respectively. On their # The easiest way to send a message to multiple recipients.
# devices, the sender will shown as "Alice". gateway2 = cpsms.Gateway('username', 'password', 'SMS Test', {
'recipients' : ['+4512345678', '+4587654321'],
gateway = cpsms.Gateway("username", "password", "Alice") 'message' : u'Another way of sending a message.',
gateway.send("4512345678", "Hello Bob") })
gateway.send("4587654321", "Hello Carol") print gateway2.send()
# The `.send()` method will return the response from the SMS gateway. Have a
# look at the CPSMS documentation to see what responses look like:
# <https://api.cpsms.dk/documentation/index.html#send>

View file

@ -1,15 +0,0 @@
from distutils.core import setup
setup(
name="cpsms",
packages=["cpsms"],
version="2.0.3",
author="Mikkel Munch Mortensen",
author_email="3xm@detfalskested.dk",
url="https://github.com/decibyte/cpsms",
description=(
"A Python wrapper around the SMS gateway from "
"CPSMS <https://www.cpsms.dk/>."
),
)