Sending SMS from Maximo calling an external Web service

In my last project I had to implement a customization to send SMS messages using Skebby. The service APIs are obviously based on REST and JSON so I ended up writing an automation script to integrate Maximo with the Skebby service.
In the process of writing the code I have faced (and solved) some interesting issues so the developed script is quite complex and is an interesting demonstration of several useful techniques:

  1. External REST service invocation (POST and GET)
  2. JSON manipulation
  3. Retrieve Maximo system properties
  4. Usage of Java classes
  5. Appropriate logging using MXLoggerFactory
  6. Display error messages with parameters

The script is based on WORKORDER object and requires two custom system properties (sms.username, sms.password) and two messages (SmsSendError, SmsSendOk).
Here it is.

from java.lang import String
from java.io import BufferedReader, InputStreamReader
from java.net import URL, URLEncoder
from java.nio.charset import StandardCharsets
from com.ibm.json.java import JSONObject, JSONArray

from psdi.server import MXServer
from psdi.util.logging import MXLoggerFactory

logger = MXLoggerFactory.getLogger("maximo.script")
logger.debug("Entering SEND_SMS script")


BASEURL = "https://api.skebby.it/API/v1.0/REST/"
SMS_SENDER = "Maximo"
SMS_DEST = "+3933511111111"

sms_text = "Ticket " + mbo.getString("WONUM") + " - " + mbo.getString("DESCRIPTION")

properties = MXServer.getMXServer().getConfig()
username = properties.getProperty("sms.username")
password = properties.getProperty("sms.password")

urltxt = BASEURL + "login?username=" + URLEncoder.encode(username, "UTF-8") + "&password=" + URLEncoder.encode(password, "UTF-8")
logger.debug("Authenticating: " + urltxt)
url = URL(urltxt)
conn = url.openConnection()
conn.setRequestMethod("GET")

if conn.getResponseCode() != 200:
conn.disconnect()
msg = "HTTP Error: " + str(conn.getResponseCode()) + " - " + str(conn.getResponseMessage())
logger.error(msg)
service.error("asts", "SmsSendError", [str(conn.getResponseCode()), str(conn.getResponseMessage()), "Authentication failed"])

br = BufferedReader(InputStreamReader(conn.getInputStream()))
authResp = br.readLine()
conn.disconnect()

#logger.debug("Authentication output:" + authResp)
# auth tokens are returned separated by a ';' character
user_key,session_key = authResp.split(';')

logger.debug("Authentication tokens:" + user_key + "," + session_key)

logger.info("Sending SMS to " + SMS_DEST + " - " + sms_text)

url = URL(BASEURL + "sms")
conn = url.openConnection()
conn.setRequestMethod("POST")
conn.setRequestProperty("user_key", user_key)
conn.setRequestProperty("Session_key", session_key)
conn.setRequestProperty("content-type", "application/json")
conn.setDoOutput(True)

recipients = JSONArray()
recipients.add(SMS_DEST)

obj = JSONObject()
obj.put("message_type", "TI")
obj.put("returnCredits", False)
obj.put("sender", SMS_SENDER)
obj.put("recipient", recipients)
obj.put("message", sms_text)
jsonStr = obj.serialize(False)

logger.debug("SMS Json Request=" + jsonStr)

os = conn.getOutputStream()
postData = String.getBytes(jsonStr, StandardCharsets.UTF_8)
os.write(postData)
os.flush()

if conn.getResponseCode() != 201:
br = BufferedReader(InputStreamReader(conn.getErrorStream()))
output = br.readLine()
logger.error("Error: " + output)
conn.disconnect()
msg = "HTTP Error: " + str(conn.getResponseCode()) + " - " + str(conn.getResponseMessage() + " - " + output)
logger.error(msg)
service.error("asts", "SmsSendError", [str(conn.getResponseCode()), str(conn.getResponseMessage()), output])

br = BufferedReader(InputStreamReader(conn.getInputStream()))
output = br.readLine()
logger.info("OK: " + output)
conn.disconnect()

service.setWarning("asts", "SmsSendOk", None)

The script has been developed to avoid external dependencies like this example.

Sending SMS from Maximo calling an external Web service

9 thoughts on “Sending SMS from Maximo calling an external Web service

  1. Hello, Bruno. I love your work. I tried to implement your script for testing purposes on Maximo 7.6.0.9 and Maximo 7.6.1, but on both systems I get Certificate error, saying:
    BMXAA7837E – An error occured that prevented the {0} script for the {1} launch point from running
    javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLHandshakeException: com.ibm.jsse2.util.h: PKIX path building failed: java.security.cert.CertPathBuilderException: PKIXCertPathBuilderImpl could not build a valid CertPath.; internal cause is:
    java.security.cert.CertPathValidatorException: The certificate issued by CN=DigiCert Global Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US is not trusted; internal cause is:
    java.security.cert.CertPathValidatorException: Certificate chaining error in script at line number 30

    Please can you tell me if you also run into this probblem?

  2. Ok. I imported the DigiCert Global Root CA into WebSphere and I've got a little further. Now I get this Error:
    BMXAA7837E – An error occured that prevented the {0} script for the {1} launch point from running
    javax.net.ssl.SSLException: javax.net.ssl.SSLException: java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 64 in script at line number 30

    Any idea?

  3. When I am trying to call .Net webserive from Maximo 7.6. i am getting below error.

    psdi.util.MXSystemException: BMXAA1481E – Cannot deliver the message to the endpoint.
    java.io.IOException: Async IO operation failed (3), reason: RC: 107 Transport endpoint is not connected
    at psdi.iface.router.WebServiceHandler.invoke(WebServiceHandler.java:258)
    at psdi.iface.mic.MicService.routeData(MicService.java:472)
    at psdi.iface.app.endpoint.MaxEndPointTestSet.execute(MaxEndPointTestSet.java:131)
    at psdi.webclient.beans.endpoint.EndPointTestBean.testxml(EndPointTestBean.java:59)
    at sun.reflect.GeneratedMethodAccessor252.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:55)
    at java.lang.reflect.Method.invoke(Method.java:508)

    It is throwing in Prod only but not in test environments. Any suggestions please????

  4. Hi Bruno, Thanks alot for your useful ideas .
    During trying this method an erroe message displayed to me
    the error says:
    java.net.SocketException: java.net.SocketException: Permission denied: connect in

    Kindly your comment

Leave a Reply to Bruno Portaluri Cancel reply

Your email address will not be published. Required fields are marked *

Scroll to top