added emessage api
parent
c950dba5a5
commit
3bce300c70
@ -1,49 +0,0 @@
|
||||
#!/bin/bash
|
||||
## Bash Library for sending out Pages and/or getting their State
|
||||
# dependencies: curl, jq
|
||||
|
||||
# echo "Bericht" | send_page "http://127.0.0.1:3000" "duplex" "birdyslim" "dapnet=dl-all#DXxxx"
|
||||
send_page() {
|
||||
text=$(cat -)
|
||||
endpoint=$1
|
||||
msgType=$2
|
||||
deviceType=$3
|
||||
argArr=("$@")
|
||||
connectorJSON=$(for arg in "${argArr[@]}"; do echo $arg; done | jq -Rcs '{array:split("\n")|.[3:-1]|map(split("=")|[(.[0]),.[1]]?)}.array')
|
||||
echo $connectorJSON |\
|
||||
jq -c --arg t "$msgType" --arg d "$deviceType" --arg p "$text" '{type:$t, routing: {connectors:.,device:$d}, payload:$p}' |\
|
||||
curl -s -XPOST -H "Content-type: application/json" "$endpoint/api/message/advanced" -d @- |\
|
||||
jq -r .
|
||||
}
|
||||
msg_status() {
|
||||
endpoint=$1
|
||||
msgid=$2
|
||||
curl -s "$endpoint/api/message/status/$msgid" |\
|
||||
jq -r ._routerData
|
||||
}
|
||||
is_msg_recv() {
|
||||
msg_status $* | jq .recvAck | grep -q "true"
|
||||
return $?
|
||||
}
|
||||
is_msg_read() {
|
||||
msg_status $* | jq .readAck | grep -q "true"
|
||||
return $?
|
||||
}
|
||||
is_msg_resp() {
|
||||
msg_status $* | jq .response | grep -vq "false"
|
||||
return $?
|
||||
}
|
||||
|
||||
ENDPOINT="http://127.0.0.1:3000"
|
||||
#echo "Test" | send_page "$ENDPOINT" "duplex" "birdyslim" "pocsag=133701D" "test=123"
|
||||
msgid=$(echo "Test" | send_page "$ENDPOINT" "duplex" "birdyslim" "pocsag=133701D" "test=123")
|
||||
#msgid="Bznka"
|
||||
msg_status "$ENDPOINT" "$msgid"
|
||||
|
||||
|
||||
if is_msg_recv "$ENDPOINT" "$msgid"; then
|
||||
echo "message is recv"
|
||||
fi
|
||||
if is_msg_read "$ENDPOINT" "$msgid"; then
|
||||
echo "message is read"
|
||||
fi
|
@ -0,0 +1,142 @@
|
||||
const Connector = require("./Connector")
|
||||
const config = require('../../config.json')
|
||||
const md5 = require('md5')
|
||||
const axios = require('axios')
|
||||
// [ "ecityruf", "123456789" ]
|
||||
class eCityrufConnector extends Connector {
|
||||
constructor (amqpConnMngr) {
|
||||
super(amqpConnMngr)
|
||||
this.name = "emessage"
|
||||
this.duplexCapable = true
|
||||
this.supportBOSkrypt = true
|
||||
}
|
||||
async transmitMessage(msg, params) {
|
||||
const UUID = this.name+':'+md5(JSON.stringify([this.name,...params]))
|
||||
const target = params[0]
|
||||
if (target.split('#').length !== 2) throw 'No valid eMessage Parameter <serviceName#identifier>'
|
||||
const serviceName = target.split('#')[ 0 ], identifier = target.split('#')[ 1 ]
|
||||
// eCityruf#8907737
|
||||
|
||||
let jwtToken = '', msgTrackID = ''
|
||||
// login
|
||||
axios.post('https://api.emessage.de/auth/login', {
|
||||
username: config.connectors.emessage.username,
|
||||
password: config.connectors.emessage.password
|
||||
})
|
||||
.then((loginReq) => { // extract jwt
|
||||
if (loginReq.data.apiStatusCode != 200) { throw loginReq }
|
||||
jwtToken = loginReq.data.data.jwt
|
||||
return jwtToken
|
||||
})
|
||||
.then(() => { // send Message Request
|
||||
return axios.post('https://api.emessage.de/rs/eSendMessages', {
|
||||
messageText: msg.payload,
|
||||
recipients: [{ serviceName, identifier }]
|
||||
}, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${ jwtToken }`
|
||||
}
|
||||
})
|
||||
})
|
||||
.then((sndMessageReq) => { // extract tracking ID from response
|
||||
if (sndMessageReq.data.apiStatusCode != 200) { throw sndMessageReq }
|
||||
this.connectorRegistry.reportState(msg, UUID, 'routed') // since we queued the message, we shall mark it was routed
|
||||
msgTrackID = sndMessageReq.data.data.trackingId
|
||||
console.log('TRACKING ID', msgTrackID)
|
||||
return msgTrackID
|
||||
})
|
||||
/*.then((_) => { // extract tracking ID from response
|
||||
this.connectorRegistry.reportState(msg, UUID, 'routed')
|
||||
msgTrackID = '04872f70-9029-11ec-b877-e5935093b691'
|
||||
return msgTrackID
|
||||
})*/
|
||||
.then(async () => { // check for response til duplexTimeout
|
||||
const delaySeconds = (timeout) => new Promise(r=>setTimeout(r, timeout * 1e3))
|
||||
const checkDelivery = async () => {
|
||||
try {
|
||||
let res = await axios.get('https://api.emessage.de/rs/eGetMessages/External/' + msgTrackID, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${ jwtToken }`
|
||||
}
|
||||
})
|
||||
let deliveryState = res.data.data.recipients[ 0 ].status[ 0 ].answer
|
||||
if (deliveryState == 'INTRANSIT') this.connectorRegistry.reportState(msg, UUID, 'transit')
|
||||
if (deliveryState == 'SENT') this.connectorRegistry.reportState(msg, UUID, 'sent')
|
||||
if (deliveryState == 'RECEIVED' || +deliveryState > 0) {
|
||||
this.connectorRegistry.reportDelivered(msg, UUID)
|
||||
return true
|
||||
}
|
||||
console.log(JSON.stringify(res.data.data))
|
||||
//this.connectorRegistry.reportState(msg, UUID, deliveryState)
|
||||
|
||||
return false
|
||||
//if (res.data.data.recipients.filter(rec=>))
|
||||
} catch (e) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
const checkResponse = async () => {
|
||||
try {
|
||||
let res = await axios.get('https://api.emessage.de/rs/eGetMessages/External/' + msgTrackID, {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${ jwtToken }`
|
||||
}
|
||||
})
|
||||
let status = res.data.data.recipients[ 0 ].status[ 0 ]
|
||||
//if (deliveryState == 'INTRANSIT') this.connectorRegistry.reportState(msg, UUID, 'transit')
|
||||
/*if (deliveryState == 'RECEIVED' || +deliveryState > 0) {
|
||||
this.connectorRegistry.reportDelivered(msg, UUID)
|
||||
return true
|
||||
}*/
|
||||
if (+status.answerNo == 1 && +status.answer > -1 ) {
|
||||
//this.connectorRegistry.response(msg, status.answer)
|
||||
require('../MessageManager').markMessageRead(msg.id)
|
||||
require('../MessageManager').respondToMessage(msg.id, +status.answer)
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
//if (res.data.data.recipients.filter(rec=>))
|
||||
} catch (e) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
const deliveryProcess = new Promise(async (res, rej) => {
|
||||
const { startInterval, duplexTimeout } = config.connectors.emessage
|
||||
let nextDelay = startInterval + 0
|
||||
do {
|
||||
let resultCheck = await checkDelivery()
|
||||
if (resultCheck == true) return res()
|
||||
await delaySeconds(nextDelay)
|
||||
nextDelay *= 2 // wait 2x longer than before
|
||||
} while (nextDelay <= duplexTimeout)
|
||||
return rej()
|
||||
})
|
||||
const responseProcess = new Promise(async (res, rej) => {
|
||||
const { startInterval, responseTimeout } = config.connectors.emessage
|
||||
let nextDelay = startInterval + 0
|
||||
do {
|
||||
let resultCheck = await checkResponse()
|
||||
if (resultCheck == true) return res()
|
||||
await delaySeconds(nextDelay)
|
||||
nextDelay *= 2 // wait 2x longer than before
|
||||
} while (nextDelay <= responseTimeout)
|
||||
return rej()
|
||||
})
|
||||
return Promise.race([
|
||||
new Promise((res, rej) => { // exit pattern after duplexTimeout
|
||||
setTimeout(rej, config.connectors.emessage.duplexTimeout * 1e3)
|
||||
}),
|
||||
deliveryProcess.then(responseProcess)
|
||||
])
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error(err)
|
||||
this.connectorRegistry.reportFail(msg, UUID)
|
||||
return false
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
module.exports = eCityrufConnector
|
@ -0,0 +1,92 @@
|
||||
const MessageManager = require("../MessageManager")
|
||||
const PagerDevice = require("./Device")
|
||||
const Str = require('@supercharge/strings')
|
||||
const config = require('../../config.json')
|
||||
|
||||
// Birdy Slim (IoT) Device
|
||||
class EMessage2Ways extends PagerDevice {
|
||||
constructor () {
|
||||
super()
|
||||
this.duplex = true
|
||||
this.supportBOSkrypt = false
|
||||
this.name = "emessage2WayS"
|
||||
}
|
||||
RandID() {
|
||||
return `E${ Str.random(8) }`
|
||||
}
|
||||
async formatTX(msg) {
|
||||
msg.id = this.RandID()
|
||||
await MessageManager.BindMsg(msg)
|
||||
//msg.payload = msg.type === 'duplex' ? `${ msg.id }${ msg.payload }` : msg.payload // only if duplex wanted we add the id
|
||||
}
|
||||
async tryReceive(data, connector) {
|
||||
if (typeof(data) === 'object' && !!data.type) {
|
||||
const stateSet = {
|
||||
lastSeen: data.date
|
||||
}
|
||||
// If we have a Battery Measurement or other Power Events, we should store it
|
||||
if (!!data.battery) stateSet.battery = data.battery/1e1
|
||||
if (data.hasOwnProperty('isCharging')) stateSet.isCharging = data.isCharging
|
||||
if (data.hasOwnProperty('poweredOn')) stateSet.poweredOn = data.poweredOn
|
||||
|
||||
// the same if we have an rssi measurement
|
||||
if (!!data.rssi) stateSet.rssi = data.rssi
|
||||
// and if we have the 3 components of a GPS Block
|
||||
if (!!data.latitude && !!data.longitude && !!data.lastGPSAcquisition) stateSet.gps = {
|
||||
lastGPSAcquisition: data.lastGPSAcquisition,
|
||||
latitude: data.latitude,
|
||||
longitude: data.longitude,
|
||||
}
|
||||
stateSet.lastLoRaPacket = data.metadata
|
||||
console.log(data, stateSet)
|
||||
/*if (!!data.metadata && !!data.metadata.uplink_message.rx_metadata) {
|
||||
const rx_metadata = data.metadata.uplink_message.rx_metadata
|
||||
|
||||
}*/
|
||||
|
||||
switch (data.type) {
|
||||
case 'ack': {
|
||||
switch (data.ack) {
|
||||
case 'recv':
|
||||
require('../ConnectorRegistry').reportDelivered({ id: data.msgid }, `lorawan:${ data.device_id }`)
|
||||
break;
|
||||
case 'read':
|
||||
require('../MessageManager').markMessageRead(data.msgid)
|
||||
break;
|
||||
case 'operational':
|
||||
require('../MessageManager').respondToMessage(data.msgid, data.operationalData)
|
||||
break;
|
||||
}
|
||||
// If we have had a Ack. Event, we should store some Metadata about it too
|
||||
require('../MessageManager').attachMetadata(data.msgid, {
|
||||
ack: data.ack,
|
||||
rssi: data.rssi,
|
||||
date: data.date,
|
||||
metadata: data.metadata,
|
||||
})
|
||||
}
|
||||
break;
|
||||
case 'sos':
|
||||
stateSet.sos = {
|
||||
sos: data.sos,
|
||||
date: data.date,
|
||||
}
|
||||
break;
|
||||
|
||||
case 'status':
|
||||
case 'cannedMessage':
|
||||
case 'low_battery':
|
||||
case 'power':
|
||||
case 'battery':
|
||||
case 'sos':
|
||||
case 'gps':
|
||||
require('../DeviceRegistry').deviceEvent(this.name, data.device_id, data)
|
||||
break;
|
||||
}
|
||||
require('../DeviceRegistry').stateSet(this.name, data.device_id, stateSet)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
module.exports = EMessage2Ways
|
@ -1,6 +1,7 @@
|
||||
module.exports = {
|
||||
GenericPager: require("./GenericPager"),
|
||||
BirdySlim: require("./BirdySlim"),
|
||||
EMessage2Ways: require("./EMessage2Ways"),
|
||||
Skyper: require("./Skyper"),
|
||||
Device: require("./Device"),
|
||||
}
|
Loading…
Reference in New Issue