Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Lua lib to send SMS with Telstra's SMS API
local telstra_sms_api = require "telstra_sms_api".new
local sleep = require "cqueues".sleep
if #arg < 2 then
io.stderr:write("Expected number and body\n")
os.exit(1)
end
local to = arg[1]
local message = table.concat(arg, " ", 2)
local api = telstra_sms_api {
client_id = "MyID";
client_secret = "MySecret";
}
local id = api:send_msg(to, message)
print("Sent message, id=", id)
repeat
local status = api:message_status(id)
sleep(2)
until status.status == "DELIVRD"
print("SMS Delivered.")
local cjson = require "cjson"
local monotime = require "cqueues".monotime
local request = require "http.request"
local http_util = require "http.util"
local wiggle_room = 5
local methods = {}
local mt = { __index = methods; }
local function telstra_sms_api(options)
return setmetatable({
client_id = assert(options.client_id, "missing client_secret ('Consumer Key')");
client_secret = assert(options.client_secret, "missing client_id ('Consumer Secret')");
token = nil;
expires = nil;
}, mt)
end
local function json_go(r)
local headers, stream = assert(r:go())
local body = assert(stream:get_body_as_string())
stream:shutdown()
local decoded
if (headers:get("content-type") or ""):match("^%s*[^;]+") == "application/json" then
decoded = cjson.decode(body)
end
if headers:get(":status"):sub(1,1) ~= "2" then
error(decoded and decoded.error or body, 2)
end
if decoded == nil then
error("not a json response", 2)
end
return decoded
end
function methods:get_token()
local r = request.new_from_uri("https://api.telstra.com/v1/oauth/token")
r.headers:upsert(":method", "POST")
r.headers:upsert("accept", "application/json")
r.headers:upsert("content-type", "application/x-www-form-urlencoded")
r:set_body(http_util.dict_to_query {
grant_type = "client_credentials";
scope = "SMS";
client_id = self.client_id;
client_secret = self.client_secret;
})
local start = monotime()
local decoded = json_go(r)
self.token = assert(decoded and decoded.access_token, "missing access_token")
self.expires = start + tonumber(decoded.expires_in) - wiggle_room
end
function methods:check_token()
if not self.token or self.expires < monotime() then
self:get_token()
end
end
function methods:send_msg(to, body)
assert(type(to) == "string")
assert(type(body) == "string")
self:check_token()
local r = request.new_from_uri("https://api.telstra.com/v1/sms/messages")
r.headers:upsert(":method", "POST")
r.headers:upsert("accept", "application/json")
r.headers:upsert("authorization", "Bearer "..self.token)
r.headers:upsert("content-type", "application/json")
r:set_body(cjson.encode {
to = to;
body = body;
})
local decoded = json_go(r)
local message_id = assert(decoded and decoded.messageId, "missing messageId")
return message_id
end
function methods:message_status(message_id)
self:check_token()
local r = request.new_from_uri("https://api.telstra.com/v1/sms/messages/"..message_id)
r.headers:upsert("accept", "application/json")
r.headers:upsert("authorization", "Bearer "..self.token)
local decoded = json_go(r)
return decoded
end
return {
new = telstra_sms_api;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment