Here is a low budget way to set up a simple, but reliable SMS gateway for your server.

You will need:

  • A server you wish to send and receive text messages (SMS) with
  • An Android mobile device with a working SIM card

How it works

  • Your Android mobile device is connected to the Google Cloud Messaging (GCM) service.
  • Your server is connected to the GCM as well.
  • Whenever your Android device receives a text message, it pushes it to your server via GCM.
  • Whenever you wish to send a text message from your server, you push it to the mobile device via GCM.

funktionsgrafik

By relying on Google Cloud Messaging for both directions of communication there is no frequent polling and no long running requests. Instead we get a high level of stability and error tolerance: E.g. GCM queues and retries faulty messages in case of network or device errors. You can relax about switching devices or maintenance work on your server. Things magically just work as they should.

Only a few steps to your own SMS gateway:

  1. Create a project on the Google Developers Console (it’s free!)
  2. Install the GCMSMS App on the Android device (it’s very inexpensive)
  3. Enter the project ID into the app (this connects the device to the Google Cloud)
  4. Connect your server/software to the GCM service (using the same project ID)
  5. Send and receive SMS like a boss

These steps in more detail:

Let’s Do It!

Step 1: Google Project

In order to use Google Cloud Messaging (GCM) you need to set up a project in the Google Developers Console. Simply go to https://console.developers.google.com/project and add a new project. Assign a name, create and then open the project. Now open the project and copy the „Project Number“ from the „Overview“ menu (you will need this later). Now open the „APIs“ menu and switch on „Google Cloud Messaging for Android“. Go to the „Credentials“ menu and under „Public API access“ add a new „Server Key“. You can restrict API access to your server’s IP only or simply allow all IPs. Copy the API KEY (you will need this later).

2015-03-24 12_17_43-Google Developers Console  2015-03-24 12_16_26-Google Developers Console  2015-03-24 12_19_08-Google Developers Console

At this point you should have a project number and an API key. You will need both to connect your mobile device and your server software to the Google cloud.

Step 2: Install GCMSMS App

This is the easiest step!

Just install THIS APP (GCMSMS) on the mobile device you wisth to turn into your SMS gateway. This app is your ready-to-run GCM Client handling inbound and outbound text messages and turns your Android device into your own SMS gateway.

Step 3: Connect mobile device to GCM project

Screenshot_2015-03-25-11-19-05Enter the Project Number into the app. This connects your mobile device to the GCM project and GCM assigns a „Registration ID“ to your device. You will need this registration id later in order to push messages from your server through the Google cloud directly to your device.

Note: Don’t even try to write down the very long registration id. Simply tap „Share RegID“ from the app’s menu to send the ID to yourself e.g. in an eMail.

 

Step 4: Connect server to GCM

This is the most tricky part of setting up your own SMS gateway via GCM.

If your server application is in Java, simply use our free library and you are ready to go! Jump to Step 5 for details.

If not Java: What you basically need to create is an application server based on XMPP for up- and downstream messaging as described here. This sounds very complicated but it is actually not that bad. There are all kinds of XMPP implementations out there! So go ahead, find a XMPP server implementation for your programming language.

Step 5: Send & Receive SMS

Screenshot_2015-03-25-10-19-12Let’s see how it’s done in Java using our free library:

From the Smack library take smack-core-X.X.X.jar and smack-tcp-X.X.X.jar and put it on your classpath. Also put the kxml2-X.X.X.jar, gson-X.X.X.jar as well as the gcmsms-X.X.X.jar on your classpath.

Code Setup:


private static final long PROJECT_ID = 1234567890L;
private static final String KEY = "XXXXXXXXXXXXXXX";
private static final String REGISTRATION_ID = "YYYYYYYYYYYYYYYYYYYYYY";

GCMSMS gcmsms = new GCMSMS();
XMPPTCPConnection connection = gcmsms.connect(PROJECT_ID, KEY, new GCMSMSMessageHandlerTest());

Here – of course – you insert your project ID, your API key and the registration ID of your mobile device.

Send SMS:


JsonObject payload = new JsonObject();
payload.addProperty("number", "+436641234567890");
payload.addProperty("message", "Testing GCMSMS gateway: Sending outbound SMS");
String msg = gcmsms.createJsonMessage(REGISTRATION_ID, payload, null, null, null);
boolean done = gcmsms.sendDownstreamMessage(msg);
System.out.println("Message pushed to GCM: " + done);

Update for bulk-send: https://netbizltd.com/sms-gateway-update-for-bulk-send/

Incoming SMS:

Implement a GCMSMSMessageHandler and its handleIncoming method like so:


public void handleIncoming(JsonObject message) {
  JsonObject payload = message.get("data").getAsJsonObject();
  if (payload.get("test") != null) {
    System.out.println("User selected menu item 'Send Test-GCM' in GCMSMS Android app");
    return;
  }

  String number = payload.get("number").getAsString();
  String text = payload.get("text").getAsString();
  System.out.println("Incoming SMS from " + number + ": " + text);
}

You can simply leave handleAck, handleNack, handleControl and handleOutgoing empty.

Note: There is a special „CONNECTION_DRAINING“ control message from GCM. If a connection is draining you can no longer send messages to GCM on it. This is handled by GCMSMS for you and calls to sendDownstreamMessage on a draining connection will automatically return false.

Keep the connection object alive (e.g. on a separate thread) so that the XMPP server keeps running for as long as your application is running. When your application shuts down, call gcmsms.disconnect() to clean things up.

This just for fun: Add a connection listener to the XMPP connection to see what’s happening there:

...
connection.addConnectionListener(new ConnectionListenerTest());
...

private static final class ConnectionListenerTest implements ConnectionListener {
  @Override
  public void connected(XMPPConnection xmppConnection) {
    System.out.println("Connected.");
  }
  ... other methods from ConnectionListener ...
}

Notes

Android SMS Limits

Android comes with a built in limit on how many SMS messages can be sent out within an hour. This is usually a good thing to prevent malware apps from riding up your mobile bill but can be very annoying for SMS gateways where you might want to send several hundred messages at once.

To remove this limit you need to have a „rooted“ device and run „SMS Limit Unlock“ or a similar app.

SMS Fees

Also note that – of course – your mobile network provider collects fees for sending text messages depending on your mobile plan.

Always On

The GCMSMS app keeps the device and screen on so you will need to plug the device in. This way the app can respond to GCM messages with very little latency and push messages to your server as soon as SMS arrive.

Also note that the GCMSMS app obviously needs an internet connection to send/receive GCM messages. Connecting to a WIFI with internet access is recommended.