sipgate_spec.rb 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. require 'rails_helper'
  3. RSpec.describe 'Integration Sipgate', type: :request do
  4. let(:agent) do
  5. create(:agent)
  6. end
  7. let!(:customer1) do
  8. create(
  9. :customer,
  10. login: 'ticket-caller_id_cti-customer1@example.com',
  11. firstname: 'CallerId',
  12. lastname: 'Customer1',
  13. phone: '+49 99999 222222',
  14. fax: '+49 99999 222223',
  15. mobile: '+4912347114711',
  16. note: 'Phone at home: +49 99999 222224',
  17. )
  18. end
  19. let!(:customer2) do
  20. create(
  21. :customer,
  22. login: 'ticket-caller_id_cti-customer2@example.com',
  23. firstname: 'CallerId',
  24. lastname: 'Customer2',
  25. phone: '+49 99999 222222 2',
  26. )
  27. end
  28. let!(:customer3) do
  29. create(
  30. :customer,
  31. login: 'ticket-caller_id_cti-customer3@example.com',
  32. firstname: 'CallerId',
  33. lastname: 'Customer3',
  34. phone: '+49 99999 222222 2',
  35. )
  36. end
  37. before do
  38. Cti::Log.destroy_all
  39. Setting.set('sipgate_integration', true)
  40. Setting.set('sipgate_config', {
  41. outbound: {
  42. routing_table: [
  43. {
  44. dest: '41*',
  45. caller_id: '41715880339000',
  46. },
  47. {
  48. dest: '491714000000',
  49. caller_id: '41715880339000',
  50. },
  51. ],
  52. default_caller_id: '4930777000000',
  53. },
  54. inbound: {
  55. block_caller_ids: [
  56. {
  57. caller_id: '491715000000',
  58. note: 'some note',
  59. }
  60. ],
  61. notify_user_ids: {
  62. 2 => true,
  63. 4 => false,
  64. },
  65. }
  66. },)
  67. Cti::CallerId.rebuild
  68. end
  69. describe 'request handling' do
  70. it 'does token check' do
  71. params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278-1&user%5B%5D=user+1&user%5B%5D=user+2'
  72. post '/api/v1/sipgate/not_existing_token/in', params: params
  73. expect(response).to have_http_status(:unauthorized)
  74. error = nil
  75. local_response_xml = REXML::Document.new(response.body)
  76. local_response_xml.elements.each('Response/Error') do |element|
  77. error = element.text
  78. end
  79. expect(error).to eq('Invalid token, please contact your admin!')
  80. end
  81. it 'does basic call' do
  82. token = Setting.get('sipgate_token')
  83. # inbound - I
  84. params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278-1&user%5B%5D=user+1&user%5B%5D=user+2'
  85. post "/api/v1/sipgate/#{token}/in", params: params
  86. expect(response).to have_http_status(:ok)
  87. on_hangup = nil
  88. on_answer = nil
  89. content = response.body
  90. response_xml = REXML::Document.new(content)
  91. response_xml.elements.each('Response') do |element|
  92. on_hangup = element.attributes['onHangup']
  93. on_answer = element.attributes['onAnswer']
  94. end
  95. expect(on_hangup).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/in")
  96. expect(on_answer).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/in")
  97. # inbound - II - block caller
  98. params = 'event=newCall&direction=in&from=491715000000&to=4930600000000&callId=4991155921769858278-2&user%5B%5D=user+1&user%5B%5D=user+2'
  99. post "/api/v1/sipgate/#{token}/in", params: params
  100. expect(response).to have_http_status(:ok)
  101. on_hangup = nil
  102. on_answer = nil
  103. content = response.body
  104. response_xml = REXML::Document.new(content)
  105. response_xml.elements.each('Response') do |element|
  106. on_hangup = element.attributes['onHangup']
  107. on_answer = element.attributes['onAnswer']
  108. end
  109. expect(on_hangup).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/in")
  110. expect(on_answer).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/in")
  111. reason = nil
  112. response_xml.elements.each('Response/Reject') do |element|
  113. reason = element.attributes['reason']
  114. end
  115. expect(reason).to eq('busy')
  116. # outbound - I - set default_caller_id
  117. params = 'event=newCall&direction=out&from=4930600000000&to=4912347114711&callId=8621106404543334274-3&user%5B%5D=user+1'
  118. post "/api/v1/sipgate/#{token}/out", params: params
  119. expect(response).to have_http_status(:ok)
  120. on_hangup = nil
  121. on_answer = nil
  122. caller_id = nil
  123. number_to_dail = nil
  124. content = response.body
  125. response_xml = REXML::Document.new(content)
  126. response_xml.elements.each('Response') do |element|
  127. on_hangup = element.attributes['onHangup']
  128. on_answer = element.attributes['onAnswer']
  129. end
  130. response_xml.elements.each('Response/Dial') do |element|
  131. caller_id = element.attributes['callerId']
  132. end
  133. response_xml.elements.each('Response/Dial/Number') do |element|
  134. number_to_dail = element.text
  135. end
  136. expect(caller_id).to eq('4930777000000')
  137. expect(number_to_dail).to eq('4912347114711')
  138. expect(on_hangup).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
  139. expect(on_answer).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
  140. # outbound - II - set caller_id based on routing_table by explicite number
  141. params = 'event=newCall&direction=out&from=4930600000000&to=491714000000&callId=8621106404543334274-4&user%5B%5D=user+1'
  142. post "/api/v1/sipgate/#{token}/out", params: params
  143. expect(response).to have_http_status(:ok)
  144. on_hangup = nil
  145. on_answer = nil
  146. caller_id = nil
  147. number_to_dail = nil
  148. content = response.body
  149. response_xml = REXML::Document.new(content)
  150. response_xml.elements.each('Response') do |element|
  151. on_hangup = element.attributes['onHangup']
  152. on_answer = element.attributes['onAnswer']
  153. end
  154. response_xml.elements.each('Response/Dial') do |element|
  155. caller_id = element.attributes['callerId']
  156. end
  157. response_xml.elements.each('Response/Dial/Number') do |element|
  158. number_to_dail = element.text
  159. end
  160. expect(caller_id).to eq('41715880339000')
  161. expect(number_to_dail).to eq('491714000000')
  162. expect(on_hangup).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
  163. expect(on_answer).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
  164. # outbound - III - set caller_id based on routing_table by 41*
  165. params = 'event=newCall&direction=out&from=4930600000000&to=4147110000000&callId=8621106404543334274-5&user%5B%5D=user+1'
  166. post "/api/v1/sipgate/#{token}/out", params: params
  167. expect(response).to have_http_status(:ok)
  168. on_hangup = nil
  169. on_answer = nil
  170. caller_id = nil
  171. number_to_dail = nil
  172. content = response.body
  173. response_xml = REXML::Document.new(content)
  174. response_xml.elements.each('Response') do |element|
  175. on_hangup = element.attributes['onHangup']
  176. on_answer = element.attributes['onAnswer']
  177. end
  178. response_xml.elements.each('Response/Dial') do |element|
  179. caller_id = element.attributes['callerId']
  180. end
  181. response_xml.elements.each('Response/Dial/Number') do |element|
  182. number_to_dail = element.text
  183. end
  184. expect(caller_id).to eq('41715880339000')
  185. expect(number_to_dail).to eq('4147110000000')
  186. expect(on_hangup).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
  187. expect(on_answer).to eq("http://zammad.example.com/api/v1/sipgate/#{token}/out")
  188. # no config
  189. Setting.set('sipgate_config', {})
  190. params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278-6&user%5B%5D=user+1&user%5B%5D=user+2'
  191. post "/api/v1/sipgate/#{token}/in", params: params
  192. expect(response).to have_http_status(:unprocessable_entity)
  193. error = nil
  194. content = response.body
  195. response_xml = REXML::Document.new(content)
  196. response_xml.elements.each('Response/Error') do |element|
  197. error = element.text
  198. end
  199. expect(error).to eq('Feature not configured, please contact your admin!')
  200. end
  201. it 'does log call' do
  202. token = Setting.get('sipgate_token')
  203. # outbound - I - new call
  204. params = 'event=newCall&direction=out&from=4930600000000&to=4912347114711&callId=1234567890-1&user%5B%5D=user+1'
  205. post "/api/v1/sipgate/#{token}/out", params: params
  206. expect(response).to have_http_status(:ok)
  207. log = Cti::Log.find_by(call_id: '1234567890-1')
  208. expect(log).to be_truthy
  209. expect(log.from).to eq('4930777000000')
  210. expect(log.to).to eq('4912347114711')
  211. expect(log.direction).to eq('out')
  212. expect(log.from_comment).to eq('user 1')
  213. expect(log.to_comment).to eq('CallerId Customer1')
  214. expect(log.comment).to be_nil
  215. expect(log.state).to eq('newCall')
  216. expect(log.done).to be(true)
  217. travel 1.second
  218. # outbound - I - hangup by agent
  219. params = 'event=hangup&direction=out&callId=1234567890-1&cause=cancel'
  220. post "/api/v1/sipgate/#{token}/out", params: params
  221. expect(response).to have_http_status(:ok)
  222. log = Cti::Log.find_by(call_id: '1234567890-1')
  223. expect(log).to be_truthy
  224. expect(log.from).to eq('4930777000000')
  225. expect(log.to).to eq('4912347114711')
  226. expect(log.direction).to eq('out')
  227. expect(log.from_comment).to eq('user 1')
  228. expect(log.to_comment).to eq('CallerId Customer1')
  229. expect(log.comment).to eq('cancel')
  230. expect(log.state).to eq('hangup')
  231. expect(log.done).to be(true)
  232. travel 1.second
  233. # outbound - II - new call
  234. params = 'event=newCall&direction=out&from=4930600000000&to=4912347114711&callId=1234567890-2&user%5B%5D=user+1'
  235. post "/api/v1/sipgate/#{token}/out", params: params
  236. expect(response).to have_http_status(:ok)
  237. log = Cti::Log.find_by(call_id: '1234567890-2')
  238. expect(log).to be_truthy
  239. expect(log.from).to eq('4930777000000')
  240. expect(log.to).to eq('4912347114711')
  241. expect(log.direction).to eq('out')
  242. expect(log.from_comment).to eq('user 1')
  243. expect(log.to_comment).to eq('CallerId Customer1')
  244. expect(log.comment).to be_nil
  245. expect(log.state).to eq('newCall')
  246. expect(log.done).to be(true)
  247. travel 1.second
  248. # outbound - II - answer by customer
  249. params = 'event=answer&direction=out&callId=1234567890-2&from=4930600000000&to=4912347114711'
  250. post "/api/v1/sipgate/#{token}/out", params: params
  251. expect(response).to have_http_status(:ok)
  252. log = Cti::Log.find_by(call_id: '1234567890-2')
  253. expect(log).to be_truthy
  254. expect(log.from).to eq('4930777000000')
  255. expect(log.to).to eq('4912347114711')
  256. expect(log.direction).to eq('out')
  257. expect(log.from_comment).to eq('user 1')
  258. expect(log.to_comment).to eq('CallerId Customer1')
  259. expect(log.comment).to be_nil
  260. expect(log.state).to eq('answer')
  261. expect(log.done).to be(true)
  262. travel 1.second
  263. # outbound - II - hangup by customer
  264. params = 'event=hangup&direction=out&callId=1234567890-2&cause=normalClearing&from=4930600000000&to=4912347114711'
  265. post "/api/v1/sipgate/#{token}/out", params: params
  266. expect(response).to have_http_status(:ok)
  267. log = Cti::Log.find_by(call_id: '1234567890-2')
  268. expect(log).to be_truthy
  269. expect(log.from).to eq('4930777000000')
  270. expect(log.to).to eq('4912347114711')
  271. expect(log.direction).to eq('out')
  272. expect(log.from_comment).to eq('user 1')
  273. expect(log.to_comment).to eq('CallerId Customer1')
  274. expect(log.comment).to eq('normalClearing')
  275. expect(log.state).to eq('hangup')
  276. expect(log.done).to be(true)
  277. travel 1.second
  278. # inbound - I - new call
  279. params = 'event=newCall&direction=in&to=4930600000000&from=4912347114711&callId=1234567890-3&user%5B%5D=user+1'
  280. post "/api/v1/sipgate/#{token}/in", params: params
  281. expect(response).to have_http_status(:ok)
  282. log = Cti::Log.find_by(call_id: '1234567890-3')
  283. expect(log).to be_truthy
  284. expect(log.to).to eq('4930600000000')
  285. expect(log.from).to eq('4912347114711')
  286. expect(log.direction).to eq('in')
  287. expect(log.to_comment).to eq('user 1')
  288. expect(log.from_comment).to eq('CallerId Customer1')
  289. expect(log.comment).to be_nil
  290. expect(log.state).to eq('newCall')
  291. expect(log.done).to be(false)
  292. travel 1.second
  293. # inbound - I - answer by customer
  294. params = 'event=answer&direction=in&callId=1234567890-3&to=4930600000000&from=4912347114711'
  295. post "/api/v1/sipgate/#{token}/in", params: params
  296. expect(response).to have_http_status(:ok)
  297. log = Cti::Log.find_by(call_id: '1234567890-3')
  298. expect(log).to be_truthy
  299. expect(log.to).to eq('4930600000000')
  300. expect(log.from).to eq('4912347114711')
  301. expect(log.direction).to eq('in')
  302. expect(log.to_comment).to eq('user 1')
  303. expect(log.from_comment).to eq('CallerId Customer1')
  304. expect(log.comment).to be_nil
  305. expect(log.state).to eq('answer')
  306. expect(log.done).to be(true)
  307. travel 1.second
  308. # inbound - I - hangup by customer
  309. params = 'event=hangup&direction=in&callId=1234567890-3&cause=normalClearing&to=4930600000000&from=4912347114711'
  310. post "/api/v1/sipgate/#{token}/in", params: params
  311. expect(response).to have_http_status(:ok)
  312. log = Cti::Log.find_by(call_id: '1234567890-3')
  313. expect(log).to be_truthy
  314. expect(log.to).to eq('4930600000000')
  315. expect(log.from).to eq('4912347114711')
  316. expect(log.direction).to eq('in')
  317. expect(log.to_comment).to eq('user 1')
  318. expect(log.from_comment).to eq('CallerId Customer1')
  319. expect(log.comment).to eq('normalClearing')
  320. expect(log.state).to eq('hangup')
  321. expect(log.done).to be(true)
  322. travel 1.second
  323. # inbound - II - new call
  324. params = 'event=newCall&direction=in&to=4930600000000&from=4912347114711&callId=1234567890-4&user%5B%5D=user+1,user+2'
  325. post "/api/v1/sipgate/#{token}/in", params: params
  326. expect(response).to have_http_status(:ok)
  327. log = Cti::Log.find_by(call_id: '1234567890-4')
  328. expect(log).to be_truthy
  329. expect(log.to).to eq('4930600000000')
  330. expect(log.from).to eq('4912347114711')
  331. expect(log.direction).to eq('in')
  332. expect(log.to_comment).to eq('user 1,user 2')
  333. expect(log.from_comment).to eq('CallerId Customer1')
  334. expect(log.comment).to be_nil
  335. expect(log.state).to eq('newCall')
  336. expect(log.done).to be(false)
  337. travel 1.second
  338. # inbound - II - answer by voicemail
  339. params = 'event=answer&direction=in&callId=1234567890-4&to=4930600000000&from=4912347114711&user=voicemail'
  340. post "/api/v1/sipgate/#{token}/in", params: params
  341. expect(response).to have_http_status(:ok)
  342. log = Cti::Log.find_by(call_id: '1234567890-4')
  343. expect(log).to be_truthy
  344. expect(log.to).to eq('4930600000000')
  345. expect(log.from).to eq('4912347114711')
  346. expect(log.direction).to eq('in')
  347. expect(log.to_comment).to eq('voicemail')
  348. expect(log.from_comment).to eq('CallerId Customer1')
  349. expect(log.comment).to be_nil
  350. expect(log.state).to eq('answer')
  351. expect(log.done).to be(true)
  352. travel 1.second
  353. # inbound - II - hangup by customer
  354. params = 'event=hangup&direction=in&callId=1234567890-4&cause=normalClearing&to=4930600000000&from=4912347114711'
  355. post "/api/v1/sipgate/#{token}/in", params: params
  356. expect(response).to have_http_status(:ok)
  357. log = Cti::Log.find_by(call_id: '1234567890-4')
  358. expect(log).to be_truthy
  359. expect(log.to).to eq('4930600000000')
  360. expect(log.from).to eq('4912347114711')
  361. expect(log.direction).to eq('in')
  362. expect(log.to_comment).to eq('voicemail')
  363. expect(log.from_comment).to eq('CallerId Customer1')
  364. expect(log.comment).to eq('normalClearing')
  365. expect(log.state).to eq('hangup')
  366. expect(log.done).to be(false)
  367. travel 1.second
  368. # inbound - III - new call
  369. params = 'event=newCall&direction=in&to=4930600000000&from=4912347114711&callId=1234567890-5&user%5B%5D=user+1,user+2'
  370. post "/api/v1/sipgate/#{token}/in", params: params
  371. expect(response).to have_http_status(:ok)
  372. log = Cti::Log.find_by(call_id: '1234567890-5')
  373. expect(log).to be_truthy
  374. expect(log.to).to eq('4930600000000')
  375. expect(log.from).to eq('4912347114711')
  376. expect(log.direction).to eq('in')
  377. expect(log.to_comment).to eq('user 1,user 2')
  378. expect(log.from_comment).to eq('CallerId Customer1')
  379. expect(log.comment).to be_nil
  380. expect(log.state).to eq('newCall')
  381. expect(log.done).to be(false)
  382. travel 1.second
  383. # inbound - III - hangup by customer
  384. params = 'event=hangup&direction=in&callId=1234567890-5&cause=normalClearing&to=4930600000000&from=4912347114711'
  385. post "/api/v1/sipgate/#{token}/in", params: params
  386. expect(response).to have_http_status(:ok)
  387. log = Cti::Log.find_by(call_id: '1234567890-5')
  388. expect(log).to be_truthy
  389. expect(log.to).to eq('4930600000000')
  390. expect(log.from).to eq('4912347114711')
  391. expect(log.direction).to eq('in')
  392. expect(log.to_comment).to eq('user 1,user 2')
  393. expect(log.from_comment).to eq('CallerId Customer1')
  394. expect(log.comment).to eq('normalClearing')
  395. expect(log.state).to eq('hangup')
  396. expect(log.done).to be(false)
  397. travel 1.second
  398. # inbound - IV - new call
  399. params = 'event=newCall&direction=in&to=4930600000000&from=49999992222222&callId=1234567890-6&user%5B%5D=user+1,user+2'
  400. post "/api/v1/sipgate/#{token}/in", params: params
  401. expect(response).to have_http_status(:ok)
  402. log = Cti::Log.find_by(call_id: '1234567890-6')
  403. expect(log).to be_truthy
  404. expect(log.to).to eq('4930600000000')
  405. expect(log.from).to eq('49999992222222')
  406. expect(log.direction).to eq('in')
  407. expect(log.to_comment).to eq('user 1,user 2')
  408. expect(log.from_comment).to eq('CallerId Customer3,CallerId Customer2')
  409. expect(log.preferences['to']).to be_falsey
  410. expect(log.preferences['from']).to be_truthy
  411. expect(log.comment).to be_nil
  412. expect(log.state).to eq('newCall')
  413. expect(log.done).to be(false)
  414. # get caller list
  415. get '/api/v1/cti/log'
  416. expect(response).to have_http_status(:forbidden)
  417. authenticated_as(agent)
  418. get '/api/v1/cti/log', as: :json
  419. expect(response).to have_http_status(:ok)
  420. expect(json_response['list']).to be_a(Array)
  421. expect(json_response['list'].count).to eq(6)
  422. expect(json_response['assets']).to be_truthy
  423. expect(json_response['assets']['User']).to be_truthy
  424. expect(json_response['assets']['User'][customer2.id.to_s]).to be_truthy
  425. expect(json_response['assets']['User'][customer3.id.to_s]).to be_truthy
  426. expect(json_response['list'][0]['call_id']).to eq('1234567890-6')
  427. expect(json_response['list'][1]['call_id']).to eq('1234567890-5')
  428. expect(json_response['list'][2]['call_id']).to eq('1234567890-4')
  429. expect(json_response['list'][3]['call_id']).to eq('1234567890-3')
  430. expect(json_response['list'][4]['call_id']).to eq('1234567890-2')
  431. expect(json_response['list'][4]['state']).to eq('hangup')
  432. expect(json_response['list'][4]['from']).to eq('4930777000000')
  433. expect(json_response['list'][4]['from_comment']).to eq('user 1')
  434. expect(json_response['list'][4]['to']).to eq('4912347114711')
  435. expect(json_response['list'][4]['to_comment']).to eq('CallerId Customer1')
  436. expect(json_response['list'][4]['comment']).to eq('normalClearing')
  437. expect(json_response['list'][4]['state']).to eq('hangup')
  438. expect(json_response['list'][5]['call_id']).to eq('1234567890-1')
  439. end
  440. it 'alternative fqdn' do
  441. token = Setting.get('sipgate_token')
  442. Setting.set('sipgate_alternative_fqdn', 'external.host.example.com')
  443. # inbound - I
  444. params = 'event=newCall&direction=in&from=4912347114711&to=4930600000000&callId=4991155921769858278-1&user%5B%5D=user+1&user%5B%5D=user+2'
  445. post "/api/v1/sipgate/#{token}/in", params: params
  446. expect(response).to have_http_status(:ok)
  447. on_hangup = nil
  448. on_answer = nil
  449. content = response.body
  450. response_xml = REXML::Document.new(content)
  451. response_xml.elements.each('Response') do |element|
  452. on_hangup = element.attributes['onHangup']
  453. on_answer = element.attributes['onAnswer']
  454. end
  455. expect(on_hangup).to eq("http://external.host.example.com/api/v1/sipgate/#{token}/in")
  456. expect(on_answer).to eq("http://external.host.example.com/api/v1/sipgate/#{token}/in")
  457. end
  458. end
  459. end