Sending SMS through GoIP GSM gateway using HTTP API
GoIP is a network device and a GSM gateway in one made by Hybertone and DBL. It can be used for SMS or VoIP features in your applications. In comparison to a simple GSM modem that can be operated through AT commands over a serial connection a GoIP device offers way more management options, is stand-alone, and can scale to many SIM cards.
Currently GoIP devices can be found on sites like Aliexpress. The starting model has a one GSM modem but the top of the line can handle over 100 SIM cards. For pure SMS handling, it can be better to use services like Twilio, but for more remote locations like islands where Twilio services are way more expensive an on-site GoIP can be a way cheaper solution for local SMS messages.
How to use a GoIP?
When you connect the device to your local network through an Ethernet cable and power on the device with the provided power supply the device will launch a web management panel. You have to check your router or use a port sniffer to see which local IP the device got assigned.
Open the IP in your browser (for example http://192.168.0.2/
) and you should see a login request. Default login and password is admin
and admin
.
When you log in you should have access to GoIP admin/management panel. You can configure the device as well as test and manage some of its GSM features.
The goal is to configure the GSM and then set up access to the device based on your use case. GoIP can be used as is, using some of its HTTP API to send SMS or through compatible web SMS servers or through compatible apps using SMMP protocol.
If you want to use the device directly with your application then either it has to be in the same local network or you have to expose the GoIP through a public IP (which can be a security risk). Ngrok can be a handy way of exposing GoIP, at least for prototyping.
SMS servers, like the one provided by DBL, allow you to keep GoIP devices off the public net, which may be the way to go when you will be operating multiple devices, or you want better access control. There are also third-party servers like Ozeki NG SMS Gateway that are compatible with GoIP. See device documentation for more info.
GSM configuration
By default the GSM module will be off. Go to Configuration
- SIM
to do basic configuration as needed. If your SIM card requires an unlock PIN you have to specify it there. When all seems to be in order you can try turning the GSM module on.
SIM/GSM switch is one you probably never expected. Go to the main Summary
page and look at the table listing available SIM channels. In the M
column you will see N
value. The N
is a link, click it to toggle the SIM on/off.
After which you should see the GSM coming up online. In Tools
- Send SMS
you can try it out by sending a message to your number.
HTTP API - Sending SMS
GoIP has a basic HTTP API for sending SMS. All you need is a GET request:
The endpoint will return a response of success/error if it's able to process and start sending the message:
This is not actual delivery status, but more of a device status. For given channel it will reject all incoming messages until it's done sending current message. That's why after sending a message you should check actual status using another endpoint:
Which will return status for each device channel. The ID you got while sending SMS will be listed here as well:
<?xml version="1.0" encoding="utf-8"?>
<send-sms-status>
<id1>SOME_MESSAGE_ID</id1>
<status1>DONE</status1>
<error1></error1>
<id2></id2>
<status2></status2>
<error2></error2>
<id3></id3>
<status3></status3>
<error3></error3>
<id4></id4>
<status4></status4>
<error4></error4>
<id5></id5>
<status5></status5>
<error5></error5>
<id6></id6>
<status6></status6>
<error6></error6>
<id7></id7>
<status7></status7>
<error7></error7>
<id8></id8>
<status8></status8>
<error8></error8>
</send-sms-status>
Note that it's the status for the last processed message. If you send another one you will not be able to check the status of the previous one. This output is from GoIP-1 which has only one channel, yet it returns XML response for 8 channels. DONE
is done while the initial status is STARTED
and until it changes you can't send another message through that channel.
Libraries for software development
Official software is written in PHP while on GitHub you will be able to find quite a lot of libraries or feature implementations using GoIP. Just check if they are still supported as some are quite old.
Python wrapper class
GoIP API is simple and all we need is Python and requests library.
import urllib.parse
import requests
import xml.etree.ElementTree as xml_tree
class GoIP:
def __init__(self, base_url, login, password):
self.base_url = base_url
self.login = login
self.password = password
def send_sms(self, number, text, sim_slot=1):
endpoint = 'default/en_US/send.html'
data = {
'n': number,
'm': text,
'l': sim_slot,
}
response = self._send_request(endpoint, data)
return self._parse_send_response(response)
def _parse_send_response(self, response):
response = response.strip()
status = response.split(',')[0].strip()
if status == 'Sending':
message_id = response.split('ID:')[-1].strip()
return {'status': status, 'message_id': message_id}
else:
error_message = response.replace(f'{status},', '')
return {'status': status, 'error_message': error_message}
def get_sms_status(self):
endpoint = 'default/en_US/send_status.xml'
data = {}
response = self._send_request(endpoint, data)
return self._parse_status_response(response)
def _parse_status_response(self, response):
xml = xml_tree.fromstring(response)
response = {}
for element in xml:
channel = element.tag[-1]
tag = element.tag[:-1]
if channel not in response:
response[channel] = {'id': None, 'status': None, 'error': None}
response[channel][tag] = element.text
return response
def _send_request(self, endpoint, data):
url = urllib.parse.urljoin(self.base_url, endpoint)
data.update({
'u': self.login,
'p': self.password,
})
return requests.get(url, data=data).text
send_sms method collects all the data that has to go into the query string and makes the GET request with requests and parses the output into a dictionary.
get_sms_status method makes the request to the status endpoint and then parses the XML grouping fields by channel and returns a dict of dicts.
import time
x = GoIP('http://GOIP_IP', 'LOGIN', 'PASSWORD')
print(x.send_sms('YOUR_NUMBER', 'Hello SMS!'))
for i in range(1, 30):
time.sleep(0.5)
print(x.get_sms_status())
Web scrapping and automating GoIP admin panel
The web admin panel isn't very sophisticated, and it's very easy to use it through automated requests from your code. All you have to do is set the Authorization header as shown by goip-sms-parser application.
As shown by the code the Authorization
header is just base64 of login and password. GoIP panel in Tools tab has a page listing incoming messages and the goip-sms-parser
is parsing data from that page using some regexp and CSV parsing:
import base64
import requests
import re
import csv
class GoipGateway:
def __init__(self, goip_addr, goip_user, goip_password):
self.goip_addr = goip_addr
self.goip_user = goip_user
self.goip_password = goip_password
def _receive_messages(self):
auth_string = f"{self.goip_user}:{self.goip_password}"
auth_header = {
"Authorization": f"Basic {base64.b64encode(auth_string.encode('utf-8')).decode('utf-8')}"
}
response = requests.get(f"{self.goip_addr}/default/en_US/tools.html?type=sms_inbox", headers=auth_header)
data = response.text
data = data.replace('\\"', '"').encode('latin1').decode('utf-8')
sms_dump_arr = re.findall(r'sms= \[(.*?)\]', data, re.IGNORECASE | re.DOTALL)
for sim_key, sim_val in enumerate(sms_dump_arr):
for sms_val in csv.reader([sim_val], skipinitialspace=True, quotechar="'"):
messages = [{'date': sms_val[i], 'phone': sms_val[i+1], 'text': sms_val[i+2]} for i in range(0, len(sms_val)-2, 3) if sms_val[i] != '""']
for message in messages:
yield message
With a response looking like so (I've edited the method slightly to use a generator instead of returning a list of lists):
If you want to use GoIP to send marketing messages you may be legally required to support unsubscription STOP
messages and for that, you have to read incoming messages and match the phone number with the marketing subscription and cancel it.
And the options don't end at SMS. There are VoIP options as well, and you can find some examples of them on GitHub.
Summary
GoIPs are unusual devices that serve a niche, and they can get the job done at a relatively low cost. It's likely not the most secure and feature-complete solution though. You should do some research on how to set up your system in most secure and reliable manner. Also, legal aspects can be a factor in your country - wherever it's allowed to use such devices or how to legally send things like marketing SMS messages or general bulk SMS sending.
I heard of this device first when a customer of a web service I work on was using it to send local SMS cheaper than Twilio or Vonage as it was on an island, far away from continental telecom infrastructure and that seems like a nice use case for those devices. You could play with a router and GSM modem, sending AT commands, but it's more crude and requires specific hardware which may be harder to get, manage, and troubleshoot.
Comment article