email_helper.rb 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. class 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 do |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. end
  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 do |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. adapter: 'smtp',
  417. options: {
  418. host: domain,
  419. port: 587,
  420. user: user,
  421. password: password,
  422. },
  423. },
  424. {
  425. adapter: 'smtp',
  426. options: {
  427. host: domain,
  428. port: 587,
  429. user: email,
  430. password: password,
  431. },
  432. },
  433. ]
  434. outbounds = outbounds.concat(outbound)
  435. end
  436. outbounds
  437. end
  438. =begin
  439. get possible outbound settings based on guess
  440. map = EmailHelper.provider_outbound_guess(user, email, password, domain)
  441. returns
  442. {
  443. adapter: 'imap',
  444. options: {
  445. host: "mail.#{domain}",
  446. port: 993,
  447. ssl: true,
  448. user: user,
  449. password: password,
  450. },
  451. },
  452. {
  453. adapter: 'imap',
  454. options: {
  455. host: "mail.#{domain}",
  456. port: 993,
  457. ssl: true,
  458. user: email,
  459. password: password,
  460. },
  461. },
  462. ...
  463. =end
  464. def self.provider_outbound_guess(user, email, password, domain)
  465. outbound = [
  466. {
  467. adapter: 'smtp',
  468. options: {
  469. host: "mail.#{domain}",
  470. port: 25,
  471. start_tls: true,
  472. user: user,
  473. password: password,
  474. },
  475. },
  476. {
  477. adapter: 'smtp',
  478. options: {
  479. host: "mail.#{domain}",
  480. port: 25,
  481. start_tls: true,
  482. user: email,
  483. password: password,
  484. },
  485. },
  486. {
  487. adapter: 'smtp',
  488. options: {
  489. host: "mail.#{domain}",
  490. port: 465,
  491. start_tls: true,
  492. user: user,
  493. password: password,
  494. },
  495. },
  496. {
  497. adapter: 'smtp',
  498. options: {
  499. host: "mail.#{domain}",
  500. port: 465,
  501. start_tls: true,
  502. user: email,
  503. password: password,
  504. },
  505. },
  506. {
  507. adapter: 'smtp',
  508. options: {
  509. host: "smtp.#{domain}",
  510. port: 25,
  511. start_tls: true,
  512. user: user,
  513. password: password,
  514. },
  515. },
  516. {
  517. adapter: 'smtp',
  518. options: {
  519. host: "smtp.#{domain}",
  520. port: 25,
  521. start_tls: true,
  522. user: email,
  523. password: password,
  524. },
  525. },
  526. {
  527. adapter: 'smtp',
  528. options: {
  529. host: "smtp.#{domain}",
  530. port: 465,
  531. start_tls: true,
  532. user: user,
  533. password: password,
  534. },
  535. },
  536. {
  537. adapter: 'smtp',
  538. options: {
  539. host: "smtp.#{domain}",
  540. port: 465,
  541. start_tls: true,
  542. user: email,
  543. password: password,
  544. },
  545. },
  546. ]
  547. outbound
  548. end
  549. =begin
  550. get dns mx records of domain
  551. mx_records = EmailHelper.mx_records('example.com')
  552. returns
  553. ['mx1.example.com', 'mx2.example.com']
  554. =end
  555. def self.mx_records(domain)
  556. mail_exchangers = mxers(domain)
  557. if mail_exchangers && mail_exchangers[0]
  558. Rails.logger.info "MX for #{domain}: #{mail_exchangers} - #{mail_exchangers[0][0]}"
  559. end
  560. mx_records = []
  561. if mail_exchangers && mail_exchangers[0] && mail_exchangers[0][0]
  562. mx_records.push mail_exchangers[0][0]
  563. end
  564. mx_records
  565. end
  566. def self.mxers(domain)
  567. begin
  568. mxs = Resolv::DNS.open do |dns|
  569. ress = dns.getresources(domain, Resolv::DNS::Resource::IN::MX)
  570. ress.map do |r|
  571. [r.exchange.to_s, IPSocket.getaddress(r.exchange.to_s), r.preference]
  572. end
  573. end
  574. rescue => e
  575. Rails.logger.error e
  576. end
  577. mxs
  578. end
  579. end