Muks
Muks

Reputation: 63

using Flask Mail to send the rendered form

I am using flask_mail to send emails, while this works for text message, I need some help if i need to send a template itself (what does this mean: so I am rendering a report that contains multiple tables and a text area on the top with a submit button, once the user fills the text area and click on submit, I need flask to send the report containing table along with text data ).

This code fetches data from service now incident table

 def incident():


        service_now_url = SERVICE_NOW_URL
        request_str = req
        user = 'username'
        pwd = 'password'
        url = service_now_url + request_str

        headers = {"Accept": "application/json"}
        response = requests.get(url, auth=(user, pwd), headers=headers)

        json_str = response.json()

        records = json_str['result']



    return records

This code below is used for rendering the text field and the table.

@app.route('/submit', methods=['GET','POST'])
def submit():
    rec = incident()
    form = Description(request.form)
    shift = form.Shift.data

    return render_template('index.html', rec=rec, state=STATES, form=form)

So for sending the email so far, I have written the function below, this sends an email but with table header only and no data.

def send_email(shift):
    msg = Message(subject=shift ,recipients=['[email protected]'])
    msg.html=render_template('index.html')
    mail.send(msg)

I am not a Flask expert and still, in the learning phase, any help would be greatly appreciated.

@George thanks for your help, but this is not working, I have pasted below the html template with the modification suggested by you.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title> {{ title }} : Graph</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='style/main.css') }}">
    {% if sending_mail %}
<style>

    {{ get_resource_as_string('static\style\main.css') }}

</style>
{% endif %}
</head>
<body>

<form action="/submit">

    <p> {{ shiftsum }}</p>



<div align='left'>
<h1>Task</h1>
<table id="customers">

            <th>Task Number</th>


            <th>Description</th>

            <th>State</th>


            {% for records in rec %}
            <tr>
                <td>{{records['number'] }}</td>

                <td>{{records['short_description']}}</td>
                <td>{{ state[records['state']]}}</td>
            </tr>

            {% endfor %}

        </table>

</div>
 </form>

</body>
</html>

Upvotes: 0

Views: 3965

Answers (2)

Muks
Muks

Reputation: 63

@George thanks for your help, anyways I have found out what was the missing link here,

So the thing is most of the email client doesn't support CSS that are stored locally(this what I found out, could be other things as well), so I used inline CSS and that is working perfectly and now I can see all the formatting that has been done inline in the HTML Template while sending the email.

Upvotes: 0

George J Padayatti
George J Padayatti

Reputation: 898

Change the definition of send_email() to as given below,

def send_email(shift, rec, STATES):
    msg = Message(subject=shift ,recipients=['[email protected]'])
    msg.html=render_template('index.html', rec=rec, state=STATES)
    mail.send(msg)

And in the index.html make sure you enclose the form inside {% if form %} ... {% endif %} where ... indicates your form code.

I hope this helps.


Update (for fixing the missing css styles)

Add the following in your flask script below app = Flask(__name__) or in respective blueprint file,

def get_resource_as_string(name, charset='utf-8'):
    with app.open_resource(name) as f:
        return f.read().decode(charset)

app.jinja_env.globals['get_resource_as_string'] = get_resource_as_string

Add the following in the index.html

{% if sending_mail %}
<style>

    {{ get_resource_as_string('static/css/styles.css') }}

</style>
{% endif %}

Where static/css/styles.css should be replaced with path to your css file. If more than one css file is there, just add {{ get_resource_as_string('static/css/styles.css') }} for each one of them, with their respective path as argument of get_resource_as_string()

Make the following changes in send_email(),

def send_email(shift, rec, STATES):
    msg = Message(subject=shift ,recipients=['[email protected]'])
    msg.html=render_template('index.html', rec=rec, state=STATES, sending_mail=True)
    mail.send(msg)

I have added sending_mail=True as argument to the render_template() so whenever sending_mail is set, the render_template will add the content from the css files to the <style>...</style>.

I hope this fixes the missing css styles.

Upvotes: 1

Related Questions