summaryrefslogtreecommitdiff
path: root/localkannel-dispatch
blob: f342721362a7cbf503e2e8f3d054149fae1a766b (plain)
  1. #!/bin/sh
  2. set -e
  3. vardir=/var/lib/kannel/hello
  4. sbindir=/usr/local/sbin
  5. exit0() {
  6. [ -n "$1" ] && echo "$1"
  7. exit 0
  8. }
  9. exit1() {
  10. response="${1:+Error: }${1:-Internal error!}"
  11. # FIXME: pass error messages via stderr (not stdout)
  12. # echo >&2 "$response"
  13. echo "$response"
  14. [ -z "$SMS_SMSC$SMS_URL" ] || $sbindir/localsendsms "$to" "$response"
  15. exit 1
  16. }
  17. simpleword() {
  18. echo "$1" | perl -ne '/([a-zæøåÆØÅ!@\/][a-zæøåÆØÅ0-9-]+)/i and print lc($1)'
  19. }
  20. uriunescape() {
  21. if [ 0 = "$urldecode" ]; then
  22. echo "$@"
  23. else
  24. echo "$@" | perl -e 'use URI::Escape; print lc(uri_unescape(<STDIN>));'
  25. fi
  26. }
  27. # Resolve var from "variable = value" pair in file below /etc/local
  28. getfilevar() {
  29. file="/etc/local/$1"
  30. var="$2"
  31. grep -m1 "^$var" "$file" | awk -F '(= )' '{print $2}'
  32. }
  33. lastservicephone() {
  34. logfile=/var/log/kannel/smsbox.log
  35. tac $logfile $logfile.1 \
  36. | perl -ne "/INFO: Starting to service <.*> from <\+$1> to <([^<>]*)>/ and print \$1 and exit 0"
  37. }
  38. #from=`uriunescape "$1" | sed -e 's/\+/ /g'`; shift
  39. from=`uriunescape "$1"`; shift
  40. #to=`uriunescape "$1" | sed -e 's/\+/ /g'`; shift
  41. to=`uriunescape "$1"`; shift
  42. set -- `uriunescape "$@" | sed -e 's/\+/ /g'`
  43. #set -- `uriunescape "$@"`
  44. app_raw="$1"
  45. app=`simpleword "$1"`; shift
  46. export debug
  47. SMS_PHONE="$from"
  48. urldecode=0
  49. export SMS_PHONE urldecode
  50. case "$SMS_REALM" in
  51. test)
  52. provider="dummy"
  53. mdpath="/home/hearth/public_webdata/hearth/content/sms"
  54. export mdpath
  55. ;;
  56. hello)
  57. provider="local"
  58. # provider="coolsms"
  59. # provider="clickatell"
  60. mdpath="/home/hearth/public_webdata/hearth/content/sms"
  61. export mdpath
  62. ;;
  63. hellobudapest)
  64. provider="clickatell"
  65. gotestphones=""
  66. gophones=""
  67. SMS_ERRFROM="+36307418279" # Jonas
  68. SMS_ERRTO1="+36307418279" # Jonas
  69. SMS_ERRTO2="+36703782127" # Emma
  70. mdpath="/home/www-hearth/public_webdata/hellobudapest/content/sms"
  71. export SMS_ERRFROM SMS_ERRTO1 SMS_ERRTO2 mdpath
  72. ;;
  73. hellotorino)
  74. provider="clickatell"
  75. gotestphones="+393453915741 +393453805531 +393453801457" # Jonas, Jacob, Vera
  76. gophones="+393407574815 +393407574813 +393381467977 +393478617029" # Alessandra, Vela, Marco, Silvia
  77. SMS_ERRFROM="+393453915741" # Jonas
  78. SMS_ERRTO1="+393453801457" # Vera
  79. SMS_ERRTO2="+393483281187" # Rescue
  80. mdpath="/home/www-hearth/public_webdata/hellotorino/content/sms"
  81. export SMS_ERRFROM SMS_ERRTO1 SMS_ERRTO2 mdpath
  82. ;;
  83. cyber)
  84. provider="local"
  85. mdpath="/home/cyberhus/public_webdata/mdsms/content/sms"
  86. export mdpath
  87. ;;
  88. *)
  89. exit1 "unknown realm \"$SMS_REALM\"!"
  90. ;;
  91. esac
  92. case "$provider" in
  93. dummy)
  94. dummy=1
  95. ADMIN_OK=1
  96. export ADMIN_OK dummy
  97. ;;
  98. local)
  99. export SMS_SMSC
  100. ;;
  101. coolsms)
  102. unset SMS_SMSC
  103. SMS_URL="https://sms.coolsmsc.dk:8081/"
  104. SMS_USER=$(getfilevar coolsms user)
  105. SMS_PW=$(getfilevar coolsms pw)
  106. SMS_CP="cp1252"
  107. SMS_MSGTAG="message"
  108. export SMS_URL SMS_USER SMS_PW SMS_CP SMS_MSGTAG
  109. ;;
  110. # supports concatenation and req_feat (e.g 48: sender ID)
  111. # does not support DLR, and only concatenates max. 3 smses
  112. clickatell)
  113. unset SMS_SMSC
  114. SMS_URL="https://api.clickatell.com/http/sendmsg"
  115. SMS_USER=$(getfilevar clickatell user)
  116. SMS_PW=$(getfilevar clickatell pw)
  117. SMS_CP="iso8859-1"
  118. SMS_USERTAG="user"
  119. SMS_API=$(getfilevar clickatell api)
  120. SMS_CALLBACK="3"
  121. SMS_CONCAT="3"
  122. SMS_ESCALATE="1"
  123. SMS_VALIDITY="1"
  124. SMS_REQ_FEAT="24611" # 1+2+32+8192+16384 = text+8bit+numeric_src+dlr+concat
  125. stripprefix="1"
  126. export SMS_URL SMS_USER SMS_PW SMS_CP SMS_USERTAG SMS_API SMS_CALLBACK SMS_CONCAT SMS_ESCALATE SMS_VALIDITY SMS_REQ_FEAT stripprefix
  127. ;;
  128. # supports DLR
  129. # Kannel clickatell profile supports concatenation but not req_feat
  130. # Kannel generic profile supports req_feat but not concatenation
  131. clickatell_via_kannel)
  132. SMS_SMSC="X"
  133. SMS_CONCATENATION="1"
  134. SMS_DLR_MASK="7"
  135. SMS_DLR_URL="http://helloearth.jones.dk/test.cgi?type=dlr&msgid=XXX&smsid=%I&from=%p&to=%P&time=%t&unixtime=%T&dlr=%d&dlrmsg=%A"
  136. SMS_CP="iso8859-1"
  137. SMS_VALIDITY="1"
  138. SMS_BINFO="req_feat=24611&concat=3&escalate=1%validity=1" # 1+2+32+8192+16384 = text+8bit+numeric_src+dlr+concat
  139. stripprefix="1"
  140. export SMS_SMSC SMS_CONCATENATION SMS_DLR_MASK SMS_DLR_URL SMS_CP SMS_VALIDITY SMS_BINFO stripprefix
  141. ;;
  142. routo_via_kannel)
  143. SMS_SMSC="Y"
  144. export SMS_SMSC
  145. ;;
  146. *)
  147. exit1 "unknown provider \"$provider\"!"
  148. ;;
  149. esac
  150. # FIXME: some safety net against abusing this imposter feature
  151. #if [ -n "$REDIRECT_OK" ]; then
  152. case "$app" in
  153. @*)
  154. # FIXME: Avoid hardcoding national prefix
  155. targetphone="$(echo "$app" | perl -pe 's/^@//;' -e 's/^([^+])/+36\1/')"
  156. # TODO: silence errors - or better: bounce those back to original sender
  157. targetfrom=$(lastservicephone "$targetphone")
  158. [ -n "$targetfrom" ] || exit1 "refusing to redirect: unknown target phone number \"$targetphone\"."
  159. SMS_PHONE="$targetfrom" $sbindir/localmarkdown2sms "$targetphone" "$@"
  160. exit 0
  161. ;;
  162. esac
  163. #fi
  164. if [ -n "$GROUP_OK" ]; then
  165. case "$app" in
  166. !*)
  167. group="$(echo "$app" | perl -pe 's/^!//;')"
  168. members=$(cd "$vardir/user" && grep -lF "$group" */group | perl -pe "s,/group$,,") || members=
  169. [ -n "$members" ] || exit1 "Message redirected for none: no members resolved in group \"$group\"!"
  170. for member in $members; do
  171. phone=$(head -n 1 "$vardir/user/$member/phone") || nophone="${nophone+$nophone }$member"
  172. [ -z "$phone" ] || $sbindir/localmarkdown2sms "$phone" "$@"
  173. done
  174. [ -n "$members" ] || exit1 "Message redirected for none: no members resolved in group \"$group\"!"
  175. membercount=$(echo "$members" | wc --word)
  176. [ -z "$nophone" ] || nophonecount=$(echo "$nophone" | wc --word)
  177. [ -z "$nophone" ] || exit1 "Message redirected for $membercount members of group \"$group\", but failed for $nophonecount of them (could not resolve phone number)!"
  178. exit0 "Message redirected for $membercount members of group \"$group\"."
  179. ;;
  180. esac
  181. fi
  182. case "$app" in
  183. /*)
  184. cmd="$(echo "$app" | perl -pe 's/^\///;')"
  185. case "$cmd" in
  186. ping)
  187. if [ "help" = "$1" ]; then
  188. $sbindir/localsendsms "$to" "Usage:
  189. /ping [...]
  190. Respond \"pong\" and echo back any addition input."
  191. exit 0
  192. fi
  193. $sbindir/localsendsms "$to" pong "$@"
  194. exit 0
  195. ;;
  196. # FIXME: generalize this ugly hacks somehow, and secure against random use
  197. go|gotest|so|sotest)
  198. case "$cmd" in
  199. go*)
  200. basecmd="go"
  201. realcmd="hello"
  202. ;;
  203. so*)
  204. basecmd="so"
  205. realcmd="szia"
  206. ;;
  207. esac
  208. if [ "help" = "$1" ]; then
  209. $sbindir/localsendsms "$to" "Usage:
  210. /$basecmd PHONE... [MSG...]
  211. /${basecmd}test PHONE... [MSG...]
  212. /$basecmd help
  213. Start thread \"$realcmd\" on behalf of each PHONE,
  214. and (if included) send MSG to subscribers."
  215. exit 0
  216. fi
  217. [ -n "$1" ] || exit1 "target phone number missing (try \"/$cmd help\" for usage)"
  218. case "$cmd" in
  219. gotest|sotest)
  220. phones="$gotestphones"
  221. ;;
  222. go|so)
  223. phones="$gophones"
  224. ;;
  225. esac
  226. # FIXME: Avoid hardcoding national prefix
  227. while targetphone="$(echo "$1" | perl -pe 's/^(?=[^+])/+36/;' -e '/^\+\d+$/ or exit 1;')"; do
  228. targetphones="${$targetphones:+$targetphones }$targetphone"
  229. shift
  230. # Sanity check
  231. targetfrom=$(lastservicephone "$targetphone")
  232. [ -n "$targetfrom" ] || exit1 "refusing to redirect: unknown target phone number \"$targetphone\"."
  233. done
  234. # send responses (threaded one last, to work in debug mode)
  235. if [ -n "$*" ]; then
  236. for phone in $phones; do
  237. $sbindir/localsendsms "$phone" "[$cmd] $@"
  238. done
  239. $sbindir/localsendsms "$to" "[info] \"$cmd\" thread started for $targetphones and trailing message forwarded to subscribers."
  240. else
  241. $sbindir/localsendsms "$to" "[info] \"$cmd\" thread started for $targetphones (no trailing message passed to subscribers)."
  242. fi
  243. for phone in $targetphones; do
  244. SMS_PHONE=$(lastservicephone "$phone") $sbindir/localmarkdown2sms "$phone" "$realcmd"
  245. done
  246. exit 0
  247. ;;
  248. esac
  249. candidates=$(cd "$vardir/user" && grep -lF "$to" */phone | perl -pe "s,/phone$,,") || candidates=
  250. [ -z "$candidates" ] || $(grep -vqF "$candidates" "$vardir/group/admin/user") || admin=true
  251. if [ -n "$ADMIN_OK" ] && [ -n "$admin" ]; then
  252. str="$($sbindir/localsmsadmin "$cmd" "$@" 2>&1)" || exit1 "$str"
  253. $sbindir/localsendsms "$to" $str
  254. exit 0
  255. elif [ "help" = "$cmd" ]; then
  256. $sbindir/localsendsms "$to" "Commands:
  257. /ping [...]
  258. /COMMAND help
  259. /help
  260. try e.g. \"/del help\"."
  261. exit 0
  262. fi
  263. ;;
  264. esac
  265. #FIXME: if sender has a mission, check for "done": process missionpending and report result to mission members
  266. # yb)
  267. # s="$(links -dump "http://www.yubnub.org/parser/parse?command=$@")"
  268. # $sbindir/localsendsms "$to" "$s"
  269. # exit 0
  270. # ;;
  271. $sbindir/localmarkdown2sms "$to" "$app_raw" "$@"