Embed images not working on IOS devices

graphing
Tags: #<Tag:0x00007fe22003d338>

#1

Hi,

Currently i’m busy with getting the template working by attaching a graph image to an email.
The thing is that when i’m at home and see a CPU alert in my inbox, it would be great if i can see a CPU graph.

So I after searching on the interweb, i came across this post: https://community.librenms.org/t/feature-request-embed-images-into-email/. When reading it, i saw that Dohald and Chas make it work; i then went to GitHub and looked at the specific PR 8646, i attached the code from here: https://github.com/librenms/librenms/pull/8646/files#diff-f81f3dff36bf04b7a070d642c858e883 into the functions.php.

 $mail->Body = $message;
        if ($html) {
            $mail->isHTML(true);
            //Addding functionality to support cid embedded graphs
            $arrContextOptions=array(
                "ssl"=>array(
                "verify_peer"=>false,
                "verify_peer_name"=>false,
                "timeout" => 1200,
                ),
                );
            preg_match_all('/ alt=\"(.*?)\"/', $mail->Body, $match);
            $countcheck = 0;
            $newcidhtml = $mail->Body;
            foreach ($match[1] as $item) {
                $newcidhtml=preg_replace("/\bembedimage\b/i", $countcheck, $newcidhtml, 1);
                $image = file_get_contents($item, false, stream_context_create($arrContextOptions));
                if ($config['webui']['graph_type'] == 'svg') {
                    $mail->addStringEmbeddedImage($image, $countcheck, 'graph.svg', 'base64', 'image/svg+xml');
                } else {
                    $mail->addStringEmbeddedImage($image, $countcheck, 'graph.png', 'base64', 'image/png');
                }
                $countcheck++;
            }
            $mail->Body = $newcidhtml;
        }
        switch (strtolower(trim($config['email_backend']))) {
            case 'sendmail':

So far so good.

I then added this code to my template, based on the input from Dohald; that didn’t work either at first: <img width="700" height="300" src="cid:embedimage" alt="http://myserver/graph.php?&type=device_processor&lazy_w=805&device=%hostname&?=yes&height=486&width=1656&from=end-1h">

I had to change the link in the alt; replacing the ampersand with slashes and i had to replace the cid:embedimage with cid:graph.png; after this, i could see the graph in my Outlook 2016 client.

<img src="cid:graph.png" alt="https://monitor.domain.nl/graph.php/device={{ $alert->device_id }}/type=device_processor/width=800/height=300/lazy_w=552/from=end-1h">

But now i wanted also it viewable in my native IOS mail app, and there i’m stuck; the graph doesnt show; it is just a blank square; i even can’t see the alt text within it; so it looks like it is loaded, but on the otherhand it is not.

Anybody idea’s how to fix this?


#2

Thanks for checking out my pull request :slight_smile:

Unfortunately it didn’t get merged, and i’ve since moved to a different alert transport. The code has updated a lot since nearly exactly 1 year ago. :smiley: so there is probably something that needs updating.

Your rather on your own here, and remember modifying core files like functions.php will break future LibreNMS upgrades. To restore the old file you will need to run ./scripts/github-remove -d which removes all custom files in your librenms directory.

By all means have a play around, firstly it followed the same concept as current html embedded images, I think as you say the embed URL may have changed and maybe you don’t right click copy image address, and you copy the main graph page URL instead. According to example with img src in the docs #https://docs.librenms.org/Alerting/Templates/#examples-html

Also i noticed “%hostname” is using old format from old templating, so bare that in mind. You could try replace using the new format as per docs {{ $alert->hostname }} then maybe the ampersand method does work.

Ensure you can see that link unauthenticated using that config parameter in the PR.

Now as you changed to cid:graph.png, this shouldn’t work, the logic i added specifically finds “embedimage” and this part should not have been changed. I think you broke it if there are multiple images into the alert by making that change.

It should work on IOS mail app, maybe check your General Settings -> WebUI settings -> and change from svg to png or vice-versa, as some mail clients do not support svg embeds.

Also check on IOS

  1. Open the settings app.
  2. Select “Mail, Contacts, Calendars.”
  3. Set the “Load Remote Images” to ON .

Good luck!


#3

Hi Chas,

Ok, understood :slight_smile:

So I will ditch the custom functions.php, and go for the Laravel approach; that being said; i’ve done the following so far:

created a new PHP file under /opt/librenms/resources/views/alerts/templates. The file i named is cpu.blade.php.

The cpu.blade.php is filled with the following code:

<html>
	<head>
	<meta http-equiv="content-type" content="multipart/alternative; charset=UTF-8">
	</head>
<div style="font-family:Helvetica;">
	<h2> @if ($alert->state == 1) <span style="color:red;">Warning @endif 
	 @if ($alert->state == 2) <span style="color:goldenrod;">Planned load @endif </span>
	 @if ($alert->state == 3) <span style="color:green;">It is recovering @endif </span>
	 @if ($alert->state == 0) <span style="color:green;">Recovered @endif </span>
	</h2>
    <body>
        <div class="container">
            @yield('content')
        </div>
    </body>
</html>

After this i created a new alert template and filled it with:

@extends('alerts.templates.cpu')

@section('content')
 <b>Hostname:</b> {{ $alert->hostname }}<br>
 <b>Limit:</b> 90 %<br>
 <b>CPU Load Length:</b> {{ $alert->elapsed }}<br>
 <br>
 <br>
 <br>
 <br>
 <b>Faults:</b><br>
  @if ($alert->faults)                                                                                     
  @foreach ($alert->faults as $key => $value)#{{ $key }}: {{ $value['string'] }}<br>
  @endforeach                                                                                                              
  @endif 
@endsection

But now the million dollar question; how can i fit in a embeded image here?
I’ve found so far this link https://laravel.com/docs/5.1/mail#inline-attachments and it says that i must use this code for inline attachments:

<body>
    Here is an image:

    <img src="<?php echo $message->embed($pathToFile); ?>">
</body>

But where and how must i fit this is in? I tried in the alert template; but i would go further due to a error.

Also i have no clue where and what i must do to get a inline image in the mail.

The thing is, is that i want to see on my phone when i’m not in office what is going on via a graph that is embedded :slight_smile:

Thanks in advance!


#4

Interesting! Looks like you got quite far already, didn’t know laravel has something for it. Looks like it might not work though with markdown emails, i see some workarounds, how about the asset approach? https://stackoverflow.com/questions/42503168/laravel-5-4-embed-image-in-mail


#5

Hi Chas,

I’ve taken a look at the code provided via your link and found the following code that works, but more in a way “close but no sigar”

<img src="data:image/png;base64,{{base64_encode(file_get_contents('https://monitor.host.nl/graph.php/device=2/type=device_processor/width=800/height=300/lazy_w=552/from=end-1h'))}}" alt="">

This code provides a base64 encoded html line in the mail; both my Outlook 2016 and my native iOS Mail app show the picture now (jeej! :star_struck:).

But now the final part; the device you see is device id=2; this can be done dynamically. Normal way to do this is via {{ $alert->device-id}} ; but when i try this in the following code:

<img src="data:image/png;base64,{{base64_encode(file_get_contents('https://monitor.host.nl/graph.php/device={{ $alert->device_id }}/type=device_processor/width=800/height=300/lazy_w=552/from=end-1h'))}}" alt="">

It can’t save the alert template in LibreNMS; it error’s out that there is a error. :exploding_head:

I suspect that I can’t do a {{}} within in {{ }} .

Any idea’s how to fix this? I’ve got the feeling i’m almost there…


#6

I thought that might be the better answer on there, i remember specifying image/png and encoding with base64 was very important for mail clients.

I think its {{ $value['device_id'] }} you could try without the brackets too as they are already used. (although i don’t really know)

and also , you might want to check out using {!! !!} not sure if it may be useful