First import of experiment short message product. Support a sms tool witch...

First import of experiment short message product. Support a sms tool witch manage gateway. Add implementation of Essendex SMS gateway. Add short message document based on mail message document

git-svn-id: https://svn.erp5.org/repos/experimental@1901 bc57dcba-3610-0410-ab4f-dc20bb96b918
parent d84f46e8
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# Francois-Xavier Algrain <fxalgrain@tiolive.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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 2
# of the License, or (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
"""Receive or send SMS"""
#Import python module
import urllib
from lxml import etree
from DateTime import DateTime
#Import Zope module
from AccessControl import ClassSecurityInfo, \
Unauthorized
from AccessControl.SecurityManagement import getSecurityManager, \
setSecurityManager, \
newSecurityManager
import zope.interface
from zLOG import LOG, INFO
from Products.ERP5Type import Permissions, PropertySheet, interfaces
from Products.ERP5Type.XMLObject import XMLObject
from Products.ERP5Security.ERP5UserManager import SUPER_USER
#Product Module
from Products.ERP5ShortMessage.Errors import SMSGatewayError
class EssendexGateway(XMLObject):
"""Base of SMS an Gateway. You can use push notification for delivered and new message notification."""
meta_type='Essendex Gateway'
portal_type = 'Essendex Gateway'
security = ClassSecurityInfo()
add_permission = Permissions.AddPortalContent
zope.interface.implements(interfaces.ISmsGateway)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.Reference
, PropertySheet.SMSGateway
)
api_url = "https://www.esendex.com/secure/messenger/formpost"
security.declarePublic('getAllowedMessageType')
def getAllowedMessageType(self):
"""List of all message type"""
return ['text', 'binary', 'smartMessage', 'unicode']
security.declarePrivate("_fetchPageAsDict")
def _fetchPageAsDict(self,page):
"""Page result is like Key=value in text format.
We transform it to a more powerfull dictionnary"""
result = dict()
for line in page.readlines():
parts = line.split('=')
#Remove \n et \r from value
result[parts[0]] = urllib.unquote(parts[1].replace('\r','').replace('\n',''))
return result
security.declarePrivate("_transformPhoneUrlToGatewayNumber")
def _transformPhoneUrlToGatewayNumber(self,phone):
"""Transform url of phone number to a valid phone number (gateway side)"""
return phone.replace('tel:', '').replace('+','')
security.declareProtected(Permissions.ManagePortal, 'send')
def send(self, text,recipient,sender=None, message_type="text",test=False,**kw):
"""Send a message.
Return message id (or list if multiple recipient)
Kw Parameters:
validity_period -- Validity Period of SMS (default,0)
"""
if message_type not in self.getAllowedMessageType():
raise ValueError, "Type of message in not allowed"
validity_period = kw.get('validity_period',0)
if not isinstance(recipient, str):
recipient = ",".join([self._transformPhoneUrlToGatewayNumber(x) for x in recipient])
else:
recipient = self._transformPhoneUrlToGatewayNumber(recipient)
base_url = self.api_url + "/SendSMS.aspx"
params = {'Username': self.getGatewayUser(),
'Password': self.getGatewayPassword(),
'Account': self.getGatewayAccount(),
'Recipient': recipient,
'Body': text,
'Type': message_type.capitalize(),
'ValidityPeriod': validity_period,
'PlainText': 1,
}
if sender:
params['Originator'] = self._transformPhoneUrlToGatewayNumber(sender)
else:
params['Originator'] = self.getDefaultSender()
if test or self.isSimulationMode():
params['Test'] = 1
params = urllib.urlencode(params)
page = urllib.urlopen(base_url, params)
result = self._fetchPageAsDict(page)
if result['Result'] == "OK":
message_ids = result.get('MessageIDs', "")
#If a message is sent to multiple recipients, multiple IDs are returned
#each seperated by a comma.
return message_ids.split(",")
elif result['Result'] == "Error":
#we get an error when call the gateway
raise SMSGatewayError, urllib.unquote(result.get('Message', "Impossible to send the SMS"))
elif result['Result'] == "Test":
#just a test, no message id
return None
else:
LOG("Unknow SMS gateway result",INFO, result)
return None
security.declareProtected(Permissions.ManagePortal, 'getMessageStatus')
def getMessageStatus(self, message_id):
"""Retrive the status of a message"""
base_url = self.api_url + "/QueryStatus.aspx"
params = {'Username': self.getGatewayUser(),
'Password': self.getGatewayPassword(),
'Account': self.getGatewayAccount(),
'PlainText': 1,
'MessageID': message_id,
}
params = urllib.urlencode(params)
page = urllib.urlopen(base_url, params)
result = self._fetchPageAsDict(page)
if result['Result'] == "OK":
return result.get('MessageStatus').lower()
elif result['Result'] == "Error":
#we get an error when call the gateway
raise SMSGatewayError, urllib.unquote(result.get('Message', "Impossible to get the message status"))
security.declarePublic('receive')
def receive(self,REQUEST):
"""Receive push notification"""
#XML is stored is BODY of request
datas = REQUEST['BODY']
if not datas:
raise SMSGatewayError, "Impossible to notify nothing"
#Get current user
sm = getSecurityManager()
try:
#Use SUPER_USER
portal_membership = self.getPortalObject().portal_membership
newSecurityManager(None, portal_membership.getMemberById(SUPER_USER))
#Parse XML
root = etree.fromstring(datas)
#Choice action corresponding to the notification type
notification_type = root.tag
#Parse text XML Element to dict
xml = {}
for child in root.getchildren():
xml[child.tag] = child.text
#Check Account id
if xml['AccountId'] != self.getGatewayAccountId():
raise Unauthorized, 'Bad accound id (%s)' % xml['AccountId']
if notification_type == 'InboundMessage':
self.notifyReception(xml)
elif notification_type == 'MessageDelivered':
self.notifyDelivery(xml)
elif notification_type == 'MessageError':
raise SMSGatewayError, "'MessageError' notification is not implemented (%s)" % str(kw)
elif notification_type == 'SubscriptionEvent':
raise SMSGatewayError, "'MessageError' notification is not implemented (%s)" % str(kw)
else:
raise SMSGatewayError, "Unknow '%s' notification (%s)" % (notification_type, str(kw))
finally:
#Restore orinal user
setSecurityManager(sm)
security.declareProtected(Permissions.ManagePortal, 'receive')
def notifyReception(self, xml):
"""The gateway inform what we ha a new message.
root: lxml Element"""
"""
<InboundMessage>
<Id>{guid-of-push-notification}</Id>
<MessageId>{guid-of-inbound-message}</MessageId>
<AccountId>{guid-of-esendex-account-for-message}</AccountId>
<MessageText>{Message text of inbound message}</MessageText>
<From>{phone number of sender of the message}</From>
<To>{phone number of the recipient of the inbound message (the
virtual number of the esendex account in use)}</To>
</InboundMessage>
"""
#Convert phone as erp5 compliant
def parsePhoneNumber(number):
#XXX: Should register well formatted number or brut number ?
#return number
return "+%s(%s)-%s" % (number[0:2],0,number[2:])
#Create the new sms in activities
module = self.getDefaultModule("Short Message")
module.activate(activity='SQLQueue').EventModule_pushNewSMS(
message_id=xml['MessageId'],
sender=parsePhoneNumber(xml['From']),
recipient=parsePhoneNumber(xml['To']),
text_content=xml['MessageText'],
message_type='text/plain',
reception_date=DateTime())
security.declareProtected(Permissions.ManagePortal, 'notifyDelivery')
def notifyDelivery(self, xml):
"""Handle delivery info
root: lxml Element"""
"""
<MessageDelivered>
<Id>{guid-of-push-notification}</Id>
<MessageId>{guid-of-inbound-message}</MessageId>
<AccountId>{guid-of-esendex-account-for-message}</AccountId>
<OccurredAt>{the UTC DateTime (yyyy-MM-ddThh:mm:ss) that the
message was delivered to the recipient}</OccurredAt>
</MessageDelivered>
"""
#Convert date to DateTime
xml['OccurredAt'] = DateTime(xml['OccurredAt'][0:19])
module = self.getDefaultModule("Short Message")
module.activate(activity='SQLQueue').EventModule_setEventDelivery(
portal_type="Short Message",
destination_reference=xml['MessageId'],
delivery_date=xml['OccurredAt'])
\ No newline at end of file
##############################################################################
#
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# Francois-Xavier Algrain <fxalgrain@tiolive.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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 2
# of the License, or (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Accessor.Constant import PropertyGetter as ConstantGetter
from Products.ERP5Type import Permissions, PropertySheet
from Products.ERP5.Document.Event import Event
class ShortMessageDocument(Event):
"""
Base class for SMS. Sms are a special Event.
They use a SMS gateway to be sended.
"""
meta_type = 'ERP5 Short Message'
portal_type = 'Short Message'
isDelivery = ConstantGetter('isDelivery', value=True)
# Declarative properties
property_sheets = ( PropertySheet.Base
, PropertySheet.XMLObject
, PropertySheet.CategoryCore
, PropertySheet.Document
, PropertySheet.DublinCore
, PropertySheet.Task
, PropertySheet.Url
, PropertySheet.TextDocument
, PropertySheet.Arrow
, PropertySheet.Movement
, PropertySheet.Event
, PropertySheet.Delivery
, PropertySheet.ItemAggregation
)
# Declarative security
security = ClassSecurityInfo()
security.declareObjectProtected(Permissions.AccessContentsInformation)
security.declareProtected(Permissions.AccessContentsInformation,
'getQuantity')
def getQuantity(self):
"""Get quantity of sms sended"""
#XXX-Fx : See with JPS for a new event implementation
#XXX-Fx : DestinationReference property must be replace by a category
return len(self.getDestinationReference().split(','))
security.declareProtected(Permissions.UseMailhostServices,
'isDelivered')
def isDelivered(self):
"""Query if message is devivered or not"""
message_quantity = self.getQuantity()
portal = self.portal_sms
if message_quantity == 0:
return None
#XXX-Fx : See with JPS for a new event implementation
#XXX-Fx : DestinationReference property must be replace by a category
status_list = [portal.getMessagesStatus(message_id) for message_id in self.getDestinationReference().split(',')]
for status in status_list:
if status != 'delivered':
return False
return True
security.declareProtected(Permissions.UseMailhostServices, 'send')
def send(self, from_url=None, to_url=None, reply_url=None, subject=None,
body=None, attachment_format=None, attachment_list=None,
download=False,**kw):
"""
Send the current sms by using a SMS gateway.
Use default mobile phone of source and destination
"""
#Get the portal
portal = self.portal_sms
#Get recipients
if not to_url:
recipient_phone_list = [person.getDefaultMobileTelephoneValue() for person in self.getDestinationValueList()]
if None in recipient_phone_list:
raise ValueError, "All recipients should have a default mobile phone"
to_url = [phone.asURL() for phone in recipient_phone_list]
if None in to_url:
raise ValueError, "All recipients should have a valid default mobile phone number"
#Get sender
if not from_url:
if self.getSourceValue():
sender_phone = self.getSourceValue().getDefaultMobileTelephoneValue()
if not sender_phone:
raise ValueError, "The sender should have a default mobile phone"
#We use the title as sender
if sender_phone.getTitle() and portal.isSendByTitleAllowed():
from_url = sender_phone.getTitle()
else:
from_url = sender_phone.asURL()
if not body:
body = self.getTextContent()
#We get the id of the message to track it
#We only send Text message today
message_id_list = portal.send(text=body, recipient=to_url, sender=from_url,message_type="text", test=download)
#set message id to be able to query the status
#XXX-Fx : See with JPS for a new event implementation
#XXX-Fx : DestinationReference property must be replace by a category
if message_id_list is not None:
self.setDestinationReference(",".join(message_id_list))
return message_id_list
\ No newline at end of file
##############################################################################
#
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# Francois-Xavier Algrain <fxalgrain@tiolive.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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 2
# of the License, or (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
"""Exception Classes for ERP5Configurator"""
# These classes are placed here so that they can be imported into TTW Python
# scripts. To do so, add the following line to your Py script:
# from Products.ERP5.Errors import DeferredCatalogError
from Products.PythonScripts.Utility import allow_class
from Products.CMFCore.WorkflowCore import WorkflowException
class SMSGatewayError(Exception):pass
allow_class(SMSGatewayError)
##############################################################################
#
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# Francois-Xavier Algrain <fxalgrain@tiolive.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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 2
# of the License, or (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
\ No newline at end of file
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# Francois-Xavier Algrain <fxalgrain@tiolive.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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 2
# of the License, or (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
class SMSGateway:
"""
Agent properties for Agent objects
"""
_properties = (
{ 'id' : 'gateway_user'
, 'description': 'User name to connect '
, 'type' : 'string'
, 'mode' : 'w'
},
{ 'id' : 'gateway_password'
, 'description': 'Password to connect'
, 'type' : 'string'
, 'mode' : 'w'
},
{ 'id' : 'gateway_account'
, 'description': 'Account to use.'
, 'type' : 'string'
, 'mode' : 'w'
},
{ 'id' : 'gateway_account_id'
, 'description': 'Id of the accound. Can be used for push notification'
, 'type' : 'string'
, 'mode' : 'w'
},
{ 'id' : 'default_sender'
, 'description': 'Default sender when send message.'
, 'type' : 'string'
, 'mode' : 'w'
},
{ 'id' : 'simulation_mode'
, 'description': 'Force the simulation mode.'
, 'type' : 'boolean'
, 'mode' : 'w'
},
{ 'id' : 'title_mode'
, 'description': 'Allow or not to send by title'
, 'type' : 'boolean'
, 'mode' : 'w'
},
)
\ No newline at end of file
ERP5ShortMessage
The ERP5ShortMessage product provides support for sending or receiving SMS from
within the Zope environment.
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# François-Xavier Algrain <fxalgrain@tiolive.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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 2
# of the License, or (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from AccessControl import ClassSecurityInfo
from Products.ERP5Type.Tool.BaseTool import BaseTool
from Products.ERP5Type.Permissions import ManagePortal
from Globals import DTMLFile
from Products.ERP5ShortMessage import _dtmldir
class SMSTool(BaseTool):
"""
This tool manages gadgets.
It is used as a central point to manage gadgets (ERP5 or external ones)...
"""
id = 'portal_sms'
meta_type = 'ERP5 SMS Tool'
portal_type = 'SMS Tool'
# Declarative Security
security = ClassSecurityInfo()
security.declareProtected(ManagePortal, 'manage_overview')
manage_overview = DTMLFile('explainSMSTool', _dtmldir )
security.declareProtected(ManagePortal, 'send')
def send(self, text,recipient, sender=None, message_type="text",
test=False, gateway_reference='default', **kw):
gateway = self.find(gateway_reference)
return gateway.send(text,recipient,sender=None, message_type="text",
test=False, **kw)
security.declareProtected(ManagePortal, 'getMessageStatus')
def getMessageStatus(self,message_id, gateway_reference='default'):
gateway = self.find(gateway_reference)
return gateway.getMessageStatus(message_id)
security.declarePublic('isSendByTitleAllowed')
def isSendByTitleAllowed(self, gateway_reference='default'):
"""Define the support or not to use the title of the telephone instead of
the number when send a message."""
gateway = self.find(gateway_reference)
return gateway.isTitleMode()
security.declarePublic('find')
def find(self,gateway_reference='default'):
"""Search the gateway by his reference"""
result = self.searchFolder(reference=gateway_reference)
if len(result) > 0:
return result[0].getObject()
else:
raise ValueError, "Impossible to find gateway with reference %s" % gateway_reference
##############################################################################
#
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# François-Xavier Algrain <fxalgrain@tiolive.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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 2
# of the License, or (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
"""
ERP5ShortMessage is a product containing everything needed to implement
Short Message management in ERP5.
"""# Update ERP5 Globals
from Products.ERP5Type.Utils import initializeProduct, updateGlobals
import sys, Permissions
this_module = sys.modules[ __name__ ]
document_classes = updateGlobals(this_module, globals(),
permissions_module=Permissions)
from Tool import SMSTool
# Define object classes and tools
object_classes = ()
portal_tools = (SMSTool.SMSTool,
)
content_classes = ()
content_constructors = ()
# Finish installation
def initialize(context):
import Document
initializeProduct(context, this_module, globals(),
document_module=Document,
document_classes=document_classes,
object_classes=object_classes,
portal_tools=portal_tools,
content_constructors=content_constructors,
content_classes=content_classes)
from AccessControl.SecurityInfo import allow_module
allow_module('Products.ERP5ShortMessage.Errors')
<dtml-var manage_page_header>
<dtml-var manage_tabs>
<h3>Explain SMS Tool</h3>
<p>
SMS Tool provides all to send and receive sms with one or more sms gateway.
</p>
<p>
You need to have a SMS Gateway with reference egal to "default" to send sms.
Other reference can be used for specific send.
</p>
<dtml-var manage_page_footer>
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
# François-Xavier Algrain <fxalgrain@tiolive.com>
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program 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 2
# of the License, or (at your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
from zope.interface import Interface
class ISmsGateway(Interface):
def send(self, text, recipient, sender=None,
message_type="text",test=False, **kw):
"""Send a message."""
def receive(self, REQUEST):
"""Public handler to push notification from the gateway"""
def getAllowedMessageType(self):
"""List of all allowed message type when send a message."""
def getMessageStatus(self, message_id):
"""Retrive the status of a message
Should return x in ['sent', 'delivered', 'queued', 'failed']"""
\ No newline at end of file
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment