I am trying to send Email with Flask-Mail,
This is the link of tutorial: https://www.twilio.com/blog/2018/03/send-email-programmatically-with-gmail-python-and-flask.html
EMAIL_USER and EMAIL_PASSWORD are environment variables, so I try to modify ~/.bashrc file(sudo vim ~/.bashrc) and add relevant information into them (in PyCharm Terminal), but it doesn't work, that is, it cannot echo something.
How to solve this problem?
Here is the email sending code:
from flask import Flask
from flask_mail import Mail, Message
import os
app = Flask(__name__)
mail_settings = {
"MAIL_SERVER": 'smtp.gmail.com',
"MAIL_PORT": 465,
"MAIL_USE_TLS": False,
"MAIL_USE_SSL": True,
"MAIL_USERNAME": os.environ['EMAIL_USER'],
"MAIL_PASSWORD": os.environ['EMAIL_PASSWORD']
}
app.config.update(mail_settings)
mail = Mail(app)
if __name__ == '__main__':
with app.app_context():
msg = Message(subject="Hello",
sender=app.config.get("MAIL_USERNAME"),
recipients=["<example#gmail.com>"], # replace with your email for testing
body="This is a test email I sent with Gmail and Python!")
mail.send(msg)
After adding the variable to the .bashrc file you may need to restart your terminal to see it echo out. Try closing a reopening your pycharm terminal or pycharm itself.
Related
When sending any message via Flask-Mail, such as below, the last line with mail.send(msg) will also result in the mail headers and content being logged.
Message("Hello", sender="from#example.com", recipients=["to#example.com"])
msg.body = 'anything'
mail.send(msg)
As my mail may contain sensitive information, I want to disable this logging entirely. Yet, playing around with the logging module, I could not find a logger configured for Flask-Mail.
How do I disable logging in Flask-Mail?
Figured this one out:
Flask-Mail uses Python's smtplib to send mail. smtplib does not use the logging module, but it prints information for debugging to stderr.
smtplib includes following method:
def set_debuglevel(self, debuglevel):
"""Set the debug output level.
A non-false value results in debug messages for connection and for all
messages sent to and received from the server.
"""
self.debuglevel = debuglevel
If we use Flask-Mail, we can set this variable when we initialize our app like this:
app = Flask(__name__)
mail = Mail(app)
app.extensions['mail'].debug = 0
Any output is now suppressed.
I am an absolute beginner in chat bot. I am learning on my own and went on developing a very simple chat bot using Dialog flow. I have a python code for responding the request to my Dialog flow bot. I have enabled "webhook" in fulfillment and also enabled in "Intent".My ngrok url is http://ae3df23b.ngrok.io/. I have written a function in my python code which respond to ngrok which connects Dialog flow. Now problem is that It is showing error "404 not found" and The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again. Please help me guys. Thanks in advance.
My code is
#import necessary packages and libraries
import urllib
import os
import json
from flask import Flask
from flask import request
from flask import make_response
app=Flask(__name__)
#app.route('/webhook', methods=['POST'])
def webhook():
req=request.get_json(silent=True, force=True)
print("Request:")
print(json.dumps(req, indent=4))
res=makeWebhookResult(req)
res=json.dumps(res, indent=4)
print(res)
r=make_response(res)
r.headers['Content-Type']='application/json'
return r
def makeWebhookResult(req):
if req.get("result").get("action")!="interest":
return {}
result=req.get("result")
parameters=result.get("parameters")
name=parameters.get("Banknames")
bank={'SBI':'10%', 'HDFC Bank':'9%', 'Bank of Baroda':'11', 'Federal Bank':'8.9%', 'ICICI Bank': '11.5%'}
speech='The interest rate of '+ name + "is" + str(bank[name])
print("Response:")
print(speech)
return {
"speech":speech,
"displayText":speech,
"source":"BankInterestRates"
}
if __name__ == "__main__":
port=int(os.getenv('PORT', 80))
print("Starting app on port %d", (port))
app.run(debug=True, port=port, host='0.0.0.0')
I think you should use https://ae3df23b.ngrok.io/webhook. You are missing the path. Also, use https and generate a new ngrok URL and update the fulfilment.
Try using this format instead https://ae3df23b.ngrok.io/[replace-with-your-project-id]/us-central1/dialogflowFirebaseFulfillment
and make sure u start ngrok with port 5000 and host your functions with "firebase serve" command
I've been trying to deploy my kik api to heroku, but it just isn't working. I've set up my procfile, my requirements.txt file, my runtime.txt file, and it shows up on my machine as running fine. However, when I open the kik app on my phone and try to message the bot, the messages aren't sent and it is not echoing my message. By Using ngrok as a webhook, I was able to get the bot to work and echo the messages just fine. However, when I tried deploying to heroku, it didn't work at all. For reference, the kik bot is written using flask and the kik api, here is my code
from flask import Flask, request, Response
import os
from kik import KikApi, Configuration
from kik.messages import messages_from_json, TextMessage
app = Flask(__name__)
BOT_USERNAME = os.environ['BOT_USERNAME']
BOT_API_KEY= os.environ['BOT_API_KEY']
kik = KikApi(BOT_USERNAME, BOT_API_KEY)
config = Configuration(webhook=os.environ['WEBHOOK'])
kik.set_configuration(config)
#app.route('/', methods=['POST'])
def incoming():
if not kik.verify_signature(request.headers.get('X-Kik-Signature'), request.get_data()):
return Response(status=403)
messages = messages_from_json(request.json['messages'])
for message in messages:
if isinstance(message, TextMessage):
kik.send_messages([
TextMessage(
to=message.from_user,
chat_id=message.chat_id,
body=message.body
)
])
return Response(status=200)
if __name__ == '__main__':
# Bind to PORT if defined, otherwise default to 5000.
print('HI')
port = int(os.environ.get('PORT', 5000))
app.run(host='0.0.0.0', port=port)
Here is my requirements.txt
Flask==0.11.1
kik==1.1.0
gunicorn==19.6.0
Here is my runtime.txt
python-2.7.12
Here is my procfile
web: python bot.py
I set up the webhook variable to be the heroku URL. When I run the app locally, it seems to be running just fine.
Heroku local app
Any help is greatly appreciated.
I figured out the issue. I had set the wrong environmental variables for my heroku deployment, so it threw a keyerror because it couldn't find the key and stopped the process.
I am attempting to get an email sent to me any time an error occurs in my Flask application. The email is not being sent despite the handler being registered. I used smtplib to verify that my SMTP login details are correct. The error is displayed in Werkzeug's debugger, but no emails are sent. How do I log exceptions that occur in my app?
import logging
from logging.handlers import SMTPHandler
from flask import Flask
app = Flask(__name__)
app.debug = True
app.config['PROPAGATE_EXCEPTIONS'] = True
if app.debug:
logging.basicConfig(level=logging.INFO)
# all of the $ names have actual values
handler = SMTPHandler(
mailhost = 'smtp.mailgun.org',
fromaddr = 'Application Bug Reporter <$mailgun_email_here>',
toaddrs = ['$personal_email_here'],
subject = 'Test Application Logging Email',
credentials = ('$mailgun_email_here', '$mailgun_password_here')
)
handler.setLevel(logging.ERROR)
app.logger.addHandler(handler)
#app.route('/')
def index():
raise Exception('Hello, World!') # should trigger an email
app.run()
The issue was which logger the handler was added to. Flask uses the werkzeug logger to log exceptions during view functions, not the base app.logger. I had to register my handler with the werkzeug logger:
logging.getLogger('werkzeug').addHandler(handler)
In addition, I had to include the port in mailhost:
handler = SMTPHandler(
mailhost=('smtp.mailgun.org', 587),
fromaddr='Application Bug Reporter <$mailgun_email_here>',
toaddrs=['$personal_email_here'],
subject='Test Application Logging Email',
credentials=('$mailgun_email_here', '$mailgun_password_here')
)
I'm trying to send emails and below works perfectly fine if executed through the web server. However, when I try to send the task to Celery, I always get an Assertion Error returned telling me that "to" needs to be a list or tuple.
I don't want the emails to be sent via the web server as it will slow things down so if anyone can help me fix this, that would be greatly appreciated.
from celery import Celery
from django.core.mail import send_mail, EmailMessage
app = Celery('tasks', backend='amqp', broker='amqp://')
#app.task
def send_mail_link():
subject = 'Thanks'
message = 'body'
recipients = ['someemail#gmail.com']
email = EmailMessage(subject=subject, body=message, from_email='info#example.com', to=recipients)
email.send()
I'm not 100% sure why, but I made some changes and it now works with no errors.
I removed the import for send_mail and changed the name of the method from send_mail_link() to send_link(). I also restarted the Celery worker and now everything works as it should.
New code is:
from celery import Celery
from django.core.mail import EmailMessage
app = Celery('tasks', backend='amqp', broker='amqp://')
#app.task
def send_link():
subject = 'Thanks'
message = 'body'
recipients = ['someemail#gmail.com']
email = EmailMessage(subject=subject, body=message, from_email='info#example.com', to=recipients)
email.send()
Hopefully somebody in the future may find this helpful.