Sending emails from silverbullet

Based on Custom search for v2 using git grep and answers, in the category “Because I can”, here’s a small tutorial to send emails from Silverbullet, assuming you already have some correctly configured SMTP relay host server.

  • make sure to have some flavor of sendmail on the machine/container running Silverbullet
    • I’m using a Docker container, so I’ve downloaded a release of GitHub - n0madic/sendmail: Standalone drop-in replacement for sendmail with direct send (it’s practical to have a statically linked binary, yay go), and linked it as a volume in the container: ./sendmail:/usr/bin/sendmail.
    • I’ve also had to set up the relayhost mode with an environment variable, in the docker-compose.yml: SENDMAIL_SMART_HOST=smtp.example.org:587
  • in your config, add a string value for from_email, that will be the sender email: from_email = "[email protected]"
  • use the following script:
command.define {
  name = "Send an email",
  run = function()
    local to = editor.prompt("To:")
    if to == nil then return end
    local subject = editor.prompt("Subject")
    if subject == nil then return end
    local content = editor.prompt("Content")
    if content == nil then return end

    local from = config.get('from_email')

    -- Write the content of the email into a temporary file.
    local run = function()
      shell.run('bash', { '-c', "rm -f /tmp/email.msg && touch /tmp/email.msg" })
      shell.run('bash', { '-c', "echo 'To: ".. to .."' >> /tmp/email.msg"})
      shell.run('bash', { '-c', "echo 'From: " .. from .. "' >> /tmp/email.msg"})
      shell.run('bash', { '-c', "echo 'Subject: ".. subject .."' >> /tmp/email.msg"})
      shell.run('bash', { '-c', "echo >> /tmp/email.msg"})
      shell.run('bash', { '-c', "echo '" .. content .. "' >> /tmp/email.msg"})
      shell.run('bash', { '-c', "echo '.' >> /tmp/email.msg"})
      shell.run('bash', { '-c', "cat /tmp/email.msg | sendmail " .. to })
    end

    local status, result = pcall(run)
    if not status then
      editor.flashNotification('error when sending email: ' .. result)
    end
  end
}

Now you have a command Send email that will allow sending oneliners to anyone. Yay. Silverbullet-based email client when?

Okay, don’t use this for realz, though; but maybe, maybe it can be used in some very specific contexts…

Implementation notes

  • I wish I could’ve used shell.spawn() to send the content of the email.msg file via stdin, instead of the series of bash -c "echo" hacks resulting in the same. But every call to send() would then result in Websocket not connected. Is this a regression, or a misconfiguration on my server, or…?
  • I’ve had to use a protected call (pcall), because while there was an error while running the final call to bash, I never saw it in the result return’s stdout or stderr; only saw the error in the browser’s developer console as a JS error, and that’s why I’ve used a pcall for this. Is this a bug?
1 Like

Haha I like it. You people do crazy stuff when handed the right/wrong tools :laughing:

2 Likes