├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── alarm_api_v1.md ├── dashboard_api_v1.md ├── examples ├── alarm-api │ └── php │ │ └── alarm-api-example.php └── dashboard-api │ ├── javascript │ └── dashboard-api-example.html │ └── php │ ├── dasboard-api-dasboard-example.php │ └── dasboard-api-login-example.php ├── import_api_v1.md └── sms_api_v1.md /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*.md] 4 | ident_style = space 5 | end_of_line = lf 6 | charset = utf-8 7 | trim_trailing_whitespace = false 8 | insert_final_newline = true 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by https://www.gitignore.io/api/intellij+iml,linux 2 | 3 | ### Intellij+iml ### 4 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm 5 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 6 | 7 | # User-specific stuff: 8 | .idea/workspace.xml 9 | .idea/tasks.xml 10 | 11 | # Sensitive or high-churn files: 12 | .idea/dataSources/ 13 | .idea/dataSources.ids 14 | .idea/dataSources.xml 15 | .idea/dataSources.local.xml 16 | .idea/sqlDataSources.xml 17 | .idea/dynamic.xml 18 | .idea/uiDesigner.xml 19 | 20 | # Gradle: 21 | .idea/gradle.xml 22 | .idea/libraries 23 | 24 | # Mongo Explorer plugin: 25 | .idea/mongoSettings.xml 26 | 27 | ## File-based project format: 28 | *.iws 29 | 30 | ## Plugin-specific files: 31 | 32 | # IntelliJ 33 | /out/ 34 | 35 | # mpeltonen/sbt-idea plugin 36 | .idea_modules/ 37 | 38 | # JIRA plugin 39 | atlassian-ide-plugin.xml 40 | 41 | # Crashlytics plugin (for Android Studio and IntelliJ) 42 | com_crashlytics_export_strings.xml 43 | crashlytics.properties 44 | crashlytics-build.properties 45 | fabric.properties 46 | 47 | ### Intellij+iml Patch ### 48 | # Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 49 | 50 | *.iml 51 | modules.xml 52 | .idea/misc.xml 53 | *.ipr 54 | 55 | 56 | ### Linux ### 57 | *~ 58 | 59 | # temporary files which can be created if a process still has a handle open of a deleted file 60 | .fuse_hidden* 61 | 62 | # KDE directory preferences 63 | .directory 64 | 65 | # Linux trash folder which might appear on any partition or disk 66 | .Trash-* 67 | 68 | # .nfs files are created when an open file is removed but is still being accessed 69 | .nfs* -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 blaulicht SMS 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # blaulichtSMS documentation 2 | 3 | ## Alarm API 4 | 5 | > Create and search for alarms using an automated alarm trigger 6 | 7 | * API description: [Alarm API](./alarm_api_v1.md) 8 | * PHP example implementation: [Alarm API PHP example](./examples/alarm-api/php/alarm-api-example.php) 9 | 10 | Please contact us if you would like to use an automatic alarm trigger: [contact](https://blaulichtsms.net/support/#kontaktformular) 11 | 12 | 13 | ## SMS API 14 | 15 | > Create alarms by SMS 16 | 17 | * API description: [SMS API](./sms_api_v1.md) 18 | 19 | Please contact us if you would like to use an SMS alarm trigger: [contact](https://blaulichtsms.net/support/#kontaktformular) 20 | 21 | ## Dashboard API 22 | 23 | > Displays information about the most recent alarm. 24 | 25 | * API description: [Dashboard API](./dashboard_api_v1.md) 26 | * Javascript example implementation: [Dashboard API Javascript Beispiel](./examples/dashboard-api/javascript/) 27 | * PHP example implementation: [Dashboard API PHP Beispiel](./examples/dashboard-api/php/) 28 | 29 | You need the login data of a dashboard to use this API. A dashboard can be created by an admin on the web platform (start.blaulichtsms.net). 30 | 31 | ## Import API 32 | 33 | > Import participants, alarm triggers, and groups via JSON or csv. 34 | > 35 | > CAUTION: This API overwrites all existing data. 36 | 37 | * API description: [Import API](./import_api_v1.md) 38 | 39 | ## Questions in case of problems 40 | 41 | * Do not hesitate to [contact us](https://blaulichtsms.net/support/#kontaktformular) 42 | 43 | ### Trial account 44 | 45 | We provide developers with a free trial account. If you are interested please [contact us](https://blaulichtsms.net/support/#kontaktformular). 46 | 47 | ## Community projects 48 | 49 | * HDMI-CEC control for the dashboard https://github.com/stg93/blaulichtsms_einsatzmonitor_tv_controller 50 | * [Node-RED](https://nodered.org/) Node for incorporating blaulichtSMS alarms https://github.com/riederch/node-red-contrib-blaulicht-sms 51 | 52 | 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /alarm_api_v1.md: -------------------------------------------------------------------------------- 1 | # blaulichtSMS Alarm API 2 | 3 | ## Version 4 | - V1.0: First Version (2016-08-12) 5 | - V1.1: Alarm Query Endpoint 6 | - V1.2: recipientConfirmation parameter added 7 | - V1.3: List Alarm end point added 8 | - V1.4: Change of Alarm Data Element: extension of recipients, deprecation of participants, Geolocation added (2017-01-19) 9 | - V1.5: extended the API by indexNumber 10 | 11 | ## General 12 | 13 | ### Encoding 14 | Encoding shall be UTF-8. 15 | 16 | ### Test Base URL 17 | https://api-staging.blaulichtsms.net/blaulicht 18 | 19 | ### Live Base URL 20 | https://api.blaulichtsms.net/blaulicht 21 | 22 | ## Alarm API 23 | 24 | In order to be able to use this API, an "automatic alarm trigger" with username and password must be configured for the relevant customerId(s). 25 | 26 | ### Trigger Alarm 27 | _**/api/alarm/v1/trigger**_ 28 | 29 | To trigger an alarm, send an HTTP POST REQUEST with header `Content-Type: application/json` to the above URL. 30 | 31 | - username: string - mandatory - username 32 | - password: string - mandatory - password 33 | - customerId: string - mandatory - customer ID 34 | - type: alarm | info - mandatory - event type 35 | - hideTriggerDetails: boolean - optional - do not send details of alarm trigger 36 | - alarmText: string - optional - content of alarm 37 | - indexNumber: integer- optional - The index number serves to distinguish different alarms. A second alarm with the same index number will be ignored. 38 | - needsAcknowledgement: boolean - mandatory - reply function 39 | - startDate: string - optional - The date of an alarm in case it is to be triggered in the future. The format shall be UTC e.g. :`"2017-01-27T14:49:52.000Z"` 40 | - duration: integer - conditional - duration for which the reply function is enabled 41 | - recipientConfirmation: boolean - optional - turn on/off confirmation that SMS was received (charges apply) 42 | - recipientConfirmationTarget: string - optional - msisdn of recipient of SMS confirmation 43 | - template: string - optional - Alarm text code e.g. `"A1"` 44 | - groupCodes: list of strings - optional - Alarm group(s) e.g. `["G1"]` 45 | - additionalMsisdns: list of strings - optional - additional msidns to be alerted e.g.: `["+4366412345678", "+4367612345678"]` 46 | - coordinates: object of Type Coordinate - optional - coordinated of location of alarm 47 | - geolocation: object of Type Geolocation - optional - instead of coordinates, a Geolocation object containing an address may also be provided. This address will then be converted to coordinates e.g.: `{"address": "Getreidemartk 11, 1060 Wien"}` 48 | 49 | An example: 50 | 51 | { 52 | "username" : "myUser", 53 | "password" : "mySuperSecretPwd", 54 | "customerId" : "100027", 55 | "hideTriggerDetails" : false, 56 | "alarmText" : "This is a test", 57 | "type" : "alarm", 58 | "needsAcknowledgement" : true, 59 | "duration" : 60, 60 | "recipientConfirmation" : false, 61 | "template" : "A1", 62 | "groupCodes" : ["G1", "G2"], 63 | "additionalMsisdns" : [], 64 | "coordinates" : { 65 | "lat" : 48.205587, 66 | "lon" : 16.342917 67 | } 68 | } 69 | 70 | The following is an exapmple of a successful API call. 71 | A list of all possible values of **result** is provided further down. In case of an error the field **description** contains a description of the error. 72 | 73 | { 74 | "result" : "OK", 75 | "alarmId" : "dakldjsfal-2343232-afsdaddfa-234", 76 | "customerId" : 100027, 77 | "description" : null 78 | "alarmData" : { see description AlarmData Object } 79 | } 80 | 81 | 82 | ### QUERY ALARM 83 | _**/api/alarm/v1/query**_ 84 | 85 | To search for an alarm, send an HTTP POST Request with header `Content-Type: application/json` to the URL mentioned above. 86 | 87 | - username: string - mandatory - username 88 | - password: string - mandatory - password 89 | - customerId: string - mandatory - customer ID 90 | - alarmid: string - mandatory - AlarmId (is returned upon triggering an alarm) 91 | 92 | An example: 93 | 94 | { 95 | "username" : "myUser", 96 | "password" : "mySuperSecretPwd", 97 | "customerId" : "100027", 98 | "alarmId" : "dakldjsfal-2343232-afsdaddfa-234" 99 | } 100 | 101 | The following is an exapmple of a successful API call. 102 | A list of all possible values of **result** is provided further down. In case of an error the field **description** contains a description of the error. 103 | 104 | { 105 | "result" : "OK", 106 | "alarmId" : "dakldjsfal-2343232-afsdaddfa-234", 107 | "customerId" : 100027, 108 | "description" : "ok", 109 | "alarmData" : { see description AlarmData object } 110 | } 111 | 112 | 113 | ### LIST ALARM 114 | _**/api/alarm/v1/list**_ 115 | 116 | To get a list of alarms, send an HTTP POST Request with header `Content-Type: application/json` to the URL mentioned above. You will receive a list of AlarmData objects. Only 100 alarms will be returned, sorted by the end date of the alarm. 117 | 118 | - username: string - mandatory - username 119 | - password: string - mandatory - password 120 | - customerIds: list of string - mandatory - list of customer IDs 121 | - startDate: date in iso format - optional - start date for search (all alarms with later end date will be returned) 122 | - endDate: date in iso format - optional - end date for search (all alarms with prior start date will be returned) 123 | 124 | Ein Beispiel: 125 | 126 | { 127 | "username" : "myUser", 128 | "password" : "mySuperSecretPwd", 129 | "customerIds" : ["100027", "900027"], 130 | "startDate" : "2016-01-01T17:00:00.000Z", 131 | "endDate" : "2016-01-01T17:30:00.000Z" 132 | } 133 | 134 | The following is an exapmple of a successful API call. 135 | A list of all possible values of **result** is provided further down. In case of an error the field **description** contains a description of the error. 136 | 137 | { 138 | "result" : "OK", 139 | "description" : "ok", 140 | "alarms" : [{ see description AlarmData object }] 141 | } 142 | 143 | #### AlarmData 144 | - customerId: Customer ID belonging to this alarm 145 | - alarmId: unique identifier of the alarm 146 | - alarmGroups: list of alarm group elements (see AlarmGroup object) 147 | - alarmDate : time of alert 148 | - endDate: end of reply function window (if activated) 149 | - authorName: name of the alarm trigger that has triggered the alarm 150 | - alarmText: the alarm text 151 | - needsAcknowledgement: reply function active/inactive 152 | - usersAlertedCount: nubmer of participants alerted 153 | - geolocation: see GeoLocation object 154 | - recipients: list of participants - see AlarmRecipient object 155 | - audioUrl: Url of audio alarm, if applicable 156 | - indexNumber: index number of the alarm 157 | 158 | 159 | An example: 160 | 161 | { 162 | "customerId" : "100027", 163 | "alarmId" : "32849abcdef23343", 164 | "alarmGroups" : [ ], // list of AlarmGroup elements 165 | "alarmDate" : "2016-01-01T17:30:21.345Z", // UTC date 166 | "endDate" : "2016-01-01T17:30:21.345Z", // UTC date 167 | "authorName" : "John Doe", 168 | "alarmText" : "This is a test", 169 | "needsAcknowledgement" : true, 170 | "usersAlertedCount" : 10, 171 | "geolocation" : { }, // see GeoLocation object 172 | "recipients" : [ ], // list of AlarmRecipient elements 173 | "audioUrl" : null, 174 | "indexNumber": null 175 | } 176 | 177 | #### AlarmGroup 178 | 179 | { 180 | "groupId" : "G1", 181 | "groupName" : "whole team" 182 | } 183 | 184 | #### AlarmRecipient 185 | 186 | { 187 | "id" : "2342343242342abcde32423423", 188 | "name" : "Jeanny Doe", 189 | "msisdn" : "+4366412345678", 190 | "comment" : "Fire Brigade ABC" // optional 191 | "participation" : "yes", // yes | no | uknown | pending 192 | "participationMessage" : "Coming in 5 minutes", 193 | "functions": [ ], // list of AlarmFunction Elementen (functions / qualifications) 194 | } 195 | 196 | #### AlarmFunction 197 | 198 | { 199 | "functionId": "123123789" 200 | "name": "respiratory equipment carriers" 201 | "order": 2 202 | "shortForm": "REC" 203 | "backgroundHexColorCode": "#3164c2" 204 | "foregroundHexColorCode" "#ffffff" 205 | } 206 | 207 | #### GeoLocation 208 | 209 | { 210 | "coordinates" : { 211 | "lat" : 17.34334, 212 | "lon" : 23.32343 213 | }, 214 | "positionSetByAuthor" : true, // if coordinates set by author 215 | "radius" : 10, // radius in m (may be null) 216 | "distance" : 10, // distance in m (may be null) 217 | "address" : "High Street 1, 1234 Metropolis" // textual address (may be null) 218 | } 219 | 220 | #### Return Codes 221 | - OK 222 | - MISSING_INPUT_DATA 223 | - MISSING_CUSTOMER_ID 224 | - MISSING_USERNAME 225 | - INVALID_CUSTOMER_ID 226 | - NOT_CONFIGURED_FOR_CUSTOMER 227 | - UNKNOWN_USER 228 | - NOT_AUTHORIZED 229 | - UNAUTHORIZED_SENDER_ID 230 | - DEACTIVATED 231 | - INVALID_GROUP 232 | - INVALID_TEMPLATE 233 | - NOT FOUND 234 | - UNKNOWN_ERROR 235 | -------------------------------------------------------------------------------- /dashboard_api_v1.md: -------------------------------------------------------------------------------- 1 | # blaulichtSMS Dashboard API 2 | 3 | ## Version 4 | - V1.0: First version (2016-08-12) 5 | - V1.1: added integrations, adapted AlarmData element (2017-01-19) 6 | 7 | ## General 8 | 9 | ### Encoding 10 | Encoding shall be UTF-8. 11 | 12 | ### Base URL 13 | https://api.blaulichtsms.net/blaulicht 14 | 15 | ## Dashboard API 16 | 17 | The dashboard needed to use this API can be created on the web platform (start.blaulichtsms.net) under "Dashboard". 18 | 19 | ### Login 20 | _**/api/alarm/v1/dashboard/login**_ 21 | 22 | To log in you need to send an HTTP POST request with header `Content-Type: application/json` to the above URL. 23 | The login data is the same as for [https://dashboard.blaulichtsms.net](https://dashboard.blaulichtsms.net/#/). 24 | 25 | { 26 | "username" : "myUser", 27 | "password" : "mySuperSecretPwd", 28 | "customerId" : "123456" 29 | } 30 | 31 | After a successful login you receive a session ID: 32 | 33 | { 34 | "success" : true, 35 | "sessionId" : "lafjdfajdslfja89324u983u2894u89jlassdfj", 36 | "error" : null 37 | } 38 | 39 | This session ID must be saved in a cookie / LocalStorage / SessionStorage gespeichert and will be used for all further requests. 40 | 41 | In case of an error you receive the following reply 42 | 43 | { 44 | "success" : false, 45 | "sessionId" : null, 46 | "error" : "MISSING_INPUT_DATA" // error codes see below 47 | } 48 | 49 | #### Error codes 50 | - MISSING_INPUT_DATA 51 | - MISSING_PASSWORD 52 | - MISSING_CUSTOMERID 53 | - MISSING_USERNAME 54 | - INVALID_CREDENTIALS 55 | 56 | Only one session at a time is possible. 57 | 58 | ### Dasboard information 59 | _**/api/alarm/v1/dashboard/{{sessionId}}**_ 60 | 61 | In order to receive information from a dashboard you must send an HTTP GET request to the above URL. 62 | 63 | If the session has expired, you will receive the reply **HTTP 401 Unauthorized**. 64 | 65 | A valid session leads to the reply **HTTP 200 OK** as a **json** object with the following contents : 66 | 67 | { 68 | "customerId" : "123456", 69 | "customerName" : "FF Test", 70 | "username" : "dashboard", 71 | "integrations" : [ ], // list of integrations 72 | "alarms" : [ ], // list of AlarmData elements 73 | "infos" : [ ] // list of AlarmData elements 74 | } 75 | 76 | All active alarms within the last 24 hours will be returned, as well as the last one, regardless of its age. 77 | 78 | #### AlarmData 79 | - alarmId: the unique identifier of the alarm 80 | - alarmGroups: list of AlarmGroup elements (see AlarmGroup object) 81 | - alarmDate : time of alert 82 | - endDate: end of reply function time window (if activated) 83 | - authorName: name of the trigger 84 | - alarmText: the alarm text 85 | - needsAcknowledgement: true = the reply function is active 86 | - usersAlertedCount: number of alerted recipients 87 | - geolocation: see GeoLocation object 88 | - recipients: list of recipients - see AlarmRecipient object 89 | - audioUrl: Url of audio alarm, if used 90 | 91 | 92 | An example: 93 | 94 | { 95 | "alarmId" : "32849abcdef23343", 96 | "alarmGroups" : [ ], // list of AlarmGroup elements 97 | "alarmDate" : "2016-01-01T17:30:21.345Z", // UTC date 98 | "endDate" : "2016-01-01T17:30:21.345Z", // UTC date 99 | "authorName" : "John Doe", 100 | "alarmText" : "This is a test", 101 | "needsAcknowledgement" : true, 102 | "usersAlertedCount" : 10, 103 | "geolocation" : { }, // GeoLocation element 104 | "recipients" : [ ], // list of AlarmRecipient elementes 105 | "audioUrl" : null 106 | } 107 | 108 | #### AlarmGroup 109 | 110 | { 111 | "groupId" : "G1", 112 | "groupName" : "whole fire department" 113 | } 114 | 115 | #### AlarmRecipient 116 | 117 | { 118 | "id" : "2342343242342abcde32423423", 119 | "name" : "Jenny Jobber", 120 | "msisdn" : "+4366412345678" 121 | "participation" : "yes", // yes | no | uknown | pending 122 | "participationMessage" : "arriving in 5 minutes", 123 | "functions": [ ], // list of AlarmFunction elements (functions / qualifications) 124 | } 125 | 126 | #### AlarmFunction 127 | 128 | { 129 | "functionId": "123123789" 130 | "name": "Atemschutzgeräteträger" 131 | "order": 2 132 | "shortForm": "AGT" 133 | "backgroundHexColorCode": "#3164c2" 134 | "foregroundHexColorCode" "#ffffff" 135 | } 136 | 137 | #### GeoLocation 138 | 139 | { 140 | "coordinates" : { 141 | "lat" : 17.34334, 142 | "lon" : 23.32343 143 | }, 144 | "positionSetByAuthor" : true, // true if set by trigger 145 | "radius" : 10, // radius in m (may be null) 146 | "distance" : 10, // distance in m (may be null) 147 | "address" : "High Street 99, 1234 Back-of-beyond" // address as test (may be null) 148 | } 149 | 150 | 151 | #### AlarmIntegration 152 | 153 | { 154 | "type" : "wasserkarte.info", 155 | "fields" : { // JSON Object with the following information 156 | "apiKey" : "23423ldjsakfjdsflj34343" 157 | } 158 | } 159 | 160 | # Dashboard automatic login 161 | 162 | The `sessionId` may also be used to create an automatic login to the dashboard. Therefore, the dashboard must be accessed using the following URL: 163 | 164 | _**https://dashboard.blaulichtsms.net/#/login?token={{sessionId}}**_ 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /examples/alarm-api/php/alarm-api-example.php: -------------------------------------------------------------------------------- 1 | USERNAME, 15 | 'password' => PASSWORD, 16 | 'hideTriggerDetails' => false, 17 | 'customerId' => CUSTOMER_ID, 18 | 'alarmText' => TEXT, 19 | 'type' => 'alarm', 20 | 'needsAcknowledgement' => true, 21 | 'duration' => 60, 22 | 'template' => '', 23 | 'groupCodes' => GROUPS, 24 | 'additionalMsisdns' => ADDITIONAL_MSISDNS 25 | ]; 26 | 27 | $ch = curl_init(); 28 | 29 | curl_setopt($ch, CURLOPT_URL, TRIGGER_URL); 30 | curl_setopt($ch, CURLOPT_POST, 1); 31 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 32 | curl_setopt($ch, CURLOPT_HTTPHEADER, [ 33 | "Content-Type: application/json" 34 | ]); 35 | 36 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($request_body)); 37 | $curlResponse = curl_exec($ch); 38 | 39 | curl_close($ch); 40 | 41 | print_r($curlResponse); 42 | -------------------------------------------------------------------------------- /examples/dashboard-api/javascript/dashboard-api-example.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /examples/dashboard-api/php/dasboard-api-dasboard-example.php: -------------------------------------------------------------------------------- 1 | alarms as $alarm) { 22 | echo(" Alarm: $alarm->alarmText
"); 23 | 24 | foreach ($alarm->recipients as $recipient) { 25 | echo("Name: $recipient->name
Status: $recipient->participation
Antwortnachricht: $recipient->participationMessage

"); 26 | } 27 | echo("
"); 28 | } -------------------------------------------------------------------------------- /examples/dashboard-api/php/dasboard-api-login-example.php: -------------------------------------------------------------------------------- 1 | USERNAME, 12 | 'password' => PASSWORD, 13 | 'customerId' => CUSTOMER_ID 14 | ]; 15 | 16 | $ch = curl_init(); 17 | 18 | curl_setopt($ch, CURLOPT_URL, LOGIN_URL); 19 | curl_setopt($ch, CURLOPT_POST, 1); 20 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 21 | curl_setopt($ch, CURLOPT_HTTPHEADER, [ 22 | "Content-Type: application/json" 23 | ]); 24 | 25 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($login_request_body)); 26 | $curlResponse = curl_exec($ch); 27 | 28 | curl_close($ch); 29 | 30 | print_r($curlResponse); 31 | -------------------------------------------------------------------------------- /import_api_v1.md: -------------------------------------------------------------------------------- 1 | # blaulichtSMS participant import API 2 | 3 | ## Version 4 | - V1.0: first version (2016-08-12) 5 | - V1.1: participant import (2017-02-15) 6 | - V1.2: group import (2017-08-31) 7 | - V1.3: alarm trigger import (2019-11-11) 8 | 9 | ## General 10 | 11 | ### Encoding 12 | The encoding shall be UTF-8. 13 | 14 | ### Test base URL 15 | https://api-staging.blaulichtsms.net/blaulicht 16 | 17 | ### Live base URL 18 | https://api.blaulichtsms.net/blaulicht 19 | 20 | ## Import API 21 | 22 | This API provides and attitional facility to the import on the [web platform](https://start.blaulichtsms.net). 23 | 24 | 25 | **Caution**: 26 | >Upon import all existing data (recipients, groups, assigments of triggers to groups and of recipients to groups) will be overwritten with new data. 27 | >This interface makes sense if the administration of participants is done by an external system. The external system periodically updates the data in blaulichtSMS. 28 | > 29 | >It is recommendend to first try the import with a dummy account in order to prevent loss of data. Please contact us for a dummy account. 30 | 31 | Authentication is done by customer ID, user name, and password. 32 | 33 | ### Import of recipients - JSON 34 | _**/api/portal/v1/import/participants/json**_ 35 | 36 | To import recipients for a customer ID, send an HTTP POST request with header: `Content-Type: application/json` to the above URL. 37 | - customerId: string - mandatory - customer ID 38 | - username: string - mandatory - user name 39 | - password: string - mandatory - password 40 | - participants: list of PartcipipantData objects 41 | 42 | #### ParticipantData 43 | 44 | - msisdn: string - mandatory - telephone number in format +(countrycode)(number), e.g. +445553939 45 | - givenname: string - mandatory - given name 46 | - surname: string - mandatory - surname 47 | - email: string - optional - e-mail address 48 | - groups: list of strings (alarm groups) - mandatory 49 | 50 | If the external system does not distinguish between groups, it is recommended to import all praticipants to groups G1. 51 | 52 | #### An example 53 | 54 | { 55 | "customerId" : "100027", 56 | "username" : "import", 57 | "password" : "mySuperSecretPwd", 58 | "participants" : [ 59 | { 60 | "msisdn" : "+4366412345678", 61 | "givenname" : "John", 62 | "surname" : "Doe", 63 | "email" : null, 64 | "groups" : ["G1"] 65 | }, 66 | { 67 | "msisdn" : "+4367612345678", 68 | "givenname" : "Joanne", 69 | "surname" : "Doe", 70 | "email" : "joanne@doe.com", 71 | "groups" : ["G1", "G2"] 72 | } 73 | ] 74 | } 75 | 76 | In case of success the reply is HTTP 200 OK without further content. 77 | 78 | In case of an error one of the following HTTP error codes will be returned to allow easier debgging: 79 | 80 | - HTTP 400 BAD Request: data validation failed 81 | - HTTP 401 Unauthorized: error in authentication 82 | - HTTP 403 Forbidden: error in authentication 83 | 84 | 85 | ### Import participants - CSV 86 | _**/api/portal/v1/import/participants/csv/{{customerId}}**_ 87 | 88 | The CSV interface works in the same way as the JSON interface above. The same rules regarding mandatory fields, optional fields, and error codes apply. Note the different URL. 89 | 90 | The following header needs to be included in the HTTP POST request: 91 | 92 | - `Content-Type: text/csv` 93 | - `X-Username: myUser` 94 | - `X-Password: mySuperSecretPwd` 95 | 96 | The following columns (separated by **;**) will be read: 97 | 98 | - givenname 99 | - surname 100 | - msisdn 101 | - email 102 | - groups 103 | 104 | It is important to keep this sequence of columns, as the first row i.e. the heading/label of the columns will be disregarded. 105 | Trailing empty lines may lead to problems, so remove them. Groups shall be separated by comma, not space. 106 | 107 | #### An example 108 | 109 | givenname;surname;msisdn;email;groups 110 | John;Doe;+4366412345678;;G1 111 | Joanne;Doe;+4367612345678;joane@doe.com;G1,G2 112 | 113 | 114 | ### Import Alarmgeber - JSON 115 | > Importing alarm triggers works the same way as importing recipients, apart from the different list. 116 | _**/api/portal/v1/import/trigger/json**_ 117 | 118 | Send an HTTP POST request with header: `Content-Type: application/json` to the above URL to import triggers for a customer ID. 119 | 120 | - customerId: string - mandatory - customer ID 121 | - username: string - mandatory - user name 122 | - password: string - mandatory - password 123 | - trigger: list of objects of typ PartcipipantData 124 | 125 | #### ParticipantData 126 | 127 | - msisdn: string - mandatory - telephone number in format +(countrycode)(number), e.g. +445553939 128 | - givenname: string - mandatory - given name 129 | - surname: string - mandatory - surname 130 | - email: string - optional - e-mail address 131 | - groups: list of strings (alarm groups) - mandatory 132 | 133 | If the external system does not distinguish between groups, it is recommended to import all praticipants to groups G1. 134 | 135 | #### An example 136 | { 137 | "customerId" : "100027", 138 | "username" : "import", 139 | "password" : "mySuperSecretPwd", 140 | "trigger" : [ 141 | { 142 | "msisdn" : "+4366412345678", 143 | "givenname" : "Max", 144 | "surname" : "Mustermann", 145 | "email" : null, 146 | "groups" : ["G1"] 147 | }, 148 | { 149 | "msisdn" : "+4367612345678", 150 | "givenname" : "Martina", 151 | "surname" : "Musterfrau", 152 | "email" : "martina.musterfrau@example.com", 153 | "groups" : ["G1", "G2"] 154 | } 155 | ] 156 | } 157 | 158 | In case of success the reply is HTTP 200 OK without further content. 159 | 160 | In case of an error one of the following HTTP error codes will be returned to allow easier debgging: 161 | 162 | - HTTP 400 BAD Request: data validation failed 163 | - HTTP 401 Unauthorized: error in authentication 164 | - HTTP 403 Forbidden: error in authentication 165 | 166 | ### Import Alarmgeber - CSV 167 | _**/api/portal/v1/import/trigger/csv/{{customerId}}**_ 168 | 169 | The CSV interface works in the same way as the JSON interface above. The same rules regarding mandatory fields, optional fields, and error codes apply. Note the different URL. 170 | 171 | The following header needs to be included in the HTTP POST request: 172 | 173 | - `Content-Type: text/csv` 174 | - `X-Username: myUser` 175 | - `X-Password: mySuperSecretPwd` 176 | 177 | The following columns (separated by **;**) will be read: 178 | 179 | - givenname 180 | - surname 181 | - msisdn 182 | - email 183 | - groups 184 | 185 | It is important to keep this sequence of columns, as the first row i.e. the heading/label of the columns will be disregarded. 186 | Trailing empty lines may lead to problems, so remove them. Groups shall be separated by comma, not space.ohne Leerzeichen) zu trennen. 187 | 188 | #### An example 189 | 190 | givenname;surname;msisdn;email;groups 191 | Max;Mustermann;+4366412345678;;G1 192 | Martina;Musterfrau;+4367612345678;martina.musterfrau@example.com;G1,G2 193 | 194 | 195 | ### Import Gruppen - JSON 196 | _**/api/portal/v1/import/groups/json**_ 197 | 198 | Send an HTTP POST request with Header: `Content-Type: application/json` to the above URL to import groups for a customer ID 199 | 200 | - customerId: string - mandatory 201 | - username: string - mandatory 202 | - password: string - mandatory 203 | - groups: liste of objects of type GroupData 204 | 205 | #### GroupData 206 | 207 | - name: string - mandatory - name of group 208 | - groupId: string - mandatory - the groupId shall start with "G" and must be followed by a number between 0 and 999999999 209 | - redo: optional int - optional - if 1, every alarm with this group will be repeated (default: 0) 210 | - redoInterval: long - optional - the time delay for the alarm repetition if redo is 1 (default: 0) 211 | 212 | 213 | #### An example 214 | 215 | { 216 | "customerId" : "100027", 217 | "username" : "import", 218 | "password" : "mySuperSecretPwd", 219 | "groups": [ 220 | { 221 | "name": "siren", 222 | "groupId": "G1" 223 | }, 224 | { 225 | "name": "silent alert", 226 | "groupId": "G2" 227 | }, 228 | { 229 | "name": "whole brigade", 230 | "groupId": "G3" 231 | } 232 | ] 233 | } 234 | 235 | In case of success the reply is HTTP 200 OK without further content. 236 | 237 | In case of an error one of the following HTTP error codes will be returned to allow easier debgging: 238 | 239 | - HTTP 400 BAD Request: data validation failed 240 | - HTTP 401 Unauthorized: error in authentication 241 | - HTTP 403 Forbidden: error in authentication 242 | 243 | 244 | ### Import groups - CSV 245 | > Upon imorting new groups, all previous groups will be deleted as well as the assignment of participants to groups. 246 | _**/api/portal/v1/import/groups/csv/{{customerId}}**_ 247 | 248 | The CSV interface works in the same way as the JSON interface above. The same rules regarding mandatory fields, optional fields, and error codes apply. Note the different URL. 249 | 250 | The following header needs to be included in the HTTP POST request: 251 | 252 | - `Content-Type: text/csv` 253 | - `X-Username: myUser` 254 | - `X-Password: mySuperSecretPwd` 255 | 256 | The following columns (separated by **;**) will be read: 257 | 258 | - groupId 259 | - name 260 | - redo 261 | - redoInterval 262 | 263 | It is important to keep this sequence of columns, as the first row i.e. the heading/label of the columns will be disregarded. 264 | Trailing empty lines may lead to problems, so remove them. Groups shall be separated by comma, not space. 265 | 266 | #### An example 267 | 268 | groupId;name;redo;redoInterval 269 | G1;siren;; 270 | G2;silent alert;; 271 | G3;whole brigade;; 272 | -------------------------------------------------------------------------------- /sms_api_v1.md: -------------------------------------------------------------------------------- 1 | # blaulichtSMS SMS API 2 | 3 | ## Version 4 | - V1.0: first version (2017-07-24) 5 | 6 | ## General 7 | 8 | ### Target number: 9 | 10 | **Austria:** +43 (0) 82822100 11 | 12 | **Germany:** +49 (0) 1771783998 13 | 14 | ## SMS API 15 | 16 | If you want to be able to alert multiple customer IDs, your sender number must be assigned to an "automatic alarm trigger". Please contact us so we can provide you with an alarm trigger. 17 | If you only want to alert your own customer ID, it is sufficient to create a manual alarm trigger on the web paltform (start.blaulichtsms.net) in section "Config" > "Alarm Trigger" 18 | 19 | ### Trigger alarm 20 | 21 | An SMS triggering an alert consists of two parts, separated by a colon `:`. 22 | To the left of the colon there is the **Alarm code**, to the right there is the payload (the **Alarm text**) 23 | 24 | #### Alarm code 25 | 26 | The alarm code consists of the following parts. You must at least provide a customer ID and a groups, the other parts are optional. Every code must begin with a "K". 27 | 28 | - **K**{{customerId}} - mandatory - customer ID e.g. `K100027` 29 | - **G**{{groupId}} - mandatory - alarm group e.g. `G1` 30 | - **A**{{templateId}} - optional - alarm test template (edited on web platform) e.g. `A1` 31 | - **Q**0 - optional - participants can reply with YES/NO; leave Q0 out to disable it 32 | - **I** - optional - type is "info", not "alarm" 33 | - **Z** - optional - recipient confirmation is active 34 | - **M**{{indexNumber}} - optional - Index nuber of an alert. An identical index number identifies two identical alarms. Caution: Do not use the same index number if you want to trigger individual alarms. Use it only to merge alarms. 35 | - **T**{{additionalMsisdn}} - optional - additional msisdns to be alerted (not members of a group) e.g. `T+4366412345678` 36 | 37 | 38 | #### Alarm text 39 | 40 | You can provide the `alarmText` and `coordinates` (location of incident). 41 | 42 | 43 | #### Coordinates 44 | 45 | Coordinates may occur anywhere within the alarm text. They will be parsed and added to the alarm. It is important that coordinates have the following format: 46 | 47 | **longitude & latitude (WGS84)** 48 | 49 | ``` 50 | [xx.xxxxxx,yy.yyyyyy] 51 | ``` 52 | or 53 | ``` 54 | (xx.xxxxxx,yy.yyyyyy) 55 | ``` 56 | e.g. `(48.220778,16.3100209)` for Vienna. 57 | 58 | **easting & northing** 59 | ``` 60 | XY: xxxxxxx.xx / yyyyyyy.yy 61 | ``` 62 | e.g. `XY:4468503.333/5333317.780` for Munich. 63 | 64 | Please note that the easting as well as the northing must consist of 7 digits. The decimal point and everything behind it are optional. 65 | 66 | #### Examples 67 | 68 | ##### Alerting groups 1 and 2 of customer 100027 with coordinates 69 | 70 | via REST: 71 | ``` 72 | { 73 | "customerId" : "100027", 74 | "alarmText" : "This is a test", 75 | "type" : "alarm", 76 | "needsAcknowledgement" : true, 77 | "recipientConfirmation" : false, 78 | "template" : "A1", 79 | "groupCodes" : ["G1", "G2"], 80 | "additionalMsisdns" : [], 81 | "coordinates" : { 82 | "lat" : 48.205587, 83 | "lon" : 16.342917 84 | } 85 | } 86 | ``` 87 | 88 | via SMS: 89 | ``` 90 | K100027G1G2A1Q0:This is a test(48.205587,16.342917) 91 | ``` 92 | 93 | ##### Alerting additional recipients 94 | 95 | 96 | via REST: 97 | ``` 98 | { 99 | "customerId" : "100027", 100 | "alarmText" : "This is a test", 101 | "type" : "alarm", 102 | "needsAcknowledgement" : true, 103 | "recipientConfirmation" : false, 104 | "groupCodes" : ["G1"], 105 | "additionalMsisdns" : ["+4366412345678", "+4367612345678"] 106 | } 107 | ``` 108 | 109 | via SMS: 110 | ``` 111 | K100027G1Q0T+4366412345678T+4367612345678:This is a test 112 | ``` 113 | --------------------------------------------------------------------------------