Hi fellow self-hosting lemmings,

In an SME setting, I’m looking for a service to regularly fetch mails from an IMAP server and print incoming mails and attachments on a local network printer based on rules (e.g., only print mails where the subject contains a specific word.)

Does a solution like that exist, ideally with a browser frontend to set it up?

Thank you!

    • @[email protected]OP
      link
      fedilink
      English
      111 months ago

      Thanks for the reply. I don’t think I fully understand what you mean.

      What I would like to have is a service running on a server, fetching and printing mails. Could you please elaborate how your idea would work?

      • @[email protected]
        link
        fedilink
        English
        4
        edit-2
        11 months ago

        … forget it. I was about to write a long-winded answer, that you can use usual cli mail softare to fetch the eml or msg files (mails) and use the tool on them and then send the pdf to the printers (most printers use pdf internally). But then i remembered that this would be the perfect job for a python script.

        But, uh, wouldn’t you better just save the mails instead of printing them? Environment and cost and so on.

        • @[email protected]OP
          link
          fedilink
          English
          311 months ago

          Gotcha. Thanks anyway. 🙂

          You’re right about printing not being all that, but certain situations (my situation) call for it, at least for the time being.

          This is for manufacturing orders in a low tech environment, and at this point in time I need to stick with a paper trail (so I can get rid of it in the future.)

  • @ikidd
    link
    English
    2
    edit-2
    11 months ago

    You might use Node Red with this node to obtain the attachments, then send to an IPP printer with this node.

    • @[email protected]OP
      link
      fedilink
      English
      2
      edit-2
      11 months ago

      Now this is an idea I like. Thank you so much, I never would have considered Node-RED for this application!

      • @ikidd
        link
        English
        111 months ago

        BTW, if you do end up using this method, I’d love to see your implementation some day. Node Red is so useful and intuitive IMO, and people sharing their solutions is valuable.

        • @[email protected]OP
          link
          fedilink
          English
          2
          edit-2
          11 months ago

          One deep dive into the IPP protocol, printer drivers, and specific supported formats (“what the hell is an octet-stream?!”) later, I have something functional.

          I’m not a JS guy, so I don’t know if it’s a very node-y way to do it. But except for the pages coming out a little scaled this works:

          Edit to briefly explain what this does: The mail node ingests unread emails and passes them forward to a function node that checks for pdf attachments. Those are passed forward one by one to a function node that takes care of converting the pdf to pcl (my printer supposedly knows how to handle pdf 1.7 but doesn’t, so I had to resort to this) and passes it to the IPP node as a data buffer .

          spoiler

          [ { "id": "86082bed0ed29155", "type": "IPPrint", "z": "08cc7c15668f2f65", "name": "Print to Network", "IP": "10.10.0.19:631/ipp/print", "JOB_name": "default_job_name", "authuser": "", "authpassword": "", "authcheck": "", "x": 780, "y": 120, "wires": [ [ "b1a8b92ede8a78a5" ] ] }, { "id": "b1a8b92ede8a78a5", "type": "debug", "z": "08cc7c15668f2f65", "name": "debug 1", "active": true, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 960, "y": 120, "wires": [] }, { "id": "1fb7fc3843af8e05", "type": "function", "z": "08cc7c15668f2f65", "name": "Convert PDF to PCL", "func": "const baseOptions = {\n width: 2480,\n height: 3508,\n density: 300,\n preserveAspectRatio: true,\n format: 'PCL'\n};\n\n// prepare conversion function\nconst convert = await pdf2pic.fromBuffer(msg.payload, baseOptions);\n// set additional conversion options\nconvert.setGM\n// bulk convert the whole input buffer to a pcl output buffer\nconvert.bulk(-1, {responseType: \"buffer\"}).then((outputs)=>{\n // pass each page on to the printer\n outputs.forEach((output, index) => {\n msg.payload = output.buffer;\n if(msg.topic){\n let jobname = msg.topic\n }\n msg.JOBName = (msg.topic ? msg.topic : \"Mailjob\").concat(\" \", index+1, \"/\", outputs.length);\n msg.docFormat = \"application/octet-stream\";\n node.send(msg);\n });\n});\n", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [ { "var": "pdf2pic", "module": "pdf2pic" } ], "x": 560, "y": 120, "wires": [ [ "86082bed0ed29155" ] ] }, { "id": "224317e794da3cb5", "type": "e-mail in", "z": "08cc7c15668f2f65", "name": "Mail ingest", "protocol": "IMAP", "server": "test.mail.com", "useSSL": false, "autotls": "always", "port": "143", "authtype": "BASIC", "saslformat": true, "token": "oauth2Response.access_token", "box": "INBOX", "disposition": "Read", "criteria": "UNSEEN", "repeat": "300", "fetch": "auto", "inputs": 0, "x": 160, "y": 80, "wires": [ [ "2fedaa18c9394b89" ] ] }, { "id": "2fedaa18c9394b89", "type": "function", "z": "08cc7c15668f2f65", "name": "PDF Filter", "func": "if(msg.attachments.length > 0){\n msg.attachments.forEach(function(attachment) {\n if(attachment.contentType == \"application/pdf\"){\n var newmsg = {};\n newmsg.topic = msg.topic;\n newmsg.filename = attachment.filename;\n newmsg.payload = attachment.content;\n node.send(newmsg);\n }\n });\n}", "outputs": 1, "timeout": 0, "noerr": 0, "initialize": "", "finalize": "", "libs": [], "x": 360, "y": 80, "wires": [ [ "1fb7fc3843af8e05" ] ] }, { "id": "3d8f7ad8e6b56d46", "type": "inject", "z": "08cc7c15668f2f65", "name": "Test print", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "payload": "", "payloadType": "date", "x": 160, "y": 160, "wires": [ [ "683ed6fe7c10540d" ] ] }, { "id": "683ed6fe7c10540d", "type": "file in", "z": "08cc7c15668f2f65", "name": "", "filename": "/data/2517.pdf", "filenameType": "str", "format": "", "chunk": false, "sendError": false, "encoding": "none", "allProps": false, "x": 340, "y": 160, "wires": [ [ "1fb7fc3843af8e05" ] ] } ]

          • @ikidd
            link
            English
            2
            edit-2
            11 months ago

            Nicely done, for not a JS guy. I’d have be a while longer figuring out that process.

            Not sure what to suggest on the scaling, that might be happening in your conversion to PCL, you might be able to execute that as a ghostscript process on the host and then just stream the resulting file out of the filesystem to the print node, or even just drop it to a queue folder and cut the IPP node out entirely to eliminate it as a source of the scaling.

            Edit: https://github.com/NickNaso/ghostscript4js

            • @[email protected]OP
              link
              fedilink
              English
              2
              edit-2
              11 months ago

              A very welcome compliment after this ordeal. Thank you! :)

              The cleanest way to solve the scaling issue would probably be to go into the pdf2pic module and hack it open to accept the “pcl:fit-to-page” option that GraphicsMagick (the underlying software package doing the actual conversion from PDF to PCL) supports. (Supposing it actually does what it says. I’m not so sure about anything in printer land anymore.)

              But since this whole thing is for internal documents only and the scaling can probably be estimated by choosing better values for width/height to account for printer margins I most likely won’t bother.

              Thanks again for suggesting Node-RED. I’m very happy with the result.

      • @ikidd
        link
        English
        1
        edit-2
        11 months ago

        I actually use NR to keep an eye on my CUPS print queue for jobs waiting, and it sends a wakeup to a tasmota wall plug to turn on the printer and then turn it off in 5 minutes. This lets me have a network printer always ready, but not using power in idle. This might work in with your project.

        spoiler

        [{“id”:“6f4056a8.eb32”,“type”:“inject”,“z”:“f268801.6c137”,“name”:“”,“props”:[{“p”:“payload”},{“p”:“topic”,“vt”:“str”}],“repeat”:“60”,“crontab”:“”,“once”:false,“onceDelay”:0.1,“topic”:“”,“payload”:“”,“payloadType”:“date”,“x”:250,“y”:240,“wires”:[[“5e57130e.32c56c”]]},{“id”:“5a7d9cb9.82e2ac”,“type”:“html”,“z”:“f268801.6c137”,“name”:“”,“property”:“payload”,“outproperty”:“payload”,“tag”:“.list > tbody:nth-child(2) > tr:nth-child(1) > td:nth-child(1) > a:nth-child(1)”,“ret”:“html”,“as”:“single”,“x”:370,“y”:300,“wires”:[[“667f6421.e13924”]]},{“id”:“5e57130e.32c56c”,“type”:“http request”,“z”:“f268801.6c137”,“name”:“”,“method”:“GET”,“ret”:“txt”,“paytoqs”:“ignore”,“url”:“http://10.10.251.50:631/jobs?“,“tls”:”“,“persist”:false,“proxy”:”“,“authType”:”“,“x”:420,“y”:240,“wires”:[[“5a7d9cb9.82e2ac”]]},{“id”:“667f6421.e13924”,“type”:“split”,“z”:“f268801.6c137”,“name”:”“,“splt”:”\\n",“spltType”:“str”,“arraySplt”:1,“arraySpltType”:“len”,“stream”:false,“addname”:“”,“x”:180,“y”:380,“wires”:[[“836d047d.c5a41”]]},{“id”:“836d047d.c5a41”,“type”:“switch”,“z”:“f268801.6c137”,“name”:“”,“property”:“payload”,“propertyType”:“msg”,“rules”:[{“t”:“eq”,“v”:“HP_LaserJet_4000_Series”,“vt”:“str”},{“t”:“null”}],“checkall”:“true”,“repair”:false,“outputs”:2,“x”:330,“y”:380,“wires”:[[“474b85e1.a317ec”],[]]},{“id”:“be8ec1f.57fad4”,“type”:"Tasmota Switch”,“z”:“f268801.6c137”,“broker”:“4ba22e0f7edb8148”,“device”:“tasmota_LJ4000”,“name”:“”,“outputs”:1,“uidisabler”:false,“fullTopic”:“”,“cmndPrefix”:“”,“statPrefix”:“”,“telePrefix”:“”,“x”:700,“y”:380,“wires”:[[]]},{“id”:“474b85e1.a317ec”,“type”:“trigger”,“z”:“f268801.6c137”,“name”:“”,“op1”:“1”,“op2”:“0”,“op1type”:“str”,“op2type”:“str”,“duration”:“5”,“extend”:true,“overrideDelay”:false,“units”:“min”,“reset”:“”,“bytopic”:“all”,“topic”:“topic”,“outputs”:1,“x”:510,“y”:380,“wires”:[[“be8ec1f.57fad4”]]},{“id”:“316b902c.639208”,“type”:“comment”,“z”:“f268801.6c137”,“name”:“LaserJet 4k Wakeup on Print”,“info”:“”,“x”:140,“y”:200,“wires”:[]},{“id”:“4ba22e0f7edb8148”,“type”:“tasmota-mqtt-broker”,“name”:“”,“broker”:“localhost”,“port”:“1883”,“clientid”:“”,“usetls”:false,“keepalive”:“60”,“cleansession”:true}]

        • @[email protected]OP
          link
          fedilink
          English
          111 months ago

          I do actually use Node-RED myself for my zigbee home automation. Funny how it never crossed my mind to pick it up for this. It’s perfect as I want a non-programmer to be able to maintain it.

          I doubt my solution will be much more than ingest and print, but I’ll report back. Still fighting to get that hp p3015 to do something over IPP…

  • stown
    link
    fedilink
    English
    111 months ago

    You might want to check out Mozilla Thunderbird or even MS outlook for this. I don’t believe roundcube (web client) has this ability.

    • @[email protected]OP
      link
      fedilink
      English
      111 months ago

      Thanks for the idea. It’s not quite what I was looking for, but I might look into it more if I don’t find anything better.

      From the looks of it, it requires python scripting anyway, so there isn’t a big advantage to fetching the mail with python and imaplib directly.