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. {
  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. end
  160. =begin
  161. get possible inbound settings based on mx
  162. map = EmailHelper.provider_inbound_mx(user, email, password, mx_domains)
  163. returns
  164. {
  165. adapter: 'imap',
  166. options: {
  167. host: mx_domains[0],
  168. port: 993,
  169. ssl: true,
  170. user: user,
  171. password: password,
  172. },
  173. },
  174. {
  175. adapter: 'imap',
  176. options: {
  177. host: mx_domains[0],
  178. port: 993,
  179. ssl: true,
  180. user: email,
  181. password: password,
  182. },
  183. },
  184. =end
  185. def self.provider_inbound_mx(user, email, password, mx_domains)
  186. inbounds = []
  187. mx_domains.each do |domain|
  188. inbound = [
  189. {
  190. adapter: 'imap',
  191. options: {
  192. host: domain,
  193. port: 993,
  194. ssl: true,
  195. user: user,
  196. password: password,
  197. },
  198. },
  199. {
  200. adapter: 'imap',
  201. options: {
  202. host: domain,
  203. port: 993,
  204. ssl: true,
  205. user: email,
  206. password: password,
  207. },
  208. },
  209. ]
  210. inbounds = inbounds.concat(inbound)
  211. end
  212. inbounds
  213. end
  214. =begin
  215. get possible inbound settings based on guess
  216. map = EmailHelper.provider_inbound_guess(user, email, password, domain)
  217. returns
  218. {
  219. adapter: 'imap',
  220. options: {
  221. host: "mail.#{domain}",
  222. port: 993,
  223. ssl: true,
  224. user: user,
  225. password: password,
  226. },
  227. },
  228. {
  229. adapter: 'imap',
  230. options: {
  231. host: "mail.#{domain}",
  232. port: 993,
  233. ssl: true,
  234. user: email,
  235. password: password,
  236. },
  237. },
  238. ...
  239. =end
  240. def self.provider_inbound_guess(user, email, password, domain)
  241. [
  242. {
  243. adapter: 'imap',
  244. options: {
  245. host: "mail.#{domain}",
  246. port: 993,
  247. ssl: true,
  248. user: user,
  249. password: password,
  250. },
  251. },
  252. {
  253. adapter: 'imap',
  254. options: {
  255. host: "mail.#{domain}",
  256. port: 993,
  257. ssl: true,
  258. user: email,
  259. password: password,
  260. },
  261. },
  262. {
  263. adapter: 'imap',
  264. options: {
  265. host: "imap.#{domain}",
  266. port: 993,
  267. ssl: true,
  268. user: user,
  269. password: password,
  270. },
  271. },
  272. {
  273. adapter: 'imap',
  274. options: {
  275. host: "imap.#{domain}",
  276. port: 993,
  277. ssl: true,
  278. user: email,
  279. password: password,
  280. },
  281. },
  282. {
  283. adapter: 'pop3',
  284. options: {
  285. host: "mail.#{domain}",
  286. port: 995,
  287. ssl: true,
  288. user: user,
  289. password: password,
  290. },
  291. },
  292. {
  293. adapter: 'pop3',
  294. options: {
  295. host: "mail.#{domain}",
  296. port: 995,
  297. ssl: true,
  298. user: email,
  299. password: password,
  300. },
  301. },
  302. {
  303. adapter: 'pop3',
  304. options: {
  305. host: "pop.#{domain}",
  306. port: 995,
  307. ssl: true,
  308. user: user,
  309. password: password,
  310. },
  311. },
  312. {
  313. adapter: 'pop3',
  314. options: {
  315. host: "pop.#{domain}",
  316. port: 995,
  317. ssl: true,
  318. user: email,
  319. password: password,
  320. },
  321. },
  322. {
  323. adapter: 'pop3',
  324. options: {
  325. host: "pop3.#{domain}",
  326. port: 995,
  327. ssl: true,
  328. user: user,
  329. password: password,
  330. },
  331. },
  332. {
  333. adapter: 'pop3',
  334. options: {
  335. host: "pop3.#{domain}",
  336. port: 995,
  337. ssl: true,
  338. user: email,
  339. password: password,
  340. },
  341. },
  342. ]
  343. end
  344. =begin
  345. get possible outbound settings based on mx
  346. map = EmailHelper.provider_outbound_mx(user, email, password, mx_domains)
  347. returns
  348. {
  349. adapter: 'smtp',
  350. options: {
  351. host: domain,
  352. port: 25,
  353. start_tls: true,
  354. user: user,
  355. password: password,
  356. },
  357. },
  358. {
  359. adapter: 'smtp',
  360. options: {
  361. host: domain,
  362. port: 25,
  363. start_tls: true,
  364. user: email,
  365. password: password,
  366. },
  367. },
  368. =end
  369. def self.provider_outbound_mx(user, email, password, mx_domains)
  370. outbounds = []
  371. mx_domains.each do |domain|
  372. outbound = [
  373. {
  374. adapter: 'smtp',
  375. options: {
  376. host: domain,
  377. port: 25,
  378. start_tls: true,
  379. user: user,
  380. password: password,
  381. },
  382. },
  383. {
  384. adapter: 'smtp',
  385. options: {
  386. host: domain,
  387. port: 25,
  388. start_tls: true,
  389. user: email,
  390. password: password,
  391. },
  392. },
  393. {
  394. adapter: 'smtp',
  395. options: {
  396. host: domain,
  397. port: 465,
  398. start_tls: true,
  399. user: user,
  400. password: password,
  401. },
  402. },
  403. {
  404. adapter: 'smtp',
  405. options: {
  406. host: domain,
  407. port: 465,
  408. start_tls: true,
  409. user: email,
  410. password: password,
  411. },
  412. },
  413. {
  414. adapter: 'smtp',
  415. options: {
  416. host: domain,
  417. port: 587,
  418. user: user,
  419. password: password,
  420. },
  421. },
  422. {
  423. adapter: 'smtp',
  424. options: {
  425. host: domain,
  426. port: 587,
  427. user: email,
  428. password: password,
  429. },
  430. },
  431. ]
  432. outbounds = outbounds.concat(outbound)
  433. end
  434. outbounds
  435. end
  436. =begin
  437. get possible outbound settings based on guess
  438. map = EmailHelper.provider_outbound_guess(user, email, password, domain)
  439. returns
  440. {
  441. adapter: 'imap',
  442. options: {
  443. host: "mail.#{domain}",
  444. port: 993,
  445. ssl: true,
  446. user: user,
  447. password: password,
  448. },
  449. },
  450. {
  451. adapter: 'imap',
  452. options: {
  453. host: "mail.#{domain}",
  454. port: 993,
  455. ssl: true,
  456. user: email,
  457. password: password,
  458. },
  459. },
  460. ...
  461. =end
  462. def self.provider_outbound_guess(user, email, password, domain)
  463. [
  464. {
  465. adapter: 'smtp',
  466. options: {
  467. host: "mail.#{domain}",
  468. port: 25,
  469. start_tls: true,
  470. user: user,
  471. password: password,
  472. },
  473. },
  474. {
  475. adapter: 'smtp',
  476. options: {
  477. host: "mail.#{domain}",
  478. port: 25,
  479. start_tls: true,
  480. user: email,
  481. password: password,
  482. },
  483. },
  484. {
  485. adapter: 'smtp',
  486. options: {
  487. host: "mail.#{domain}",
  488. port: 465,
  489. start_tls: true,
  490. user: user,
  491. password: password,
  492. },
  493. },
  494. {
  495. adapter: 'smtp',
  496. options: {
  497. host: "mail.#{domain}",
  498. port: 465,
  499. start_tls: true,
  500. user: email,
  501. password: password,
  502. },
  503. },
  504. {
  505. adapter: 'smtp',
  506. options: {
  507. host: "smtp.#{domain}",
  508. port: 25,
  509. start_tls: true,
  510. user: user,
  511. password: password,
  512. },
  513. },
  514. {
  515. adapter: 'smtp',
  516. options: {
  517. host: "smtp.#{domain}",
  518. port: 25,
  519. start_tls: true,
  520. user: email,
  521. password: password,
  522. },
  523. },
  524. {
  525. adapter: 'smtp',
  526. options: {
  527. host: "smtp.#{domain}",
  528. port: 465,
  529. start_tls: true,
  530. user: user,
  531. password: password,
  532. },
  533. },
  534. {
  535. adapter: 'smtp',
  536. options: {
  537. host: "smtp.#{domain}",
  538. port: 465,
  539. start_tls: true,
  540. user: email,
  541. password: password,
  542. },
  543. },
  544. ]
  545. end
  546. =begin
  547. get dns mx records of domain
  548. mx_records = EmailHelper.mx_records('example.com')
  549. returns
  550. ['mx1.example.com', 'mx2.example.com']
  551. =end
  552. def self.mx_records(domain)
  553. mail_exchangers = mxers(domain)
  554. if mail_exchangers && mail_exchangers[0]
  555. Rails.logger.info "MX for #{domain}: #{mail_exchangers} - #{mail_exchangers[0][0]}"
  556. end
  557. mx_records = []
  558. if mail_exchangers && mail_exchangers[0] && mail_exchangers[0][0]
  559. mx_records.push mail_exchangers[0][0]
  560. end
  561. mx_records
  562. end
  563. def self.mxers(domain)
  564. begin
  565. mxs = Resolv::DNS.open do |dns|
  566. ress = dns.getresources(domain, Resolv::DNS::Resource::IN::MX)
  567. ress.map do |r|
  568. [r.exchange.to_s, IPSocket.getaddress(r.exchange.to_s), r.preference]
  569. end
  570. end
  571. rescue => e
  572. Rails.logger.error e
  573. end
  574. mxs
  575. end
  576. end