<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Development on dotnet.work</title>
        <link>https://dotnet.work/categories/development/</link>
        <description>Recent content in Development on dotnet.work</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-US</language>
        <managingEditor>dotnet@oles.cloud (Ole Albers)</managingEditor>
        <webMaster>dotnet@oles.cloud (Ole Albers)</webMaster>
        <copyright>Ole Albers</copyright>
        <lastBuildDate>Sun, 17 Dec 2023 12:00:00 +0100</lastBuildDate><atom:link href="https://dotnet.work/categories/development/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>How to track a squirrel</title>
            <link>https://dotnet.work/blog/squirrel/</link>
            <pubDate>Sun, 17 Dec 2023 12:00:00 +0100</pubDate><author>dotnet@oles.cloud (Ole Albers)</author>
            <guid>https://dotnet.work/blog/squirrel/</guid>
            <description>&lt;img src=&#34;https://dotnet.work/blog/squirrel/feeder_hu_5e0b693f30391cc3.png&#34; alt=&#34;Featured image of post How to track a squirrel&#34; /&gt;&lt;p&gt;[Disclaimer: This is not meant as a tutorial, more as some chitchat. You can find the source on github nonetheless, but I assume this is a VERY specific use case noone else uses]&lt;/p&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s start by telling you that this whole project ist utter nonsense. Noone really &lt;em&gt;needs&lt;/em&gt; this feature. I decided to create this nonetheless.&lt;/p&gt;&#xA;&lt;h3 id=&#34;the-goal&#34;&gt;&lt;a href=&#34;#the-goal&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;The Goal&#xA;&lt;/h3&gt;&lt;p&gt;I own a little feeding box for squirrels of the neighbourhood. And it works as designed: Squirrels get here, steal their food and run away.&lt;/p&gt;&#xA;&lt;p&gt;I can see them through my glass door and it just looks amazing, especially in the typical &amp;ldquo;Hamburger Wetter&amp;rdquo; (Hamburg weather, means: raining horizontally). Sometimes I take a picture or even a video, but through the door that just does not look very great.&lt;/p&gt;&#xA;&lt;p&gt;So I decided to add a surveillance cam to the mix, and while I am on it: Automatically publish whenever a squirrel appears&lt;/p&gt;&#xA;&lt;h4 id=&#34;hardware&#34;&gt;&lt;a href=&#34;#hardware&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Hardware&#xA;&lt;/h4&gt;&lt;p&gt;I use a dlink - outdoor webcam with WiFi. Not really worth looking up the model number here, just the cheapest WiFi-Cam I could find which is compatible with Synology Surveillance Station (but nearly all are)&lt;/p&gt;&#xA;&lt;p&gt;In addition the Synology NAS with installed surveillance station. I own a DS920+, but any should do&lt;/p&gt;&#xA;&lt;h4 id=&#34;privacy&#34;&gt;&lt;a href=&#34;#privacy&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Privacy&#xA;&lt;/h4&gt;&lt;p&gt;I do not want to track any persons. Not me, not others. This is not meant to be surveillance, it is meant to film squirrels. TBH I did not ask the squirrels how they think about privacy and GDPR, but I assume they are fine with it. After all they accepted all Cookies until now, and not only the required ones.&lt;/p&gt;&#xA;&lt;p&gt;To make sure only squirrels (or other animals) get caught I wanted to do a few conditions:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Only track movement directly in front of the feeder.&#xA;&lt;ul&gt;&#xA;&lt;li&gt;So I can make sure not Humans or Traffic in the background trigger the motion sensor&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Put the Camera in &amp;ldquo;Squirrel&amp;rdquo;-height.&#xA;&lt;ul&gt;&#xA;&lt;li&gt;So even if someone (me or my guests) manages to trigger the alarm no faces can be seen&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;Have a simple to use approval workflow&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Just in case. If someone ends up lying there drunk I do not want to publish a video of that person anywhere&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;h5 id=&#34;only-track-movement-directly-in-front-of-the-feeder&#34;&gt;&lt;a href=&#34;#only-track-movement-directly-in-front-of-the-feeder&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Only Track movement directly in front of the feeder&#xA;&lt;/h5&gt;&lt;p&gt;That is one of the reasons why I use the Surveillance Station of Synology. The Camera itself has movement detection and (according to the documentation) even a fancy AI &amp;ldquo;this is a person&amp;rdquo; algortihm. I do not want the last for obvious reasons and especially can not decide which area of the image should be used for detection. In addition this seems to require a cloud feature.&#xA;I do not want my camera feed in the cloud from anyone. This should never leave my house without my consent. The surveillance station can select very small pieces of the image to be selected as alert regions. I put it directly in front of the feeder where no background movement can be detected. This way I can also adjust the sensibility of the detection to quite a high value because no noise becaues of branches moving in the wind etc. is to be expected.&lt;/p&gt;&#xA;&lt;h5 id=&#34;put-the-camera-in-squirrel-height&#34;&gt;&lt;a href=&#34;#put-the-camera-in-squirrel-height&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Put the camera in squirrel-height&#xA;&lt;/h5&gt;&lt;p&gt;That was easy as there are some flowerboxes directly before the feeder where I mounted the cam&#xA;&lt;img alt=&#34;Photo from garden. A squirrelfeeder in the back, the camera on front&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;187px&#34; data-flex-grow=&#34;78&#34; height=&#34;701&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/squirrel/feeder_hu_5e0b693f30391cc3.png&#34; width=&#34;548&#34;&gt;&lt;/p&gt;&#xA;&lt;h5 id=&#34;have-a-simple-approval-workflow&#34;&gt;&lt;a href=&#34;#have-a-simple-approval-workflow&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Have a simple approval workflow&#xA;&lt;/h5&gt;&lt;p&gt;Because I mostly am at Mastodon at time of this writing (these sentences sometimes age very bad. A few months ago that would have been the artist formerly known as Twitter, which itself was just a replacement for Google+ which, well, you know the sad story). Let&amp;rsquo;s just hope that was the last Social Media switch for me.&lt;/p&gt;&#xA;&lt;p&gt;One of the advantages of Mastodon is that it has a very nice, simple API that allows sending toots, getting Notifications and so on. So my idea for the workflow is to notify me (and only me) that a new movement has been detected. Attach an image of that movement and if I approve this (e.g. by adding a &amp;ldquo;fav&amp;rdquo; to that toot) the bot knows that this detection was a valid Squirrel video and posts it. So AI without the &amp;ldquo;A&amp;rdquo;. (some might argue even without the &amp;ldquo;I&amp;rdquo;&amp;hellip;)&lt;/p&gt;&#xA;&lt;h3 id=&#34;synology&#34;&gt;&lt;a href=&#34;#synology&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Synology&#xA;&lt;/h3&gt;&lt;p&gt;Adding the Webcam is quite simple. It nearly is found automatically in Surveillance station. Finding out how to connect was a bit harder. Username is always &amp;ldquo;admin&amp;rdquo; and the required password is a PIN. Printed onto the Power Plug, not the device&amp;hellip;&#xA;After that the App of the camera does not like the Camera anymore, which is bonus for  me as I do not want images to be uploaded to dlink, anyways.&lt;/p&gt;&#xA;&lt;p&gt;The detection area can be set in the Camera options. &lt;img alt=&#34;Screenshot from “Motion Detection Area” within Surveillance Station&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;474px&#34; data-flex-grow=&#34;197&#34; height=&#34;631&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/squirrel/motiondetection_hu_2689ea674daa870d.png&#34; srcset=&#34;https://dotnet.work/blog/squirrel/motiondetection_hu_29f7050f1aceaac3.png 800w, https://dotnet.work/blog/squirrel/motiondetection_hu_2689ea674daa870d.png 1247w&#34; width=&#34;1247&#34;&gt; Fiddling with the thresholds takes a while, especially as I do not have a trained squirrel to assist me on that. I then changed the time plan to always motion detection (so disabling the constant recording) and updated the minimum record time to five minutes. A good comprimise between getting everything and not creating videos that are too big for mastodon/youtube/wherever I wanted to upload this, which I had not decided at this point&lt;/p&gt;&#xA;&lt;p&gt;Synology has multiple ways to notify about movements: Email, SMS, Push notifications and Webhooks. Obviously the last one was the way to go as it does not spam me in any way and I have to program stuff anyways.&lt;/p&gt;&#xA;&lt;h3 id=&#34;writing-a-webhook&#34;&gt;&lt;a href=&#34;#writing-a-webhook&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Writing a Webhook&#xA;&lt;/h3&gt;&lt;p&gt;&lt;img alt=&#34;Alt text&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;330px&#34; data-flex-grow=&#34;137&#34; height=&#34;590&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/squirrel/synowebhook_hu_51827eb84ea23d97.png&#34; srcset=&#34;https://dotnet.work/blog/squirrel/synowebhook_hu_156b73cfdf29fd8.png 800w, https://dotnet.work/blog/squirrel/synowebhook_hu_51827eb84ea23d97.png 813w&#34; width=&#34;813&#34;&gt;&#xA;A webhook is just an HTTP-call essentially. Synology allows POST and PUT in Surveillance Station. So I created a simple Web Api in Visual Studio and was ready to debug the incoming data.&lt;/p&gt;&#xA;&lt;h4 id=&#34;firewalls-firewalls-everywhere&#34;&gt;&lt;a href=&#34;#firewalls-firewalls-everywhere&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Firewalls, Firewalls everywhere!&#xA;&lt;/h4&gt;&lt;p&gt;Synology allows you to send a test-notification which just resulted in an error. WHAT exactly went wrong is nowhere to be seen. Not in surveillance station and not in the logs from the synology. So I had to fly blind at this point.&lt;/p&gt;&#xA;&lt;p&gt;I knew it worked when using my local machine, either via localhost or the ipadress from my development machine.&lt;/p&gt;&#xA;&lt;p&gt;So the next step was to connect to my synology via SSH and try to access my API throuh a simple webcall via GET:&#xA;&lt;code&gt;wget https://192.168.178.23:6789/ping&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;This simple call already did not work. So must have been a firewall issue. I checked everything in my Synology configuration FOR A VERY LONG TIME and did find nothing. Finally I put my attention to Windows, disabled the Defender Firewall and it went through. Because I do not want to have the firewall open I added an exception through the &amp;ldquo;allow an app through windows firewall&amp;rdquo; and finally it did work with the firewall still enabled.&#xA;&lt;img alt=&#34;Windows Firewall Rules&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;334px&#34; data-flex-grow=&#34;139&#34; height=&#34;444&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/squirrel/firewall_hu_72f0a67ccecaa8b.png&#34; width=&#34;618&#34;&gt;&lt;/p&gt;&#xA;&lt;h4 id=&#34;receiving-data-from-the-webhook&#34;&gt;&lt;a href=&#34;#receiving-data-from-the-webhook&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Receiving data from the webhook&#xA;&lt;/h4&gt;&lt;p&gt;The Webhook arrived as expected, has some informations in it and can even provide an url to a preview image. That image URL is a generated &amp;ldquo;public&amp;rdquo; (within my LAN) Address I am able to receive and download:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MapPost&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/squirrel&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requestBody&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReadFromJsonAsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SynologyBody&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;requestBody&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(!&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;requestBody&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Capture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;previewImage&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;downloader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DownloadFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;requestBody&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Capture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;                                    &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;else&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;received event without image. Will ignore it&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteAsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;event received&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;SynologyBody&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Subject&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Desc&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Capture&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(Synology does not really care about the response but I found it useful when testing locally through Postman)&lt;/p&gt;&#xA;&lt;p&gt;At this point I do not have a video yet which is to be expected, as &amp;ldquo;normal&amp;rdquo; users would expect to receive the warning &lt;em&gt;immediately&lt;/em&gt; and not five minutes &lt;em&gt;after&lt;/em&gt; someone stole their nuts.&lt;/p&gt;&#xA;&lt;h4 id=&#34;send-private-notification-to-mastodon&#34;&gt;&lt;a href=&#34;#send-private-notification-to-mastodon&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Send private notification to Mastodon&#xA;&lt;/h4&gt;&lt;p&gt;After an event have been received the Image is downloaded and a message is sent to Mastodon using MastoNet:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MastodonClient&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Login&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MastodonClient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_instance&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_accessToken&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Task&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SendPreview&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Stream&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;previewFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DateTime&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;notificationDate&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Login&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;text&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;$&amp;#34;{_approver} ALARM! Possible Squirrel detection! ALARM! #preview DATE:\n{notificationDate}\n&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;media&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UploadMedia&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;previewFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;squirrel.png&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;possibly a squirrel&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PublishStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Visibility&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Direct&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mediaIds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;media&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Id&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Could not send preview&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$&amp;#34;Published to Mastodon with id {status.Id}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This creates the following toot:&#xA;&lt;img alt=&#34;Private Notification in Mastodon with previewimage&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;202px&#34; data-flex-grow=&#34;84&#34; height=&#34;468&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/squirrel/notasquirrel_hu_d5d3b1454f2618bf.png&#34; width=&#34;395&#34;&gt;&lt;/p&gt;&#xA;&lt;h4 id=&#34;waiting-for-approval&#34;&gt;&lt;a href=&#34;#waiting-for-approval&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Waiting for approval&#xA;&lt;/h4&gt;&lt;p&gt;This toot has only been sent to me privately (mastodon has no encryption so always keep that in mind about the &amp;ldquo;privacy&amp;rdquo; - part). I can then decide that this is a valid Squirrel detection by setting the &amp;ldquo;fav&amp;rdquo; star of that toot.&lt;/p&gt;&#xA;&lt;h4 id=&#34;keeping-the-state&#34;&gt;&lt;a href=&#34;#keeping-the-state&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Keeping the state&#xA;&lt;/h4&gt;&lt;p&gt;To be able to understand which previewtoot belongs to what webhook call I need to store the state. I uses LitDB for this. LiteDB is a &lt;strong&gt;very&lt;/strong&gt; simple document database which needs no installation at all. It completely only lives within the NuGet-Package and the data is stored in a Bson-Format (Json, but compressed).&#xA;It is a bit like simply serializing my contents and store it into a Json file. Just performing much better.&lt;/p&gt;&#xA;&lt;p&gt;That is why the complete &amp;ldquo;database&amp;rdquo;-class is as simple as this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;DataBase&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;const&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_databaseName&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;@&amp;#34;Filename=squirrel.db;connection=shared&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GetContents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LiteDatabase&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_databaseName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetCollection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FindById&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BsonValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;RemoveContents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LiteDatabase&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_databaseName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetCollection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Delete&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BsonValue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UpsertContents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LiteDatabase&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_databaseName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetCollection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;T&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Upsert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;contents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SquirrelData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FindByFilename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;db&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;LiteDatabase&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_databaseName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetCollection&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SquirrelData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FindOne&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ExpectedMovieFile&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now the data inside the Database contains the following stuff:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;class&lt;/span&gt; &lt;span class=&#34;nc&#34;&gt;SquirrelData&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;na&#34;&gt;        [BsonId]&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Id&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;  &lt;span class=&#34;c1&#34;&gt;// First MastodonID&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string?&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;PublicId&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DateTime&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EventReceived&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DateTime&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SentForApproval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DateTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SentPublic&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DateTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Faved&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string?&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ExpectedMovieFile&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The Id simply is the Id from the message just posted to mastodon. This object mostly contains Mastodon-Information and Information about the WebHook event.&lt;/p&gt;&#xA;&lt;p&gt;As mentioned above the WebHook has no information about the Video that is created (or most likely: Is still being created when the WebHook is sent). So we simply have to find it.&#xA;The rules are quite simple: Within the directory with surveillance videos it is simply the newest file we can find.&lt;/p&gt;&#xA;&lt;p&gt;One problem remains: The preview image was within the WebHook and did not need authentication do be downloaded. The surveillance directory does need authentication. So I created a user for that specific purpouse allowed it to access the folder and needed to do some SMB-Stuff for authentication.&lt;/p&gt;&#xA;&lt;p&gt;I used the SMBLibrary for that. It isn&amp;rsquo;t as straight forward as navigating through a filesystem, but it does work fine. First I have to connect using my credentials:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Connect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;smbClient&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SMB1Client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;isConnected&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;smbClient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Connect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IPAddress&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Parse&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;_server&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SMBTransportType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DirectTCPTransport&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;isConnected&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;NTStatus&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;smbClient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Login&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Empty&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_username&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_password&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NTStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STATUS_SUCCESS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;_smbClient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;smbClient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;throw&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Exception&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Connecting failed. Check your credentials&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After successfully connecting I can access the share and search for the most current mp4-file recursively:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;     &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FindMostCurrentVideo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;store&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_smbClient&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TreeConnect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;surveillance&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;out&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NTStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STATUS_SUCCESS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;throw&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Exception&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Connecting to Share failed&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mostCurrentFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetMostCurrentFileRec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SMB1FileStore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;store&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_startPath&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Combine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mostCurrentFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mostCurrentFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Filename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MostCurrentFile&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GetMostCurrentFileRec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SMB1FileStore&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;store&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;folder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;folder&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;\\&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mostCurrentFile&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MostCurrentFile&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Created&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DateTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MinValue&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;store&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;QueryDirectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subdirectoryList&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;folder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SMBLibrary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SMB1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FindInformationLevel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SMB_FIND_FILE_DIRECTORY_INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NTStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STATUS_SUCCESS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;kt&#34;&gt;object&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;directoryHandle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;FileStatus&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fileStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;store&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreateFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;directoryHandle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;out&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fileStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;folder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;AccessMask&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GENERIC_READ&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SMBLibrary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FileAttributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Directory&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SMBLibrary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FileAttributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Normal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ShareAccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Read&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ShareAccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Write&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CreateDisposition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FILE_OPEN&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;CreateOptions&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FILE_DIRECTORY_FILE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;NTStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;STATUS_SUCCESS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FindInformation&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fileList2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;store&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;QueryDirectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;out&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fileList2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;folder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FindInformationLevel&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SMB_FIND_FILE_DIRECTORY_INFO&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;dirInfo&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fileList2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Where&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;typeof&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FindFileDirectoryInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cast&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FindFileDirectoryInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subdirectories&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dirInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Where&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ExtFileAttributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HasFlag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ExtendedFileAttributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;dirInfo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Where&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ExtFileAttributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;HasFlag&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ExtendedFileAttributes&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;// Look for subdirectories and drill down to them:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;foreach&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;directory&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;subdirectories&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Contains&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;.&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;continue&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mostCurrentSubFile&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GetMostCurrentFileRec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;store&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Combine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;folder&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;directory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;));&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mostCurrentSubFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Created&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mostCurrentFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Created&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mostCurrentFile&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mostCurrentSubFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;c1&#34;&gt;// Look for .mp4 - Files in current directory and check if they are newer than the most current file known:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;k&#34;&gt;foreach&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;files&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Where&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;q&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EndsWith&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;.mp4&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreationTime&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mostCurrentFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Created&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;n&#34;&gt;mostCurrentFile&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;MostCurrentFile&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;Created&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreationTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Value&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;Filename&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FileName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                        &lt;span class=&#34;n&#34;&gt;Path&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;folder&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                    &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;n&#34;&gt;status&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;store&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CloseFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;directoryHandle&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mostCurrentFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At this point I do not need the filecontents itself, but only the path so I can use it lateron.&lt;/p&gt;&#xA;&lt;p&gt;After that we have the whole WebHook complete:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Reveive the Contents (including preview image) from the webhook&lt;/li&gt;&#xA;&lt;li&gt;Determine which Video File matches&lt;/li&gt;&#xA;&lt;li&gt;CHeck if we already had this file (if within a video multiple webhooks are fired) and avoid duplicates&lt;/li&gt;&#xA;&lt;li&gt;Send a notification to Mastodon&lt;/li&gt;&#xA;&lt;li&gt;Store all known information into our database.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;So our Webhook from the beginning now looks like this:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;app&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MapPost&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/squirrel&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;received&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;DateTime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;Received squirrel Event&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;requestBody&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Request&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ReadFromJsonAsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SynologyBody&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;requestBody&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(!&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IsNullOrWhiteSpace&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;requestBody&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Capture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;previewImage&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;downloader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DownloadFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;requestBody&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Capture&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;downloader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Connect&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;videoFilename&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;downloader&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FindMostCurrentVideo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;??&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;throw&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Exception&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;No Video Found&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;existingItem&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;database&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FindByFilename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;videoFilename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;existingItem&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$&amp;#34;&amp;#39;{videoFilename}&amp;#39; already processed with MastodonId {existingItem.Id}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteAsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;duplicate event&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mastodonStatus&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mastodon&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;SendPreview&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;previewImage&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;received&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mastodonStatus&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;database&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UpsertContents&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SquirrelData&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;EventReceived&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;received&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ExpectedMovieFile&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;videoFilename&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Id&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mastodonStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;SentForApproval&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mastodonStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CreatedAt&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;context&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Response&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteAsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;event received&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;checking-for-notifications&#34;&gt;&lt;a href=&#34;#checking-for-notifications&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Checking for Notifications&#xA;&lt;/h3&gt;&lt;p&gt;As mentioned the &amp;ldquo;approval workflow&amp;rdquo; (a big word for this simple mechanism, I know) is to wait for a fav. If the fav is received it means I decided this is a valid Squirrel detection and the video can be published.&lt;/p&gt;&#xA;&lt;p&gt;Also do not wait longer than 7 days. If I did not approve in that time, it probably is not a good video.&lt;/p&gt;&#xA;&lt;p&gt;Again using MastoNet I can receive the Notifications for that user:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Task&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GetFavs&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;favourites&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Login&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;notifications&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetNotifications&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;foreach&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;notification&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;in&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;notifications&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;switch&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Type&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;mention&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PublishStatus&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$&amp;#34;Sorry. I am just a bot and will not respond to this. Ask {_approver} if you want to know anything about what I do&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;replyStatusId&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DismissNotification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;case&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;favourite&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;favourites&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;k&#34;&gt;default&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$&amp;#34;discarding notification of type {notification.Type}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;client&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DismissNotification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;notification&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;k&#34;&gt;break&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;favourites&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The nofication.Status.Id now is the id we already stored in the Database and can use to find all known WebHook-Data of that event and send a new Toot. This time just with the Video file instead of the preview image.&lt;/p&gt;&#xA;&lt;h5 id=&#34;why-no-mastodon-webhooks&#34;&gt;&lt;a href=&#34;#why-no-mastodon-webhooks&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Why no Mastodon Webhooks?&#xA;&lt;/h5&gt;&lt;p&gt;The Mastodon API also offers Webhooks. So instead of periodially polling for new notifications this could be used to receive the favs. The main reason why I did not use this (apart from the fact that polling is simply fast enough) is the fact that my application is not accessible from the outside. To allow this I would need to make my NAS (where the application is hosted) accessible from the Internet. And I do not want that. I could add Firewall rules to only allow specific ports and so on, but no access is even a bit better than a limited access. Even if noone would get through, just bots &lt;em&gt;trying&lt;/em&gt; the flood my machine with requests is a headache I do not need.&lt;/p&gt;&#xA;&lt;h3 id=&#34;uploading-the-video&#34;&gt;&lt;a href=&#34;#uploading-the-video&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Uploading the Video&#xA;&lt;/h3&gt;&lt;p&gt;After trying to uplaad the Video directly to Mastodon the next problem came up: The file was too big. While it was way inside the limits the upload (to the mastodon.social instance) just responded with an error &amp;ldquo;something went wrong&amp;rdquo;. I suspect the Library to be the main issue as the Upload is not done async and so a timeout might be the cause.&lt;/p&gt;&#xA;&lt;p&gt;That is why I decided to upload the Video to YouTube instead. YouTube provides APIs to do that. The main issue is that this also requires an OAuth authentication. Luckily the documentation for this are quite straight-forward so a simple Test worked fine:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Task&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UploadVideo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Stream&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fileStream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;youtubeService&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;YouTubeService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BaseClientService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Initializer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;ApiKey&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;_apiKey&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;ApplicationName&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetType&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ToString&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;UserCredential&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;credential&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;using&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;stream&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FileStream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;secrets.json&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FileMode&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Open&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FileAccess&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Read&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;n&#34;&gt;credential&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GoogleWebAuthorizationBroker&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;AuthorizeAsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GoogleClientSecrets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Load&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Secrets&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;YouTubeService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Scope&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;YoutubeUpload&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;user&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CancellationToken&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;None&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;youtubeService&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;YouTubeService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BaseClientService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Initializer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;HttpClientInitializer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;credential&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;ApplicationName&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Assembly&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetExecutingAssembly&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GetName&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;().&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Name&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;});&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;video&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Video&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;video&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Snippet&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;VideoSnippet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;video&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Snippet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Title&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Squirrel detected&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;video&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Snippet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Description&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;You should have bought a squirrel&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;video&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Snippet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Tags&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[]&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;squirrel&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;video&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Snippet&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CategoryId&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;22&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;video&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Status&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;VideoStatus&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;MadeForKids&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;n&#34;&gt;SelfDeclaredMadeForKids&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;video&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Status&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PrivacyStatus&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;private&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt; &#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;videosInsertRequest&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;youtubeService&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Videos&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Insert&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;video&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;snippet,status&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;fileStream&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;video/*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;videosInsertRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProgressChanged&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;videosInsertRequest_ProgressChanged&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;videosInsertRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ResponseReceived&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;videosInsertRequest_ResponseReceived&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;videosInsertRequest&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;UploadAsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;videosInsertRequest_ResponseReceived&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Video&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$&amp;#34;done&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;private&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;void&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;videosInsertRequest_ProgressChanged&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;IUploadProgress&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;obj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;n&#34;&gt;Console&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WriteLine&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;$&amp;#34;Bytes: {obj.BytesSent}| Status: {obj.Status}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;(secrets.json contains a client_id and client_secret for oauth)&#xA;While uploading the &lt;code&gt;ProgressChanged&lt;/code&gt; event gets fired a few times. Obj.Status cycles from Starting, Uploading to Completed. Which is also the Status when &lt;code&gt;ResponseReceived&lt;/code&gt; is fired.&lt;/p&gt;&#xA;&lt;p&gt;Because I had to switch to YouTube I also changed the workflow a bit. Now I already upload the video when posting the preview toot as private on YouTube. So I can verify the complete contents before an approval. And YouTube can process the video while it is waiting for approval. At the end I just switch from &lt;code&gt;private&lt;/code&gt; to &lt;code&gt;unlisted&lt;/code&gt; if it is approved or delete the Video if no approval has been made for a period of time.&lt;/p&gt;&#xA;&lt;h4 id=&#34;another-pitfall&#34;&gt;&lt;a href=&#34;#another-pitfall&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Another Pitfall&#xA;&lt;/h4&gt;&lt;p&gt;YouTube does &lt;strong&gt;not&lt;/strong&gt; allow using service accounts when uploading Videos. This was crucial for my application because this should run on a server. While the code above works I hit a dead end here. So back to Mastodon:&lt;/p&gt;&#xA;&lt;h4 id=&#34;ffmpeg&#34;&gt;&lt;a href=&#34;#ffmpeg&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;FfMpeg&#xA;&lt;/h4&gt;&lt;p&gt;To reduce the filesize I went to FFMpeg. I can compress Videos and - if required - even resize them. Because I do not want to call something on the console, I needed a wrapper. I found FfmpegCore which does exactly what I want:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Task&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;bool&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;ResizeVideo&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FFMpegArguments&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FromFileInput&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;source&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;OutputToFile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;target&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;options&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&#x9;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WithVideoCodec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;VideoCodec&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;LibX265&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&#x9;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WithVideoFilters&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;=&amp;gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;filter&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&#x9;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Scale&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;videoSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;FFMpegCore&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Enums&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;VideoSize&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;FullHd&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&#x9;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;WithFastStart&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;())&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ProcessAsynchronously&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This tiny little piece of code takes any videofile, compresses it as h265 (using default quality settings) and resized it to FullHD (1080 height) maintaining the correvt aspect ratio.&lt;/p&gt;&#xA;&lt;p&gt;That all works fine on my machine, but because I want to host this (like all my bots) on my Synology-NAS I had to dockerize the contents.  I was in luck this time, but this also turned out to be quite easy:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;RUN apt-get -y update &amp;amp;&amp;amp; apt-get -y upgrade &amp;amp;&amp;amp; apt-get install -y --no-install-recommends ffmpeg&lt;/code&gt;&#xA;A single Line in the DockerFile and everything was working smoothly&lt;/p&gt;&#xA;&lt;h4 id=&#34;fixing-the-api&#34;&gt;&lt;a href=&#34;#fixing-the-api&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Fixing the Api&#xA;&lt;/h4&gt;&lt;p&gt;The reduced Filesize did not solve the problem that Mastodon did not want to upload my file. So I digged a bit deeper into the Mastodon API. The media upload used by MastoNet seemed to marked as depricated (v1) exactly for the reason why I did not work in my project: It was meant for small preview images, not for Video files.&lt;/p&gt;&#xA;&lt;p&gt;A V2-Version &lt;a class=&#34;link&#34; href=&#34;https://docs.joinmastodon.org/methods/media/#v2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;is available&lt;/a&gt; but not implemented by MastoNet. So I forked the packages from Github and added a V2-Version:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Task&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;UploadMediaAsync&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MediaDefinition&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;media&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string?&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;AttachmentFocusData&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;?&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;focus&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;n&#34;&gt;media&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ParamName&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;file&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;list&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;List&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;MediaDefinition&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;()&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;media&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;};&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;new&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Dictionary&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;();&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;description&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;description&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;if&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;focus&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Add&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;focus&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;$&amp;#34;{focus.X},{focus.Y}&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Post&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/api/v2/media&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;list&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This was confusingly easy as I simpy just replaced &amp;ldquo;v1&amp;rdquo; by &amp;ldquo;v2&amp;rdquo;. Still it worked. Problem was: The next step, usually taking the returned Id and add this to a toot failed, because Mastodon was not finished, yet. I could simply have waited a long enough time, but decided to add a poll to receive status updates. Every Media of a known I can be requested. There is no statusflag about it processing but some properties give a hint:&#xA;First there is the &lt;code&gt;previewUrl&lt;/code&gt; this is filled at the very start after uploading. Tbe &lt;code&gt;Url&lt;/code&gt;-Property, however &lt;em&gt;isn&amp;rsquo;t&lt;/em&gt;. This will always be Null until everything is processed. So just requesting the Media every 10 seconds until the Url is filled did the trick;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-csharp&#34; data-lang=&#34;csharp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Task&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;WaitUntilMediaIsUploaded&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Attachment&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;waitSeconds&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;maxWaitSeconds&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;300&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;kt&#34;&gt;int&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;totalTimeWasted&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Id&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;==&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PreviewUrl&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;!=&lt;/span&gt; &lt;span class=&#34;kc&#34;&gt;null&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;totalTimeWasted&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;maxWaitSeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;n&#34;&gt;Thread&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Sleep&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;waitSeconds&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;*&lt;/span&gt; &lt;span class=&#34;m&#34;&gt;1000&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;n&#34;&gt;totalTimeWasted&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;+=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;waitSeconds&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&#x9;&lt;span class=&#34;n&#34;&gt;attachment&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GetMedia&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kd&#34;&gt;public&lt;/span&gt; &lt;span class=&#34;kd&#34;&gt;async&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Task&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;GetMedia&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;kt&#34;&gt;string&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mediaId&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attachment&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;await&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Get&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;&amp;gt;(&lt;/span&gt;&lt;span class=&#34;s&#34;&gt;&amp;#34;/api/v1/media/&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;+&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;mediaId&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;prev&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PreviewUrl&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;kt&#34;&gt;var&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Url&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&#x9;&lt;span class=&#34;k&#34;&gt;return&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;attachment&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;finally&#34;&gt;&lt;a href=&#34;#finally&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Finally&#xA;&lt;/h2&gt;&lt;p&gt;So that was the last Pitfall. Now everything works:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;If a motion is detected my WebHook gets called&lt;/li&gt;&#xA;&lt;li&gt;The Webhook posts a previewimage as a direct toot (only be seen by me) to Mastodon including a Preview Image&lt;/li&gt;&#xA;&lt;li&gt;If &amp;ldquo;fav&amp;rdquo; the toot when this is a valid Squirrel detection&lt;/li&gt;&#xA;&lt;li&gt;The Bot checks for new Favs and finds mine&lt;/li&gt;&#xA;&lt;li&gt;The according Video is found in the LiteDB&lt;/li&gt;&#xA;&lt;li&gt;The Video gets downloaded via SMB-Stuff&lt;/li&gt;&#xA;&lt;li&gt;The Video gets Resized by FfMpeg&lt;/li&gt;&#xA;&lt;li&gt;The resized video gets uploaded to Mastodon&lt;/li&gt;&#xA;&lt;li&gt;A public toot containing the video is created&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;(Using standard Mastodon-Features, all toots will get deleted after two weeks reducing the space required)&lt;/p&gt;&#xA;&lt;h3 id=&#34;but-why&#34;&gt;&lt;a href=&#34;#but-why&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;But WHY?&#xA;&lt;/h3&gt;&lt;p&gt;I am &lt;strong&gt;very&lt;/strong&gt; aware that this was mostly a waste of time. A lot of time for a simple &amp;ldquo;Lets show when there is a squirrel&amp;rdquo;. Simone Giertz once did a great TED - Talk &lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=c0bsKc4tiuY&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Why you should make useless things&lt;/a&gt;. While she talks about robots, by fun thing to do was alway coding. No matter how useless the results are.&#xA;So: Yes. I totally agree with her. Creating stupid things just because it is fun, with noone asking why this takes so long and even be able to quit if something becomes boring is a nice diversion to the normal coding reality I have for paying the rent.&lt;/p&gt;&#xA;&lt;p&gt;I hope you also had some fun reading this; I had writing it :)&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Two Apps at the same time: Deploy SharePoint Add-In to Cloud AND On-Premise</title>
            <link>https://dotnet.work/blog/two-apps-at-the-same-time/</link>
            <pubDate>Tue, 13 Dec 2016 12:00:00 +0100</pubDate><author>dotnet@oles.cloud (Ole Albers)</author>
            <guid>https://dotnet.work/blog/two-apps-at-the-same-time/</guid>
            <description>&lt;img src=&#34;https://dotnet.work/blog/two-apps-at-the-same-time/showBuildConfigurations-300x221_hu_6302578466ea388f.png&#34; alt=&#34;Featured image of post Two Apps at the same time: Deploy SharePoint Add-In to Cloud AND On-Premise&#34; /&gt;&lt;p&gt;What the fuzz is this about?&lt;/p&gt;&#xA;&lt;p&gt;I am not absolutely sure if I am the first one who did this, but it seems at least noone else wrote it down until now. :) We hat a customer who liked our Office365 Provider-Hosted App &amp;ldquo;Mydea&amp;rdquo;, but wanted us to install that on his SharePoint 2013 - Installation. In Germany a lot of companies do not trust the cloud. So we had three options:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;Tell the customer this does not work&lt;/li&gt;&#xA;&lt;li&gt;Copy&amp;amp;paste the whole solution and change it so it works on OnPrem&lt;/li&gt;&#xA;&lt;li&gt;Do something else&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;The first option - of course - wasn&amp;rsquo;t valid for me. The second would have worked. But I did not want to end up in maintanance hell. Our product is about innovation management. And the most innovative about that is the product itself. We develop agile, adding new features (and sometimes bugs) continuously. We do not want to do that twice.&lt;/p&gt;&#xA;&lt;p&gt;So I ended up on the third option: Changing my solution so it will run in an Office365 - SharePoint &lt;strong&gt;and&lt;/strong&gt; on an On-Premise installation of SharePoint 2013 (or above).&lt;/p&gt;&#xA;&lt;p&gt;Common sense about that path seems to be: &lt;em&gt;That does not work&lt;/em&gt;. But it does. It just is a real bumby road to get there. This also means: You should know the basics. You should have created at least one &lt;abbr title=&#34;Microsoft renamed &#39;Apps&#39; to &#39;Add-Ins&#39; Whenever I write one of those it is just always the same&#34;&gt;Add-In&lt;/abbr&gt; for Office365 and one for SharePoint 2013 or above. I will not explain these steps here (which are complicated enough for local installation). I also cannot help you there in the comments or by mail.&lt;/p&gt;&#xA;&lt;p&gt;There are plenty of documents out there that explain what&amp;rsquo;s needed for this. You should read those, first.&lt;/p&gt;&#xA;&lt;p&gt;If you find this article useful and earn lots of money because of it: Feel free to buy me a beer :)&lt;/p&gt;&#xA;&lt;h3 id=&#34;analyzing-the-differences-what-has-to-be-done&#34;&gt;&lt;a href=&#34;#analyzing-the-differences-what-has-to-be-done&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Analyzing the differences: What has to be done?&#xA;&lt;/h3&gt;&lt;p&gt;I started with an Office365-App and added the possibility to run that App under an OnPrem-Installation, too. But you should be able to go the other way with little modifications.&lt;/p&gt;&#xA;&lt;p&gt;My first step was to create two dummy &amp;ldquo;Hello World&amp;quot;ish Applications. One for O365 and one for an OnPrem-Installation and look at the source, to &amp;ldquo;diff&amp;rdquo; it. These are the conclusions I came around:&lt;/p&gt;&#xA;&lt;p&gt;At most of us use NuGet-Packages, that was the starting point. There are different Packages: You need the following:&lt;/p&gt;&#xA;&lt;p&gt;OnPrem: - AppForSharePointWebToolKit&lt;/p&gt;&#xA;&lt;p&gt;Office 365: - AppForSharePointOnlineWebToolKit - Microsoft.SharePointOnline.CSOM&lt;/p&gt;&#xA;&lt;p&gt;These Packages result in different DLLs with the Prefix &lt;em&gt;&amp;ldquo;Microsoft.SharePoint.Client.*&amp;rdquo;&lt;/em&gt;, but different Versions. OnPrem: - Version 15.xxx Office 365: - Version 16.xxx&lt;/p&gt;&#xA;&lt;p&gt;The Sourcecode of the *.cs - files created by that NuGet-Packages (_SharePointContext.cs_ &amp;amp; _Tokenhelper.cs_) are exactly the same. So no need to change anything there.&lt;/p&gt;&#xA;&lt;p&gt;Finally you usually store your Office365-Apps on Azure, but don&amp;rsquo;t for On-Premise-Installations. This results in different Authentications: OnPrem: - Using Certificates - Using Windows Authentication&lt;/p&gt;&#xA;&lt;p&gt;Office 365: - Using ClientSecret - Using OAuth Authentication&lt;/p&gt;&#xA;&lt;p&gt;These Informations are stored inside the &lt;em&gt;Web.Config&lt;/em&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;before-we-start&#34;&gt;&lt;a href=&#34;#before-we-start&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Before we start&#xA;&lt;/h3&gt;&lt;p&gt;&lt;strong&gt;Create a new Branch in your repository.&lt;/strong&gt; You never know what can go wrong :)&lt;/p&gt;&#xA;&lt;h3 id=&#34;the-web-project-mvc-most-likely&#34;&gt;&lt;a href=&#34;#the-web-project-mvc-most-likely&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;The Web-Project (MVC most likely)&#xA;&lt;/h3&gt;&lt;h5 id=&#34;creating-different-build-configurations&#34;&gt;&lt;a href=&#34;#creating-different-build-configurations&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Creating different Build configurations&#xA;&lt;/h5&gt;&lt;p&gt;The main purpose if this action was to have just one CodeBase for both versions. So new features or bugfixes have only to be made once. No extra code, no branch, no nothing.&lt;/p&gt;&#xA;&lt;p&gt;So I started by creating new Build Configurations. You can create them using &amp;ldquo;Build - Configuration Manager&amp;rdquo;: &lt;img alt=&#34;Show Build Configurations&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;325px&#34; data-flex-grow=&#34;135&#34; height=&#34;221&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/two-apps-at-the-same-time/showBuildConfigurations-300x221_hu_6302578466ea388f.png&#34; width=&#34;300&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt; &lt;/p&gt;&#xA;&lt;p&gt;Create two Configurations. One for Debug and one for Release. Make sure to copy the Settings from the existing &amp;ldquo;Debug&amp;rdquo;- and &amp;ldquo;Release&amp;rdquo;-Configuration &lt;img alt=&#34;New build configuration&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;331px&#34; data-flex-grow=&#34;138&#34; height=&#34;217&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/two-apps-at-the-same-time/newBuildConfiguration-300x217_hu_48cb9448667d9621.png&#34; width=&#34;300&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;At this point, only do this for your web project and - if you have - any backend-projects that are used by your webproject. We will add others later on, but this way you have the chance to validate every single step:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;Changed build configurations&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;328px&#34; data-flex-grow=&#34;136&#34; height=&#34;219&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/two-apps-at-the-same-time/buildConfigurationShow-300x219_hu_9fb22bccea96f250.png&#34; width=&#34;300&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Now its time to create your config file. Find your web.config, click on it with the right mouse button and select &amp;ldquo;Add config transform&amp;rdquo;. After that you should have a Config file for each configuration&lt;/p&gt;&#xA;&lt;h5 id=&#34;nuget-references&#34;&gt;&lt;a href=&#34;#nuget-references&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Nuget-References&#xA;&lt;/h5&gt;&lt;p&gt;I used the PnP - Packages to develop our O365-Add-In. If you only use the &amp;ldquo;base&amp;rdquo; Packages that come with the Add-In-Solution-Template you might have different packages. Nonetheless you will always have a package &lt;em&gt;&amp;ldquo;AppForSharePointOnlineWebToolKit&amp;rdquo;&lt;/em&gt;.&lt;/p&gt;&#xA;&lt;p&gt;Package-wise the main difference between the O365/OnPrem - road are the Azure- and OAuth-packages that are only on the 365-PnP. Also the Office365 Libraries use Version 16, While OnPrem use Version 15.&lt;/p&gt;&#xA;&lt;p&gt;To be able to keep your application updated no matter what configuration you use, create two dummy projects e.g. &lt;em&gt;dummy365&lt;/em&gt; &amp;amp; &lt;em&gt;dummyOnprem&lt;/em&gt;. It does not matter what kind of projects these are. The only purpose of these projects is that there are always the packages for both O365 and OnPrem in the &lt;em&gt;./packages&lt;/em&gt; - folder.&lt;/p&gt;&#xA;&lt;p&gt;Add the O365-pnp-NuGet-packages to your dummy365 and the 2013-pnp-nuget-package to your dummyOnPrem&lt;/p&gt;&#xA;&lt;p&gt;Now: Before you continue, **make a backup of you .csproj - file. It conains information that will be lost after the next step.&lt;/p&gt;&#xA;&lt;p&gt;Now add the &amp;ldquo;other&amp;rdquo; PnP-Package. If you already have the &lt;em&gt;SharePointPnPCoreOnline&lt;/em&gt;-Package installed. now install the &lt;em&gt;SharePointPnpCore2013&lt;/em&gt; NuGet-Package (and vice-versa)&lt;/p&gt;&#xA;&lt;h5 id=&#34;csproj-changes&#34;&gt;&lt;a href=&#34;#csproj-changes&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;csProj-Changes&#xA;&lt;/h5&gt;&lt;p&gt;You can now diff your csproj - files before and after. Or simply believe my words: There are now two differences. One of them is the &lt;em&gt;OfficeDevPnP.Core&lt;/em&gt; - package. The &lt;em&gt;HintPath&lt;/em&gt; from the O365 contains &lt;em&gt;SharePointPnPCoreOnline&lt;/em&gt;, the &lt;em&gt;HintPath&lt;/em&gt; from the 2013-Version contains &lt;em&gt;SharePointPnpCore2013&lt;/em&gt;. This does not seem to be an issue as both DLLs are identical. Nonetheless we will have a look at it. Just in case.&lt;/p&gt;&#xA;&lt;p&gt;The more interesting detail is the Reference to &lt;em&gt;&amp;ldquo;Microsoft.Online.SharePoint.Client.Tenant&amp;rdquo;&lt;/em&gt;. The Office365 - Version uses Version 16.x and the OnPrem - Version uses 15.x. This is absolutely something we have to care about.&lt;/p&gt;&#xA;&lt;p&gt;Luckily, the csProj allows some conditions. So create the following new lines:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;ItemGroup Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug.OnPrem&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release.OnPrem&amp;#39;&amp;#34;&amp;gt;&#xA;&amp;lt;Reference Include=&amp;#34;Microsoft.Online.SharePoint.Client.Tenant, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL&amp;#34;&amp;gt;&#xA;&amp;lt;HintPath&amp;gt;..\\packages\\SharePointPnPCore2013.2.9.1611.0\\lib\\net45\\Microsoft.Online.SharePoint.Client.Tenant.dll&amp;lt;/HintPath&amp;gt;&#xA;&amp;lt;Private&amp;gt;True&amp;lt;/Private&amp;gt;&#xA;&amp;lt;/Reference&amp;gt;&#xA;&amp;lt;Reference Include=&amp;#34;OfficeDevPnP.Core, Version=2.9.1611.0, Culture=neutral, PublicKeyToken=3751622786b357c2, processorArchitecture=MSIL&amp;#34;&amp;gt;&#xA;&amp;lt;HintPath&amp;gt;..\\packages\\SharePointPnPCore2013.2.9.1611.0\\lib\\net45\\OfficeDevPnP.Core.dll&amp;lt;/HintPath&amp;gt;&#xA;&amp;lt;Private&amp;gt;True&amp;lt;/Private&amp;gt;&#xA;&amp;lt;/Reference&amp;gt;&#xA;&amp;lt;/ItemGroup&amp;gt;&#xA;&#xA;&amp;lt;ItemGroup Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release&amp;#39;&amp;#34;&amp;gt;&#xA;&amp;lt;Reference Include=&amp;#34;Microsoft.Online.SharePoint.Client.Tenant, Version=16.1.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL&amp;#34;&amp;gt;&#xA;&amp;lt;HintPath&amp;gt;..\\packages\\Microsoft.SharePointOnline.CSOM.16.1.5813.1200\\lib\\net45\\Microsoft.Online.SharePoint.Client.Tenant.dll&amp;lt;/HintPath&amp;gt;&#xA;&amp;lt;Private&amp;gt;True&amp;lt;/Private&amp;gt;&#xA;&amp;lt;/Reference&amp;gt;&#xA;&#xA;&amp;lt;Reference Include=&amp;#34;OfficeDevPnP.Core, Version=2.9.1611.0, Culture=neutral, PublicKeyToken=3751622786b357c2, processorArchitecture=MSIL&amp;#34;&amp;gt;&#xA;&amp;lt;HintPath&amp;gt;..\\packages\\SharePointPnPCoreOnline.2.9.1611.0\\lib\\net45\\OfficeDevPnP.Core.dll&amp;lt;/HintPath&amp;gt;&#xA;&amp;lt;Private&amp;gt;True&amp;lt;/Private&amp;gt;&#xA;&amp;lt;/Reference&amp;gt;&#xA;&amp;lt;/ItemGroup&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;strong&gt;Do not just copy/paste the content from here!&lt;/strong&gt; Use the lines from within &lt;strong&gt;your&lt;/strong&gt; csProj-File instead! Versions will change over time. And when you read these lines, my version used might already be outdated.&lt;/p&gt;&#xA;&lt;p&gt;As a last step, remove the original lines from within the main &lt;em&gt;ItemGroup&lt;/em&gt; containing these two libraries.&lt;/p&gt;&#xA;&lt;p&gt;Well done. You should now try to rebuild your solution on all your four Build configurations, where the OnPrem-Configurations should create a &lt;em&gt;Microsoft.Online.SharePoint.Client.Tenant.dll&lt;/em&gt; with Version 15 in your bin-directory and the Office365-Version should create a V16-dll. If you encounter a problem try to unload and reload the projects.&lt;/p&gt;&#xA;&lt;p&gt;Please be advised: I am not sure what happens if you update one of those two Nuget-Packages. You might have to modify your csproj-file again&lt;/p&gt;&#xA;&lt;h5 id=&#34;webconfig&#34;&gt;&lt;a href=&#34;#webconfig&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Web.Config&#xA;&lt;/h5&gt;&lt;p&gt;Now its time to modify your Web.Configs.&lt;/p&gt;&#xA;&lt;p&gt;Add the following lines just before the closing &lt;em&gt;&amp;quot;&lt;/configuration&gt;&amp;rdquo;&lt;/em&gt; section into your *.OnPrem.config - files:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;runtime&amp;gt;&#xA;&amp;lt;assemblyBinding xmlns=&amp;#34;urn:schemas-microsoft-com:asm.v1&amp;#34;&amp;gt;&#xA;&amp;lt;dependentAssembly xdt:Transform=&amp;#34;Replace&amp;#34; xdt:Locator=&amp;#34;Condition(./\_defaultNamespace:assemblyIdentity/@name=&amp;#39;Microsoft.Online.SharePoint.Client.Tenant&amp;#39;)&amp;#34;&amp;gt;&#xA;&amp;lt;assemblyIdentity name=&amp;#34;Microsoft.Online.SharePoint.Client.Tenant&amp;#34; publicKeyToken=&amp;#34;71e9bce111e9429c&amp;#34; culture=&amp;#34;neutral&amp;#34; /&amp;gt;&#xA;&amp;lt;bindingRedirect oldVersion=&amp;#34;0.0.0.0-15.0.0.0&amp;#34; newVersion=&amp;#34;15.0.0.0&amp;#34; /&amp;gt;&#xA;&amp;lt;/dependentAssembly&amp;gt;&#xA;&amp;lt;/assemblyBinding&amp;gt;&#xA;&amp;lt;/runtime&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As before: If at time of reading, the most current version is not 15.0, but 15.1 or higher replace the version numbers instead.&lt;/p&gt;&#xA;&lt;p&gt;Now it is time to modify your &amp;ldquo;normal&amp;rdquo; Configs for Debug and Release&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;runtime&amp;gt;&#xA;&amp;lt;assemblyBinding xmlns=&amp;#34;urn:schemas-microsoft-com:asm.v1&amp;#34;&amp;gt;&#xA;&amp;lt;dependentAssembly xdt:Transform=&amp;#34;Replace&amp;#34; xdt:Locator=&amp;#34;Condition(./\_defaultNamespace:assemblyIdentity/@name=&amp;#39;Microsoft.Online.SharePoint.Client.Tenant&amp;#39;)&amp;#34;&amp;gt;&#xA;&amp;lt;assemblyIdentity name=&amp;#34;Microsoft.Online.SharePoint.Client.Tenant&amp;#34; publicKeyToken=&amp;#34;71e9bce111e9429c&amp;#34; culture=&amp;#34;neutral&amp;#34; /&amp;gt;&#xA;&amp;lt;bindingRedirect oldVersion=&amp;#34;0.0.0.0-16.1.0.0&amp;#34; newVersion=&amp;#34;16.1.0.0&amp;#34; /&amp;gt;&#xA;&amp;lt;/dependentAssembly&amp;gt;&#xA;&amp;lt;/assemblyBinding&amp;gt;&#xA;&amp;lt;/runtime&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This is not 100% necessary at this time as these values should already be in the main Web.Config, but this makes sure it still works if that changes. Again: Check the version number.&lt;/p&gt;&#xA;&lt;h3 id=&#34;authentication&#34;&gt;&lt;a href=&#34;#authentication&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Authentication&#xA;&lt;/h3&gt;&lt;p&gt;Your O365 - Config Files should still contain something like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;appSettings&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientValidationEnabled&amp;#34; value=&amp;#34;true&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;UnobtrusiveJavaScriptEnabled&amp;#34; value=&amp;#34;true&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientId&amp;#34; value=&amp;#34;aaaaaaaa-beef-face-bbbb-cchcchcchcch&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientSecret&amp;#34; value=&amp;#34;lsdschnabbeldiwuppsfkjashriuae=&amp;#34; /&amp;gt;&#xA;&amp;lt;/appSettings&amp;gt;&#xA;`now your OnPrem-configs looks a little bit different:`&#xA;&amp;lt;appSettings&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientValidationEnabled&amp;#34; value=&amp;#34;true&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;UnobtrusiveJavaScriptEnabled&amp;#34; value=&amp;#34;true&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientId&amp;#34; value=&amp;#34;aaaaaaaa-beed-face-bbbb-cchcchcchcch&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientSigningCertificatePath&amp;#34; value=&amp;#34;C:\\Certs\\myCert.pfx&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;ClientSigningCertificatePassword&amp;#34; value=&amp;#34;p@ssw0rd&amp;#34; /&amp;gt;&#xA;&amp;lt;add key=&amp;#34;IssuerId&amp;#34; value=&amp;#34;bbbbbbbb-beef-face-bbbb-cchcchcchcch&amp;#34; /&amp;gt;&#xA;&amp;lt;/appSettings&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The main difference here is that you don&amp;rsquo;t just use a ClientId/ClientSecret - Combination for an OnPrem-Installation but have to use a Certificate. I will not describe here how to obtain it. It is just the &amp;ldquo;normal&amp;rdquo; OnPrem-procedure for provider hosted apps. Also be aware that the IssuerId is &lt;strong&gt;not&lt;/strong&gt; the ClientId.&lt;/p&gt;&#xA;&lt;p&gt;If you need help on this part: There are plenty of documents about this. For example on&lt;a class=&#34;link&#34; href=&#34;https://msdn.microsoft.com/en-us/library/office/fp179901.aspx&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;MSDN&lt;/a&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;backend-webjobs-and-other-projects-that-talk-directly-to-sharepoint&#34;&gt;&lt;a href=&#34;#backend-webjobs-and-other-projects-that-talk-directly-to-sharepoint&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Backend, Webjobs and other projects that talk directly to SharePoint&#xA;&lt;/h3&gt;&lt;h5 id=&#34;appconfig&#34;&gt;&lt;a href=&#34;#appconfig&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;App.Config&#xA;&lt;/h5&gt;&lt;p&gt;If you have any other Projects than the Web Project and the AddIn, you might have to do some extra steps. For example if you use a backend-project, you have to modify that, too. Ignore this chapter if you don&amp;rsquo;t have any additional projects.&lt;/p&gt;&#xA;&lt;p&gt;But if you have any console application (like Azure WebJobs) you have to modify those configs, too. Sadly. Config-transform does not work out of the box with App.Config - files. But there is a way to change that.&lt;/p&gt;&#xA;&lt;p&gt;First: Create your Config Files manually. So select Add - New Item and select &amp;ldquo;&lt;em&gt;Application Config File&lt;/em&gt;&amp;rdquo;. Name it &lt;em&gt;App.OnPrem.config&lt;/em&gt;. Now open the csProj-File with Notepad. Look for an &lt;em&gt;ItemGroup&lt;/em&gt; containing the App.Config. There already should be an &lt;em&gt;App.Debug.config&lt;/em&gt; and &lt;em&gt;App.Release.config&lt;/em&gt; with a &amp;ldquo;&lt;em&gt;DependentUpon&lt;/em&gt;&amp;rdquo; - Attribute. Just copy that attribute to your newly created files. So that you end with something like this:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;ItemGroup&amp;gt;&#xA;&amp;lt;None Include=&amp;#34;App.config&amp;#34; /&amp;gt;&#xA;&amp;lt;None Include=&amp;#34;App.Debug.config&amp;#34;&amp;gt;&#xA;&amp;lt;DependentUpon&amp;gt;App.config&amp;lt;/DependentUpon&amp;gt;&#xA;&amp;lt;/None&amp;gt;&#xA;&amp;lt;None Include=&amp;#34;App.Debug.OnPrem.config&amp;#34; &amp;gt;&#xA;&amp;lt;DependentUpon&amp;gt;App.config&amp;lt;/DependentUpon&amp;gt;&#xA;&amp;lt;/None&amp;gt;&#xA;&amp;lt;None Include=&amp;#34;App.Release.OnPrem.config&amp;#34; &amp;gt;&#xA;&amp;lt;DependentUpon&amp;gt;App.config&amp;lt;/DependentUpon&amp;gt;&#xA;&amp;lt;/None&amp;gt;&#xA;&amp;lt;None Include=&amp;#34;App.Release.config&amp;#34;&amp;gt;&#xA;&amp;lt;DependentUpon&amp;gt;App.config&amp;lt;/DependentUpon&amp;gt;&#xA;&amp;lt;/None&amp;gt;&#xA;&amp;lt;/ItemGroup&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;After that all your OnPrem-Configs should be displayed as children from App.Config in Visual Studio (2015). Now transform should work. You can check your csproj - File. If there is something like &lt;em&gt;&amp;lt;UsingTask TaskName=&amp;ldquo;TransformXml&amp;rdquo; ../&amp;gt;&lt;/em&gt; in it you are ready to go. If not, you are probably using an older Visual Studio version. I would not advise it, but you can go with it, but have to do some extra steps: &lt;a class=&#34;link&#34; href=&#34;http://harrewijnen.net/app-config-xdt-transforms/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;XDT Transforms for older VS Versions&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Now its the same fun again with the config files as before. So add the same stuff into the App.*.config - files as you have done with the web.configs. In addtion add the transform Property to the configuration tag, so it looks like this: &lt;configuration xmlns:xdt=&#34;http://schemas.microsoft.com/XML-Document-Transform&#34;&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;test-what-you-have-done-until-now&#34;&gt;&lt;a href=&#34;#test-what-you-have-done-until-now&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Test what you have done until now&#xA;&lt;/h3&gt;&lt;p&gt;Now you should build your Solution for all four configurations. Check if all DLLs where created correctly for the O365 and OnPrem-Configurations. Deploy your application still with the O365 - Settings. Everything should look like before.&lt;/p&gt;&#xA;&lt;h3 id=&#34;changes-on-the-web-project&#34;&gt;&lt;a href=&#34;#changes-on-the-web-project&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Changes on the Web Project&#xA;&lt;/h3&gt;&lt;p&gt;Now it is time to modify your main SharePoint-Project.&lt;/p&gt;&#xA;&lt;p&gt;First of all: Add your SharePoint-Project to the build configurations. The good thing is: This time you don&amp;rsquo;t have to care about the configs. There will most likely be an app.config in your SharePoint-project, but you can just ignore it, because there are no real references in this project.&lt;/p&gt;&#xA;&lt;h5 id=&#34;sharepoint---url&#34;&gt;&lt;a href=&#34;#sharepoint---url&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;SharePoint - URL&#xA;&lt;/h5&gt;&lt;p&gt;The (nearly) final step is to put the right SharePoint-URL to your AddIn-Project depending on your Configuration. The simple way is to just enter the right URL each time you start debugging. The more complex (but better) way is to go the same way as you did with the MVC (Server) part. To do this, enter your Build-Configuration Settings again and set &amp;ldquo;&lt;em&gt;Debug.OnPrem&lt;/em&gt;&amp;rdquo; and &amp;ldquo;&lt;em&gt;Release.OnPrem&lt;/em&gt;&amp;rdquo; for your AddIn-Project.&lt;/p&gt;&#xA;&lt;p&gt;The URL is stored in the user-settings instead of the project settings. But you can use the same magic to make a conditional path there. Open the file YourApp.csproj.user and add the condition to the &amp;ldquo;SharePointSiteUrl&amp;rdquo; - entry:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;PropertyGroup&amp;gt;&#xA;&amp;lt;SharePointSiteUrl Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug.OnPrem&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release.OnPrem&amp;#39;&amp;#34;&amp;gt;http://myDevMachine:10000/sites/Dev\_Ole/&amp;lt;/SharePointSiteUrl&amp;gt;&#xA;&amp;lt;SharePointSiteUrl Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release&amp;#39;&amp;#34;&amp;gt;https://my365AppName.sharepoint.com/sites/dev-ole/&amp;lt;/SharePointSiteUrl&amp;gt;&#xA;&amp;lt;/PropertyGroup&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;IF you want you can also simply delete the user-file and put these values into your main .csproj. Sadly this cannot be loaded &amp;ldquo;on the fly&amp;rdquo; by switching your Build configuration . You have to unload and reload your project for this setting to be re-read. This is no issue when deploying your solution using an automated build (like tfs online), but while debugging locally.&lt;/p&gt;&#xA;&lt;h5 id=&#34;target-office-version--sharepoint-url&#34;&gt;&lt;a href=&#34;#target-office-version--sharepoint-url&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Target office version &amp;amp; SharePoint-URL&#xA;&lt;/h5&gt;&lt;p&gt;The csproj - file contains an entry called &amp;ldquo;&lt;em&gt;TargetOfficeVersion&lt;/em&gt;&amp;rdquo; which should contain the value &amp;ldquo;16.1&amp;rdquo;. Just like before we need to modify this using conditional values.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;TargetOfficeVersion Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release&amp;#39;&amp;#34;&amp;gt;16.1&amp;lt;/TargetOfficeVersion&amp;gt;&#xA;&amp;lt;TargetOfficeVersion Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug.OnPrem&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release.OnPrem&amp;#39;&amp;#34;&amp;gt;15.0&amp;lt;/TargetOfficeVersion&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;You can validate this setting while selecting the properties of the project and display the &amp;ldquo;Sharepoint&amp;rdquo;-Tab. Under &amp;ldquo;Target Sharepoint version&amp;rdquo; it should say &amp;ldquo;SharePoint 2013&amp;rdquo; if 15.0 is used or &amp;ldquo;SharePoint Online&amp;rdquo; if 16.1 is used.&lt;/p&gt;&#xA;&lt;h5 id=&#34;authentication-1&#34;&gt;&lt;a href=&#34;#authentication-1&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Authentication&#xA;&lt;/h5&gt;&lt;p&gt;Office365 uses OAuth for Authentication. For SharePoint 2013 you have to use Windows Authentication instead. As I wrote before: There are a few documents out there explaining the Certificate-Part. But you also have to tell your project to use Windows Authentication. Again we use the same conditions like before, but this time use it for the IISExpressAuth:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;IISExpressWindowsAuthentication Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug.OnPrem&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release.OnPrem&amp;#39;&amp;#34;&amp;gt;enabled&amp;lt;/IISExpressWindowsAuthentication&amp;gt;&#xA;&amp;lt;IISExpressWindowsAuthentication Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release&amp;#39;&amp;#34;&amp;gt;disabled&amp;lt;/IISExpressWindowsAuthentication&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h5 id=&#34;appmanifest&#34;&gt;&lt;a href=&#34;#appmanifest&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;AppManifest&#xA;&lt;/h5&gt;&lt;p&gt;The Appmanifest does not allow any conditional entries. That&amp;rsquo;s why we have to create a copy of it and do the conditional stuff inside the csproj file. So first create a copy called AppManifest.OnPrem.xmlns&lt;/p&gt;&#xA;&lt;p&gt;In that file change the &amp;ldquo;SharePointMinVersion&amp;rdquo; from &lt;em&gt;16.0.0.0&lt;/em&gt; to &lt;em&gt;15.0.0.0&lt;/em&gt; in the &amp;ldquo;&lt;em&gt;App&lt;/em&gt;&amp;quot;-Section.&lt;/p&gt;&#xA;&lt;p&gt;Now it is finally time again to modify the csproj - File. You should be used to it by now :)&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;&amp;lt;ItemGroup Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug.OnPrem&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release.OnPrem&amp;#39;&amp;#34;&amp;gt;&#xA;&amp;lt;AppManifestFile Include=&amp;#34;AppManifest.OnPrem.xml&amp;#34;&amp;gt;&#xA;&amp;lt;SubType&amp;gt;Designer&amp;lt;/SubType&amp;gt;&#xA;&amp;lt;/AppManifestFile&amp;gt;&#xA;&amp;lt;/ItemGroup&amp;gt;&#xA;&amp;lt;ItemGroup Condition=&amp;#34;&amp;#39;$(Configuration)&amp;#39;==&amp;#39;Debug&amp;#39; Or &amp;#39;$(Configuration)&amp;#39;==&amp;#39;Release&amp;#39;&amp;#34;&amp;gt;&#xA;&amp;lt;AppManifestFile Include=&amp;#34;AppManifest.xml&amp;#34;&amp;gt;&#xA;&amp;lt;SubType&amp;gt;Designer&amp;lt;/SubType&amp;gt;&#xA;&amp;lt;/AppManifestFile&amp;gt;&#xA;&amp;lt;/ItemGroup&amp;gt;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; &lt;/p&gt;&#xA;&lt;h2 id=&#34;things-to-mention-on-v-150-sharepoint-2013&#34;&gt;&lt;a href=&#34;#things-to-mention-on-v-150-sharepoint-2013&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Things to mention on V 15.0 (SharePoint 2013)&#xA;&lt;/h2&gt;&lt;p&gt;While most of the code works on Version 15.0 as well on 16.1, there are some minor differences between these two. The following issues appeared on my project: - FieldUserValue has no Property &amp;ldquo;Email&amp;rdquo; - Microsoft.Client.SharePoint.Folder has no &amp;ldquo;Exists()&amp;rdquo; Both work on 16.1 but not on 15.0. So you have to write your own code to get around this issue.&lt;/p&gt;&#xA;&lt;h3 id=&#34;custom-compiler-symbols&#34;&gt;&lt;a href=&#34;#custom-compiler-symbols&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Custom Compiler Symbols&#xA;&lt;/h3&gt;&lt;p&gt;Because of the differences between V16 and V15 you might want to have custom code depending on your configuration. Just like the DEBUG - Symbol you can add your custom Symbol for the OnPrem-Configurations. Just select the properties of each project you need that symbol in, select the Build - tab and into &amp;ldquo;_Conditional compilation symbol_s&amp;rdquo; enter &amp;ldquo;&lt;em&gt;ONPREM&lt;/em&gt;&amp;rdquo; (or whatever you like):&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;symbol&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;612px&#34; data-flex-grow=&#34;255&#34; height=&#34;278&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/two-apps-at-the-same-time/symbol_hu_350c26df9784dc31.png&#34; width=&#34;710&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Afterwards you can use the following code:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;#if OnPrem&#xA;var userMail=GetMailFromUser(fieldUserValue); &#xA;#else &#xA;var userMail=FieldUserValue.Email;&#xA;#endif&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;h2 id=&#34;final-thoughts&#34;&gt;&lt;a href=&#34;#final-thoughts&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Final thoughts&#xA;&lt;/h2&gt;&lt;p&gt;You are done now. Just keep in mind: If you use any Azure-connections (e.g. for caching, insights, blob-storage) you will have to handle that, too if you need to get rid of any external connection. The custom Compiler Symbols should help you with that task&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>FlashAirDownloader 2</title>
            <link>https://dotnet.work/blog/flashairdownloader-2/</link>
            <pubDate>Sun, 01 May 2016 12:00:00 +0200</pubDate><author>dotnet@oles.cloud (Ole Albers)</author>
            <guid>https://dotnet.work/blog/flashairdownloader-2/</guid>
            <description>&lt;img src=&#34;https://dotnet.work/blog/flashairdownloader-2/autocopy_hu_dd06e496e28f5a46.png&#34; alt=&#34;Featured image of post FlashAirDownloader 2&#34; /&gt;&lt;blockquote class=&#34;alert alert-warning&#34;&gt;&#xA;        &lt;div class=&#34;alert-header&#34;&gt;&#xA;            &lt;span class=&#34;alert-icon&#34;&gt;⚠️&lt;/span&gt;&#xA;            &lt;span class=&#34;alert-title&#34;&gt;Warning&lt;/span&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;div class=&#34;alert-body&#34;&gt;&#xA;            &lt;p&gt;&lt;strong&gt;Development stopped!&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://dotnet.work/blog/flashairdownloader-development-now-its-your-turn/&#34; &gt;Please read this&lt;/a&gt; before downloading FAD&lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;    &lt;/blockquote&gt;&#xA;&lt;blockquote class=&#34;alert alert-note&#34;&gt;&#xA;        &lt;div class=&#34;alert-header&#34;&gt;&#xA;            &lt;span class=&#34;alert-icon&#34;&gt;📝&lt;/span&gt;&#xA;            &lt;span class=&#34;alert-title&#34;&gt;Note&lt;/span&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;div class=&#34;alert-body&#34;&gt;&#xA;            &lt;p&gt;Keep your Version updated! Always click onto the &amp;ldquo;Check for Updates&amp;rdquo; in the Program after installation&lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;The FlashAirDownloader 2 is out there (Because of my Laziness I will just call it FAD from now on)&lt;/p&gt;&#xA;&lt;p&gt;A lot of people used the FlashAirDownloader which was meant as a personal tool and quick hack to access my Toshiba FlashAir Card. As more and more people asked me for features (and some for the code) I decided to make it open source so more folks can help improve the tool.&lt;/p&gt;&#xA;&lt;p&gt;Sadly so: The code was a mess. As I told you: Just a quick hack. It would be to embarrassing to make this public :D So I decided to rewrite it from scratch: This time making it right regarding code quality and UI design. Nonetheless this program still uses Framework 4.0, cause I know there are Windows XP users out there who have no other possibilities to access the FlashAir.&lt;/p&gt;&#xA;&lt;p&gt;But enough of talk. Here is the new FAD:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img class=&#34;gallery-image&#34; data-flex-basis=&#34;436px&#34; data-flex-grow=&#34;181&#34; height=&#34;620&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/flashairdownloader-2/autocopy_hu_dd06e496e28f5a46.png&#34; srcset=&#34;https://dotnet.work/blog/flashairdownloader-2/autocopy_hu_c1dcdd4024d23a07.png 800w, https://dotnet.work/blog/flashairdownloader-2/autocopy_hu_dd06e496e28f5a46.png 1127w&#34; width=&#34;1127&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;You can &lt;a class=&#34;link&#34; href=&#34;https://github.com/OleAlbers/fad2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;download the source directly from Github&lt;/a&gt;. Feel free to make the code better. Or download the binary here:&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;(The download from the old site is gone, please build from source.)&lt;/em&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;You will get an annoying amount of warnings from your browser and/or operating system. This is because the file isn&amp;rsquo;t signed. Valid signing requires a valid certificate which does not come for free. (and requires some amount of work) Feel free to build from source in GitHub if you have any doubts.&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;h2 id=&#34;first-start&#34;&gt;&lt;a href=&#34;#first-start&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;First start&#xA;&lt;/h2&gt;&lt;p&gt;After Installation and starting FAD you should see something like this:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img class=&#34;gallery-image&#34; data-flex-basis=&#34;377px&#34; data-flex-grow=&#34;157&#34; height=&#34;730&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/flashairdownloader-2/searching-card_hu_253f747665c1ef66.png&#34; srcset=&#34;https://dotnet.work/blog/flashairdownloader-2/searching-card_hu_216bdb2a59a5aeb4.png 800w, https://dotnet.work/blog/flashairdownloader-2/searching-card_hu_253f747665c1ef66.png 1147w&#34; width=&#34;1147&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;If your FlashAir - card is already configured it should be found and the display should change to this:&lt;/p&gt;&#xA;&lt;p&gt;&lt;img class=&#34;gallery-image&#34; data-flex-basis=&#34;375px&#34; data-flex-grow=&#34;156&#34; height=&#34;738&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/flashairdownloader-2/foundcard_hu_161662514a5c1345.png&#34; srcset=&#34;https://dotnet.work/blog/flashairdownloader-2/foundcard_hu_fded45859a3bddeb.png 800w, https://dotnet.work/blog/flashairdownloader-2/foundcard_hu_161662514a5c1345.png 1154w&#34; width=&#34;1154&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;For now: Keep calm and do not click on any of the blue squares. Use &amp;ldquo;File/Settings&amp;rdquo; instead.&lt;/p&gt;&#xA;&lt;h2 id=&#34;setup&#34;&gt;&lt;a href=&#34;#setup&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Setup&#xA;&lt;/h2&gt;&lt;p&gt;&lt;img class=&#34;gallery-image&#34; data-flex-basis=&#34;443px&#34; data-flex-grow=&#34;184&#34; height=&#34;745&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/flashairdownloader-2/settings1_hu_56098891be23d5a3.png&#34; srcset=&#34;https://dotnet.work/blog/flashairdownloader-2/settings1_hu_d53401fe7a55266a.png 800w, https://dotnet.work/blog/flashairdownloader-2/settings1_hu_56098891be23d5a3.png 1376w&#34; width=&#34;1376&#34;&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;program-settings&#34;&gt;&lt;a href=&#34;#program-settings&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Program Settings&#xA;&lt;/h3&gt;&lt;p&gt;Check if your settings are ok. Here is a small description from the settings:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;FlashAir Url This is the Url from your FlashAir. You can try if you can access your FlashAir by entering that address into your Browser&lt;/li&gt;&#xA;&lt;li&gt;Local Path Here the Images will be saved when using the Auto-Mode&lt;/li&gt;&#xA;&lt;li&gt;Existing Files (Auto mode) Decide what to do if the file already exists.&lt;/li&gt;&#xA;&lt;li&gt;Delete files after downloading (Auto mode) If checked, the files will be deleted after a successful download from the FlashAir&lt;/li&gt;&#xA;&lt;li&gt;Flashair Imagepath Where your Images are located (may contain subfolders)&lt;/li&gt;&#xA;&lt;li&gt;Filetypes to copy (Auto mode) Decide if you only want image files or other files, too&lt;/li&gt;&#xA;&lt;li&gt;Load Thumbnails If enabled Thumbnails from Images on the FlashAir will be collected and shown. Might take a while. Thumbnails for local files are always displayed regardless of this setting.&lt;/li&gt;&#xA;&lt;li&gt;Automatic folder Creation (Auto Mode) * Multiple Cards Use your Card ID or AppID to create subfolders if you use more than one card * Create By Date Decide in what format the directories should be named * Custom You can als create your own custom path. {0} stands for the CardId, {1} for the AppId and {2} for the current date. Examples about the date-format &lt;a class=&#34;link&#34; href=&#34;http://www.csharp-examples.net/string-format-datetime/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;can be found here&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;Styling Decide if (and what) images should be displayed on the start page and the settings page of FAD.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Don&amp;rsquo;t forget to click onto [Save] under Card Settings in the lower left area of the screen.&lt;/p&gt;&#xA;&lt;h3 id=&#34;card-settings&#34;&gt;&lt;a href=&#34;#card-settings&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Card Settings&#xA;&lt;/h3&gt;&lt;p&gt;Now after the application is set up it is time to check your FlashAir-Card. Just put your SD-Card into the computer and click onto [Load] in the upper left corner. After a few seconds three new tabs should appear: &amp;ldquo;Vendor&amp;rdquo;, &amp;ldquo;WLANSD&amp;rdquo; and &amp;ldquo;Disable Functions&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;&lt;img class=&#34;gallery-image&#34; data-flex-basis=&#34;444px&#34; data-flex-grow=&#34;185&#34; height=&#34;739&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/flashairdownloader-2/settings2_hu_1f9588edf82daffb.png&#34; srcset=&#34;https://dotnet.work/blog/flashairdownloader-2/settings2_hu_fa17fd284fd9eec8.png 800w, https://dotnet.work/blog/flashairdownloader-2/settings2_hu_1f9588edf82daffb.png 1370w&#34; width=&#34;1370&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;Click onto &amp;ldquo;Vendor&amp;rdquo; to setup the most important settings. I will only describe the most critical values. A complete list is available &lt;a class=&#34;link&#34; href=&#34;https://flashair-developers.com/en/documents/api/config/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;at the Toshiba FlashAir Website.&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;First make sure the Connection Timeout is correct. It must be at least 1 Minute. You can also set it to &amp;ldquo;0&amp;rdquo; to disable timeout completely. &amp;ldquo;App-Info&amp;rdquo; and &amp;ldquo;Card ID&amp;rdquo; can be modified if you want to use those values in the automatic folder creation.&lt;/p&gt;&#xA;&lt;p&gt;If your Network settings already work, don&amp;rsquo;t touch them here. Otherwise &lt;a class=&#34;link&#34; href=&#34;https://www.toshiba.co.jp/p-media/wwsite/flashair.htm&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;follow the instructions on the FlashAir website.&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Now make sure the &amp;ldquo;Upload Directory&amp;rdquo; fits the &amp;ldquo;Flashair Imagepath&amp;rdquo; in the &amp;ldquo;Application Settings&amp;rdquo;.&lt;/p&gt;&#xA;&lt;p&gt;The last setting to check is &amp;ldquo;Upload Enabled&amp;rdquo;. This is required if you want to be able to save files onto the Flashair or want to delete files after downloading.&lt;/p&gt;&#xA;&lt;p&gt;Now all you have to do is to click [Save] in the upper Left region and FAD is ready to go.&lt;/p&gt;&#xA;&lt;p&gt;For the first run I would advice just keeping your card in your card-reader. It works exactly there like in your camera, but you can modify your settings more easy this way.&lt;/p&gt;&#xA;&lt;h3 id=&#34;auto---mode&#34;&gt;&lt;a href=&#34;#auto---mode&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Auto - Mode&#xA;&lt;/h3&gt;&lt;p&gt;&lt;img class=&#34;gallery-image&#34; data-flex-basis=&#34;375px&#34; data-flex-grow=&#34;156&#34; height=&#34;738&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/flashairdownloader-2/foundcard_hu_161662514a5c1345.png&#34; srcset=&#34;https://dotnet.work/blog/flashairdownloader-2/foundcard_hu_fded45859a3bddeb.png 800w, https://dotnet.work/blog/flashairdownloader-2/foundcard_hu_161662514a5c1345.png 1154w&#34; width=&#34;1154&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;After FAD found your card click onto &amp;ldquo;Auto Mode&amp;rdquo; to start automatic downloading of your data:&lt;/p&gt;&#xA;&lt;p&gt;At first the files are loaded recursively from your card. In the next step (if activated) the thumbnails gets downloaded. Then the files are being downloaded and deleted (if selected).&lt;/p&gt;&#xA;&lt;p&gt;&lt;img class=&#34;gallery-image&#34; data-flex-basis=&#34;436px&#34; data-flex-grow=&#34;181&#34; height=&#34;620&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/flashairdownloader-2/autocopy_hu_dd06e496e28f5a46.png&#34; srcset=&#34;https://dotnet.work/blog/flashairdownloader-2/autocopy_hu_c1dcdd4024d23a07.png 800w, https://dotnet.work/blog/flashairdownloader-2/autocopy_hu_dd06e496e28f5a46.png 1127w&#34; width=&#34;1127&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;If the thumbnails cannot be retrieved red squares are displayed instead.&lt;/p&gt;&#xA;&lt;h3 id=&#34;file-explorer&#34;&gt;&lt;a href=&#34;#file-explorer&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;File Explorer&#xA;&lt;/h3&gt;&lt;p&gt;The file explorer does not download automatically images from the Flashair. Instead you can browse through your card and copy files manually. Just mark them by clicking and select the [&amp;laquo;] or [&amp;raquo;] - Button to copy them#&lt;/p&gt;&#xA;&lt;p&gt;&lt;img class=&#34;gallery-image&#34; data-flex-basis=&#34;438px&#34; data-flex-grow=&#34;182&#34; height=&#34;617&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/flashairdownloader-2/markedright_hu_4048b87f5c92571d.png&#34; srcset=&#34;https://dotnet.work/blog/flashairdownloader-2/markedright_hu_30bd2edf0ffe4317.png 800w, https://dotnet.work/blog/flashairdownloader-2/markedright_hu_4048b87f5c92571d.png 1127w&#34; width=&#34;1127&#34;&gt;&lt;/p&gt;&#xA;&lt;h3 id=&#34;known-issues&#34;&gt;&lt;a href=&#34;#known-issues&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Known issues&#xA;&lt;/h3&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.youtube.com/watch?v=PtXtIivRRKQ&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;https://www.youtube.com/watch?v=PtXtIivRRKQ&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt; &lt;/p&gt;&#xA;&lt;p&gt;The FlashAir is sometimes a bit unstable (at least mine). There are a lot of reasons why something goes wrong. That&amp;rsquo;s why FAD tries up to five times to download or upload data. (Just Thumbnails are only tried once). There are many reasons why a download does not work. There can be a timeout, the Card can &amp;ldquo;crash&amp;rdquo; (it is a webserver running on it) or the camera just goes into standby. So often the best solution is to try again and or restart the camera and re-enter the FlashAir.&lt;/p&gt;&#xA;&lt;h3 id=&#34;any-more-questions&#34;&gt;&lt;a href=&#34;#any-more-questions&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Any more questions?&#xA;&lt;/h3&gt;&lt;p&gt;Just look at the documentation on GitHub or open an issue there if you encounter any problems.&lt;/p&gt;&#xA;&lt;p&gt;Love it?&lt;/p&gt;&#xA;&lt;p&gt;Feel free to send some money to my Panama-Account&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>SCRUM and Git: Optimized Gitflow // with a lot of fancy colors :)</title>
            <link>https://dotnet.work/blog/scrum-and-git-optimized-gitflow-with-a-lot-of-fancy-colors/</link>
            <pubDate>Wed, 04 Mar 2015 12:00:00 +0100</pubDate><author>dotnet@oles.cloud (Ole Albers)</author>
            <guid>https://dotnet.work/blog/scrum-and-git-optimized-gitflow-with-a-lot-of-fancy-colors/</guid>
            <description>&lt;img src=&#34;https://dotnet.work/blog/scrum-and-git-optimized-gitflow-with-a-lot-of-fancy-colors/gitflow1_hu_ef8620f4237a401d.png&#34; alt=&#34;Featured image of post SCRUM and Git: Optimized Gitflow // with a lot of fancy colors :)&#34; /&gt;&lt;p&gt;For a lot of teams, GIT is the first choice for maintaining the code. So it is for mine. But this post isn&amp;rsquo;t limited to GIT and should work with SVN or TFS with little modifications, too.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-is-the-git-flow-important-when-using-scrum&#34;&gt;&lt;a href=&#34;#why-is-the-git-flow-important-when-using-scrum&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Why is the Git flow important when using SCRUM?&#xA;&lt;/h2&gt;&lt;p&gt;Aren&amp;rsquo;t those just two worlds, anyway?&lt;/p&gt;&#xA;&lt;p&gt;Well. Kind of. But while SCRUM is quite flexible, scrums paradigm still has some very basic contents when it comes to manage projects:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;You and your team work in sprints.&lt;/li&gt;&#xA;&lt;li&gt;Inside these sprints there are user-stories you want to implement.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;We decided to map sprints and user stories to our git flow.&lt;/p&gt;&#xA;&lt;h2 id=&#34;classic-git-flow&#34;&gt;&lt;a href=&#34;#classic-git-flow&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;Classic git flow:&#xA;&lt;/h2&gt;&lt;p&gt;You usually have the following structure in a git flow: (More fancy description and image at &lt;a class=&#34;link&#34; href=&#34;https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;Atlassian&lt;/a&gt;)&lt;/p&gt;&#xA;&lt;p&gt;&lt;img alt=&#34;classic git flow&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;492px&#34; data-flex-grow=&#34;205&#34; height=&#34;288&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/scrum-and-git-optimized-gitflow-with-a-lot-of-fancy-colors/gitflow1_hu_ef8620f4237a401d.png&#34; width=&#34;591&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;You always got your master branch. From that branch you create single branches for each Hotfix. Your daily work is done in feature branches that start at the development branch. When a feature is finished, you merge it into your development branch. For a release, the development branch (which contains the added features) is the root of a new Release-branch. That release is tested and maybe modified until it fits the needs of your customer. When you are happy with that release you merge it back into the development branch as well as the master branch.&lt;/p&gt;&#xA;&lt;h2 id=&#34;scrumified-git-flow&#34;&gt;&lt;a href=&#34;#scrumified-git-flow&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;&amp;ldquo;Scrumified&amp;rdquo; Git Flow:&#xA;&lt;/h2&gt;&lt;p&gt;&lt;img alt=&#34;scrum git flow&#34; class=&#34;gallery-image&#34; data-flex-basis=&#34;365px&#34; data-flex-grow=&#34;152&#34; height=&#34;388&#34; loading=&#34;lazy&#34; sizes=&#34;(max-width: 767px) calc(100vw - 30px), (max-width: 1023px) 700px, (max-width: 1279px) 950px, 1232px&#34; src=&#34;https://dotnet.work/blog/scrum-and-git-optimized-gitflow-with-a-lot-of-fancy-colors/gitflow2_hu_22260977631a1eb5.png&#34; width=&#34;591&#34;&gt;&lt;/p&gt;&#xA;&lt;p&gt;When trying to put SCRUM into the flow you keep your basic structure but add &lt;strong&gt;two additional layers&lt;/strong&gt; to it. The single features are not created directly from the development branch. Instead at first for each sprint a new branch is created from the development branch. From the sprint there are branches created from each user story. After you&amp;rsquo;ve done that, the features are created from the corresponding stories. Merging back goes the same way. You merge your features back into the user story and the user story back into the sprint before merging the sprint back into your development branch.&lt;/p&gt;&#xA;&lt;p&gt;This is a bit more work (and might look a little bit chaotic on these pictures at first) but it offers the advantages you have from &amp;ldquo;normal&amp;rdquo; git flow also to your sprint. Like before you only merge features that are finished. But now you also only merge user stories that are complete. And as a small bonus you can always analyze which user story was started and finished in which sprint. A Win-Win-situation like those unlikable marketing guys would call it. (If they were able to understand a single word I just wrote here) :)&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>IMAP-HTML-Autoresponder with PHP</title>
            <link>https://dotnet.work/blog/imap-html-php-autoresponder-autoreply/</link>
            <pubDate>Fri, 13 Feb 2015 12:00:00 +0100</pubDate><author>dotnet@oles.cloud (Ole Albers)</author>
            <guid>https://dotnet.work/blog/imap-html-php-autoresponder-autoreply/</guid>
            <description>&lt;p&gt;Everyone knows spam. Everyone &lt;strong&gt;hates&lt;/strong&gt; spam. And everyone who has his email-address written on the net (for example in the NIC-records for a domain) gets &lt;strong&gt;a lot of&lt;/strong&gt; spam.&lt;/p&gt;&#xA;&lt;p&gt;I am one of those guys who gets a lot of spam. Of course there are anti-spam solutions out there, but the best would be to not even receive spam. And spam filters need a lot of work and / or do not filter 100% perfect. That is why I decided to use a public email that has to go through a &amp;ldquo;gatekeeper&amp;rdquo;. A PHP-script that tells everyone that this is not my real mail address, but that there is another one where I could be contacted.&lt;/p&gt;&#xA;&lt;p&gt;That email-address is not displayed in plain text but as an image to get rid of all those bots. SOME bots however should be able to get through: For example my hoster who needs to validate my email periodically. So these messages just are being forwarded.&lt;/p&gt;&#xA;&lt;p&gt;I wanted to be as simple as possible. That&amp;rsquo;s why this script does not need much more than plain php. Only a replacement for phps &amp;ldquo;mail&amp;rdquo; was needed.&lt;/p&gt;&#xA;&lt;p&gt;First step: Download swiftmailer. Just put the contents of the &amp;ldquo;lib&amp;rdquo; - directory onto your web space. That&amp;rsquo;s it. Ready to go.&lt;/p&gt;&#xA;&lt;p&gt;Simple include the following line to access swiftmailer:&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;require\_once &#39;./swift/lib/swift\_required.php&#39;;&lt;/code&gt;&#xA;To access your mail you need to enter the IMAP-Settings. POP would work, too, but IMAP would be much more useful because we do not want to download the email-body of the messages processed:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;// IMAP-Settings:&#xA; $hostname = &amp;#34;{imap.hostname.com:993/imap/ssl}INBOX&amp;#34;;&#xA; $username = &amp;#34;username&amp;#34;;&#xA; $password = &amp;#34;password&amp;#34;;&#xA;`Now enter your email-addresses. $targetMail is your real (&amp;#34;hidden&amp;#34;) email-address where valid emails should be forwarded to. $thisMail is the public address that receives the spam.`&#xA;$targetMail=&amp;#34;private@mydomain.com&amp;#34;; &#xA;$thisMail=&amp;#34;webmaster@mydomain.com&amp;#34;;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Next you need to create an image with your favourite picture editing tool (GiMP, Paint.NET, PaintShopPro, etc.) This image should only contain your private email. Take a font you like. You might also use a &amp;ldquo;Captcha&amp;rdquo;-font. I - personally - hate that&amp;hellip; :)&lt;/p&gt;&#xA;&lt;p&gt;Upload that image to your web server and enter the url of that image. PNG would be a good choice.&lt;/p&gt;&#xA;&lt;p&gt;$image=&amp;ldquo;&lt;a class=&#34;link&#34; href=&#34;http://www.example.com/images/mail.png%22;&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;http://www.example.com/images/mail.png&#34;;&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;Next, enter the text the sender should receive. By default everyone receives $templateHtml. For those who do not have the capabilities to display html (or don&amp;rsquo;t want to) a simple text-mail ($templatePlain) will be displayed. Users with a html-browser will see your email-image directly in the mail. Plain-text mail-clienst will display a link to the image instead.&lt;/p&gt;&#xA;&lt;p&gt;$templateForward defines the mail content YOU will see if a mail is forwarded to you from a valid sender&lt;/p&gt;&#xA;&lt;p&gt;So it is time to be creative :)&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;$templateHtml=&amp;#34;&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;Thanks for your mail. Please note that this mail is no more. It has ceased to be! It is expired and gone to meet its maker! This is an Ex-Mail!&amp;lt;br/&amp;gt;But don&amp;#39;t be afraid, there is a replacement for that. Just send your mail to: &amp;lt;br/&amp;gt;&amp;lt;img src=\\&amp;#34;\_\_EMBED\_\_\\&amp;#34;/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;If you cannot see that image: Click onto the following link to see my: &amp;lt;a href=\\&amp;#34;\_\_URL\_\_\\&amp;#34;&amp;gt;new mail-address&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;And no: This mail will not be forwarded. No one will see this until you forward it to my new mail-address. Thanks!&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;#34;;&#xA;&#xA;$templatePlain=&amp;#34;Thanks for your mail. Please note that this mail is no more. It has ceased to be! It is expired and gone to meet its maker! This is an Ex-Mail!\\r\\nBut don&amp;#39;t be afraid, there is a replacement for that. Just click onto the following link to see my: new mail-address: \_\_URL\_\_&amp;#34;;&#xA;&#xA;$templateForward=&amp;#34;new message redirected&amp;#34;;&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As you can see there are two special tags in those templates. &amp;ldquo;__EMBED__&amp;rdquo; will be replaced with the embedded image (html-template only) and &amp;ldquo;__URL__&amp;rdquo; will contain a link to that image.&lt;/p&gt;&#xA;&lt;p&gt;The last variable you can define is the white-list. Everything entered there is interpreted as a valid sender. Enter multiple values seperated by commas.&#xA;&lt;code&gt;$whitelist = &amp;quot;uberspace,denic.de,domainbox.net,romrobot.com,inwx.de,millerntor.hamburg,dotnet.work&amp;quot;;&lt;/code&gt;&#xA;that&amp;rsquo;s all for configuration. Now just some explanation what the script does:&lt;/p&gt;&#xA;&lt;p&gt;First of all the script checks your IMAP-Server for unread messages. It collects the header of each of those messages and compares the sender with the white-list. If the sender is recognized, the mail body is downloaded and sent as an attachment to the mail address you defined as $targetMail.&lt;/p&gt;&#xA;&lt;p&gt;If the sender is not in the white-list, an automatic reply is generated using your html-template. It contains the image you downloaded as an attachment and embedded image of the mail. The last step is to mark the mail as read so it won&amp;rsquo;t be processed again.&lt;/p&gt;&#xA;&lt;p&gt;In a perfect world&amp;hellip;&lt;/p&gt;&#xA;&lt;p&gt;Everything works now. But you can (and will) get problems sending the mail to the sender if the sender&amp;rsquo;s address does not comply with RFC 2822. While most spammers DO comply, mom DOESN&amp;rsquo;T&amp;hellip; :) That&amp;rsquo;s because there is a mail client from a tiny little software company in Redmond, where they do not know much about standards. But this is no big problem at all. Just open &lt;em&gt;lib\classes\swift\Mime\Headers\MailboxHeader.php&lt;/em&gt; from swiftmailer and put &lt;em&gt;/* */&lt;/em&gt; around the throw-part of the last function:&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private function \_assertValidAddress($address)&#xA;{&#xA;   if (!preg\_match(&amp;#39;/^&amp;#39;.$this-&amp;gt;getGrammar()-&amp;gt;getDefinition(&amp;#39;addr-spec&amp;#39;).&amp;#39;$/D&amp;#39;, $address)) {&#xA;     /\* throw new Swift\_RfcComplianceException(&amp;#39;Address in mailbox given \[&amp;#39;.$address.&amp;#39;\] does not comply with RFC 2822, 3.6.2.&amp;#39;);\*/&#xA;   }&#xA;}&#xA;`So finally here is the complete script.`&#xA;&amp;lt;?php&#xA;   require\_once &amp;#39;./swift/lib/swift\_required.php&amp;#39;;// IMAP-Settings:&#xA;   $hostname = &amp;#34;{imap.example.com:993/imap/ssl}INBOX&amp;#34;;&#xA;   $username = &amp;#34;username&amp;#34;;&#xA;   $password = &amp;#34;password&amp;#34;; // Script-Settings:&#xA;   $targetMail=&amp;#34;private@example.com&amp;#34;; // &amp;#34;hidden&amp;#34; target mail-address&#xA;   $thisMail=&amp;#34;webmaster@example.com&amp;#34;; // &amp;#34;official&amp;#34; mail-address (which receives the spam) &#xA;   $image=&amp;#34;http://www.dotnet.work/reply/mail.png&amp;#34;; // Image to be shown&#xA;   $templateHtml=&amp;#34;&amp;lt;html&amp;gt;&amp;lt;body&amp;gt;Thanks for your mail. Please note that this mail is no more. It has ceased to be! It is expired and gone to meet its maker! This is an Ex-Mail!&amp;lt;br/&amp;gt;But don&amp;#39;t be afraid, there is a replacement for that. Just send your mail to: &amp;lt;br/&amp;gt;&amp;lt;img src=\\&amp;#34;\_\_EMBED\_\_\\&amp;#34;/&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;If you cannot see that image: Click onto the following link to see my: &amp;lt;a href=\\&amp;#34;\_\_URL\_\_\\&amp;#34;&amp;gt;new mail-address&amp;lt;/a&amp;gt;&amp;lt;br/&amp;gt;And no: This mail will not be forwarded. No one will see this until you forward it to my new mail-address. Thanks!&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;&amp;#34;;&#xA;   $templatePlain=&amp;#34;Thanks for your mail. Please note that this mail is no more. It has ceased to be! It is expired and gone to meet its maker! This is an Ex-Mail!\\r\\nBut don&amp;#39;t be afraid, there is a replacement for that. Just click onto the following link to see my: new mail-address: \_\_URL\_\_&amp;#34;;&#xA;   $templateForward=&amp;#34;new message redirected&amp;#34;;&#xA;&#xA;   $whitelist = &amp;#34;uberspace,denic.de,domainbox.net,romrobot.com,inwx.de,millerntor.hamburg,dotnet.work&amp;#34;;&#xA; &#xA;   $allowedSenders=explode(&amp;#34;,&amp;#34;,$whitelist);&#xA;   $inbox = imap\_open($hostname,$username,$password) or die(&amp;#34;Sorry, connection failed&amp;#34;);&#xA;   $emails = imap\_search($inbox,&amp;#34;UNSEEN&amp;#34;);&#xA;   $count=0; &#xA;   echo &amp;#34;&amp;lt;pre&amp;gt;&amp;#34;; &#xA;   if($emails) {&#xA;     $transport = Swift\_MailTransport::newInstance();&#xA;     foreach($emails as $email) {&#xA;        $count++;&#xA;        $header = imap\_fetch\_overview($inbox,$email,0); &#xA;        $subject=$header\[0\]-&amp;gt;subject;&#xA;        $sender=$header\[0\]-&amp;gt;from;&#xA;&#xA;        $messageHeader =  imap\_fetchheader($inbox, 1)&#xA;        if (strpos($messageHeader,&amp;#34;X-RESPONDERDATE&amp;#34;)!==false) {&#xA;          continue; // no wild bouncing, please&#xA;        }&#xA;&#xA;        if (strpos($sender,$targetMail!==false || strpos($sender,$thisMail!==false) {&#xA;           // We want no loops... :)&#xA;           continue;&#xA;        }&#xA;        echo &amp;#34;retrieving &amp;#34;.$subject.&amp;#34; from &amp;#34;.$sender.&amp;#34;\\r\\n&amp;#34;;&#xA;        // Whitelist: &#xA;        $isWhiteListed=false;&#xA;      &#xA;        foreach($allowedSenders as $allowedSender) {&#xA;           if (stripos($sender,$allowedSender)!==false) {&#xA;              $isWhiteListed=true;&#xA;              break;&#xA;           }&#xA;        }&#xA; &#xA;        if ($isWhiteListed) {&#xA;           $email\_body = imap\_body($inbox, $email);&#xA;           $mailer = Swift\_Mailer::newInstance($transport);&#xA;           $message = Swift\_Message::newInstance()&#xA;              -&amp;gt;setSubject(&amp;#34;Fw:&amp;#34;.$subject)&#xA;              -&amp;gt;setFrom($sender)&#xA;              -&amp;gt;setTo($targetMail)&#xA;              -&amp;gt;setBody($templateForward)&#xA;           ;&#xA; &#xA;           $attachment = Swift\_Attachment::newInstance($email\_body, &amp;#39;origin.eml&amp;#39;, &amp;#39;message/rfc822&amp;#39;); &#xA;           $message-&amp;gt;attach($attachment);&#xA; &#xA;           $result = $mailer-&amp;gt;send($message);&#xA;           echo &amp;#34;whitelist redirect\\r\\n&amp;#34;;&#xA;        } else { &#xA;           $mailer = Swift\_Mailer::newInstance($transport);&#xA;           $message = Swift\_Message::newInstance();&#xA;           $swiftheaders = $message-&amp;gt;getHeaders();&#xA;           $swiftheaders-&amp;gt;addTextHeader(&amp;#39;X-RESPONDERDATE&amp;#39;, date(&amp;#39;Y-m-d H:i:s&amp;#39;));&#xA;           $cid = $message-&amp;gt;embed(Swift\_Image::fromPath($image));&#xA;           $html=str\_replace(&amp;#34;\_\_URL\_\_&amp;#34;,$image,$templateHtml);&#xA;           $html=str\_replace(&amp;#34;\_\_EMBED\_\_&amp;#34;,$cid,$html);&#xA;           $plain=str\_replace(&amp;#34;\_\_URL\_\_&amp;#34;,$image,$templatePlain);&#xA;           $message&#xA;              -&amp;gt;setSubject(&amp;#34;Re:&amp;#34;.$subject)&#xA;              -&amp;gt;setFrom($thisMail)&#xA;              -&amp;gt;setTo($sender) &#xA;              -&amp;gt;setBody($html, &amp;#39;text/html&amp;#39;)&#xA;              -&amp;gt;addPart($plain, &amp;#39;text/plain&amp;#39;)&#xA;           ;&#xA;           $result = $mailer-&amp;gt;send($message);&#xA;           echo &amp;#34;answered\\r\\n&amp;#34;;&#xA;        } &#xA;        imap\_setflag\_full($inbox, imap\_uid($inbox,$email), &amp;#34;\\\\Seen \\\\Flagged&amp;#34;, ST\_UID);&#xA;     } &#xA;  }&#xA;  imap\_close($inbox);&#xA;  echo &amp;#34;done redirecting &amp;#34;.$count.&amp;#34; mails\\r\\n&amp;#34;;&#xA;  echo &amp;#34;&amp;lt;/pre&amp;gt;&amp;#34;;&#xA;?&amp;gt;&#xA;`Just save this program as &amp;#34;reply.php&amp;#34;, send test-mails and open &amp;#34;reply.php&amp;#34; in your browser to test the settings. When everything works fine you can simply add a cronjob so this script is run automaticly. The following example runs the script every 5 minutes:`&#xA;\*/5 \* \* \* \* php /var/www/reply.php&#xA;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt; &lt;/p&gt;&#xA;&lt;p&gt;Just use the comments if you need any help&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>FlashAir Downloader for Windows</title>
            <link>https://dotnet.work/blog/flashair-downloader-for-windows/</link>
            <pubDate>Thu, 25 Sep 2014 12:00:00 +0200</pubDate><author>dotnet@oles.cloud (Ole Albers)</author>
            <guid>https://dotnet.work/blog/flashair-downloader-for-windows/</guid>
            <description>&lt;blockquote class=&#34;alert alert-warning&#34;&gt;&#xA;        &lt;div class=&#34;alert-header&#34;&gt;&#xA;            &lt;span class=&#34;alert-icon&#34;&gt;⚠️&lt;/span&gt;&#xA;            &lt;span class=&#34;alert-title&#34;&gt;Warning&lt;/span&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;div class=&#34;alert-body&#34;&gt;&#xA;            &lt;p&gt;&lt;strong&gt;Development stopped!&lt;/strong&gt; &lt;a class=&#34;link&#34; href=&#34;https://dotnet.work/blog/flashairdownloader-development-now-its-your-turn/&#34; &gt;Please read this&lt;/a&gt; before downloading FAD&lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;    &lt;/blockquote&gt;&#xA;&lt;blockquote class=&#34;alert alert-note&#34;&gt;&#xA;        &lt;div class=&#34;alert-header&#34;&gt;&#xA;            &lt;span class=&#34;alert-icon&#34;&gt;📝&lt;/span&gt;&#xA;            &lt;span class=&#34;alert-title&#34;&gt;Note&lt;/span&gt;&#xA;        &lt;/div&gt;&#xA;        &lt;div class=&#34;alert-body&#34;&gt;&#xA;            &lt;p&gt;**New Version available!**This version is obsolete. I would strongly suggest to use the FAD2 instead. You can download it here: &lt;a class=&#34;link&#34; href=&#34;http://dotnet.work/fad2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;http://dotnet.work/fad2&lt;/a&gt;.&lt;/p&gt;&#xA;        &lt;/div&gt;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;Toshibas FlashAir is an SD-Card with built-in WiFi. It allows you to download Pictures from your DigiCam through WiFi. Sadly there is no working Windows-Application.&lt;/p&gt;&#xA;&lt;p&gt;The FlashAir-Downloader solves that issue. It allowes Bulk-Downloading of your images. Your pictures can be saved in folders created automaticly containing date-information.&lt;/p&gt;&#xA;&lt;p&gt;Installation:&lt;/p&gt;&#xA;&lt;p&gt;Unpack the Zip and start the Setup.Exe&lt;/p&gt;&#xA;&lt;p&gt;Start the Application and go to Settings:&lt;/p&gt;&#xA;&lt;!-- image missing: images/flash1_qn247z.png (flash1) --&gt;&#xA;&lt;p&gt;Adjust the Settings if needed. Especially for “local Path”.&lt;/p&gt;&#xA;&lt;p&gt;To use the Delete-Option you have to adjust the configuration of the SD-Card. Insert the SD-Card into your computer and open the file “CONFIG” file in the hidden “SD_WLAN”-folder with a text editor. Add the line&#xA;&lt;code&gt;UPLOAD=1&lt;/code&gt;&#xA;to the CONFIG-File.&lt;/p&gt;&#xA;&lt;p&gt;Thats it. Close that window, turn on your camera and click onto “CONNECT”. If the connection works, you should see the folders and images of your SD-Card. Enter a folder or preview an image by double-clicking onto the icon. Mark the images you want to download and start downloading by clicking onto “Download”.&lt;/p&gt;&#xA;&lt;p&gt;I give no guarantee about anything. This application shouldn’t do anything bad. But if your Camera explodes: Don’t blame me.This tool is and always will be free. But I don’t mind donations, of course :)&lt;/p&gt;&#xA;&lt;p&gt;— Update V 1.1 —&lt;/p&gt;&#xA;&lt;p&gt;I just updated the FlashAirDownloader to Version 1.1.&lt;/p&gt;&#xA;&lt;p&gt;The following has changed:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Bugfix: If the file date is quite old (&amp;lt;2000) it could not be downloaded. This has been fixed. [*Yeah! Year 2000 bug in 2014. Well done, Toshiba *🙄  😁  ]&lt;/li&gt;&#xA;&lt;li&gt;New Feature: You can now change the contents of the CONFIG – File directly. Just insert the SD-Card into your computer and Select “Card Properties &lt;a class=&#34;link&#34; href=&#34;http://res.cloudinary.com/dyzmmxp1s/image/upload/v1422648202/fadConfig_nvxiz4.png&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;&lt;!-- image missing: images/fadConfig_nvxiz4.png (fadConfig) --&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;New Feature: If you use more than just One FlashAir-Card you can now automatically create subfolders for each card. You can use the internal “CID” ID for that or the Application ID which may contain any custom name. &lt;!-- image missing: images/fadconfig2_arr8bm.png (fadconfig2) --&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;(Tested with Windows 7 and Windows 8.1)&lt;/p&gt;&#xA;&lt;p&gt;A new Version is available: &lt;a class=&#34;link&#34; href=&#34;http://dotnet.work/fad2&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;http://dotnet.work/fad2&lt;/a&gt;&lt;/p&gt;&#xA;</description>
        </item><item>
            <title>Emptying SharePoint-List the (quite) fast way</title>
            <link>https://dotnet.work/blog/emptying-sharepoint-list-the-quite-fast-way/</link>
            <pubDate>Fri, 10 Aug 2012 12:00:00 +0200</pubDate><author>dotnet@oles.cloud (Ole Albers)</author>
            <guid>https://dotnet.work/blog/emptying-sharepoint-list-the-quite-fast-way/</guid>
            <description>&lt;p&gt;I already offered a solution to &lt;a class=&#34;link&#34; href=&#34;http://www.stammtischphilosoph.com/2012/08/emptying-sharepoint-lists-the-ultra-fast-way/&#34;  title=&#34;Emptying SharePoint lists the ultra fast way&#34;&#xA;     target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;empty a SharePoint list at light speed&lt;/a&gt;&lt;/p&gt;&#xA;&lt;p&gt;But this solution hast two big disadvantages:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;You cannot empty a list that has more entries thatn the allowed list view threshold (default is 5000)&lt;/li&gt;&#xA;&lt;li&gt;All Lookups will be lost&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;This solution has non of those drawbacks. It is much slower than that solution but also much faster than “normal” deletion of SPListItems or using a Caml-Query to do that.&lt;/p&gt;&#xA;&lt;p&gt;Just be asure that this is not thread-safe. So make sure noone is writing into that list in the same time or that lines might not be deleted.&lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;private int rest;&#xA;public static void TruncateList(Guid listId, int limit)&#xA;{&#xA;SPSecurity.RunWithElevatedPrivileges(delegate()&#xA;{&#xA;using (SPSite site = new SPSite(SPContext.Current.Site.ID))&#xA;{&#xA;using (SPWeb web = SPContext.Current.Web)&#xA;{&#xA;try&#xA;{&#xA;\_rest = limit;&#xA;web.AllowUnsafeUpdates = true;&#xA;SPList listCopy = web.Lists\[listId\];&#xA;&#xA;ContentIterator iterator = new ContentIterator();&#xA;iterator.ProcessListItems(listCopy, ProcessItem, ProcessError);&#xA;&#xA;web.Update();&#xA;web.AllowUnsafeUpdates = false;&#xA;}&#xA;catch (Exception ex)&#xA;{&#xA;if (!ex.Message.Contains(&amp;#34;Limit reached&amp;#34;))&#xA;{&#xA;Debug.WriteLine(ex);&#xA;}&#xA;&#xA;}&#xA;}&#xA;}&#xA;}&#xA;);&#xA;}&#xA;&#xA;public static bool ProcessError(SPListItem item, Exception ex)&#xA;{&#xA;if (!ex.Message.Contains(&amp;#34;Limit reached&amp;#34;))&#xA;{&#xA;Debug.WriteLine(ex);&#xA;}&#xA;&#xA;return true;&#xA;}&#xA;&#xA;public static void ProcessItem(SPListItem item)&#xA;{&#xA;if (rest&amp;lt;=0)&#xA;{&#xA;Debug.WriteLine(&amp;#34;Limit reached&amp;#34;);&#xA;throw new Exception(&amp;#34;Limit reached&amp;#34;);&#xA;return;&#xA;}&#xA;item.Delete();&#xA;\_rest–;&#xA;&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
        </item><item>
            <title>Emptying SharePoint lists the ultra fast way</title>
            <link>https://dotnet.work/blog/emptying-sharepoint-lists-the-ultra-fast-way/</link>
            <pubDate>Thu, 09 Aug 2012 12:00:00 +0200</pubDate><author>dotnet@oles.cloud (Ole Albers)</author>
            <guid>https://dotnet.work/blog/emptying-sharepoint-lists-the-ultra-fast-way/</guid>
            <description>&lt;p&gt;SharePoint is damn slow when deleting lines from lists. Each entry can take up to some seconds which isn’t nice when you have to delete thousands of lines.&lt;/p&gt;&#xA;&lt;p&gt;Also no Trunc-Methode is available.&lt;/p&gt;&#xA;&lt;p&gt;Other solutions found on the net creating xml-files to bulk delete aren’t very fast either.&lt;/p&gt;&#xA;&lt;p&gt;That’s why I decided to write my own fast truncate-method for SharePoint-Lists.&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;All content of that list will be deleted. Use at your own risk!&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&lt;em&gt;What it does&lt;/em&gt;:&lt;/p&gt;&#xA;&lt;p&gt;First a template of that list is being created. After that the list is deleted completely. Than a new list using that template is being created and at the end that template is being deleted.&lt;/p&gt;&#xA;&lt;p&gt;Works damn fast (just a few seconds even on big lists). IF anything goes wrong you can use the template to create a list manually.&lt;/p&gt;&#xA;&lt;p&gt; &lt;/p&gt;&#xA;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;public void TruncateList(Guid listID)&#xA;{&#xA;SPSecurity.RunWithElevatedPrivileges(delegate()&#xA;{&#xA;using (SPSite site = new SPSite(SPContext.Current.Site.ID))&#xA;{&#xA;using (SPWeb web = SPContext.Current.Web)&#xA;{&#xA;try&#xA;{&#xA;web.AllowUnsafeUpdates = true;&#xA;// alte Werte merken&#xA;SPList listCopy = web.Lists\[listID\];&#xA;string title = listCopy.Title;&#xA;string description = listCopy.Description;&#xA;&#xA;string backupName = string.Format(&amp;#34;BACKUP{0}{1:d} {1:HH}{1:mm}&amp;#34;, title,DateTime.Now);&#xA;&#xA;// save template&#xA;listCopy.SaveAsTemplate(backupName, backupName, string.Empty, false);&#xA;SPListTemplate template = web.Site.GetCustomListTemplates(web)\[backupName\];&#xA;&#xA;// delete list&#xA;listCopy.Delete();&#xA;web.Lists.Add(title, description, template);&#xA;&#xA;//  remove template&#xA;SPList gallery = web.Lists\[&amp;#34;List Template Gallery&amp;#34;\];&#xA;foreach (SPListItem item in gallery.Items.Cast().Where(item =&amp;gt; item.Title == backupName))&#xA;{&#xA;item.Delete();&#xA;break;&#xA;}&#xA;&#xA;web.Update();&#xA;web.AllowUnsafeUpdates = false;&#xA;}&#xA;catch (Exception ex)&#xA;{&#xA;\_log.Error(ex);&#xA;throw;&#xA;}&#xA;}&#xA;}&#xA;}&#xA;);&#xA;}&#xA;&lt;/code&gt;&lt;/pre&gt;</description>
        </item></channel>
</rss>
