Xojo is able to send texts directly via BulkSMS.com

Should you need to send SMS texts from your Xojo app, I have been able to send them successfully with BulkSMS.com. I plan to support other services in the future.

If you’re interested I have added the code below:

I have a button on my page that has a Pressed event that calls SMSTestButtonPressed (see below). This collates the correct variables then passes these to a generic Method getURLConnectionSendSync that talks to the BulkSMS host and returns the host JSON response.

It also uses a Method called getSMSRequestContent to return the correct JSON to be sent to the BulkSMS host. It is used in SMSTestButtonPressed to build the URLConnection’s RequestContent variable.

There is only one header to add (‘Authorization’), so it is passed as a String array of only one element per Header Name and Value. The MIME Type is 'application/json’ by default

Private Sub SMSTestButtonPressed
  Var isError As Boolean = False
  Var ErrorMessage As String
  Var ErrorCode As Integer = -1
  Var SMSMessage As String = "Hi, just a quick message from David to say SMS is working from my new app via the BulkSMS service"
  Var SMSRequestContent As String = getSMSRequestContent("+447557311234", “+447557314567,+447557316789", SMSMessage)
  Var SMSURL As String = "https://api.bulksms.com/v1/messages”
  Var AuthorisationCode As String = “…” 'get your own!
  
  Var ReplyJSON As String = getURLConnectionSendSync(isError, ErrorMessage, ErrorCode, SMSURL, SMSRequestContent, Array ("Authorization"), Array (AuthorisationCode))
  If isError Then
    'doDisplayError(ErrorMessage, CurrentMethodName, ErrorCode)
  End If
 
'Check the ReplyJSON String below
…
End Sub
Private Function getURLConnectionSendSync(ByRef isError As Boolean, ByRef ErrorMessage As String, ByRef ErrorCode As Integer, URLConnectionHost As String, RequestContent As String, HeaderNames() As String = Nil, HeaderValues() As String = Nil, URLConnectionMethod As String = "POST", MIMEType As String = "application/json", URLConnectionTimeOut As Integer = 30) As String
  Var tempURLConnection As New URLConnection
  Var ReturnJSON As String
  
  If URLConnectionHost = "" Then
    isError = True
    ErrorMessage = "Host is missing"
    Return ""
    
  ElseIf URLConnectionHost.left(7) <> "http://" And URLConnectionHost.left(8) <> "https://" Then
    URLConnectionHost = "https://" + URLConnectionHost
  End If
  
  If RequestContent <> "" Then
    tempURLConnection.SetRequestContent(RequestContent, MIMEType)
  End If
  
  If HeaderNames <> Nil And HeaderNames.LastIndex >= 0 And HeaderValues <> Nil And HeaderValues.LastIndex >= 0 And HeaderNames.LastIndex = HeaderValues.LastIndex Then
    For tempInt As Integer = 0 To HeaderNames.LastIndex
      Var HeaderName As String = HeaderNames(tempInt)
      Var HeaderValue As String = HeaderValues(tempInt)
      
      tempURLConnection.RequestHeader(HeaderName) = HeaderValue
    Next
  End If
  
  Try 'network timeout causes exception!
    tempURLConnection.AllowCertificateValidation = False
    ReturnJSON = tempURLConnection.SendSync(URLConnectionMethod, URLConnectionHost, URLConnectionTimeOut)
    tempURLConnection.Disconnect
    
  Catch Error
    isError = True
    ErrorMessage = Error.Message
    ErrorCode = tempURLConnection.HTTPStatusCode
    Return ""
  End Try
  
  Return ReturnJSON.DefineEncoding(Encodings.UTF8)
End Function
Private Function getSMSRequestContent(SMSPhoneNumber As String, SMSRecipients As String, SMSMessage As String, isUnicode As Boolean = True) As String
  If SMSPhoneNumber = "" Or SMSRecipients = "" Or SMSMessage = "" Then
    Break
    Return ""
  End If
  
  Var tempDictionary As New Dictionary
  tempDictionary.Value("from") = SMSPhoneNumber
  Var TestSMSRecipientsArray() As String = SMSRecipients.ToArray(",")
  If TestSMSRecipientsArray.LastIndex = 0 Then
    tempDictionary.Value("to") = SMSRecipients
  Else
    tempDictionary.Value("to") = TestSMSRecipientsArray
  End If
  tempDictionary.Value("body") = SMSMessage
  If isUnicode Then
    tempDictionary.Value("encoding") = "UNICODE"
  End If
  
  Var tempJSONMBS As JSONMBS = JSONMBS.Convert(tempDictionary)
  
  Return tempJSONMBS.toString
End Function
8 Likes

Tweaked to remove unnecessary plugins:

Private Function getSMSRequestContent(SMSPhoneNumber as String, SMSRecipients as String, SMSMessage as String, isUnicode as Boolean = True) As String
  If SMSPhoneNumber = "" Or SMSRecipients = "" Or SMSMessage = "" Then
    Break
    Return ""
  End If
  
  var jsBody as new JSONItem
  jsBody.Value("from") = SMSPhoneNumber
  jsBody.Value("body") = SMSMessage
  
  // Allow for CSV of recipients
  var arsRecipients() as String = SMSRecipients.ToArray(",")
  if arsRecipients.LastIndex = 0 then
    // Single recipient
    jsBody.Value("to") =  SMSRecipients
    
  else
    // Array
    jsBody.Value("to") = arsRecipients
    
  end
  
  if isUnicode then
    jsBody.Value("encoding") = "UNICODE"
    
  end
  
  return jsBody.ToString
End Function

Also, I would generally recommend against AllowCertificateValidation = False when using someone else’s service.

4 Likes

Yes, I use this whenever I test the app to look to the REST WebApp running on 127.0.0.1, so I should’ve commented it. Thank you.