email_helper.rb 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620
  1. module EmailHelper
  2. =begin
  3. get available driver
  4. result = EmailHelper.available_driver
  5. returns
  6. {
  7. inbound: {
  8. imap: 'IMAP',
  9. pop3: 'POP3',
  10. },
  11. outbound: {
  12. smtp: 'SMTP - configure your own outgoing SMTP settings',
  13. sendmail: 'Local MTA (Sendmail/Postfix/Exim/...) - use server setup',
  14. },
  15. }
  16. =end
  17. def self.available_driver
  18. if Setting.get('system_online_service')
  19. return {
  20. inbound: {
  21. imap: 'IMAP',
  22. pop3: 'POP3',
  23. },
  24. outbound: {
  25. smtp: 'SMTP - configure your own outgoing SMTP settings',
  26. },
  27. }
  28. end
  29. {
  30. inbound: {
  31. imap: 'IMAP',
  32. pop3: 'POP3',
  33. },
  34. outbound: {
  35. smtp: 'SMTP - configure your own outgoing SMTP settings',
  36. sendmail: 'Local MTA (Sendmail/Postfix/Exim/...) - use server setup',
  37. },
  38. }
  39. end
  40. =begin
  41. get mail parts
  42. user, domain = EmailHelper.parse_email('somebody@example.com')
  43. returns
  44. [user, domain]
  45. =end
  46. def self.parse_email(email)
  47. user = nil
  48. domain = nil
  49. if email =~ /^(.+?)@(.+?)$/
  50. user = $1
  51. domain = $2
  52. end
  53. [user, domain]
  54. end
  55. =begin
  56. get list of providers with inbound and outbound settings
  57. map = EmailHelper.provider(email, password)
  58. returns
  59. {
  60. google: {
  61. domain: 'gmail.com|googlemail.com|gmail.de',
  62. inbound: {
  63. adapter: 'imap',
  64. options: {
  65. host: 'imap.gmail.com',
  66. port: 993,
  67. ssl: true,
  68. user: email,
  69. password: password,
  70. },
  71. },
  72. outbound: {
  73. adapter: 'smtp',
  74. options: {
  75. host: 'smtp.gmail.com',
  76. port: 25,
  77. start_tls: true,
  78. user: email,
  79. password: password,
  80. }
  81. },
  82. },
  83. ...
  84. }
  85. =end
  86. def self.provider(email, password)
  87. # check domain based attributes
  88. provider_map = {
  89. google_imap: {
  90. domain: 'gmail|googlemail|google',
  91. inbound: {
  92. adapter: 'imap',
  93. options: {
  94. host: 'imap.gmail.com',
  95. port: 993,
  96. ssl: true,
  97. user: email,
  98. password: password,
  99. },
  100. },
  101. outbound: {
  102. adapter: 'smtp',
  103. options: {
  104. host: 'smtp.gmail.com',
  105. port: 25,
  106. start_tls: true,
  107. user: email,
  108. password: password,
  109. }
  110. },
  111. },
  112. microsoft: {
  113. domain: 'outlook.com|hotmail.com',
  114. inbound: {
  115. adapter: 'imap',
  116. options: {
  117. host: 'imap-mail.outlook.com',
  118. port: 993,
  119. ssl: true,
  120. user: email,
  121. password: password,
  122. },
  123. },
  124. outbound: {
  125. adapter: 'smtp',
  126. options: {
  127. host: 'smtp-mail.outlook.com',
  128. port: 25,
  129. start_tls: true,
  130. user: email,
  131. password: password,
  132. }
  133. },
  134. },
  135. google_pop3: {
  136. domain: 'gmail|googlemail|google',
  137. inbound: {
  138. adapter: 'pop3',
  139. options: {
  140. host: 'pop.gmail.com',
  141. port: 995,
  142. ssl: true,
  143. user: email,
  144. password: password,
  145. },
  146. },
  147. outbound: {
  148. adapter: 'smtp',
  149. options: {
  150. host: 'smtp.gmail.com',
  151. port: 25,
  152. start_tls: true,
  153. user: email,
  154. password: password,
  155. }
  156. },
  157. },
  158. }
  159. provider_map
  160. end
  161. =begin
  162. get possible inbound settings based on mx
  163. map = EmailHelper.provider_inbound_mx(user, email, password, mx_domains)
  164. returns
  165. {
  166. adapter: 'imap',
  167. options: {
  168. host: mx_domains[0],
  169. port: 993,
  170. ssl: true,
  171. user: user,
  172. password: password,
  173. },
  174. },
  175. {
  176. adapter: 'imap',
  177. options: {
  178. host: mx_domains[0],
  179. port: 993,
  180. ssl: true,
  181. user: email,
  182. password: password,
  183. },
  184. },
  185. =end
  186. def self.provider_inbound_mx(user, email, password, mx_domains)
  187. inbounds = []
  188. mx_domains.each { |domain|
  189. inbound = [
  190. {
  191. adapter: 'imap',
  192. options: {
  193. host: domain,
  194. port: 993,
  195. ssl: true,
  196. user: user,
  197. password: password,
  198. },
  199. },
  200. {
  201. adapter: 'imap',
  202. options: {
  203. host: domain,
  204. port: 993,
  205. ssl: true,
  206. user: email,
  207. password: password,
  208. },
  209. },
  210. ]
  211. inbounds = inbounds.concat(inbound)
  212. }
  213. inbounds
  214. end
  215. =begin
  216. get possible inbound settings based on guess
  217. map = EmailHelper.provider_inbound_guess(user, email, password, domain)
  218. returns
  219. {
  220. adapter: 'imap',
  221. options: {
  222. host: "mail.#{domain}",
  223. port: 993,
  224. ssl: true,
  225. user: user,
  226. password: password,
  227. },
  228. },
  229. {
  230. adapter: 'imap',
  231. options: {
  232. host: "mail.#{domain}",
  233. port: 993,
  234. ssl: true,
  235. user: email,
  236. password: password,
  237. },
  238. },
  239. ...
  240. =end
  241. def self.provider_inbound_guess(user, email, password, domain)
  242. inbound = [
  243. {
  244. adapter: 'imap',
  245. options: {
  246. host: "mail.#{domain}",
  247. port: 993,
  248. ssl: true,
  249. user: user,
  250. password: password,
  251. },
  252. },
  253. {
  254. adapter: 'imap',
  255. options: {
  256. host: "mail.#{domain}",
  257. port: 993,
  258. ssl: true,
  259. user: email,
  260. password: password,
  261. },
  262. },
  263. {
  264. adapter: 'imap',
  265. options: {
  266. host: "imap.#{domain}",
  267. port: 993,
  268. ssl: true,
  269. user: user,
  270. password: password,
  271. },
  272. },
  273. {
  274. adapter: 'imap',
  275. options: {
  276. host: "imap.#{domain}",
  277. port: 993,
  278. ssl: true,
  279. user: email,
  280. password: password,
  281. },
  282. },
  283. {
  284. adapter: 'pop3',
  285. options: {
  286. host: "mail.#{domain}",
  287. port: 995,
  288. ssl: true,
  289. user: user,
  290. password: password,
  291. },
  292. },
  293. {
  294. adapter: 'pop3',
  295. options: {
  296. host: "mail.#{domain}",
  297. port: 995,
  298. ssl: true,
  299. user: email,
  300. password: password,
  301. },
  302. },
  303. {
  304. adapter: 'pop3',
  305. options: {
  306. host: "pop.#{domain}",
  307. port: 995,
  308. ssl: true,
  309. user: user,
  310. password: password,
  311. },
  312. },
  313. {
  314. adapter: 'pop3',
  315. options: {
  316. host: "pop.#{domain}",
  317. port: 995,
  318. ssl: true,
  319. user: email,
  320. password: password,
  321. },
  322. },
  323. {
  324. adapter: 'pop3',
  325. options: {
  326. host: "pop3.#{domain}",
  327. port: 995,
  328. ssl: true,
  329. user: user,
  330. password: password,
  331. },
  332. },
  333. {
  334. adapter: 'pop3',
  335. options: {
  336. host: "pop3.#{domain}",
  337. port: 995,
  338. ssl: true,
  339. user: email,
  340. password: password,
  341. },
  342. },
  343. ]
  344. inbound
  345. end
  346. =begin
  347. get possible outbound settings based on mx
  348. map = EmailHelper.provider_outbound_mx(user, email, password, mx_domains)
  349. returns
  350. {
  351. adapter: 'smtp',
  352. options: {
  353. host: domain,
  354. port: 25,
  355. start_tls: true,
  356. user: user,
  357. password: password,
  358. },
  359. },
  360. {
  361. adapter: 'smtp',
  362. options: {
  363. host: domain,
  364. port: 25,
  365. start_tls: true,
  366. user: email,
  367. password: password,
  368. },
  369. },
  370. =end
  371. def self.provider_outbound_mx(user, email, password, mx_domains)
  372. outbounds = []
  373. mx_domains.each { |domain|
  374. outbound = [
  375. {
  376. adapter: 'smtp',
  377. options: {
  378. host: domain,
  379. port: 25,
  380. start_tls: true,
  381. user: user,
  382. password: password,
  383. },
  384. },
  385. {
  386. adapter: 'smtp',
  387. options: {
  388. host: domain,
  389. port: 25,
  390. start_tls: true,
  391. user: email,
  392. password: password,
  393. },
  394. },
  395. {
  396. adapter: 'smtp',
  397. options: {
  398. host: domain,
  399. port: 465,
  400. start_tls: true,
  401. user: user,
  402. password: password,
  403. },
  404. },
  405. {
  406. adapter: 'smtp',
  407. options: {
  408. host: domain,
  409. port: 465,
  410. start_tls: true,
  411. user: email,
  412. password: password,
  413. },
  414. },
  415. ]
  416. outbounds = outbounds.concat(outbound)
  417. }
  418. outbounds
  419. end
  420. =begin
  421. get possible outbound settings based on guess
  422. map = EmailHelper.provider_outbound_guess(user, email, password, domain)
  423. returns
  424. {
  425. adapter: 'imap',
  426. options: {
  427. host: "mail.#{domain}",
  428. port: 993,
  429. ssl: true,
  430. user: user,
  431. password: password,
  432. },
  433. },
  434. {
  435. adapter: 'imap',
  436. options: {
  437. host: "mail.#{domain}",
  438. port: 993,
  439. ssl: true,
  440. user: email,
  441. password: password,
  442. },
  443. },
  444. ...
  445. =end
  446. def self.provider_outbound_guess(user, email, password, domain)
  447. outbound = [
  448. {
  449. adapter: 'smtp',
  450. options: {
  451. host: "mail.#{domain}",
  452. port: 25,
  453. start_tls: true,
  454. user: user,
  455. password: password,
  456. },
  457. },
  458. {
  459. adapter: 'smtp',
  460. options: {
  461. host: "mail.#{domain}",
  462. port: 25,
  463. start_tls: true,
  464. user: email,
  465. password: password,
  466. },
  467. },
  468. {
  469. adapter: 'smtp',
  470. options: {
  471. host: "mail.#{domain}",
  472. port: 465,
  473. start_tls: true,
  474. user: user,
  475. password: password,
  476. },
  477. },
  478. {
  479. adapter: 'smtp',
  480. options: {
  481. host: "mail.#{domain}",
  482. port: 465,
  483. start_tls: true,
  484. user: email,
  485. password: password,
  486. },
  487. },
  488. {
  489. adapter: 'smtp',
  490. options: {
  491. host: "smtp.#{domain}",
  492. port: 25,
  493. start_tls: true,
  494. user: user,
  495. password: password,
  496. },
  497. },
  498. {
  499. adapter: 'smtp',
  500. options: {
  501. host: "smtp.#{domain}",
  502. port: 25,
  503. start_tls: true,
  504. user: email,
  505. password: password,
  506. },
  507. },
  508. {
  509. adapter: 'smtp',
  510. options: {
  511. host: "smtp.#{domain}",
  512. port: 465,
  513. start_tls: true,
  514. user: user,
  515. password: password,
  516. },
  517. },
  518. {
  519. adapter: 'smtp',
  520. options: {
  521. host: "smtp.#{domain}",
  522. port: 465,
  523. start_tls: true,
  524. user: email,
  525. password: password,
  526. },
  527. },
  528. ]
  529. outbound
  530. end
  531. =begin
  532. get dns mx records of domain
  533. mx_records = EmailHelper.mx_records('example.com')
  534. returns
  535. ['mx1.example.com', 'mx2.example.com']
  536. =end
  537. def self.mx_records(domain)
  538. mail_exchangers = mxers(domain)
  539. if mail_exchangers && mail_exchangers[0]
  540. Rails.logger.info "MX for #{domain}: #{mail_exchangers} - #{mail_exchangers[0][0]}"
  541. end
  542. mx_records = []
  543. if mail_exchangers && mail_exchangers[0] && mail_exchangers[0][0]
  544. mx_records.push mail_exchangers[0][0]
  545. end
  546. mx_records
  547. end
  548. def self.mxers(domain)
  549. begin
  550. mxs = Resolv::DNS.open do |dns|
  551. ress = dns.getresources(domain, Resolv::DNS::Resource::IN::MX)
  552. ress.map { |r|
  553. [r.exchange.to_s, IPSocket.getaddress(r.exchange.to_s), r.preference]
  554. }
  555. end
  556. rescue => e
  557. Rails.logger.error e.message
  558. Rails.logger.error e.backtrace.inspect
  559. end
  560. mxs
  561. end
  562. end