How to pipe an email into Django? - django

I'm part of a two-man business selling LED glow toys and one aspect of this is handling support requests. I have a server running exim4 and DJango and have email working so that if a user sends an email to support#myhost.com I'm able to pick up the email and respond.
I'd like to develop something a bit tidier to keep track of the email chain for a particular support request.
To do this, I was thinking of piping the output of my email using a rule in my support email's filter:
pipe /usr/bin/email_to_django_script
What I'm unsure of is how best to go about the last step to actually turning the email content into something DJango can process.
What's the best method to do this? Would a script using curl -d be a sensible option or are there better / less convoluted ways?

You can pipe the output of the email server into a management command. As an example, I have a file /inquiries/management/commands/proc_email.py. I have a single Command class, and the handle() method gets most of the email from the environment, and the body of the email from STDIN:
from_email = strip_tags(os.environ.get('SENDER', None))
to_email = strip_tags(os.environ.get('RECIPIENT', None))
emailMessage = email.message_from_string(''.join(sys.stdin.readlines()))
There is other code in there, but that is how I get the important bits out of it. You can then pipe this into your ORM objects, and access it from the website at some later time.
This is then accessed through /path/to/project/manage.py proc_email.
Depending on your email server, you can also use plus addressing to insure replies come back to the same address. For example, I have my Reply-To headers set to inquiry+12345#whatever.com. The mail server (postfix) then dumps this into the environment under EXTENSION. If no number is supplied, I simply create a new Inquiry, instead of attaching to an existing one.

Not exactly a pure Django solution but I would recommend taking a look at Lamson Project. It's an email server written in Python that you can use to build email applications like what you are describing. I can also integrate with the Django ORM. http://lamsonproject.org/docs/hooking_into_django.html

Related

Scrapy. How to return request results to calling method? Can I use python requests library inside scrapy?

I have Scrapy spider that runs well.
What I need to do is make an API call from inside parse method and use results from response in the same method with the same items. How do I do this? The only simple thing comes to mind is use python requests library but I am not sure if this works in scrapy and moreover at scrapinghub. Is there any built in solution?
Here is an example.
def agency(self, response):
# inspect_response(response, self)
agents = response.xpath('//a[contains(#class,"agency-carousel__item")]')
Agencie_Name = response.xpath('//h1[#class = "agency-header__name"]/text()').extract_first()
Business_Adress = response.xpath('//div[#class = "agency-header__address"]//text()').extract()
Phone = response.xpath('//span[#class = "modal-item__text"]/text()').extract_first()
Website = response.xpath('//span[#class = "modal-item__text"][contains(text(),"Website")]/../#href').extract_first()
if Website:
pass
# 1 send request to hunter io and get pattern. Apply to entire team. Pass as meta
# do smth with this pattern in here using info from this page.
So here i normaly extract all info from scrapy response, and if Website variable is populated I need to send api call to hunter io to get email pattern for this domain and use it to generate emails in the same method.
Hopes that makes sence.
As for vanilla scrapy on your own PC / server, there is no problem accessing third party libraries inside a scraper. You can just do whatever you want, so something like this is no problem at all (which would fetch a mail address from an API using requests and then send out a mail using smtplib).
import requests
import smtplib
from email.mime.text import MIMEText
[...]
if Website:
r = requests.get('https://example.com/mail_for_site?url=%s' % Website, auth=('user', 'pass'))
mail = r.json()['Mail']
msg = MIMEText('This will be the perfect job offer for you. ......')
msg['Subject'] = 'Perfect job for you!'
msg['From'] = 'sender#example.com'
msg['To'] = mail
s = smtplib.SMTP('example.com')
s.sendmail('sender#example.com', [mail], msg.as_string())
However, as for scrapinghub I do not know. For this, I can just give you a developer's point of view, because I also develop a managed scraping platform.
I assume that sending a HTTP(S) request using requests would not be any problem at all. They do not gain security by blocking it, because HTTP(S) traffic is allowed for scrapy anyway. So if somebody would want to do harmful attacks with requests through HTTP(S), they could just call the same requests with scrapy.
However, SMTP might be another point, you'd have to try. It's possible that they do not allow SMTP traffic from their servers, because it is not required for scraping tasks and can be abused for sending spam. However, since there are legitimate uses for sending mails during a scraping process (e.g. errors), it might as well be possible that SMTP is perfectly fine on scrapinghub, too (and they employ rate limiting or something else against spam).

Postfix header_check for multiple recipients

I have some development and test servers, that are only used for internal testing and development, but they often use setup from live solutions, including email addresses of customers and customers customers.
I would like to avoid the dev-solutions sending emails to customers, but allow them to send emails to developers, so that they can test the email part of the solution. I have tried a header_checks rule like this:
/^To:.*#(myowndomaion.com|myotherdomain.com|athirddomain.net)/ DUNNO
/^To:.*#/ REDIRECT mytestemail#myowndomain.com
And this works fine. If I send an email to test#gmail.com it will be forwarded to mytestemail#myowndomain.com and not be sent to test#gmail.com. But if I however send an email to myuser#myowndomain.comit will be send straight to the correct user. That is all fine.
The problem arises if I send emails to several email addresses!
So, if I send an email to test#gmail.com and myuser#myowndomain.com in the same email, they will both get the email (which they should not). The order does not matter, both will get emails in both cases.
So, does anyone have a better regex or some other better way to solve this?
Note: We use Postfix on Debian. (pretty standard Debian 6 and Debian 8)

Override mail settings in application for dev server environments

I am currently in the finishing stages of building an application and have asked the user group to perform production-level usage testing on the application. My application is a makeshift order management system that sends an email to a customer when an order is saved that includes an invoice.
I ran into a problem yesterday when I was doing some testing; this environment currently contains production-quality data, including old customer records. I processed a few orders and forgot about the functionality, and the customer who I did the orders for received emails saying the order is complete. Good that it worked, bad that it lead to this confusion.
The action I would prefer would be to set something somewhere within the application that forces all emails, regardless of the to recipient, to be sent to a specific address, though I would settle for simply being able to turn it off for this application alone. Turning it off on the server level is available not a preferred option due to the need to perform testing on other applications that process email, but are not populated with production-quality data.
Are there any specific flags or code I can use to override server settings in the application to only send email to a certain address based on how we identify our environment, or to not send email altogether?
Reference this page:
http://cookbooks.adobe.com/post_How_can_I_use_Application_level_SMTP_Server_Settin-16469.html
For testing purposes you could set the SMTP server to a non existant IP address. The cfmail routine will still work and coldfusion will move it to an undeliverable folder.
You could add <cfif> statements around it to determine if your on a production URL or dev URL so that it uses the right server while on the production server, or uses the "fake" server while on your development server. OR while on the production server, have an on/off variable that you could use to test emails through your smtp server or shut off emails and route them to the fake SMTP server.
If your on version 8.0 or older, you can setup an application level variable for your mail server and modify your cfmail tags to reference:
<cfmail server="#application.mailserver#" to="" from="" subject="">
This solution presumes you use the same mail server but just want to swap emails to a test address (perhaps yours, so you can see the result). It also presumes your live server name resolves to something that has 'www.something.somethong.' and your dev/test/qa etc servers do not.
In your Application cfc onApplicationStart() try this:
<cfscript>
if(listFirst(CGI.SERVER_NAME,'.') != 'www') {
Application.szEmailToTestEnv = 'test#somewhere.com'; // Use your test email here
}
</cfscript>
Then where you send the email have a bit of logic infront of your mail param such that:
<cfscript>
if(isDefined('Application.szEmailToTestEnv') && len(Application.szEmailToTestEnv)) {
Variables.szEmailTo = Application.szEmailToTestEnv;
} else Variables.szEmailTo = Variables.qCustomerEmail;
</cfscript>
And then in your cfmail:
<cfmail to="#Variables.szEmailTo#"....
Adjust scopes and variable names and value as necessary.
Essentially, any 'site' (say dev.yoursite.com) that is not your live site will then use the test email you set at app startup to send the email and live will continue to use the correct customer email with no code changes between your live and test code.

How do I intgrate Django and XMPP-over-BOSH

I need some advice on setting up an environment that is based on Django and XMPP.
My site has two parts.
Part A: users use an in-browser XMPP client, like Strophe.JS on a page that si served through Django.
Part B: Used by a different set of users to communicate with users who're communicating using the part A of the site. Users here will also use an in-browser XMPP client, like Strope.JS on a page that is server through Djano.
Since the communication happens in-browser, I'll not using a real XMPP stream but XMPP over BOSH. I've read that XMPP over BOSH is the de-facto way of transport XMPP messages over HTTP interfaces.
The solution for Part A is simple. A regular web-page with the Strophe.JS library thrown in. The difficult part for me seems to be figuring out how to handle the users of Part B. I need to relay XMPP messages between the Part A users and Part B users. The Part B users, need to able access information from the Django system for the user of Part A. I would need pretty good integration between XMPP and Django.
Could someone tell me how I would write a system like this? What tools would I use? Would a I use a stand alone XMPP server and integrate it to Django? If so, what? When a user on Part A initiates a chat session, it will show up on user of Part B of the site but which user will handle the chat request of the user will depend on some information retrieved from Django.
Thanks in advance everyone.
You'll definitely need stand alone Jabber/XMPP server (e.g. ejabberd). I'll make a wild guess that Part A users communicate within chat room A (MUC), and the same users in Part B communicate within chat room B. You need to write 3 scripts/daemons (I use perl and Net::Jabber (Net::XMPP can not join MUC)). They would be: scripta, scriptb, mediator.
script/daemon A will join the MUC room A, while mediator being part of it's roster. It will listen to all message stanzas but will react only to some (e.g. message stanza with body "SendToB MSG"). This message is sent by user that has joined chat room A. Then "RelayToB MSG" should be sent to mediator by scripta (From: scripta#jabberserver.dom, To: mediator#jabberserver.dom). The mediator will send the "RelayFromA MSG" to MUC B based on "RelayToB" part of the message stanza body. scriptb will receive "RelayFromA MSG" and will send "MSG" to chat room B.
script/daemon B (the same logic) with mediator#jabberserver.dom being in users roster.
mediator will not join any chat room. It will have scripta#jabberserver.dom and scriptb#jabberserver.dom in it's roster. It will only relay messages between the chat rooms.
I have already posted sample code here How to create a jabber/XMPP proxy/logging service?. The code will apply scripta/b. The code is rather long, and make sure you check InMessage and InPresence subs. Other stuff concerns my needs.
I hope I was clear enough. Don't hesitate to ask more questions.
EDIT:
Create script using perl and Net::Jabber. The user that will login to XMPP server will be mediator#jabberserver.dom. Everyone will be able to send messages to him. The mediator will forward messages to the support person in format (From:user1 MSG). Support person will reply to mediator#jabberserver.dom with the message (Reply:user1 REPLY). The mediator will forward REPLY to user1.
Check mod_shared_roster here http://www.ejabberd.im/shared-roster-all (example 4) and here http://www.process-one.net/docs/ejabberd/guide_en.html#htoc61.
I think that the 2-nd solution will require no additional coding apart from javascript/strophe code in your page.

Django Email backend (keeps sending email from incorrect "sender")

I have several instances in my project where I attempt to send an email within a Django view.
I want to be able to hardcode the email sender within the view. When I try to do so, though, it continues to send the emails from the default account specified in my settings file.
Here is an example:
if testform.is_valid():
beta=testform.save()
subject="Hi Beta Tester"
sender="correct#email.com"
recipient=[testform.cleaned_data['email']]
text=loader.get_template('registration/beta_email.txt')
html=loader.get_template('registration/beta_email.html')
site_name='mysite'
d=Context({'site_name':site_name})
text_content=text.render(d)
html_content=html.render(d)
#This sends two mail versions, plain text and html
msg=EmailMultiAlternatives(subject, text_content, sender, recipient)
msg.attach_alternative(html_content, "text/html")
msg.send()
return HttpResponseRedirect('/splash/')
I thought that I could send specify the sender argument explicitly here. And, yet, when I test it, the email is being sent from the address listed in my settings file, configured as the following:
EMAIL_USE_TLS=True
EMAIL_HOST='smtp.gmail.com'
EMAIL_HOST_USER='wrong#email.com'
EMAIL_HOST_PASSWORD='private'
DEFAULT_FROM_EMAIL='wrong#email.com'
Do I just have to remove the DEFAULT_FROM_EMAIL constant to make it work? I tried doing so and it seems to be working but I'm confused. In the Django documentation, it suggests that setting sender in the view should override the DEFAULT.
I've finally figured out the issue here. Unfortunately, gmail rewrites the from and the
envelope on authenticated smtp.
If you want to get around that, you have to use a third party mail server (which doesn't act like such a prissy) and then send mail to gmail users.
For the sender e-mail try putting it in < > and you can add a name:
sender = "Formal Name <correct#email.com>"
that is exactly the syntax I have in my e-mail sending view and it works.
There really shouldn't be a reason that adding the name to it would change how it's sending, but it may be worth trying and perhaps you want an easily readable name anyway.