Skip to content

Commit

Permalink
Add Sendgrid modules
Browse files Browse the repository at this point in the history
  • Loading branch information
ecino committed Jun 26, 2017
1 parent ab7cbe4 commit c00876e
Show file tree
Hide file tree
Showing 42 changed files with 2,149 additions and 0 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Expand Up @@ -29,6 +29,7 @@ virtualenv:
install:
- git clone --depth=1 https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools
- export PATH=${HOME}/maintainer-quality-tools/travis:${PATH}
- pip install sendgrid
- travis_install_nightly

script:
Expand Down
120 changes: 120 additions & 0 deletions mail_sendgrid/README.rst
@@ -0,0 +1,120 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License: AGPL-3

==================================
SendGrid Mail Sending and Tracking
==================================

This module integrates
`SendGrid <https://sendgrid.com/>`_ with Odoo. It can send transactional emails
through SendGrid, using templates defined on the
`SendGrid web interface <https://sendgrid.com/templates>`_. It also supports
substitution of placeholder variables in these templates. The list of available
templates can be fetched automatically.
E-mails sent through SendGrid will be tracked using Sendgrid Webhook Events.

Installation
============
You need to install python-sendgrid v3 API in order to install the module.

If you're using a multi-database installation (with or without dbfilter option)
where /web/databse/selector returns a list of more than one database, then
you need to add ``mail_sendgrid`` addon to wide load addons list
(by default, only ``web`` addon), setting ``--load`` option.
For example, ``--load=web,mail_tracking,mail_sendgrid``

Configuration
=============

You can add the following system parameters to configure the usage of SendGrid:

* ``mail_sendgrid.substitution_prefix`` Any symbol or character used as a
prefix for `SendGrid Substitution Tags <https://sendgrid.com/docs/API_Reference/SMTP_API/substitution_tags.html>`_.
``{`` is used by default.
* ``mail_sendgrid.substitution_suffix`` Any symbol or character used as a
suffix for SendGrid Substitution Tags.
``}`` is used by default.
* ``mail_sendgrid.send_method`` Use value 'sendgrid' to override the traditional SMTP server used to send e-mails with sendgrid.
Use any other value to disable traditional e-mail sending. By default, SendGrid will co-exist with traditional system
(two buttons for sending either normally or with SendGrid).

In order to use this module, the following variables have to be defined in the
server command-line options (or in a configuration file):

- ``sendgrid_api_key`` A valid API key obtained from the
SendGrid web interface <https://app.sendgrid.com/settings/api_keys> with
full access for the ``Mail Send`` permission and read access for the
``Template Engine`` permission.

Optionally, the following configuration variables can be set as well:

- ``sendgrid_test_address`` Destination email address for testing purposes.
You can use ``odoo@sink.sendgrid.net``, which is an address that
will simply receive and discard all incoming email.

For tracking events to work, make sure you configure your Sendgrid Account with the correct Event Notification Url.
You can do it under 'Settings -> Mail Settings -> Event Notification '.
Set the URL to ``https://<your_domain>/mail/tracking/sendgrid/<your_database>``

Replace '<your_domain>' with your Odoo install domain name
and '<your_database>' with your database name.

Usage
=====

If you designed templates in Sendgrid that you wan't to use with Odoo:
* Go to 'Settings -> Email -> SendGrid Templates'
* Create a new Template
* Click the "Update" button : this will automatically import all your templates

In e-mail templates 'Settings -> Email -> Templates', you can attach a SendGrid template for any language.
You can substitute Sendgrid keywords with placeholders or static text like in the body of the e-mail.
The preview wizard now renders your e-mail with the SendGrid template applied.

From e-mails, use the "Send (SendGrid)" button to send the e-mail using Sendgrid.

.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/205/9.0

Known issues / Roadmap
======================

* Extend the features from SendGrid

Bug Tracker
===========

Bugs are tracked on `GitHub Issues
<https://github.com/OCA/social/issues>`_. In case of trouble, please
check there if your issue has already been reported. If you spotted it first,
help us smashing it by providing a detailed and welcomed feedback.

Credits
=======

Images
------

* Sengrid logo: `SVG Icon <http://seeklogo.com/vector-logo/289294/sendgrid>`_.

Contributors
------------

* Emanuel Cino <ecino@compassion.ch>
* Roman Zoller <rzcomp@gmail.com>

Maintainer
----------

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

This module is maintained by the OCA.

OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.

To contribute to this module, please visit http://odoo-community.org.
14 changes: 14 additions & 0 deletions mail_sendgrid/__init__.py
@@ -0,0 +1,14 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2015 Compassion CH (http://www.compassion.ch)
# Releasing children from poverty in Jesus' name
# @author: Roman Zoller
#
# The licence is in the file __openerp__.py
#
##############################################################################

from . import models
from . import wizards
from . import controllers
51 changes: 51 additions & 0 deletions mail_sendgrid/__openerp__.py
@@ -0,0 +1,51 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# ______ Releasing children from poverty _
# / ____/___ ____ ___ ____ ____ ___________(_)___ ____
# / / / __ \/ __ `__ \/ __ \/ __ `/ ___/ ___/ / __ \/ __ \
# / /___/ /_/ / / / / / / /_/ / /_/ (__ |__ ) / /_/ / / / /
# \____/\____/_/ /_/ /_/ .___/\__,_/____/____/_/\____/_/ /_/
# /_/
# in Jesus' name
#
# Copyright (C) 2015-2017 Compassion CH (http://www.compassion.ch)
# @author: Emanuel Cino, Roman Zoller
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################


{
'name': 'SendGrid',
'version': '9.0.1.0.0',
'category': 'Social Network',
'author': 'Compassion CH',
'website': 'http://www.compassion.ch',
'depends': ['mail_tracking'],
'data': [
'security/ir.model.access.csv',
'views/sendgrid_email_view.xml',
'views/sendgrid_template_view.xml',
'views/mail_compose_message_view.xml',
'views/email_template_view.xml',
],
'demo': [],
'installable': True,
'auto_install': False,
'external_dependencies': {
'python': ['sendgrid'],
},
}
13 changes: 13 additions & 0 deletions mail_sendgrid/controllers/__init__.py
@@ -0,0 +1,13 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch)
# Releasing children from poverty in Jesus' name
# @author: Emanuel Cino <ecino@compassion.ch>
#
# The licence is in the file __openerp__.py
#
##############################################################################

from . import json_request
from . import sendgrid_event_webhook
53 changes: 53 additions & 0 deletions mail_sendgrid/controllers/json_request.py
@@ -0,0 +1,53 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch)
# Releasing children from poverty in Jesus' name
# @author: Emanuel Cino <ecino@compassion.ch>
#
# The licence is in the file __openerp__.py
#
##############################################################################
import simplejson

from openerp.http import JsonRequest, Root, Response

# Monkeypatch type of request rooter to use RESTJsonRequest
old_get_request = Root.get_request


def get_request(self, httprequest):
if (httprequest.mimetype == "application/json" and
httprequest.environ['PATH_INFO'].startswith('/mail')):
return RESTJsonRequest(httprequest)
return old_get_request(self, httprequest)


Root.get_request = get_request


class RESTJsonRequest(JsonRequest):
""" Special RestJson Handler to enable receiving lists in JSON
body
"""
def __init__(self, *args):
try:
super(RESTJsonRequest, self).__init__(*args)
except AttributeError:
# The JSON may contain a list
self.params = dict()
self.context = dict(self.session.context)

def _json_response(self, result=None, error=None):
response = {}
if error is not None:
response['error'] = error
if result is not None:
response['result'] = result

mime = 'application/json'
body = simplejson.dumps(response)

return Response(
body, headers=[('Content-Type', mime),
('Content-Length', len(body))])
31 changes: 31 additions & 0 deletions mail_sendgrid/controllers/sendgrid_event_webhook.py
@@ -0,0 +1,31 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch)
# Releasing children from poverty in Jesus' name
# @author: Emanuel Cino <ecino@compassion.ch>
#
# The licence is in the file __openerp__.py
#
##############################################################################
import logging

from openerp import http
from openerp.addons.mail_tracking.controllers.main import \
MailTrackingController, _env_get

_logger = logging.getLogger(__name__)


class SendgridTrackingController(MailTrackingController):
"""
Sendgrid is posting JSON so we must define a new route for tracking.
"""
@http.route('/mail/tracking/sendgrid/<string:db>',
type='json', auth='none', csrf=False)
def mail_tracking_sendgrid(self, db, **kw):
try:
_env_get(db, self._tracking_event, None, None, **kw)
return {'status': 200}
except:
return {'status': 400}
18 changes: 18 additions & 0 deletions mail_sendgrid/models/__init__.py
@@ -0,0 +1,18 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2015 Compassion CH (http://www.compassion.ch)
# Releasing children from poverty in Jesus' name
# @author: Roman Zoller
#
# The licence is in the file __openerp__.py
#
##############################################################################

from . import mail_mail
from . import substitution
from . import sendgrid_template
from . import email_template
from . import email_lang_template
from . import email_tracking
from . import mail_tracking_event
29 changes: 29 additions & 0 deletions mail_sendgrid/models/email_lang_template.py
@@ -0,0 +1,29 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2016 Compassion CH (http://www.compassion.ch)
# Releasing children from poverty in Jesus' name
# @author: Emanuel Cino
#
# The licence is in the file __openerp__.py
#
##############################################################################

from openerp import models, fields


class LanguageTemplate(models.Model):
""" This class is the relation between and email_template object
and a sendgrid_template. It allows to specify a different
sendgrid_template for any selected language.
"""
_name = 'sendgrid.email.lang.template'

email_template_id = fields.Many2one('mail.template', 'E-mail Template')
lang = fields.Selection('_lang_get', 'Language', required=True)
sendgrid_template_id = fields.Many2one(
'sendgrid.template', 'Sendgrid Template', required=True)

def _lang_get(self):
languages = self.env['res.lang'].search([])
return [(language.code, language.name) for language in languages]

0 comments on commit c00876e

Please sign in to comment.