<repo_name>kmurata08/pubusub-sample<file_sep>/mailpubsub/requirements.txt
astroid==2.2.4
autopep8==1.4.3
cachetools==3.1.0
certifi==2018.11.29
chardet==3.0.4
Click==7.0
Flask==1.0.2
google-api-core==1.8.0
google-auth==1.6.3
google-cloud-pubsub==0.39.1
googleapis-common-protos==1.5.8
grpc-google-iam-v1==0.11.4
grpcio==1.19.0
idna==2.8
isort==4.3.12
itsdangerous==1.1.0
Jinja2==2.11.3
lazy-object-proxy==1.3.1
MarkupSafe==1.1.1
mccabe==0.6.1
protobuf==3.7.0
pyasn1==0.4.5
pyasn1-modules==0.2.4
pycodestyle==2.5.0
pylint==2.3.1
python-dotenv==0.10.1
pytz==2018.9
requests==2.21.0
rsa==4.7
six==1.12.0
typed-ast==1.3.2
urllib3==1.24.1
Werkzeug==0.15.3
wrapt==1.11.1
<file_sep>/mailpubsub/utils/sendgrid_utils.py
import sendgrid
from sendgrid.helpers.mail import Email, Content, Mail
from dotenv import load_dotenv
import os
import textwrap


def loadenv():
    dotenv_path = os.path.join(os.path.dirname(
        os.path.dirname(__file__)), '.env')
    load_dotenv(dotenv_path)


def get_api_key():
    loadenv()
    return os.environ.get('SENDGRID_API_KEY')


def send_mail(to_email, subject, message):
    sg = sendgrid.SendGridAPIClient(apikey=get_api_key())

    content_message = get_content_message(to_email, message)

    mail = Mail(
        Email('<EMAIL>'),
        subject,
        Email(to_email),
        Content('text/plain', content_message))

    response = sg.client.mail.send.post(request_body=mail.get())
    print(response.status_code)
    if response.status_code >= 400:
        return False

    return True


def get_content_message(to_email, message):
    content = textwrap.dedent('''
    {email}様

    フォームに入力いただきありがとうございます。

    {email}様の一言は、{message}です。
    ''').format(email=to_email, message=message).strip()

    return content
<file_sep>/mailpubsub/main.py
from flask import Flask, render_template, request, redirect, url_for
from utils.pubsub_utils import push_to_topic, pull_from_subscriber
from utils.sendgrid_utils import send_mail

import json

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')


@app.route('/mail/push', methods=['POST'])
def mail_push():
    push_data = {
        'email': request.form['email'],
        'subject': request.form['subject'],
        'message': request.form['message']
    }
    push_msg = json.dumps(push_data)

    # json形式でメッセージをPub/SubにPush
    push_to_topic(push_msg)

    return redirect(url_for('mail_push_done', message="mail jobを登録しました！"))


@app.route('/mail/push/done')
def mail_push_done():
    message = request.args['message']
    return render_template('notify.html', message=message)


@app.route('/mail/pull')
def mail_pull():
    def pub_callback(msg):
        data = json.loads(msg.data)

        # SendGridからメール送信
        send_mail(data['email'], data['subject'], data['message'])
        msg.ack()
        print('Pulled message.')

    # Pub/Subからメッセージを引っ張ってきて、コールバック
    pull_from_subscriber(pub_callback)
    return redirect(url_for('index'))


if __name__ == '__main__':
    app.debug = True
    app.run(host='0.0.0.0')
<file_sep>/mailpubsub/utils/pubsub_utils.py
from google.cloud import pubsub_v1
from dotenv import load_dotenv
import os


def loadenv():
    dotenv_path = os.path.join(os.path.dirname(
        os.path.dirname(__file__)), '.env')
    load_dotenv(dotenv_path)


def get_project_id():
    loadenv()
    return os.environ.get('PROJECT_ID')


def get_topic_name():
    loadenv()
    return os.environ.get('TOPIC_NAME')


def get_subscription_name():
    loadenv()
    return os.environ.get('SUBSCRIPTION_NAME')


def push_to_topic(msg):
    project_id = get_project_id()
    topic_name = get_topic_name()

    publisher = pubsub_v1.PublisherClient()
    topic_path = publisher.topic_path(project_id, topic_name)

    data = msg.encode('utf-8')
    publisher.publish(topic_path, data=data)
    print('Published message.')


def pull_from_subscriber(callback):
    project_id = get_project_id()
    subscription_name = get_subscription_name()

    subscriber = pubsub_v1.SubscriberClient()
    subscription_path = subscriber.subscription_path(
        project_id, subscription_name)

    subscriber.subscribe(subscription_path, callback=callback)
