9 ms·
Mailit: A Tiny Drop-In REST API to Send Emails
- bmn__ 9y agoThere are no hypermedia controls. This isn't REST, merely HTTP (with tight and brittle coupling).
- bjpbakker 9y agoIt migt be just me, but I honestly don't understand why people would use an HTTP API to send mail. SMTP really is a very simple protocol, that's matured for decades now. Also it is fully specified by RFCs. I can see why mail services that provide templating (eg Mandrill) have special APIs, they offer something different from sending regular emails. This specific REST API seems more like a standin for sendmail, which IMO makes things only more complicated.
- icebraining 9y agoPlaying Devil's advocate: SMTP has some back-and-forth stateful chatter. With a custom HTTP API, you can authenticate and send an email in a single request. SMTP Pipelining can reduce this problem, but not all libraries support it (e.g. Python's smtplib).
- mariusmg 9y ago>SMTP has some back-and-forth stateful chatter. So what ? Is not like you implement the SMTP protocol into your application to send emails. Any language under the sun has a SMTP implementation exposed as a library.
- jsudhams 9y agoAnother reason i would do is , i have only port 80/443 allowed outside my network. so using https api helps with that
- Rjevski 9y agoWhy is that? What security does it provide? This very project just demonstrated that you can send pretty much anything in HTTP(S) so any malware (I presume) you're trying to defeat can do the same.
- ctrlrsf 9y agoSpam malware can scan IPs to find open SMTP ports to send spam so some ISPs and hosting providers lock down these ports to avoid getting their IPs blacklisted when a compromised host starts sending a bunch of spam through an open relay. I can see this being used to send email out from some restricted hosting providers.
- icebraining 9y agoIt's slower, which is important when you're trying to push a lot of emails. If you keep the TLS connection open, sending an HTTP request is very fast. Waiting for the roundtrips of that chatter reduces the throughput, especially on higher latency links.
- bjpbakker 9y ago> If you keep the TLS connection open, sending an HTTP request is very fast. Waiting for the roundtrips of that chatter reduces the throughput, especially on higher latency links. I agree that for a high load of sending email it can be beneficial to use an intermediate service. IMO a local sendmail is still preferred, but I see your point. However, the Mailit service makes the client wait on the SMTP traffic too [1]. So with this particular service you now have to wait for both SMTP /and/ HTTP communication. Doesn't really speed thinks up :) [1] https://github.com/dthree/mailit/blob/master/src/routes.js#L119 https://github.com/dthree/mailit/blob/master/src/routes.js#L...
- icebraining 9y agoHowever, the Mailit service makes the client wait on the SMTP traffic too [1]. So with this particular service you now have to wait for both SMTP /and/ HTTP communication. Doesn't really speed thinks up :) That depends, you could host the Mailit service in the same machine as the email server, which your application instances on other machines would call. This could be useful if you have multiple machines but only want to run a single email server.
- joantune 9y agoWe have configured at work an intermediate postfix for this effect, but it takes a bit to learn how to configure it So I can see the benefits of this approach
- deleted 9y ago[deleted]
- kowdermeister 9y agoI've looked at setting up sendmail as a "LAMP guy" and I said nope nope nope, just use mailgun.
- pmlnr 9y agoSendmail is everything but simple. The question was SMTP in general, which indeed is an extremely simple protocol. Here, this is how you send a plain text* mail in python: https://petermolnar.net/not-mime-email-python-3/ https://petermolnar.net/not-mime-email-python-3/ Using an HTTP API for this is a massive overkill. * I'm aware using utf-8 like this may confuse older clients but I didn't have problem with anything relatively modern I tested the receiving on.
- kowdermeister 9y agoSending is not the tricky part, implementing it right is probably another story. I wouldn't call it massive overkill. REST is extremely simple as well. You have to make an request anyways so it's just a question of preference how you connect to that the email sending service.
- pmlnr 9y ago> I wouldn't call it massive overkill. You're running a web server to emulate telnet. It's a massive overkill.
- bjpbakker 9y ago> implementing it right is probably another story Do you implement your own HTTP communication every time you need it or do you use a library? Just as for HTTP there are many good libraries for SMTP communication that you can easily use. No need to roll your own.
- beaconstudios 9y agonowadays you have the option of using postfix+dovecot, which for me at least seems to be a lot easier.
- 9y ago
- z3t4 9y agoFor example to make it possible for a static (client only) web app to send mail. Watch out for spammers though! It should be secure by default, because most people either don't care or don't know how to change the defaults!
- pmlnr 9y agoGmail is IMAP and SMTP, and Google Talk is (or was) XMPP, all on port 80 in the same browser window. Others are more metaphorical. Twitter is IRC on port 80, although one primarily listens to users instead of channels — but listening to channels is still possible, if one uses a client that can follow hashtags, and the syntax is even the same. Dropbox is FTP on port 80. Reddit is Usenet on port 80. https://medium.com/@maradydd/on-port-80-d8d6d3443d9a https://medium.com/@maradydd/on-port-80-d8d6d3443d9a
- lugg 9y ago> SMTP really is a very simple protocol, that's matured for decades now. Also it is fully specified by RFCs. So simple and so mature it needs an RFC. I'll take the http API I can figure out in 10 seconds because I make API requests all day over some ancient tech I don't even want to begin to understand. Does that make me lazy and a shit developer? Probably. Do I care. Definitely not.
- GordonS 9y agoHaving an RFC hardly means it's not simple; it means it has a well-defined specification. Do you actually think HTTP isn't specified in an RFC?
- w458cmau 9y agoI want to send mails from embedded devices, similar to e.g. an ESP8266, with intermittent connectivity and a semi-stable power source. An HTTP API seems simpler for me to interface with than SMTP.
- zAy0LfpBZLC8mAC 9y agoI can't comment on what seems simpler to you, but ... what does intermittent connectivity have to do with whether you transmit the email via SMTP or via HTTP?
- bjpbakker 9y ago> what does intermittent connectivity have to do with whether you transmit the email via SMTP or via HTTP SMTP uses a stateful connection where HTTP is basically a single request/response. I.e. the device can close the HTTP connection after a single roundtrip where SMTP requires waiting for server responses after commands and then continuing the request. Not sure if it's simpler on those devices to use an HTTP interface (because HTTP requires a bit more overhead data) but it might be simpler, sure.
- zAy0LfpBZLC8mAC 9y agoHTTP runs on top of TCP, which already gives you at least two round trips. Also, if it's a device that's connected via the public internet, you probably should be using TLS, which gives you a couple more round trips. Really, realistically, if your internet connectivity is too bad to support SMTP, it most likely won't work for HTTP either, and you probably should be using some custom UDP thingy with an appropriate retry strategy.
- vinaysshenoy 9y agoWe were sending email via SMTP from our Android apps for a while until we ran into quite a few cases where SMTP was blocked at the router level. We had to move to HTTP mailing to let the mails go through.
- BrandoElFollito 9y agoFor instance to send messages from client only web applications where the only thing you have is an AJAX call.
- Michielvv 9y agoIn our case the reason we switched from SMTP to an HTTP API was mostly speed. At least for Sendgrid, their HTTP API is much faster than SMTP. In general I agree that I'm not seeing a big advantage in having another service to keep up and maintain, just to wrap SMTP.
- sleepychu 9y agoIs this authless? You just send mail as the account configured and anyone can send mail?
- bjpbakker 9y agoI haven't tried it myself (and won't) but given this section "Passing Secrets" in the README [1] I dont think its authless. [1] https://github.com/dthree/mailit/blob/master/readme.md#passing-secrets https://github.com/dthree/mailit/blob/master/readme.md#passi...
- icebraining 9y agoThose secrets are for Mailit itself to connect and authenticate against the email server.
- carl_dr 9y ago> This service defaults to no authentication.
- beefhash 9y agoThat default really did not work out well for MongoDB[1]. Why are we perpetuating this mistake? [1] https://www.bleepingcomputer.com/news/security/mongodb-apocalypse-professional-ransomware-group-gets-involved-infections-reach-28k-servers/ https://www.bleepingcomputer.com/news/security/mongodb-apoca...
- thesorrow 9y agoThe total opposite of this project would be way more useful : A sendmail replacement that can call a REST / Webhook endpoint. You'll get free alerting directly from crontab/smartd/zfs to your monitoring / logging system
- beagle3 9y agoKenneth Reitz's inbox.py does 99% of that for you. Just add a call to requests (also by reitz) and you are good.
- azifali 9y agoI wouldn't add another HTTP layer for a functionality that is within my own app / network, unless I were to expose this as a service for outside the network as a service. I would think that this is bad design - call a http service that wraps smtp, when pretty much every language has an SMTP client.
- chrismatheson 9y agoI really like this library (from a conceptual level) id love to see more "drop in" API's, rather than proxying to a bunch of other services.
- csomar 9y agoI really like this approach. Let's say you want to build a first beta. You are going to use your own server for sending mail to reduce costs and also not introduce dependencies early on. There are two ways to do it: 1. Call the SMTP library like some here suggested. 2. Create your own encapsulation of the SMTP functionality, and call these functions to send email. It is obvious why you want to use 2. But, from experience, it makes your code base bigger and debugging more problematic. By using a Docker container, you are separating matters: Now sending emails is a small service that can scale in the future, but doesn't consume lots of resources today. With a docker/rest api, it also means that have you decided to switch to Mailchimp in the future; it'll be an easy task. You don't have to go through all your code and look which parts send emails and update them. You don't have to update your library encapsulation. You don't have to redeploy your whole instance to update the code. All you do is create a new docker instance and then shutdown the old one. Tada!
- bjpbakker 9y agoFor a first beta (MVP?) I would strongly advice against using your own mail server. It takes a while for a server to build up a reputation, hence mails from an "unknown" server are quicker marked as spam (especially by common services like gmail and outlook). Instead configure a local sendmail (so you have all the benefits of local mail delivery, like queuing and availability so on) to relay through your provider's mail servers.
- askz 9y agoMailIt doesn't provide a SMTP server. Instead it takes your existing SMTP settings, so you can take the advantage of your existing reputation, or your provider's one. (assuming you already have an email account somewhere, and it can be gmail, outlook, [popularprovider]...)
- StavrosK 9y agoI don't really understand what you gain from this. SMTP is much more widespread than this API. If you want to migrate to a service later on, all you need to do is change the hostname to that service, how much easier is it to have to babysit a service in a container?
- mike-cardwell 9y agoCould do with an end-point to do some basic validation of email addresses. I.e a syntax check, and also a DNS check to make sure that the domain has MX or A/AAAA records, and potentially a check to make sure that there is an SMTP server listening at the destination on port 25. Perhaps all 3 of those things configurable at request time.
- zAy0LfpBZLC8mAC 9y agoThe latter is a terrible idea: Mail servers as well as networks can and do fail temporarily, that should not prevent you from sending emails to addresses hosted on those servers, that is exactly what MTA queuing is there for.
- mike-cardwell 9y agoI'm not going to make assumptions about other peoples use cases. If your use case demands that an email be immediately accepted, then the idea is not necessarily terrible. Regardless, that's why I said it should be configurable.
- zAy0LfpBZLC8mAC 9y agoBut it doesn't give you that guarantee. Just because you can connect now, does not mean you can actually send an email later, let alone that particular email. If you want that, then you should provide feedback whether the email that you want to send actually was accepted by the destination server. But even that is probably not a sensible idea: Just because the MX accepted the messages does not in any way guarantee that it will actually be delivered immediately.
- mike-cardwell 9y agoNothing you've said is non-obvious. What if the thing you want to do is not "send an email", but is: "test if an address is likely to be able to receive an email". Could you conceive of a scenario where a message pops up to a user stating: "It looks like you may have entered your email address incorrectly. Are you sure it is ok?" I'm sure there are lots of use cases. Just because you can't think of one does not mean that none exist.
- blablubbla 9y agoWe wrote a similar service in Erlang [1] which is used for bug reporting of client side software (since most corporate networks block outgoing SMTP). [1] https://gitHub.com/lindenbaum/http2smtp https://gitHub.com/lindenbaum/http2smtp
- omi 9y agoREST version of sendmail... what could go wrong.
- kwhitefoot 9y agoThe example in the readme uses curl to send an email. But curl can already send email through SMTP directly. I'm sure the author has a good reason for creating this but it needs a better example.
- Tepix 9y agoGood catch. I suppose it's because curl seems to be the standard tool when showing an example for a REST API.
- avenoir 9y agoIs there some kind of a template out there to create the API documentation used by this project?
- homero 9y agoLike a reverse ssmtp?
- jitix 9y agoLove the idea.. although we can call SMTP directly, having the SMTP APIs encapsulated with a HTTP interface is pretty neat. Plus its a readymade microservice that you just spin up and use. I worked for 2 years on a monolith that used to call SMTP directly and it was a pain to debug.
- Tepix 9y agoBuilt this for a hackathon the other day. The ability to send email attachments is a must.
- deathanatos 9y agoI've worked with APIs like this. The email gets more complicated, and inevitably, the API starts breaking down. E.g., with this API, how do I send attachments? To essentially every email endpoint in the world, I always end up wondering: why is there not just an endpoint: POST /email?from=<sender>&to=<recipient1>&to=<recipient2> Content-Type: message/rfc822 … the actual email to send, encoded according to RFC 822. I.e., an email. i.e., these endpoints conflate two tasks: building the email and transmitting the email. I'm fine with simple helper methods like those offered, but once things reach their inevitable complexity (because lets face it, I'm sending an email designed by marketing. It's got tons of inline images and shiny design stuff…, and maybe an attachment) I really just want a "transmit this email to these people" endpoint. (Of course, this starts to very much resembled SMTP. I'm frankly okay with the above: I have tons of readily available tooling for HTTP, and I understand how TLS works and doesn't with it. But I do also understand why some might balk at this with a "that's just SMTP!") (And just to note: I don't want to trivialize building an email. Email's format is super complex. But I have in my standard library a module that handles that for me…)