pimalaya / himalaya

CLI to manage emails
https://pimalaya.org
MIT License
3.17k stars 95 forks source link

Set up custom SMTP send command #351

Closed soywod closed 2 years ago

soywod commented 2 years ago

https://github.com/soywod/himalaya/discussions/177#discussioncomment-2298474

jarkkojs commented 2 years ago

For reference, this is how it works in Evolution: https://www.dropbox.com/s/r151wkp33y7480w/Screenshot%20from%202022-03-21%2006-19-42.png?dl=0

jarkkojs commented 2 years ago

@soywod I've kind of started working on this, so here's what I've planned.

Git has chosen the approach of having a single option:

[sendemail]
    smtpserver = /usr/bin/msmtp

On the other hand, mutt has a separate option:

set sendmail = "/usr/bin/msmtp"

The upside of Git approach is less ambiguity in semantics because both SMTP server and a send command cannot exist in the same configuration file. The downside is more ambiguity in the mean and purpose of the configuration option.

I'm leaning towards adding a new option smtp-host-cmd and sane defaults: if the configuration option exists for an account, it overrides smtp-host if they co-exists. Or should it be an error condition?

jarkkojs commented 2 years ago

I can prepare a PR but need to know first the preferable semantics for the user interface :-)

soywod commented 2 years ago

@soywod I've kind of started working on this

First of all, thanks for considering helping the project! I invite you to read the contributing guide. I just realize that this guide misses information about the branch to start from (development). I also invite you to check this discussion about where I plan to bring the tool in the nearest future.

The upside of Git approach is less ambiguity in semantics because both SMTP server and a send command cannot exist in the same configuration file. The downside is more ambiguity in the mean and purpose of the configuration option.

Backends got the same dilemma (https://github.com/soywod/himalaya/issues/344). Using the untagged enum was a mistake because it leads to helpless error messages when the config does not match anything. We should go for an adjacently-tagged enum, which can be resumed by:

It will break the API, but I'm OK with that. The tool is growing, breaking changes are unavoidable. Plus it did not reach the v1 yet, it is the good moment!

What do you think?

soywod commented 2 years ago

smtpserver = /usr/bin/msmtp

I just understood what you mean. The fact to use a path to an executable at the place of the smtp-server config entry. I'm not so fan because this will lead to some messy conditional stuff in the config parsing. I would like to keep it really simple and to let serde do the job as much as possible. I still highly consider the explicit way with an adjacently-tagged enum.

jarkkojs commented 2 years ago

@soywod I've kind of started working on this

First of all, thanks for considering helping the project! I invite you to read the contributing guide. I just

Yeah, I mean I just found about this. It kind of complements my mutt workflow (I'm a kernel maintainer so a great email workflow matters to me a lot), rather than replaces mutt :-) This kind of command-line interface is perfect when you're working on e.g. a patch set, but do not want to do a full context switch to email but still want to have full access to it. Thank you for making such a great program!

jarkkojs commented 2 years ago

I was thinking something along the lines of this.

SMTP:

sender-type = "smtp" # default

Sendmail:

sender-type = "sendmail"
sendmail-command = "/usr/bin/msmtp"

The 2nd is any command that is (semi)compatible with the command-line of the original sendmail program. smtp-* has effect when the sender type is SMTP, and sendmail-* for sendmail type.

sendmail is these days more like a "protocol" for piping an email to a command than the actual program that was called sendmail. I.e. himalaya speaks "sendmail", not SMTP, in this case by forming a compatible command-line, and piping the payload.

That's why I think that smtp and sendmail are better names than internal and script.

soywod commented 2 years ago

I understand your point. I was stuck to the fact that no matter if we use the Rust SMTP client or a script, it is still a SMTP client. Then sender-type makes sense.

To be in phase with https://github.com/soywod/himalaya/issues/344, I suggest the following:

# everything related to sending emails goes here,
# in contrast of having everything at the root level
# starting by `smtp-*`
[outgoing]
type = "smtp"
host =
port =
starttls =
insecure =
login =
passwd-cmd =

# does it make sense to have multiple types,
# one per tool (to maximize the compatibility)?
[outgoing]
type = "sendmail"
bin = "/usr/bin/sendmail"

[outgoing]
type = "msmtp"
bin = "/usr/bin/msmtp"

[outgoing]
type = "mailx"
bin = "/usr/bin/mailx"

# ...
jarkkojs commented 2 years ago

The layout you proposed makes sense but I would add just sendmail type for now. It has worked for Git, mutt and Evolution for years and people use msmtp, mailx, ssmtp, postfix etc. as a drop-in replacement for it. So as long as the structure is extensible I would focus solely on sendmail and consider anything else on request. Sendmail has such a strong legacy that you cannot realistically make an MTA that does not adhere to it.

jarkkojs commented 2 years ago

Maximizing compatibility should happen on-need basis but it is of course important to make design that allows to do it on need :-)

jarkkojs commented 2 years ago

Thanks, from that example I anyway fully understood how and why you would prefer adjacently-tagged enum :-) Makes a lot of sense.

soywod commented 2 years ago

The layout you proposed makes sense but I would add just sendmail type for now.

Alright, let's go for it! Thanks for your precious help. Let me know if you need help implementing this.

Just for info, the development branch is a bit "messed up" because of https://github.com/soywod/himalaya/issues/340. For now I just moved everything in a cargo cli workspace, but stuff needs to be extracted into the lib workspace. Maybe it could be a good occasion for you to develop it directly inside the lib workspace to limit future conflicts!

soywod commented 2 years ago

Added in the last release v0.6.1 :tada: you can set up the command using the sendmail sender:

sender = "sendmail"
sendmail-cmd = "your-command" # for eg. /usr/bin/msmtp