VPMS Web Application

SMS integration through an email-sms gateway

Details

  • Type: New Feature New Feature
  • Status: Closed Closed
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: None
  • Fix Version/s: 1.5
  • Component/s: None
  • Labels:
    None

Description

The goal is to get SMS communication into the following areas:

1. Within the Customer summary will contain an SMS button. The button will only be enabled if there is a valid mobile number for the Customer that has an active Customer-Patient relationship. This would pop up a standard compose email dialogue with the email address formatted appropriately for the email-sms provider (eg.i.e 0411999999@smsprovider.com.au ).

2. The ability to ADD SMS reminders as a method of delivery of reminders from within the Reminder configuration if a Customer has a valid mobile number.

3. Add SMS email gateway provider to Practice Organisation.

4. (Optional) Identical functionality and context for Fax sending by utilising email-fax gateway options. Note that this could integrate very well with sites where hylafax may already be operational.

Forum: www.openvpms.org/forum/sms-project

Issue Links

Activity

Hide
Matt Costa added a comment -

Hi guys,
Estimate on this one?
Matt C

Show
Matt Costa added a comment - Hi guys, Estimate on this one? Matt C
Hide
Tim Anderson added a comment -

Each SMS gateway has its own API, so any support for this needs to be pluggable to enable integrators to customise.
This also allows other HTTP, SOAP, etc gateways to be plugged in as required.

E.g www.clickatell.com requires the following layout in the message body:

user:xxxxx
password:xxxxx
api_id:xxxxx
to: 448311234567
reply:youremail@yourdomain.com
text:Meet me at home 

whereas www.messagenet.com.au just requires it be addressed to 04xxxxxxxx@messagenet.com.au

Therefore, for point 1, displaying an email dialog is not really sufficient. It would be better to:

  • to pop up a dialog which contains a text field that restricts input to 160 characters,
  • compose the email internally, according to the gateway's requirements. This could be done via a templating mechanism to simplify customization

There is also the issue that any errors and responses will likely be sent by the provider to the From: address. Do we need to receive these and attempt to interpret them, or can that be left as a manual task to the user?

Show
Tim Anderson added a comment - Each SMS gateway has its own API, so any support for this needs to be pluggable to enable integrators to customise. This also allows other HTTP, SOAP, etc gateways to be plugged in as required. E.g www.clickatell.com requires the following layout in the message body:
user:xxxxx
password:xxxxx
api_id:xxxxx
to: 448311234567
reply:youremail@yourdomain.com
text:Meet me at home 
whereas www.messagenet.com.au just requires it be addressed to 04xxxxxxxx@messagenet.com.au Therefore, for point 1, displaying an email dialog is not really sufficient. It would be better to:
  • to pop up a dialog which contains a text field that restricts input to 160 characters,
  • compose the email internally, according to the gateway's requirements. This could be done via a templating mechanism to simplify customization
There is also the issue that any errors and responses will likely be sent by the provider to the From: address. Do we need to receive these and attempt to interpret them, or can that be left as a manual task to the user?
Hide
Tony De Keizer added a comment -

I agree that we need a simple message dialogue only with the limit of length as Tim suggests. Support for macros should be included as many messages are similar in nature and this speed up process.

Not sure the initial implementation needs a pluggable architecture but will definitely need some templating facility for the subject and message body. This should be able to be achieved with a minimum of placeholders and (mobile number, message) and a single practice wide setting for the reply/from address ?

Where do you think the template will be located Tim ? Database (tyep of template) or external filesystem/webapp ?

Show
Tony De Keizer added a comment - I agree that we need a simple message dialogue only with the limit of length as Tim suggests. Support for macros should be included as many messages are similar in nature and this speed up process. Not sure the initial implementation needs a pluggable architecture but will definitely need some templating facility for the subject and message body. This should be able to be achieved with a minimum of placeholders and (mobile number, message) and a single practice wide setting for the reply/from address ? Where do you think the template will be located Tim ? Database (tyep of template) or external filesystem/webapp ?
Hide
Tim Anderson added a comment -

I envisage the default implementation would work as follows:

  • configuration for the gateway is via a custom entity, with prefix entity.emailSMSGateway
  • the SMS gateway configuration would be linked to the practice via an entity relationship with target archetype entity.emailSMSGateway*
  • a practice would have at most 1 entity.emailSMSGateway
  • an entity.emailSMSGateway would contain at least the following nodes:
    • to - this indicates the format of the to address
    • body - this indicates the format of the message body
    • practice - link to the practice
  • when generating the message, the implementation would evaluate the to address and body supplied in the configuration using xpath. The following variables would be defined:
    • phone - the mobile no
    • text - the SMS text

E.g, for clickatell above, there would be an entity.emailSMSGatewayClickATell. This would have the following nodes:

  • to
  • body
  • user
  • password
  • api_id
  • reply

An instance of this might look like:

  • to = sms@messaging.clickatell.com
  • body
    concat('user:', openvpms:get(., 'user'),'\n',
    'password:', openvpms:get(.,'password'), '\n',
    'api_id:', openvpms:get(.,'api_id'), '\n',
    'to:', $phone, '\n',
    'reply:', party:getEmailAddress(openvpms:get(. 'practice.source')), '\n'
    'text:', $text)
    

For messagenet, it would be entity.emailSMSGatewayMessageNet. This would have the following nodes:

  • to
  • body
  • from

An instance of this might look like:

  • to = concat($phone, '@messagenet.com.au')
  • body = $text
  • from = party:getEmailAddress(openvpms:get(. 'practice.source'))
Show
Tim Anderson added a comment - I envisage the default implementation would work as follows:
  • configuration for the gateway is via a custom entity, with prefix entity.emailSMSGateway
  • the SMS gateway configuration would be linked to the practice via an entity relationship with target archetype entity.emailSMSGateway*
  • a practice would have at most 1 entity.emailSMSGateway
  • an entity.emailSMSGateway would contain at least the following nodes:
    • to - this indicates the format of the to address
    • body - this indicates the format of the message body
    • practice - link to the practice
  • when generating the message, the implementation would evaluate the to address and body supplied in the configuration using xpath. The following variables would be defined:
    • phone - the mobile no
    • text - the SMS text
E.g, for clickatell above, there would be an entity.emailSMSGatewayClickATell. This would have the following nodes:
  • to
  • body
  • user
  • password
  • api_id
  • reply
An instance of this might look like:
  • to = sms@messaging.clickatell.com
  • body
    concat('user:', openvpms:get(., 'user'),'\n',
    'password:', openvpms:get(.,'password'), '\n',
    'api_id:', openvpms:get(.,'api_id'), '\n',
    'to:', $phone, '\n',
    'reply:', party:getEmailAddress(openvpms:get(. 'practice.source')), '\n'
    'text:', $text)
    
For messagenet, it would be entity.emailSMSGatewayMessageNet. This would have the following nodes:
  • to
  • body
  • from
An instance of this might look like:
  • to = concat($phone, '@messagenet.com.au')
  • body = $text
  • from = party:getEmailAddress(openvpms:get(. 'practice.source'))
Hide
Matt Costa added a comment -

We should get an hours estimate on this one

Show
Matt Costa added a comment - We should get an hours estimate on this one
Hide
Matt Costa added a comment -

Hey Tim,
You got an idea on how long this one might take? It will probably be a popular one at the users meeting next week.

Matt C

Show
Matt Costa added a comment - Hey Tim, You got an idea on how long this one might take? It will probably be a popular one at the users meeting next week. Matt C
Hide
Tim Anderson added a comment -

60 hours to:

  • develop interface for SMS messaging
  • provide implementation of the interface that supports SMS via email
  • provide archetypes to configure at least 2 email to SMS gateways (e.g clickatell.com, messagenet.com.au') - up to you
  • provide editor to configure the gateways - this includes support for sending a test SMS through to verify it works
  • provide SMS button in customer summary to send SMS to default mobile if a customer has one
  • provide SMS button in phone contacts to send SMS to arbitrary mobile

Can cost on reminder SMSs too if you like.

Show
Tim Anderson added a comment - 60 hours to:
  • develop interface for SMS messaging
  • provide implementation of the interface that supports SMS via email
  • provide archetypes to configure at least 2 email to SMS gateways (e.g clickatell.com, messagenet.com.au') - up to you
  • provide editor to configure the gateways - this includes support for sending a test SMS through to verify it works
  • provide SMS button in customer summary to send SMS to default mobile if a customer has one
  • provide SMS button in phone contacts to send SMS to arbitrary mobile
Can cost on reminder SMSs too if you like.
Hide
Matt Costa added a comment -

Thanks Tim,
Probably should include reminder SMS in costing as a separate hrs tally.
Also would we list multiple target mobile numbers for those cutomers with more then one mobile in a drop down box with the default number being the one selected initially?
Cheers

Show
Matt Costa added a comment - Thanks Tim, Probably should include reminder SMS in costing as a separate hrs tally. Also would we list multiple target mobile numbers for those cutomers with more then one mobile in a drop down box with the default number being the one selected initially? Cheers
Hide
Tim Anderson added a comment -

OK. So for the customer summary the behaviour would now be:

  • if the customer has a single phone no, display it
  • if the customer has multiple phone no.s, display them in a drop down with the preferred no. selected
  • if the displayed phone no. has sms = true, display a small button to send an SMS
    Add an hour to the estimate.

Raised OVPMS-951 for reminder notification via SMS

Show
Tim Anderson added a comment - OK. So for the customer summary the behaviour would now be:
  • if the customer has a single phone no, display it
  • if the customer has multiple phone no.s, display them in a drop down with the preferred no. selected
  • if the displayed phone no. has sms = true, display a small button to send an SMS Add an hour to the estimate.
Raised OVPMS-951 for reminder notification via SMS
Hide
Tim Anderson added a comment -

A simpler and cheaper implementation requires only two new archetypes, yet still enables implementers to plugin in their own SMS support.

  • entity.SMSGatewayEmail
    Contains configuration for the default SMS gateway implementation shipped with OpenVPMS
    • name: string - name of the gateway provider
    • mailto: string - an xpath expression
    • header: string - an xpath expression
    • body: string - an xpath expression
  • entityRelationship.SMSGateway
    Enables the appropriate SMSGateway to be linked to the party.organisationPractice

An interface would be defined:

interface SMSGateway {
    void send(String phoneNumber, String message);
}

There would be an implementation of this for email providers, EmailSMSGateway, that uses the entity.SMSGatewayEmail configuration, and be configured in applicationContext.xml. This could be replaced by implementers.

The EmailSMSGateway would evaluate the mailto, header and body xpath expressions against the supplied message and phone number, and format them into an email.
E.g, for www.clickatell.com the expressions would look like:

  • mailto = 'sms@messaging.clickatell.com'
  • header = concat('user: xxxxx', '\n', 'password: xxxxx', '\n', 'api_id: xxxxx', 'to: $phone', '\n', 'reply: mypractice.com')
  • body = concat('text: ', $message)

For messagenet it would look like:

  • mailto = concat($phone, '@messagenet.com.au')
  • header = ''
  • body = $text

This approach is simpler to implement, but not as straight forward to configure.

Costing this as:

  • provide email gateway implementation - 24 hours + 4 hours testing per provider
  • provide editor to configure the email gateway - this includes support for sending a test SMS through to verify it works - 8 hours
  • provide SMS button in customer summary to send SMS to default mobile if a customer has one - 4 hours
  • provide SMS button in phone contacts to send SMS to arbitrary mobile - 4 hours
Show
Tim Anderson added a comment - A simpler and cheaper implementation requires only two new archetypes, yet still enables implementers to plugin in their own SMS support.
  • entity.SMSGatewayEmail Contains configuration for the default SMS gateway implementation shipped with OpenVPMS
    • name: string - name of the gateway provider
    • mailto: string - an xpath expression
    • header: string - an xpath expression
    • body: string - an xpath expression
  • entityRelationship.SMSGateway Enables the appropriate SMSGateway to be linked to the party.organisationPractice
An interface would be defined:
interface SMSGateway {
    void send(String phoneNumber, String message);
}
There would be an implementation of this for email providers, EmailSMSGateway, that uses the entity.SMSGatewayEmail configuration, and be configured in applicationContext.xml. This could be replaced by implementers. The EmailSMSGateway would evaluate the mailto, header and body xpath expressions against the supplied message and phone number, and format them into an email. E.g, for www.clickatell.com the expressions would look like:
  • mailto = 'sms@messaging.clickatell.com'
  • header = concat('user: xxxxx', '\n', 'password: xxxxx', '\n', 'api_id: xxxxx', 'to: $phone', '\n', 'reply: mypractice.com')
  • body = concat('text: ', $message)
For messagenet it would look like:
  • mailto = concat($phone, '@messagenet.com.au')
  • header = ''
  • body = $text
This approach is simpler to implement, but not as straight forward to configure. Costing this as:
  • provide email gateway implementation - 24 hours + 4 hours testing per provider
  • provide editor to configure the email gateway - this includes support for sending a test SMS through to verify it works - 8 hours
  • provide SMS button in customer summary to send SMS to default mobile if a customer has one - 4 hours
  • provide SMS button in phone contacts to send SMS to arbitrary mobile - 4 hours
Hide
Matt Costa added a comment -

This is fully funded Tim

Show
Matt Costa added a comment - This is fully funded Tim
Hide
Tim Anderson added a comment - - edited

The SMS API is now available from svn://svn.openvpms.org/openvpms/openvpms-sms/trunk, and will be released in the final 1.5 release.

The main interfaces are ConnectionFactory and Connection:

/**
 * Creates connections to an SMS provider.
 */
public interface ConnectionFactory {

    /**
     * Creates a new connection.
     *
     * @return a new connection
     */
    Connection createConnection();
}

/**
 * A Connection is a client's active connection to its SMS provider.
 */
public interface Connection {

    /**
     * Sends an SMS.
     *
     * @param phone the phone number to send the SMS to
     * @param text  the SMS text
     */
    void send(String phone, String text);

    /**
     * Closes the connection, freeing resources.
     */
    void close();}
}

An email based implementation of these is provided, via the classes MailConnectionFactory and MailConnection. These enable SMS messages to be sent via mail-to-SMS gateways.
These are configured using an entity.SMSConfigEmail* archetype, linked to the practice.
The initial implementation includes:

  • entity.SMSConfigEmailGeneric - generic configuration, using user specified xpath expressions to generate emails
  • entity.SMSConfigEmailClickatell - configuration for the Clickatell mail-to-SMS gateway (http://www.clickatell.com )
  • entity.SMSConfigEmailSMSGlobal - configuration for the SMSGlobal Email2SMS gateway (http://www.smsglobal.com )

It is possible to configure both SMSGlobal and Clickatell via entity.SMSConfigEmailGeneric, but it requires the user to have some knowledge of xpath expressions. The entity.SMSConfigEmailSMSGlobal and entity.SMSConfigEmailClickatell hide the underlying xpath expressions.

It should be possible to support a wide range of email-to-SMS gateways using either entity.SMSConfigEmailGeneric or developing an archetype that follows the following conventions:

  1. must be named entity.SMSConfigEmail<provider>
  2. must provide "id", "name", and "active", nodes
  3. must provide a "description" node
  4. must provide an "website" node, indicating the suppplier website.
  5. must provide a "countryPrefix" node, indicating the country to prefix phone numbers with. E.g., "61" in Australia
  6. must provide an "areaPrefix" node, indicating the area prefix to remove from phone numbers. E.g, "0" in Australia
  7. must provide one or both of:
    • from - the from-address
    • fromExpression - the from-address xpath expression
      This is used to populate the email "from" address. If only the "from" node is provided, this is used. If the "fromExpression" is provided, is is evaluated and the result used. The "fromExpression" may refer to the "from" node as "$from".
  8. must provide one or both of:
    • to - the 'to' address
    • toExpression - the 'to' address xpath expression
      This is used to populate the email "to" address. If only the "to" node is provided, this is used. If the "toExpression" is provided, it is evaluated and the result used. The "toExpression" may refer to the "to" node as "$to".
  9. may provide one or both of:
    • replyTo - the 'reply-to' address
    • replyToExpression - the 'reply-to' address xpath expression
      This is used to populate the email "reply-to" address. If only the "replyTo" node is provided, this is used. If the "replyToExpression" is provided, it is evaluated and the result used. The "replyToExpression" may refer to the "replyTo" node as "$replyTo".
  10. may provide one or both of:
    • subject - the mail subject
    • subjectExpression - the mail subject xpath expression
      This is used to populate the email subject. If only the "subject" node is provided, this is used. If the "subjectExpression" is provided, it is evaluated and the result used. The "subjectExpression" may refer to the "subject" node as "$subject".
  11. must provide one or both of:
    • text - the mail text
    • textExpression - the mail text expression
      This is used to populate the email body. If only the "text" node is provided, this is used. If the "textExpression" is provided, it is evaluated and the result used. The "textExpression" may refer to the "text" node as "$text", and the user supplied message as "$message".

With the exception of "name", "description", "active" and "website", the nodes may be hidden if they shouldn't be seen/edited by users.
With the exception of "name", "id", and "active", nodes may have "minCardinality="0"

The countryPrefix and areaPrefix nodes are used to format phone numbers. The countryPrefix is only used if a phone number has a matching areaPrefix.
E.g, given a countryPrefix of "61" and an area prefix of "0", the phone number "0412345678" will be converted to "61412345678".
Both may be omitted if the SMS provider doesn't require international prefixes.

The following variables may be used in xpath expressions:

  • $phone - the phone number
  • $message - the SMS message
  • $countryPrefix - the value of the "countryPrefix" node
  • $areaPrefix - the value of the "areaPrefix" node
  • $from - the value of the "from" node
  • $to - the value of the "to" node
  • $replyTo - the value of the "replyTo" node
  • $subject - the value of the "subject" node
  • $text - the value of the "text" node
  • $nl - a new line character, to simplify handling of new lines in expressions

Additionally, string nodes in the archetype are available to expressions using $<nodeName>. This excludes nodes named "name", "description", "website", "fromExpression", "toExpression", "replyToExpression", "subjectExpression", and "textExpression"

entity.SMSConfigEmailGeneric

    <archetype name="entity.SMSConfigEmailGeneric.1.0" latest="true"
               type="org.openvpms.component.business.domain.im.common.Entity" displayName="SMS Configuration: Generic Email Gateway">
        <node name="id" path="/id" type="java.lang.Long" hidden="true" readOnly="true"/>
        <node name="name" type="java.lang.String" path="/name" minCardinality="1"/>
        <node name="description" type="java.lang.String" path="/description" minCardinality="0"/>
        <node name="website" displayName="Web Site" type="java.lang.String" path="/details/website" minCardinality="0"/>
        <node name="active" path="/active" type="java.lang.Boolean" defaultValue="true()"/>
        <node name="countryPrefix" path="/details/countryPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="areaPrefix" path="/details/areaPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="from" path="/details/from" type="java.lang.String" minCardinality="0"/>
        <node name="fromExpression" path="/details/fromExpression" type="java.lang.String" minCardinality="0" defaultValue="'$from'"/>
        <node name="to" path="/details/to" type="java.lang.String" minCardinality="0"/>
        <node name="toExpression" path="/details/toExpression" type="java.lang.String" minCardinality="0" defaultValue="'$phone'"/>
        <node name="replyTo" path="/details/replyTo" type="java.lang.String" minCardinality="0"/>
        <node name="replyToExpression" path="/details/replyToExpression" type="java.lang.String" minCardinality="0" defaultValue="'$replyTo'"/>
        <node name="subject" path="/details/subject" type="java.lang.String" minCardinality="0"/>
        <node name="subjectExpression" path="/details/subjectExpression" type="java.lang.String" minCardinality="0" defaultValue="'$subject'"/>
        <node name="text" path="/details/text" type="java.lang.String" minCardinality="0"/>
        <node name="textExpression" path="/details/textExpression" type="java.lang.String" minCardinality="0" defaultValue="'$message'" maxLength="256"/>
    </archetype>

entity.SMSConfigEmailSMSGlobal

    <archetype name="entity.SMSConfigEmailSMSGlobal.1.0" latest="true"
               type="org.openvpms.component.business.domain.im.common.Entity" displayName="SMS Configuration: SMSGlobal Email2SMS">
        <node name="id" path="/id" type="java.lang.Long" hidden="true" readOnly="true"/>
        <node name="name" type="java.lang.String" path="/name" minCardinality="1" defaultValue="'SMS Global Email2SMS Configuration'"/>
        <node name="description" type="java.lang.String" path="/description"/>
        <node name="website" displayName="Web Site" type="java.lang.String" path="/details/website" readOnly="true" defaultValue="'http://www.smsglobal.com'"/>
        <node name="active" path="/active" type="java.lang.Boolean" defaultValue="true()"/>
        <node name="countryPrefix" path="/details/countryPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="areaPrefix" path="/details/areaPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="from" path="/details/from" type="java.lang.String" minCardinality="1"/>
        <node name="toExpression" path="/details/toExpression" type="java.lang.String" minCardinality="1" 
              defaultValue="'concat($phone, &quot;@email.smsglobal.com&quot;)'" hidden="true"/>
        <node name="textExpression" path="/details/textExpression" type="java.lang.String" minCardinality="1" defaultValue="'$message'" hidden="true"/>
    </archetype>

entity.SMSConfigEmailClickatell

    <archetype name="entity.SMSConfigEmailClickatell.1.0" latest="true"
               type="org.openvpms.component.business.domain.im.common.Entity" displayName="SMS Configuration: Clickatell SMTP Connection">
        <node name="id" path="/id" type="java.lang.Long" hidden="true" readOnly="true"/>
        <node name="name" type="java.lang.String" path="/name" minCardinality="1" defaultValue="'Clickatell SMTP Connection Configuration'"/>
        <node name="description" type="java.lang.String" path="/description"/>
        <node name="website" displayName="Web Site" type="java.lang.String" path="/details/website" readOnly="true" defaultValue="'http://www.clickatell.com'"/>
        <node name="active" path="/active" type="java.lang.Boolean" defaultValue="true()"/>
        <node name="countryPrefix" path="/details/countryPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="areaPrefix" path="/details/areaPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="user" path="/details/user" type="java.lang.String" minCardinality="1"/>
        <node name="password" path="/details/password" type="java.lang.String" minCardinality="1"/>
        <node name="apiId" path="/details/apiId" type="java.lang.String" minCardinality="1"/>
        <node name="to" path="/details/to" type="java.lang.String" minCardinality="1" defaultValue="'sms@messaging.clickatell.com'" hidden="true"/>
        <node name="from" path="/details/from" type="java.lang.String" minCardinality="1"/>
        <node name="replyTo" path="/details/replyTo" type="java.lang.String" minCardinality="0"/>
        <node name="textExpression" path="/details/textExpression" type="java.lang.String" minCardinality="1" hidden="true"
              defaultValue="'concat(&quot;user:&quot;, $user, &quot;&#xA;password:&quot;, $password, &quot;&#xA;api_id:&quot;, $apiId, &quot;&#xA;to:&quot;, $phone, &quot;&#xA;reply:&quot;, $replyTo, &quot;&#xA;text:&quot;, replace($message, &quot;&#xA;&quot;,&quot;&#xA;text:&quot;))'"/>
    </archetype>
Show
Tim Anderson added a comment - - edited The SMS API is now available from svn://svn.openvpms.org/openvpms/openvpms-sms/trunk, and will be released in the final 1.5 release. The main interfaces are ConnectionFactory and Connection:
/**
 * Creates connections to an SMS provider.
 */
public interface ConnectionFactory {

    /**
     * Creates a new connection.
     *
     * @return a new connection
     */
    Connection createConnection();
}

/**
 * A Connection is a client's active connection to its SMS provider.
 */
public interface Connection {

    /**
     * Sends an SMS.
     *
     * @param phone the phone number to send the SMS to
     * @param text  the SMS text
     */
    void send(String phone, String text);

    /**
     * Closes the connection, freeing resources.
     */
    void close();}
}
An email based implementation of these is provided, via the classes MailConnectionFactory and MailConnection. These enable SMS messages to be sent via mail-to-SMS gateways. These are configured using an entity.SMSConfigEmail* archetype, linked to the practice. The initial implementation includes:
  • entity.SMSConfigEmailGeneric - generic configuration, using user specified xpath expressions to generate emails
  • entity.SMSConfigEmailClickatell - configuration for the Clickatell mail-to-SMS gateway (http://www.clickatell.com )
  • entity.SMSConfigEmailSMSGlobal - configuration for the SMSGlobal Email2SMS gateway (http://www.smsglobal.com )
It is possible to configure both SMSGlobal and Clickatell via entity.SMSConfigEmailGeneric, but it requires the user to have some knowledge of xpath expressions. The entity.SMSConfigEmailSMSGlobal and entity.SMSConfigEmailClickatell hide the underlying xpath expressions. It should be possible to support a wide range of email-to-SMS gateways using either entity.SMSConfigEmailGeneric or developing an archetype that follows the following conventions:
  1. must be named entity.SMSConfigEmail<provider>
  2. must provide "id", "name", and "active", nodes
  3. must provide a "description" node
  4. must provide an "website" node, indicating the suppplier website.
  5. must provide a "countryPrefix" node, indicating the country to prefix phone numbers with. E.g., "61" in Australia
  6. must provide an "areaPrefix" node, indicating the area prefix to remove from phone numbers. E.g, "0" in Australia
  7. must provide one or both of:
    • from - the from-address
    • fromExpression - the from-address xpath expression This is used to populate the email "from" address. If only the "from" node is provided, this is used. If the "fromExpression" is provided, is is evaluated and the result used. The "fromExpression" may refer to the "from" node as "$from".
  8. must provide one or both of:
    • to - the 'to' address
    • toExpression - the 'to' address xpath expression This is used to populate the email "to" address. If only the "to" node is provided, this is used. If the "toExpression" is provided, it is evaluated and the result used. The "toExpression" may refer to the "to" node as "$to".
  9. may provide one or both of:
    • replyTo - the 'reply-to' address
    • replyToExpression - the 'reply-to' address xpath expression This is used to populate the email "reply-to" address. If only the "replyTo" node is provided, this is used. If the "replyToExpression" is provided, it is evaluated and the result used. The "replyToExpression" may refer to the "replyTo" node as "$replyTo".
  10. may provide one or both of:
    • subject - the mail subject
    • subjectExpression - the mail subject xpath expression This is used to populate the email subject. If only the "subject" node is provided, this is used. If the "subjectExpression" is provided, it is evaluated and the result used. The "subjectExpression" may refer to the "subject" node as "$subject".
  11. must provide one or both of:
    • text - the mail text
    • textExpression - the mail text expression This is used to populate the email body. If only the "text" node is provided, this is used. If the "textExpression" is provided, it is evaluated and the result used. The "textExpression" may refer to the "text" node as "$text", and the user supplied message as "$message".
With the exception of "name", "description", "active" and "website", the nodes may be hidden if they shouldn't be seen/edited by users. With the exception of "name", "id", and "active", nodes may have "minCardinality="0" The countryPrefix and areaPrefix nodes are used to format phone numbers. The countryPrefix is only used if a phone number has a matching areaPrefix. E.g, given a countryPrefix of "61" and an area prefix of "0", the phone number "0412345678" will be converted to "61412345678". Both may be omitted if the SMS provider doesn't require international prefixes. The following variables may be used in xpath expressions:
  • $phone - the phone number
  • $message - the SMS message
  • $countryPrefix - the value of the "countryPrefix" node
  • $areaPrefix - the value of the "areaPrefix" node
  • $from - the value of the "from" node
  • $to - the value of the "to" node
  • $replyTo - the value of the "replyTo" node
  • $subject - the value of the "subject" node
  • $text - the value of the "text" node
  • $nl - a new line character, to simplify handling of new lines in expressions
Additionally, string nodes in the archetype are available to expressions using $<nodeName>. This excludes nodes named "name", "description", "website", "fromExpression", "toExpression", "replyToExpression", "subjectExpression", and "textExpression" entity.SMSConfigEmailGeneric
    <archetype name="entity.SMSConfigEmailGeneric.1.0" latest="true"
               type="org.openvpms.component.business.domain.im.common.Entity" displayName="SMS Configuration: Generic Email Gateway">
        <node name="id" path="/id" type="java.lang.Long" hidden="true" readOnly="true"/>
        <node name="name" type="java.lang.String" path="/name" minCardinality="1"/>
        <node name="description" type="java.lang.String" path="/description" minCardinality="0"/>
        <node name="website" displayName="Web Site" type="java.lang.String" path="/details/website" minCardinality="0"/>
        <node name="active" path="/active" type="java.lang.Boolean" defaultValue="true()"/>
        <node name="countryPrefix" path="/details/countryPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="areaPrefix" path="/details/areaPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="from" path="/details/from" type="java.lang.String" minCardinality="0"/>
        <node name="fromExpression" path="/details/fromExpression" type="java.lang.String" minCardinality="0" defaultValue="'$from'"/>
        <node name="to" path="/details/to" type="java.lang.String" minCardinality="0"/>
        <node name="toExpression" path="/details/toExpression" type="java.lang.String" minCardinality="0" defaultValue="'$phone'"/>
        <node name="replyTo" path="/details/replyTo" type="java.lang.String" minCardinality="0"/>
        <node name="replyToExpression" path="/details/replyToExpression" type="java.lang.String" minCardinality="0" defaultValue="'$replyTo'"/>
        <node name="subject" path="/details/subject" type="java.lang.String" minCardinality="0"/>
        <node name="subjectExpression" path="/details/subjectExpression" type="java.lang.String" minCardinality="0" defaultValue="'$subject'"/>
        <node name="text" path="/details/text" type="java.lang.String" minCardinality="0"/>
        <node name="textExpression" path="/details/textExpression" type="java.lang.String" minCardinality="0" defaultValue="'$message'" maxLength="256"/>
    </archetype>
entity.SMSConfigEmailSMSGlobal
    <archetype name="entity.SMSConfigEmailSMSGlobal.1.0" latest="true"
               type="org.openvpms.component.business.domain.im.common.Entity" displayName="SMS Configuration: SMSGlobal Email2SMS">
        <node name="id" path="/id" type="java.lang.Long" hidden="true" readOnly="true"/>
        <node name="name" type="java.lang.String" path="/name" minCardinality="1" defaultValue="'SMS Global Email2SMS Configuration'"/>
        <node name="description" type="java.lang.String" path="/description"/>
        <node name="website" displayName="Web Site" type="java.lang.String" path="/details/website" readOnly="true" defaultValue="'http://www.smsglobal.com'"/>
        <node name="active" path="/active" type="java.lang.Boolean" defaultValue="true()"/>
        <node name="countryPrefix" path="/details/countryPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="areaPrefix" path="/details/areaPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="from" path="/details/from" type="java.lang.String" minCardinality="1"/>
        <node name="toExpression" path="/details/toExpression" type="java.lang.String" minCardinality="1" 
              defaultValue="'concat($phone, &quot;@email.smsglobal.com&quot;)'" hidden="true"/>
        <node name="textExpression" path="/details/textExpression" type="java.lang.String" minCardinality="1" defaultValue="'$message'" hidden="true"/>
    </archetype>
entity.SMSConfigEmailClickatell
    <archetype name="entity.SMSConfigEmailClickatell.1.0" latest="true"
               type="org.openvpms.component.business.domain.im.common.Entity" displayName="SMS Configuration: Clickatell SMTP Connection">
        <node name="id" path="/id" type="java.lang.Long" hidden="true" readOnly="true"/>
        <node name="name" type="java.lang.String" path="/name" minCardinality="1" defaultValue="'Clickatell SMTP Connection Configuration'"/>
        <node name="description" type="java.lang.String" path="/description"/>
        <node name="website" displayName="Web Site" type="java.lang.String" path="/details/website" readOnly="true" defaultValue="'http://www.clickatell.com'"/>
        <node name="active" path="/active" type="java.lang.Boolean" defaultValue="true()"/>
        <node name="countryPrefix" path="/details/countryPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="areaPrefix" path="/details/areaPrefix" type="java.lang.String" minCardinality="0"/>
        <node name="user" path="/details/user" type="java.lang.String" minCardinality="1"/>
        <node name="password" path="/details/password" type="java.lang.String" minCardinality="1"/>
        <node name="apiId" path="/details/apiId" type="java.lang.String" minCardinality="1"/>
        <node name="to" path="/details/to" type="java.lang.String" minCardinality="1" defaultValue="'sms@messaging.clickatell.com'" hidden="true"/>
        <node name="from" path="/details/from" type="java.lang.String" minCardinality="1"/>
        <node name="replyTo" path="/details/replyTo" type="java.lang.String" minCardinality="0"/>
        <node name="textExpression" path="/details/textExpression" type="java.lang.String" minCardinality="1" hidden="true"
              defaultValue="'concat(&quot;user:&quot;, $user, &quot;&#xA;password:&quot;, $password, &quot;&#xA;api_id:&quot;, $apiId, &quot;&#xA;to:&quot;, $phone, &quot;&#xA;reply:&quot;, $replyTo, &quot;&#xA;text:&quot;, replace($message, &quot;&#xA;&quot;,&quot;&#xA;text:&quot;))'"/>
    </archetype>
Hide
Tim Anderson added a comment -

Changes applied to:

  • archetypes, revisions: 4394, 4400
  • vpms, revisions 4395, 4397, 4398, 4402, 4415
  • release, revisions: 4399, 4413
  • openvpms-sms, revisions: 4377, 4383, 4385, 4393, 4401, 4403, 4414
Show
Tim Anderson added a comment - Changes applied to:
  • archetypes, revisions: 4394, 4400
  • vpms, revisions 4395, 4397, 4398, 4402, 4415
  • release, revisions: 4399, 4413
  • openvpms-sms, revisions: 4377, 4383, 4385, 4393, 4401, 4403, 4414

People

Vote (0)
Watch (0)

Dates

  • Created:
    Updated:
    Resolved:

Time Tracking

Estimated:
Not Specified
Original Estimate - Not Specified
Remaining:
0h
Remaining Estimate - 0h
Logged:
44h
Time Spent - 44h