You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

153 lines
6.2 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. import re
  5. import time
  6. from datetime import datetime
  7. from odoo import models, api, fields
  8. import odoo.addons.decimal_precision as dp
  9. class MailTrackingEvent(models.Model):
  10. _name = "mail.tracking.event"
  11. _order = 'timestamp desc'
  12. _rec_name = 'event_type'
  13. _description = 'MailTracking event'
  14. recipient = fields.Char(string="Recipient", readonly=True)
  15. recipient_address = fields.Char(
  16. string='Recipient email address', readonly=True, store=True,
  17. compute='_compute_recipient_address', index=True)
  18. timestamp = fields.Float(
  19. string='UTC timestamp', readonly=True,
  20. digits=dp.get_precision('MailTracking Timestamp'))
  21. time = fields.Datetime(string="Time", readonly=True)
  22. date = fields.Date(
  23. string="Date", readonly=True, compute="_compute_date", store=True)
  24. tracking_email_id = fields.Many2one(
  25. string='Message', readonly=True, required=True, ondelete='cascade',
  26. comodel_name='mail.tracking.email')
  27. event_type = fields.Selection(string='Event type', selection=[
  28. ('sent', 'Sent'),
  29. ('delivered', 'Delivered'),
  30. ('deferral', 'Deferral'),
  31. ('hard_bounce', 'Hard bounce'),
  32. ('soft_bounce', 'Soft bounce'),
  33. ('open', 'Open'),
  34. ('click', 'Clicked'),
  35. ('spam', 'Spam'),
  36. ('unsub', 'Unsubscribed'),
  37. ('reject', 'Rejected'),
  38. ], readonly=True)
  39. smtp_server = fields.Char(string='SMTP server', readonly=True)
  40. url = fields.Char(string='Clicked URL', readonly=True)
  41. ip = fields.Char(string='User IP', readonly=True)
  42. user_agent = fields.Char(string='User agent', readonly=True)
  43. mobile = fields.Boolean(string='Is mobile?', readonly=True)
  44. os_family = fields.Char(string='Operating system family', readonly=True)
  45. ua_family = fields.Char(string='User agent family', readonly=True)
  46. ua_type = fields.Char(string='User agent type', readonly=True)
  47. user_country_id = fields.Many2one(string='User country', readonly=True,
  48. comodel_name='res.country')
  49. error_type = fields.Char(string='Error type', readonly=True)
  50. error_description = fields.Char(string='Error description', readonly=True)
  51. error_details = fields.Text(string='Error details', readonly=True)
  52. @api.multi
  53. @api.depends('recipient')
  54. def _compute_recipient_address(self):
  55. for email in self:
  56. if email.recipient:
  57. matches = re.search(r'<(.*@.*)>', email.recipient)
  58. if matches:
  59. email.recipient_address = matches.group(1).lower()
  60. else:
  61. email.recipient_address = email.recipient.lower()
  62. else:
  63. email.recipient_address = False
  64. @api.multi
  65. @api.depends('time')
  66. def _compute_date(self):
  67. for email in self:
  68. email.date = fields.Date.to_string(
  69. fields.Date.from_string(email.time))
  70. def _process_data(self, tracking_email, metadata, event_type, state):
  71. ts = time.time()
  72. dt = datetime.utcfromtimestamp(ts)
  73. return {
  74. 'recipient': metadata.get('recipient', tracking_email.recipient),
  75. 'timestamp': metadata.get('timestamp', ts),
  76. 'time': metadata.get('time', fields.Datetime.to_string(dt)),
  77. 'date': metadata.get('date', fields.Date.to_string(dt)),
  78. 'tracking_email_id': tracking_email.id,
  79. 'event_type': event_type,
  80. 'ip': metadata.get('ip', False),
  81. 'url': metadata.get('url', False),
  82. 'user_agent': metadata.get('user_agent', False),
  83. 'mobile': metadata.get('mobile', False),
  84. 'os_family': metadata.get('os_family', False),
  85. 'ua_family': metadata.get('ua_family', False),
  86. 'ua_type': metadata.get('ua_type', False),
  87. 'user_country_id': metadata.get('user_country_id', False),
  88. 'error_type': metadata.get('error_type', False),
  89. 'error_description': metadata.get('error_description', False),
  90. 'error_details': metadata.get('error_details', False),
  91. }
  92. def _process_status(self, tracking_email, metadata, event_type, state):
  93. tracking_email.sudo().write({'state': state})
  94. return self._process_data(tracking_email, metadata, event_type, state)
  95. def _process_bounce(self, tracking_email, metadata, event_type, state):
  96. tracking_email.sudo().write({
  97. 'state': state,
  98. 'bounce_type': metadata.get('bounce_type', False),
  99. 'bounce_description': metadata.get('bounce_description', False),
  100. })
  101. return self._process_data(tracking_email, metadata, event_type, state)
  102. @api.model
  103. def process_delivered(self, tracking_email, metadata):
  104. return self._process_status(
  105. tracking_email, metadata, 'delivered', 'delivered')
  106. @api.model
  107. def process_deferral(self, tracking_email, metadata):
  108. return self._process_status(
  109. tracking_email, metadata, 'deferral', 'deferred')
  110. @api.model
  111. def process_hard_bounce(self, tracking_email, metadata):
  112. return self._process_bounce(
  113. tracking_email, metadata, 'hard_bounce', 'bounced')
  114. @api.model
  115. def process_soft_bounce(self, tracking_email, metadata):
  116. return self._process_bounce(
  117. tracking_email, metadata, 'soft_bounce', 'soft-bounced')
  118. @api.model
  119. def process_open(self, tracking_email, metadata):
  120. return self._process_status(tracking_email, metadata, 'open', 'opened')
  121. @api.model
  122. def process_click(self, tracking_email, metadata):
  123. return self._process_status(
  124. tracking_email, metadata, 'click', 'opened')
  125. @api.model
  126. def process_spam(self, tracking_email, metadata):
  127. return self._process_status(tracking_email, metadata, 'spam', 'spam')
  128. @api.model
  129. def process_unsub(self, tracking_email, metadata):
  130. return self._process_status(tracking_email, metadata, 'unsub', 'unsub')
  131. @api.model
  132. def process_reject(self, tracking_email, metadata):
  133. return self._process_status(
  134. tracking_email, metadata, 'reject', 'rejected')