<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Layla</title>
    <description>The latest articles on DEV Community by Layla (@laylacodesit).</description>
    <link>https://dev.to/laylacodesit</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F239357%2F1cf5be7a-6bec-4f88-a2f1-f159d374a09f.jpeg</url>
      <title>DEV Community: Layla</title>
      <link>https://dev.to/laylacodesit</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/laylacodesit"/>
    <language>en</language>
    <item>
      <title>Rainy with a chance of Azure cloud</title>
      <dc:creator>Layla</dc:creator>
      <pubDate>Mon, 30 Sep 2019 13:39:07 +0000</pubDate>
      <link>https://dev.to/laylacodesit/rainy-with-a-chance-of-azure-cloud-ekf</link>
      <guid>https://dev.to/laylacodesit/rainy-with-a-chance-of-azure-cloud-ekf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is part of &lt;a href="https://dev.to/azure/serverless-september-content-collection-2fhb"&gt;#ServerlessSeptember&lt;/a&gt;. You'll find other helpful articles, detailed tutorials, and videos in this all-things-Serverless content collection. New articles are published every day — that's right, every day — from community members and cloud advocates in the month of September.&lt;/p&gt;

&lt;p&gt;Find out more about how Microsoft Azure enables your Serverless functions at &lt;a href="https://docs.microsoft.com/azure/azure-functions/?WT.mc_id=servsept_devto-blog-cxa"&gt;https://docs.microsoft.com/azure/azure-functions/&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We all have good days and bad days. On a good day, we may be filled with positive thoughts and on a bad day, we may forget that anything was ever positive!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hGWyyHof--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/original_images/vTeT5o3zl2dU45-38Zg611iR7AK_9tdjsGg9FVPHMQ70XUulqO6_jtFJLjmdIMS9tkPJrMe0_UxkVU" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hGWyyHof--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/original_images/vTeT5o3zl2dU45-38Zg611iR7AK_9tdjsGg9FVPHMQ70XUulqO6_jtFJLjmdIMS9tkPJrMe0_UxkVU" alt="alt gif of cartoon animal crying in the rain" title="Bad days"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this post, we will use Twilio to text your positive thoughts and affirmations to an Azure Function and save them in Azure Table Storage. We will then create a timer-based function that will send a random happy thought from the table storage via SMS to your friends.&lt;/p&gt;

&lt;p&gt;This post assumes some basic knowledge of C# and RESTful APIs.&lt;/p&gt;

&lt;p&gt;To get started, we will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;This &lt;a href="https://github.com/Layla-P/DailyAffirmations"&gt;GitHub&lt;/a&gt; project cloned&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://www.twilio.com/try-twilio"&gt;Twilio account&lt;/a&gt; and an SMS enabled &lt;a href="https://www.twilio.com/console/phone-numbers/search"&gt;Twilio number&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;An Azure Account (&lt;a href="https://azure.microsoft.com/en-us/free/"&gt;sign up for free here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;The latest .NET Core 2.2 SDK (&lt;a href="https://dotnet.microsoft.com/download/dotnet-core/2.2"&gt;download here&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/en-us/azure/azure-functions/functions-run-local#v2"&gt;Azure Functions Core Tools&lt;/a&gt; version 2.6.666 or later&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.microsoft.com/en-us/cli/azure/install-azure-cli"&gt;Azure CLI&lt;/a&gt; version 2.0 or later&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.getpostman.com/"&gt;Postman&lt;/a&gt; for testing our functions locally&lt;/li&gt;
&lt;li&gt;An IDE or code editor with C# support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Create an Azure resource group and required resources
&lt;/h3&gt;

&lt;p&gt;Once logged into your &lt;a href="https://portal.azure.com"&gt;Azure portal&lt;/a&gt;, we will create a Resource Group, Functions App Service and Azure Function.&lt;/p&gt;

&lt;p&gt;To create the Resource Group, go to "Resource groups" and then click the "plus" button to add a new resource. You will be taken to the "Create a new resource group" page where you can enter a name for your resource group, such as "RainyDays", choose a suitable region and then click "Review + create". Your resource will take a few moments to deploy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bk1CTGrp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/i0d3DEVlr0Uc45ik5D11006S8fyFhICClfL_NA7y8QHXTW.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bk1CTGrp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/i0d3DEVlr0Uc45ik5D11006S8fyFhICClfL_NA7y8QHXTW.width-500.png" alt="alt azure portal create a resource group page image" title="Create a resource group"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once deployed, we can create a new "Function App" resource. Click the "Create a resource" button on the top left of the side menu. In the search bar, search for and select  "Function App", then click "Create".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--KxeJ1giS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/r-_tnUgyAMB6IZcr5FgbLaTOd2ATtXSWVAphXWv8N6sjKo.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--KxeJ1giS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/r-_tnUgyAMB6IZcr5FgbLaTOd2ATtXSWVAphXWv8N6sjKo.width-500.png" alt="alt azure portal create a function app image" title="Add a resource"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A "Create Function App” dialogue will come up and you will need to give the app a unique name. Add it to the Resource Group that we just created. Then set the "Hosting Plan" to "Consumption Plan", choose an appropriate location, set "Runtime stack" to ".NET Core". There are a few other tabs on this wizard; "Hosting" and "Monitoring" being the more important ones. You can leave everything as the default. Finally, click the "Review and create" button at the bottom of the form.&lt;br&gt;
After a few moments, you should have a new Function App Service, which you can then navigate to. In the centre of the screen will be a button called "+ New function". Click on this.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rIu4AGAH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/V0r6kGGTDLLy9CZ6RtZcnIs_nNOjijvFepSVjD0MH3LnWy.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rIu4AGAH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/V0r6kGGTDLLy9CZ6RtZcnIs_nNOjijvFepSVjD0MH3LnWy.width-500.png" alt="alt azure portal create a function image" title="Create a function"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next screen will give several options, choose the IDE that you are using and if it's not there just choose the "Any editor + Core Tools" option.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Sacn0O7R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/8X4-SBONyEMAYI7DZhs0cTdMbXJ7HHm1qmKEHsKmc4i3Ti.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Sacn0O7R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/8X4-SBONyEMAYI7DZhs0cTdMbXJ7HHm1qmKEHsKmc4i3Ti.width-500.png" alt="alt azure portal choose a dev environment image" title="Choose dev environment"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You should then be shown a very helpful "cheat sheet" with all the commands that you need to work with your project locally, using the CLI. Especially useful is the "Deploy your code to Azure" command, so you may want to make a note of that for later.&lt;br&gt;
Now that we have the Azure side of everything set up, it's time to look at the code.&lt;/p&gt;
&lt;h3&gt;
  
  
  The Function App
&lt;/h3&gt;

&lt;p&gt;Open up the solution that we cloned at the beginning of this post in your editor of choice. We will work on the &lt;code&gt;master&lt;/code&gt; branch, the completed code is on the &lt;code&gt;complete&lt;/code&gt; branch if you would rather see the finished solution.&lt;/p&gt;

&lt;p&gt;We will focus on the code in &lt;code&gt;src/Functions&lt;/code&gt; for this post.&lt;/p&gt;

&lt;p&gt;Within this directory, we have two additional directories, &lt;code&gt;Models&lt;/code&gt; and &lt;code&gt;TableServices&lt;/code&gt;.&lt;br&gt;
The  &lt;code&gt;Models&lt;/code&gt; directory contains &lt;code&gt;TableConfiguration.cs&lt;/code&gt; and its interface for setting up the table storage dependency injection. It also has &lt;code&gt;QuoteEntity.cs&lt;/code&gt; and &lt;code&gt;Message.cs&lt;/code&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  Table Storage structure and the "QuoteEntity" model
&lt;/h3&gt;

&lt;p&gt;Table storage is a way to store NoSQL data in a structured way, with a schemaless design and a key/attribute store. For more information on how the data is structured, check out the docs &lt;a href="https://docs.microsoft.com/en-us/azure/storage/tables/table-storage-overview"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The model, &lt;code&gt;QuoteEntity&lt;/code&gt; provided in the source code already, inherits from &lt;code&gt;TableEntity&lt;/code&gt;. The overloaded constructor, &lt;code&gt;public QuoteEntity(string phoneNumber, string quote)&lt;/code&gt;, creates an object with all the properties needed to store it in a table store.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//"src/Functions/Models/QuoteEntity.cs"&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;QuoteEntity&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;TableEntity&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;QuoteEntity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;  &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;QuoteEntity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;PartitionKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Quotes"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="n"&gt;RowKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Guid&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NewGuid&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
       &lt;span class="n"&gt;UserPhoneNumber&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
       &lt;span class="n"&gt;Quote&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;UserPhoneNumber&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Quote&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Writing to an Azure table store
&lt;/h3&gt;

&lt;p&gt;To avoid duplicating code, we will use &lt;code&gt;TableDbContext&lt;/code&gt; to talk to the Azure Table Store. This code is in the "TableServices" directory and already provided. We will use dependency injection, recently added to Azure Functions natively, to inject the context into the constructor of both our functions.  This DbContext has already been registered to the IoT container in the &lt;code&gt;Startup.cs&lt;/code&gt; file as seen below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//"src/Functions/Startup.cs"&lt;/span&gt;
&lt;span class="n"&gt;ITableConfiguration&lt;/span&gt; &lt;span class="n"&gt;tableConfig&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TableConfiguration&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;ConnectionString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TableStorage-ConnectionString"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
   &lt;span class="n"&gt;TableName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TableStorage-TableName"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;tableConfig&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;ITableDbContext&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;TableDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;TableDbContext&lt;/code&gt; will handle all interactions with the table storage. It implements the &lt;code&gt;ITableDbContext&lt;/code&gt; and has two private methods, &lt;code&gt;CreateStorageAccountFromConnectionString&lt;/code&gt;, which ensures the table is created and &lt;code&gt;GetRandom&lt;/code&gt;, which generates a random integer based upon the number of rows in a given collection.&lt;/p&gt;

&lt;p&gt;Both the &lt;code&gt;ILoggerFactory&lt;/code&gt; and the &lt;code&gt;ITableConfiguration&lt;/code&gt; dependencies are injected into the class.&lt;/p&gt;

&lt;p&gt;Let's implement the &lt;code&gt;CreateTableAsync&lt;/code&gt; method first. We will use the private method &lt;code&gt;CreateStorageAccountFromConnectionString()&lt;/code&gt; to validate the connection string and return a &lt;code&gt;CloudStorageAccount&lt;/code&gt; object. We can then use this object to create a &lt;code&gt;CloudTableClient&lt;/code&gt; object called &lt;code&gt;tableClient&lt;/code&gt; which we can then use to create a table object, assuming that one doesn't exist already, and assign that to the &lt;code&gt;CloudTable&lt;/code&gt; object called &lt;code&gt;_table&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//"src/Functions/TableServices/TableDbContext.cs"&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;CloudTable&lt;/span&gt; &lt;span class="n"&gt;_table&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;CreateTableAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="c1"&gt;// Retrieve storage account information from connection string.&lt;/span&gt;
   &lt;span class="n"&gt;CloudStorageAccount&lt;/span&gt; &lt;span class="n"&gt;storageAccount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;CreateStorageAccountFromConnectionString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

   &lt;span class="c1"&gt;// Create a table client for interacting with the table service&lt;/span&gt;
   &lt;span class="n"&gt;CloudTableClient&lt;/span&gt; &lt;span class="n"&gt;tableClient&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storageAccount&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateCloudTableClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;TableClientConfiguration&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

   &lt;span class="c1"&gt;// Create the table&lt;/span&gt;
   &lt;span class="n"&gt;_table&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tableClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetTableReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_tableConfiguration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TableName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;CreateIfNotExistsAsync&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Created Table named: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;_tableConfiguration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TableName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;else&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Table &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;_tableConfiguration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TableName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; already exists"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let's implement the method that will write data to the table, &lt;code&gt;InsertOrMergeEntityAsync&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;First, we must check if the table already exists, and if not, call the &lt;code&gt;CreateTableAsync&lt;/code&gt; method that we previously created. Next, we check if the incoming &lt;code&gt;TableEntity&lt;/code&gt; argument &lt;code&gt;entity&lt;/code&gt; is null and throw an error if it is.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt;  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;QuoteEntity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;InsertOrMergeEntityAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TableEntity&lt;/span&gt; &lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_table&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;CreateTableAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;ArgumentNullException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;nameof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;try&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
 &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;entity&lt;/code&gt; is not null, then we move immediately into a "try/catch" statement. Add the following code to the &lt;code&gt;try{}&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;

       &lt;span class="c1"&gt;// Create the InsertOrMerge table operation&lt;/span&gt;
       &lt;span class="n"&gt;TableOperation&lt;/span&gt; &lt;span class="n"&gt;insertOrMergeOperation&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;TableOperation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InsertOrMerge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

       &lt;span class="c1"&gt;// Execute the operation.&lt;/span&gt;
       &lt;span class="n"&gt;TableResult&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;insertOrMergeOperation&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;insertedQuote&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Result&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;QuoteEntity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

       &lt;span class="c1"&gt;// Get the request units consumed by the current operation. RequestCharge of a TableResult is only applied to Azure CosmoS DB&lt;/span&gt;
       &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestCharge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Request Charge of InsertOrMerge Operation:&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RequestCharge&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
       &lt;span class="p"&gt;}&lt;/span&gt;

       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;insertedQuote&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above code, we attempt to use the &lt;code&gt;TableOperation.InsertOrMerge(TableEntity entity)&lt;/code&gt; method provided in &lt;br&gt;
 &lt;code&gt;Microsoft.Azure.Cosmos.Table&lt;/code&gt; library to create a table operation. We then execute the operation using &lt;code&gt;_table.ExecuteAsync(TableOperation insertOrMergeOperation)&lt;/code&gt; method from the same library.&lt;/p&gt;

&lt;p&gt;If all goes well, we are returned the created entity. If not we log any errors in the "catch".&lt;/p&gt;
&lt;h3&gt;
  
  
  The Inbound Function
&lt;/h3&gt;

&lt;p&gt;Our first function, &lt;code&gt;InboundFunction&lt;/code&gt;, is found in the "Functions" directory.  It is an HTTP triggered function that we will invoke using a POST request from Twilio. The &lt;code&gt;TableDbContext&lt;/code&gt; is injected into the constructor, so it is immediately available for us to use.&lt;/p&gt;

&lt;p&gt;First, we will need to read the body of the request and write it to a string, so add the following line to the &lt;code&gt;Run&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//"src/Functions/InboundFunction.cs"&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;FunctionName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"InboundFunction"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
   &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpTrigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AuthorizationLevel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Anonymous&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"post"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Route&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
   &lt;span class="n"&gt;HttpRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;requestBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ReadToEndAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will need to extract the "From" number and the "Body" from the incoming request and map it to a &lt;code&gt;Message&lt;/code&gt; model object. &lt;code&gt;Message&lt;/code&gt; has a constructor available that will take the incoming request body as a string and map it for us.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;requestBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ReadToEndAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can create a new &lt;code&gt;QuoteEntity&lt;/code&gt;, using the overloaded constructor and the &lt;code&gt;From&lt;/code&gt; and &lt;code&gt;Body&lt;/code&gt; properties of the &lt;code&gt;Message&lt;/code&gt; object. This can then be passed to the &lt;code&gt;InsertOrMergeEntityAsync&lt;/code&gt; method on our DB context, &lt;code&gt;_tableContext&lt;/code&gt; which will create and save our new quote:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;requestBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;StreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ReadToEndAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;requestBody&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;quoteEntity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;QuoteEntity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;From&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;newQuote&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_tableContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;InsertOrMergeEntityAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quoteEntity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;QuoteEntity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I would recommend adding some logging to the above code. If you would like to see how that's done, then check out the &lt;code&gt;complete&lt;/code&gt; branch of the repo.&lt;/p&gt;

&lt;h3&gt;
  
  
  Writing to an Azure table store
&lt;/h3&gt;

&lt;p&gt;We can now write data to our table store, but we also need to read it back out. Let's return to the &lt;code&gt;TableDbContext&lt;/code&gt; and implement the remaining methods.&lt;/p&gt;

&lt;p&gt;We want to be able to pick a random quote from our store and send it to all our friends. To do this we will need to bring back all the quotes as an array, create a random number based upon the length of our array, and then use that number to select a quote via its index.&lt;/p&gt;

&lt;p&gt;But first, we need to check if the table exists!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//"src/Functions/TableServices/TableDbContext"&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;QuoteEntity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetRandomEntityAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_table&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;CreateTableAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we are sure that we have a table created, we can then, within a "try/catch" statement, create a new table query &lt;code&gt;TableQuery&amp;lt;TableEntity&amp;gt;&lt;/code&gt;, execute that query, and then create an array from the result.&lt;br&gt;
As a precaution, if the array is empty, we return a default quote.&lt;br&gt;
If it is populated, we then use the private &lt;code&gt;GetRandom&lt;/code&gt; method to return a random number based upon the length of the array.&lt;br&gt;
This random number will then be used to select a quote via its index, casting the result to a &lt;code&gt;QuoteEntity&lt;/code&gt; and returning that value. If something goes wrong, we log it in the "catch".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TableQuery&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;TableEntity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
   &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;quotes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;QuoteEntity&lt;/span&gt;
       &lt;span class="p"&gt;{&lt;/span&gt;
           &lt;span class="n"&gt;Quote&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"You look lovely today, text in and say something nice for your friends!"&lt;/span&gt;
       &lt;span class="p"&gt;};&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
   &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;random&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetRandom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;randomQuote&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;random&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;QuoteEntity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;randomQuote&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In addition to a random quote, we will also want a list of all the numbers that have texted a quote in. We can then use this list to send the random quote to all our friends, assuming your friends are sending in their happy thoughts to your app, too!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ListNumbersAsync&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_table&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;CreateTableAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;First, we again check if our table is created.&lt;br&gt;
If it is, we can create our query from within a "try/catch" statement. We then create an empty list of type string, ready to populate with phone numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;_log&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;LogInformation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;throw&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will need to create a &lt;code&gt;TableQuery&lt;/code&gt; object and execute this. Only this time, instead of creating an array, we will group by phone number, to ensure we only get each number once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TableQuery&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;QuoteEntity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;quotes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;GroupBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserPhoneNumber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can then iterate over our collection, adding the phone numbers to our newly created list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;query&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;TableQuery&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;QuoteEntity&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;quotes&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_table&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExecuteQuery&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;query&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;GroupBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UserPhoneNumber&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;quote&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;quotes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;quote&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Outbound Function
&lt;/h3&gt;

&lt;p&gt;Our second function, &lt;code&gt;OutboundFunction&lt;/code&gt;, canalso found in the "Functions" directory.  It is a function that is time-triggered based upon a schedule described by a &lt;a href="https://en.wikipedia.org/wiki/Cron"&gt;cron expression&lt;/a&gt;. The &lt;code&gt;TableDbContext&lt;/code&gt; is injected into the constructor and is available for us to use as a private attribute throughout the class. &lt;/p&gt;

&lt;p&gt;We also fetch the Twilio phone number from settings, which we will set up soon, and assign it to the private attribute &lt;code&gt;_phoneNumber&lt;/code&gt;, within the constructor.&lt;/p&gt;

&lt;p&gt;Our Function cron expression is set to &lt;code&gt;0 0 10 * * *&lt;/code&gt;, which means it will fire at 10 am every day. If you would like it to fire differently, then this handy &lt;a href="https://codehollow.com/2017/02/azure-functions-time-trigger-cron-cheat-sheet/"&gt;cheat sheet&lt;/a&gt; for cron expressions can help you.&lt;/p&gt;

&lt;p&gt;We will be using Twilio to send our SMS messages. We will need to initialise the Twilio client within the &lt;code&gt;Run&lt;/code&gt; method. The Twilio Account SID and Auth token will also be taken from settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//"src/Functions/OutboundFunction.cs"&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nf"&gt;TimerTrigger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"0 0 10 * * *"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="n"&gt;TimerInfo&lt;/span&gt; &lt;span class="n"&gt;myTimer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ILogger&lt;/span&gt; &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;TwilioClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TWILIO_ACCOUNT_SID"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="n"&gt;Environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEnvironmentVariable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"TWILIO_AUTH_TOKEN"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now use our &lt;code&gt;_tableContext&lt;/code&gt; to first fetch the list of phone numbers and then the random quote we wish to send.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;//collect all the telephone numbers of our users from the table storage&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_tableContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ListNumbersAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;//get a random quote from the database&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;quoteEntity&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_tableContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetRandomEntityAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final piece of this code, is to iterate over our number collection and send the quote to each user phone number.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;  &lt;span class="n"&gt;MessageResource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
       &lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PhoneNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_phoneNumber&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PhoneNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
       &lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;quoteEntity&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Quote&lt;/span&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setting the configuration
&lt;/h3&gt;

&lt;p&gt;When developing locally, Azure functions rely on having all configuration within the &lt;code&gt;local.settings.json&lt;/code&gt; file. You won't have this in your copy that you cloned from GitHub, as the &lt;code&gt;.gitignore&lt;/code&gt; that comes with a function app excludes it. This is to ensure sensitive data isn't accidentally pushed to repositories. As a workaround, there should be a &lt;code&gt;local.settings.demo.json&lt;/code&gt; file in the GitHub copy, so just rename that to be &lt;code&gt;local.settings.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It is in this &lt;code&gt;local.settings.json&lt;/code&gt; file where we will need to add all of the connection strings and secrets.&lt;/p&gt;

&lt;p&gt;You can find the Table Storage connection string in the Azure portal.&lt;br&gt;
Navigate to the Resource Group that we made earlier and click into the "storage account" which is used for our Table Storage. On the left-hand menu, click into "Access keys" and copy the "Connection string" listed against "key1".&lt;/p&gt;

&lt;p&gt;This connection string will be the value applied to the following three keys in &lt;code&gt;local.settings.json&lt;/code&gt;; "StorageConnectionSettings", "AzureWebJobsStorage" and "TableStorage-ConnectionString".&lt;/p&gt;

&lt;p&gt;Your Twilio Account SID and Auth token can be found on the Twilio console. Grab your Twilio number and set it as a value against the setting "PhoneNumber".&lt;/p&gt;

&lt;p&gt;We are now ready to test our functions!&lt;/p&gt;
&lt;h3&gt;
  
  
  Getting up and running
&lt;/h3&gt;

&lt;p&gt;Start your functions from your IDE or from within the CLI with the following command from the following location "~/DailyAffirmations/src/Functions":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;func start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your function will start and you will receive the following message in the console telling you about the HTTP trigger endpoints.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Http Functions:
    InboundFunction: [POST] http://localhost:7071/api/InboundFunction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will want to wire the Twilio number to this endpoint using ngrok.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up ngrok
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.twilio.com/blog/2013/10/test-your-webhooks-locally-with-ngrok.html"&gt;ngrok creates a public-facing&lt;/a&gt; URL that tunnels to our project running locally so we can test our endpoint without deploying to a server. Follow the &lt;a href="https://ngrok.com/download"&gt;instructions on the ngrok site to download and install it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Once installed, run the following on your command line to start ngrok:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ngrok http 7071 &lt;span class="nt"&gt;-host-header&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"localhost:7071"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your function isn't running on port 7071, then just update the above command with your port number.&lt;/p&gt;

&lt;p&gt;You will then see an output similar to below.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6gkq0v1g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/D3XLian-zic0S-QgfpnnnvWze8OTitTNrh98u-bzG7kv5L.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6gkq0v1g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/D3XLian-zic0S-QgfpnnnvWze8OTitTNrh98u-bzG7kv5L.width-500.png" alt="alt ngrok in the console image" title="ngrok in the console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the public-facing URL which should be along the lines of &lt;code&gt;https://12345.ngrok.io&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To enable Twilio to make the initial request that fires off our string of events, we need to set up the webhook.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--g5whUSVR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/1zrMcMi_gxz-UPey9laAMlw9DaFyS8RaB8y5gttt2IRTkx.width-500.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--g5whUSVR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/images/1zrMcMi_gxz-UPey9laAMlw9DaFyS8RaB8y5gttt2IRTkx.width-500.png" alt="alt image of twilio console and where to set up webhook" title="Twilio webhook page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Go to the &lt;a href="https://www.twilio.com/console"&gt;Twilio console&lt;/a&gt; and find the number that you added for this project.  Next, add the API endpoint &lt;code&gt;https://&amp;lt;NGROK_NUMBER&amp;gt;.ngrok.io/api/Inbound Function&lt;/code&gt; from ngrok and paste into the A MESSAGE COMES IN section, then save.&lt;br&gt;
Now you can send an SMS with your inspiring thought as the message and it will be written to the table store.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zPCDp9bE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/original_images/qnsMGCQj_1DjDjGOh_OHBBcWL5jRQ_5_63iOzwHd0JxrzgGdv62F4dLKMzvA06_A994B4sRJfpWnuf" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zPCDp9bE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://s3.amazonaws.com/com.twilio.prod.twilio-docs/original_images/qnsMGCQj_1DjDjGOh_OHBBcWL5jRQ_5_63iOzwHd0JxrzgGdv62F4dLKMzvA06_A994B4sRJfpWnuf" alt="alt gif with inspirational affirmations" title="Affirmations gif"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Testing the timer trigger
&lt;/h3&gt;

&lt;p&gt;We don't want to wait for our trigger to fire in order to test it… that only happens once a day! It's much more convenient to test it with an HTTP POST request.&lt;br&gt;
For the purpose of testing, we’ll use Postman to create a new POST request to the following URL "&lt;a href="http://localhost:7071/admin/functions/OutboundFunction"&gt;http://localhost:7071/admin/functions/OutboundFunction&lt;/a&gt;", with "Content-Type" set to "application/json" and the body set to an empty JSON object &lt;code&gt;{}&lt;/code&gt;.&lt;br&gt;
Once you send this post you will receive an SMS with a happy thought!&lt;/p&gt;

&lt;p&gt;Publishing to Azure&lt;br&gt;
An easy way to publish your app is by using the Azure CLI. First, make sure you are logged into your Azure account with the command &lt;code&gt;az login&lt;/code&gt;, which will open a browser and enable you to log in to Azure.&lt;br&gt;
Then, from within "src/Functions" run the command we made a note of at the beginning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;func azure functionapp publish &amp;lt;FUNCTION_APP_NAME&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to add your app settings and update your Twilio endpoint to your Function app's URL.&lt;/p&gt;

&lt;h3&gt;
  
  
  What next?
&lt;/h3&gt;

&lt;p&gt;We've seen how we can quickly receive an incoming SMS message and send out an email.  A great update to the above code would be to add further logging and error handling. You could also add a third function that enables you to add your friend's numbers without them having to text a quote in. &lt;/p&gt;

&lt;p&gt;Let me know what other cool ideas you have for Twilio SMS and Azure Functions. I can't wait to see what you build!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Email: &lt;a href="mailto:lporter@twilio.com"&gt;lporter@twilio.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Twitter: &lt;a href="https://github.com/Layla-P"&gt;@LaylaCodesIt&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href="https://github.com/Layla-P"&gt;layla-p&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>serverless</category>
      <category>dotnet</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
