Update My Blog Via Email with Azure Functions
Starting with a Manual, Multi-Step Process
I have [blogged](/post/building-blog) about the changes I made to streamline my site architecture and continue to work on ways to improve it. One thing that I did a month ago was replace the static page that was my [speaking page][/speaking] and make it more dynamic. Before whenever I had a new speaking gig, I would go into my repo and edit the HTML, EVERY... TIME.... I quickly became not a fan of that, so I started to look into options that were less cringey. I discovered in Hugo you can have data-driven pages using a source like json to house content. What I did was build a [shortcode](https://gohugo.io/content-management/shortcodes/) to read data from a json file and output it in a format I wanted, in this case, an HTML table.
|
|
and here is how I declare it
|
|
What this code does loops over a json file called data.json
and builds an HTML table from it. Here is a subset of what that data looks like
|
|
This data represents all the pertinent information for my speaking engagements, and now all I have to do is update that json file, commit to my repo, and my blog gets updated, pretty cool!
NOTE: There are 2 tables because I separate past/present events.
Replacing with Something More Automated
So I quickly realizes that even though this is better, I still don’t like it, because I have to go to a repo and commit still, there has to be a better way!!! I started thinking of an idea.
- Have some process that triggers an event (email, txt, etc.)
- Said process will have data that represents an event
- Event will take data and commit it to repo using code
Azure Functions works perfectly for these one-off processes that can be spun up pretty quick, so I moved forward there. I immediately ran into a roadblock as most of the git libraries that exist don't work in Azure Functions, but I knew that I was able to do Git commands in Kudu (the engine behind Azure App Service, and you can run commands via console in it) so I knew that Git is installed in the environment for App Service, now to just find a way to get it all to work. After talking with a few colleagues, I discovered that running `git clone url` would not work, because the path to the git executable is not in the PATH variable, so I had to declare the full path, which is `D:\PROGRA~1\Git\cmd\git.exe` (I like to use short names in commands). Now if I wanted to, I could call git commands via C# using `Process.Start()` but I wasn't too keen on having that done all in code, as I would have to start processes for all these things
- git config X2
- git clone
- git add
- git commit
- git push
So I decided to put these commands in a .cmd
file and run that file from C# (same process). Here is what the 2 files look like
|
|
If I run both these files, my function will clone my repo, and add any changes, commit and push. This would than trigger a CI build on my repo and my blog would update. Now I just need to write some code to update the data.json file.
Since I am in C#, updating a json file is easy, thanks to Json.NET. After my repo is cloned, some code like this will Deserialize the string into an object, where I can make updates to, and than Serialize back into json format to save the file.
|
|
So now I can clone my repo, update the json file, and commit and push those changes. Final step is to actually update the content. I decided on an email as the "trigger" for all this, and may possibly move to a SMS message or PowerApp in the future. So I want to send an email to an email address, and my function picks up that email and processes it. This again is quite easy in C#, if you take advantage of the [MailKit](https://github.com/jstedfast/MailKit) project. Since the email I am sending to is an O365 Mailbox, I can use IMAP to easily parse the inbox, look for a particular message, parse it, and serialize into an object.
|
|
So what this code does is read my inbox, look for a message and parses the message. The email will be in the following format
|
|
Wiring all this up, I have a function that checks my email, and if there is a certain message, it parses that message. It than does a clone of my blog’s git repo and updates the data.json file with the event that was sent from email. Finally a commit and push is done to trigger a blog update. This was interesting as I discovered some new wrinkles to the App Service Sandbox. Take a look at the GitHub repo of the function if you like.