<?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: Christy Jacob</title>
    <description>The latest articles on DEV Community by Christy Jacob (@christyjacob4).</description>
    <link>https://dev.to/christyjacob4</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%2F119691%2F5be2bcad-e1ee-4ef8-928b-d71f4e355af6.png</url>
      <title>DEV Community: Christy Jacob</title>
      <link>https://dev.to/christyjacob4</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/christyjacob4"/>
    <language>en</language>
    <item>
      <title>Introducing Password Dictionary In Appwrite: A New Layer Of Security</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Wed, 12 Apr 2023 09:45:28 +0000</pubDate>
      <link>https://dev.to/appwrite/introducing-password-dictionary-in-appwrite-a-new-layer-of-security-2356</link>
      <guid>https://dev.to/appwrite/introducing-password-dictionary-in-appwrite-a-new-layer-of-security-2356</guid>
      <description>&lt;p&gt;The internet has undeniably brought a myriad of benefits to our lives, making it easier than ever to connect, share, and learn. However, these benefits come with a price. Our digital identities, personal information, and financial data are constantly at risk of being compromised. One of the primary culprits? Weak, commonly used passwords. &lt;/p&gt;

&lt;p&gt;If you're an app developer, security is always on your mind. You'll also know your secure APIs are only as strong as your user's passwords, and users who aren't tech-savvy pick horrible passwords!&lt;/p&gt;

&lt;p&gt;In Appwrite 1.3, we released two new features to help mitigate this risk and protect user data. &lt;strong&gt;Password History&lt;/strong&gt; in combination with &lt;strong&gt;Password Dictionary&lt;/strong&gt; prevent common pitfalls when users are faced with the need to set or update their passwords. In this post, we'll show you how Appwrite's Password Dictionary can prevent a potential data breach in your app.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⛔ The Problem: Commonly Used Passwords and Data Breaches
&lt;/h2&gt;

&lt;p&gt;To understand the extent of the problem, let's take a look at some real-life examples of data breaches caused by commonly used passwords.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.nytimes.com/2017/10/03/technology/yahoo-hack-3-billion-users.html"&gt;The Yahoo Data Breach (2013-2014)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In 2013 and 2014, Yahoo suffered two massive data breaches affecting over 3 billion user accounts. While the breaches were orchestrated by a state-sponsored hacker group that used various sophisticated techniques, the use of weak passwords by Yahoo users exacerbated the situation. Once the hackers had access to Yahoo's databases, they were able to crack and compromise many user accounts more quickly and easily because a significant portion of the users had weak, commonly used passwords.&lt;/p&gt;

&lt;p&gt;An analysis of the leaked data revealed that many users relied on simple, easily guessable passwords like "123456," "password," and "qwerty." These weak passwords made it easier for the attackers to use brute-force or dictionary attacks to crack them, thus providing an open door for attackers to compromise user accounts and gain unauthorized access to personal information.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.cbsnews.com/news/linkedin-2012-data-breach-hack-much-worse-than-we-thought-passwords-emails/"&gt;The LinkedIn Data Breach (2012)&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In 2012, LinkedIn suffered a data breach that affected 167 million user accounts. Again, weak passwords played a significant role in the breach. A staggering 65% of the leaked passwords were easily crackable due to their simplicity or their appearance on common password lists. This breach not only highlighted the importance of strong, unique passwords but also the need for organizations to protect users from themselves by implementing better security measures.&lt;/p&gt;

&lt;p&gt;These examples demonstrate the risks associated with using weak, commonly used passwords. But what can be done to mitigate this problem?&lt;/p&gt;

&lt;h2&gt;
  
  
  🔐 Introducing Password Dictionary
&lt;/h2&gt;

&lt;p&gt;A password dictionary is a tool designed to help address the issue of weak, commonly used passwords. It is essentially a large database of commonly used passwords that are considered insecure. When a user attempts to set a new password, the password dictionary checks if the proposed password is on the list. If it is, the user is prompted to choose a different, more secure password. &lt;/p&gt;

&lt;p&gt;The newly introduced password dictionary in Appwrite adds an additional layer of security for user accounts. By preventing users from setting commonly used passwords, the password dictionary:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduces the risk of password-based attacks&lt;/li&gt;
&lt;li&gt;Encourages stronger passwords&lt;/li&gt;
&lt;li&gt;Enhances overall system security&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By default, the Password Dictionary is disabled. To enable it, head over to the &lt;strong&gt;Auth&lt;/strong&gt; section in your project and look for the &lt;strong&gt;Security&lt;/strong&gt; tab in the top navigation bar. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy4jd64pmx2zki8g82sxe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy4jd64pmx2zki8g82sxe.png" alt="Appwrite Auth Settings" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Scroll down to find the &lt;strong&gt;Password Dictionary&lt;/strong&gt; settings and enable it. Password Dictionary will now be enforced for all new users that sign up as well as when users try to update their passwords.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqcx2skoxb7qdpubi2wzi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqcx2skoxb7qdpubi2wzi.png" alt="Password Dictionary Toggle" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⏭️ What’s next?
&lt;/h2&gt;

&lt;p&gt;As we continue to rely on digital services in our daily lives, it is crucial for individuals and organizations alike to prioritize security. By making strong, unique passwords the norm rather than the exception, we can all contribute to a safer and more secure digital world. &lt;/p&gt;

&lt;p&gt;You can learn more about &lt;a href="https://dev.to/appwrite/protect-your-applications-from-bad-passwords-introducing-password-history-19n5"&gt;Password History&lt;/a&gt;, which is another security measure to protect users from reusing their old passwords and all the other cool features added in the latest version of Appwrite in &lt;a href="https://dev.to/appwrite/join-celebrations-appwrite-13-ships-relationships-57fc"&gt;our announcement post&lt;/a&gt;. &lt;/p&gt;

</description>
      <category>opensource</category>
      <category>programming</category>
      <category>news</category>
    </item>
    <item>
      <title>Phone Authentication with Appwrite and Twilio</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Wed, 29 Jun 2022 14:28:58 +0000</pubDate>
      <link>https://dev.to/appwrite/phone-authentication-with-appwrite-and-twilio-26ek</link>
      <guid>https://dev.to/appwrite/phone-authentication-with-appwrite-and-twilio-26ek</guid>
      <description>&lt;p&gt;Appwrite 0.15 was just announced and brings with it one of the most anticipated Appwrite features! Yes, you guessed that right! We’re introducing &lt;strong&gt;phone authentication in Appwrite!&lt;/strong&gt; With this release you’ll now be able to authenticate users using their phone numbers. This release also introduces 3 new phone providers including &lt;strong&gt;Twilio&lt;/strong&gt;, &lt;strong&gt;TextMagic&lt;/strong&gt; &amp;amp; &lt;strong&gt;TeleSign&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3p8isoccuq8n8ie08xw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs3p8isoccuq8n8ie08xw.png" alt="Built App"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this tutorial we’ll learn how to set up a &lt;strong&gt;Twilio&lt;/strong&gt; account and configure it for use with Appwrite and build a Svelte app to put it all together! The app will demonstrate the usage of all the new phone authentication endpoints introduced in &lt;strong&gt;Appwrite 0.15!&lt;/strong&gt; Here's what we will learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To create sessions using a phone number and verify them. &lt;/li&gt;
&lt;li&gt;To update a user’s phone number, send verification codes and update the verification status. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without further ado, let’s get started!&lt;/p&gt;

&lt;h4&gt;
  
  
  🤔 New to Appwrite?
&lt;/h4&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="http://appwrite.io/" rel="noopener noreferrer"&gt;Appwrite&lt;/a&gt; is an open-source back-end-as-a-service that abstracts all the complexity of building a modern application by providing you with a set of REST and Realtime APIs for your core back-end needs. Appwrite takes the heavy lifting for developers and handles user authentication and authorization, databases, file storage, cloud functions, webhooks, and much more!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🧑‍💻 Setting up Twilio
&lt;/h2&gt;

&lt;p&gt;The first step is to create a Twilio account. Head over to the &lt;a href="https://www.twilio.com/try-twilio" rel="noopener noreferrer"&gt;Sign Up page&lt;/a&gt;, fill in your details, verify your email and phone number. On the Twilio Dashboard, click on the &lt;strong&gt;Get a Twilio phone number&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fisd8qzj5no1nx78r65e1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fisd8qzj5no1nx78r65e1.png" alt="Twilio Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This generates a phone number that we can use to send messages from. Under the Account Info section, you’ll find the &lt;strong&gt;Account SID&lt;/strong&gt;, &lt;strong&gt;Auth Token&lt;/strong&gt; and the newly generated phone number. Keep these handy as you’ll need them in the next step.&lt;/p&gt;

&lt;p&gt;There’s one last thing that we need to do in the Dashboard before we move to the next step. Since we’re using Twilio’s free trial, we can only send an SMS to verified phone numbers. Head over to the &lt;a href="https://console.twilio.com/us1/develop/phone-numbers/manage/verified" rel="noopener noreferrer"&gt;Verified Callers IDs&lt;/a&gt; page and enter the numbers that you’d like to send messages to.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Install Appwrite
&lt;/h2&gt;

&lt;p&gt;Next, we need to get an Appwrite server up and running. You can either choose to &lt;a href="https://appwrite.io/docs/installation#installWithDocker" rel="noopener noreferrer"&gt;install it locally&lt;/a&gt; on your system or deploy it on the cloud with one of our &lt;a href="https://appwrite.io/docs/installation#one-click-setups" rel="noopener noreferrer"&gt;one click setups&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;TLDR; It only takes a single magic command! 😊 &lt;/p&gt;

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

docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--volume&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--volume&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;/appwrite:/usr/src/code/appwrite:rw &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--entrypoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"install"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    appwrite/appwrite:0.15.1


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

&lt;/div&gt;

&lt;p&gt;This command installs Appwrite and creates an &lt;strong&gt;appwrite&lt;/strong&gt; folder with &lt;strong&gt;docker-compose.yml&lt;/strong&gt; and &lt;strong&gt;.env&lt;/strong&gt; files. Once the installation is complete, head over to the &lt;strong&gt;appwrite&lt;/strong&gt; folder. &lt;/p&gt;

&lt;p&gt;We need to update two variables in the &lt;strong&gt;.env&lt;/strong&gt; file namely &lt;strong&gt;_APP_PHONE_PROVIDER&lt;/strong&gt; and &lt;strong&gt;_APP_PHONE_FROM&lt;/strong&gt;. &lt;strong&gt;_APP_PHONE_FROM&lt;/strong&gt; is the phone number you just obtained from Twilio and &lt;strong&gt;_APP_PHONE_PROVIDER&lt;/strong&gt; is a DSN string that helps Appwrite connect to the Twilio API.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;_APP_PHONE_PROVIDER&lt;/strong&gt; takes the following format&lt;/p&gt;

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

&lt;span class="nv"&gt;_APP_PHONE_PROVIDER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;phone://&amp;lt;Account SID&amp;gt;:&amp;lt;Auth Token&amp;gt;@twilio


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

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;_APP_PHONE_FROM&lt;/strong&gt; takes the following format&lt;/p&gt;

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

&lt;span class="nv"&gt;_APP_PHONE_FROM&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;+14344251928


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

&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favctf0wwvj14o27873bm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Favctf0wwvj14o27873bm.png" alt="Account Info"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can obtain the &lt;strong&gt;Account SID&lt;/strong&gt;, &lt;strong&gt;Auth Token&lt;/strong&gt; and the phone number from the Account Info section of the Twilio Dashboard.&lt;/p&gt;

&lt;p&gt;Once that is done, we need to restart the Appwrite server for the environment variables to take effect. Please note that this command needs to be executed from the &lt;strong&gt;appwrite&lt;/strong&gt; folder that was created during installation.&lt;/p&gt;

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

docker compose up &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;--force-recreate&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Next, head over to &lt;strong&gt;localhost&lt;/strong&gt; ( or your public IP address ) and create a new user account followed by a project with a name of your choosing.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5qz9r9jobl1h448rgusf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5qz9r9jobl1h448rgusf.png" alt="Appwrite create user"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zf94zqooxr4a4iyjsel.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1zf94zqooxr4a4iyjsel.png" alt="Appwrite Project Dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the &lt;strong&gt;projectId&lt;/strong&gt; and the &lt;strong&gt;endpoint&lt;/strong&gt; from the &lt;strong&gt;Settings&lt;/strong&gt; page as we’ll need it for the web app we build in the next step!&lt;/p&gt;

&lt;h2&gt;
  
  
  🔮 Setting up Our SvelteKit Project
&lt;/h2&gt;

&lt;p&gt;For the sake of this example, we’ll be using &lt;strong&gt;SvelteKit&lt;/strong&gt; but the concepts and code examples remain true for all frameworks out there. First, we’ll need to create a new SvelteKit project and set up &lt;strong&gt;Tailwind CSS&lt;/strong&gt;. I’ve found the official &lt;a href="https://tailwindcss.com/docs/guides/sveltekit" rel="noopener noreferrer"&gt;Tailwind installation guide&lt;/a&gt; to be extremely helpful here. &lt;/p&gt;

&lt;p&gt;Instead of re-inventing the wheel here, I’d recommend you to complete the setup and return back to this tutorial. &lt;/p&gt;

&lt;p&gt;Alright! It’s time to install some of our dependencies! We’ll be using two dependencies for our project. Head over to the project folder and install them with the following commands&lt;/p&gt;

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

npm i &lt;span class="nt"&gt;-D&lt;/span&gt; @zerodevx/svelte-toast
npm i appwrite


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

&lt;/div&gt;

&lt;p&gt;Next, add the following entries into your .env file. You might need to create this file if it does not exist already.&lt;/p&gt;

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

&lt;span class="nv"&gt;VITE_APPWRITE_ENDPOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;http://localhost/v1
&lt;span class="nv"&gt;VITE_APPWRITE_PROJECT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&amp;lt;YOUR_PROJECT_ID]


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

&lt;/div&gt;

&lt;p&gt;Don’t forget to replace the values with your own Appwrite &lt;strong&gt;projectId&lt;/strong&gt; and &lt;strong&gt;endpoint&lt;/strong&gt; that you obtained from the Dashboard earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔨 Setting up the Appwrite SDK
&lt;/h2&gt;

&lt;p&gt;Next, let’s create our Appwrite service that will help abstract all the SDK calls to a single place. Create a new file &lt;code&gt;src/lib/appwrite.ts&lt;/code&gt; and fill in the following contents&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Account&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;appwrite&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;client&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VITE_APPWRITE_ENDPOINT&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;import&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;VITE_APPWRITE_PROJECT_ID&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppwriteService&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;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;getAccount&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&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;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;createAccount&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unique()&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&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;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;createEmailSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createEmailSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&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;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;deleteSession&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deleteSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;current&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/** Phone Authentication endpoints */&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;createPhoneSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createPhoneSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;unique()&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;number&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;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;updatePhoneSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updatePhoneSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&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;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;updatePhone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updatePhone&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;password&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;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;createPhoneVerification&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createPhoneVerification&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;static&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;updatePhoneVerification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;account&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;updatePhoneVerification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;userId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;secret&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;Here,  we import the appwrite SDK and initialize the &lt;strong&gt;Client&lt;/strong&gt; and &lt;strong&gt;Account&lt;/strong&gt; services. We also export an &lt;strong&gt;AppwriteService&lt;/strong&gt; class with a lot of static methods that we can use across our app. The &lt;code&gt;appwrite.ts&lt;/code&gt; file is all it takes to integrate Appwrite into the project. All the other files deal with the UI of the project and should be fairly straightforward to read and understand.&lt;/p&gt;

&lt;p&gt;In order to keep this tutorial concise, we’ll just copy over the contents for all the other files from the completed &lt;a href="https://github.com/christyjacob4/appwrite-auth-demo" rel="noopener noreferrer"&gt;GitHub project&lt;/a&gt;. Here are a list of files we need to copy&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/christyjacob4/appwrite-auth-demo/blob/main/src/lib/Toast.ts" rel="noopener noreferrer"&gt;Toast.ts&lt;/a&gt; - This file contains the theming configuration for our toast messages&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/christyjacob4/appwrite-auth-demo/blob/main/src/routes/__layout.svelte" rel="noopener noreferrer"&gt;__layout.svelte&lt;/a&gt; - This file defines the base layout for all our screens&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/christyjacob4/appwrite-auth-demo/blob/main/src/routes/index.svelte" rel="noopener noreferrer"&gt;index.svelte&lt;/a&gt; - UI for the user profile page&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/christyjacob4/appwrite-auth-demo/blob/main/src/routes/login.svelte" rel="noopener noreferrer"&gt;login.svelte&lt;/a&gt; - UI for the login with email page&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/christyjacob4/appwrite-auth-demo/blob/main/src/routes/loginPhone.svelte" rel="noopener noreferrer"&gt;loginPhone.svelte&lt;/a&gt; - UI for the login with phone page&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/christyjacob4/appwrite-auth-demo/blob/main/src/routes/signup.svelte" rel="noopener noreferrer"&gt;signup.svelte&lt;/a&gt; - UI for the signup page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once complete, we’re all ready to preview the project. Run the following command to run a local development server.&lt;/p&gt;

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

npm run dev


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

&lt;/div&gt;

&lt;p&gt;That brings us to the end of this tutorial! I hope this guide helped you set up phone authentication in your web app and above all, I hope you enjoyed learning something new! I had a lot of fun learning Svelte and building a web app for this tutorial and I can’t wait to build some more apps!&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Resources
&lt;/h2&gt;

&lt;p&gt;If you’re stuck at any point during the tutorial, feel free to reach out for help in our &lt;a href="https://appwrite.io/discord" rel="noopener noreferrer"&gt;friendly discord channels&lt;/a&gt; run by humans! If you like what we do at Appwrite, don’t forget to drop us a tiny star on GitHub 😉 Here are some great resources to help you get started. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/awesome-appwrite" rel="noopener noreferrer"&gt;Appwrite Resource Showcase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://svelte.dev/tutorial/basics" rel="noopener noreferrer"&gt;Svelte Documentation&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs" rel="noopener noreferrer"&gt;Appwrite Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/appwrite" rel="noopener noreferrer"&gt;Appwrite's GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Cloud Functions Using the New Java Runtime</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Fri, 20 May 2022 12:21:02 +0000</pubDate>
      <link>https://dev.to/appwrite/cloud-functions-using-the-new-java-runtime-39j0</link>
      <guid>https://dev.to/appwrite/cloud-functions-using-the-new-java-runtime-39j0</guid>
      <description>&lt;p&gt;One of the highlights of Appwrite’s latest release is the addition of &lt;strong&gt;four&lt;/strong&gt; new Cloud Function runtimes! &lt;strong&gt;Java, Kotlin, .NET and C++&lt;/strong&gt; are now a part of our ever growing list of runtimes! 🤯&lt;/p&gt;

&lt;p&gt;In this article, we’ll take a look at writing Cloud Functions using the &lt;strong&gt;Java runtime&lt;/strong&gt;. If you’re an Android developer, you could essentially build your app and write any necessary Cloud Functions without the need to learn any new language! 🤩&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  🤔 New to Appwrite?
&lt;/h4&gt;

&lt;p&gt;Appwrite is &lt;strong&gt;open source backend-as-a-service&lt;/strong&gt; that abstracts all the complexity involved in building a modern application by providing you with a set of REST APIs for your core backend needs. Appwrite handles user authentication and authorization, realtime databases, file storage, cloud functions, webhooks and much more! If there is anything missing, you can extend Appwrite using your favorite backend language.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📝 Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we get started, there are a couple of prerequisites. If you have the prerequisites setup already, you can skip to the following section. &lt;/p&gt;

&lt;p&gt;In order to follow along, you’ll need a few things beforehand.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🖥 &lt;strong&gt;An Appwrite instance&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you haven’t set up an Appwrite instance yet, you can follow the getting started guides to get up and running quickly. You can choose between &lt;a href="https://appwrite.io/docs/installation#one-click-setups"&gt;One-click installations&lt;/a&gt; on DigitalOcean or &lt;a href="https://appwrite.io/docs/installation#installWithDocker"&gt;Manual installations&lt;/a&gt; with Docker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; - It's just a single command to install Appwrite&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--volume&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--volume&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;/appwrite:/usr/src/code/appwrite:rw &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--entrypoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"install"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    appwrite/appwrite:0.14.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your server is up and running, head over to the Appwrite Dashboard on your server’s public IP address ( or localhost if you installed locally ) and create a new user account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcsmgu5zt6aeacshr59t3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcsmgu5zt6aeacshr59t3.png" alt="Create User" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧑‍💻 &lt;strong&gt;The Appwrite CLI&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll use the Appwrite CLI during this exercise as it makes the process super simple. If you have Node.js installed, the installation command is a simple&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; appwrite-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;npm&lt;/code&gt; is not your thing, we have numerous installation options you can find in the &lt;a href="https://appwrite.io/docs/command-line"&gt;getting started guide for the CLI&lt;/a&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  🏁 Getting Started
&lt;/h2&gt;

&lt;p&gt;With everything set up, we can now begin! Login to the Appwrite CLI using the following command and use the credentials we used when setting up the Appwrite server to login.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite login
? Enter your email &lt;span class="nb"&gt;test&lt;/span&gt;@test.com
? Enter your password &lt;span class="k"&gt;********&lt;/span&gt;
✓ Success
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we need to create a new Appwrite project to work with. We can use the following command to set it up&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite init project
? How would you like to start? Create a new Appwrite project
? What would you like to name your project? My Awesome Project
✓ Success
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can give your project any name of your choice. I’m going to stick to the defaults in this case. You’ll notice a new &lt;code&gt;appwrite.json&lt;/code&gt; file in the current directory which stores all the information about your project.&lt;/p&gt;

&lt;p&gt;It’s time to start writing our function! But wait, we don't need to start from scratch! The CLI can setup all the boilerplate for us using the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite init &lt;span class="k"&gt;function&lt;/span&gt;
? What would you like to name your &lt;span class="k"&gt;function&lt;/span&gt;? java-example
? What runtime would you like to use? Java &lt;span class="o"&gt;(&lt;/span&gt;java-17.0&lt;span class="o"&gt;)&lt;/span&gt;
✓ Success 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Give your function a name and choose the &lt;strong&gt;Java 17.0&lt;/strong&gt; runtime. This will create a new Appwrite Function in your project and set up all the boilerplate code necessary. Feel free to examine the files created in the &lt;code&gt;functions/java-example&lt;/code&gt; directory. You’ll find the CLI created a simple Java function that returns a very important JSON message&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"areDevelopersAwesome"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we go ahead and modify the function, let’s deploy it to get a feel of the end-to-end workflow from initializing the function to deploying it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite deploy &lt;span class="k"&gt;function&lt;/span&gt;
? Which functions would you like to deploy? java-example &lt;span class="o"&gt;(&lt;/span&gt;6286f6905af1e032e934&lt;span class="o"&gt;)&lt;/span&gt;
ℹ Info Deploying &lt;span class="k"&gt;function &lt;/span&gt;java-example &lt;span class="o"&gt;(&lt;/span&gt; 6286f6905af1e032e934 &lt;span class="o"&gt;)&lt;/span&gt;
ℹ Info Ignoring files using configuration from appwrite.json
✓ Success Deployed java-example &lt;span class="o"&gt;(&lt;/span&gt; 6286f6905af1e032e934 &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;appwrite deploy function&lt;/code&gt; command packages your source code, uploads it to the Appwrite server and initiates the build process. During this time, all the function’s dependencies are installed and a &lt;code&gt;.jar&lt;/code&gt; file is generated for your function. &lt;/p&gt;

&lt;p&gt;You can head over to your Appwrite Dashboard to track the progress of your deployment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgx2ndbw9bwimegq4uw1s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgx2ndbw9bwimegq4uw1s.png" alt="Deployment" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the deployment completes, you can execute your function by clicking the &lt;strong&gt;Execute Now&lt;/strong&gt; button. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frv1vutd97ugar0b67v6d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frv1vutd97ugar0b67v6d.png" alt="Execution Logs" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first execution results in what we call a &lt;strong&gt;Cold Start&lt;/strong&gt;. Essentially this is the first time a runtime is created, so it takes a bit longer. As you can see, the first execution took about &lt;strong&gt;331ms&lt;/strong&gt; and subsequent executions were around &lt;strong&gt;4ms&lt;/strong&gt;. Now that we have an idea of the complete workflow, we can start tinkering with the code and write some cool functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧮 Answering the Most Fundamental Question in Mathematics
&lt;/h2&gt;

&lt;p&gt;As the title suggests we’re going to write a cloud function to answer one of the most fundamental questions in Mathematics.&lt;/p&gt;

&lt;p&gt;Is the given number odd or even? I know what you’re thinking… It’s so easy! Why do I need a Cloud Function for it? I could just write&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But wait! We’re taking this to the next level. We’re going to decide if our number is even or odd using one of the most sophisticated and well written APIs out there! The &lt;a href="https://isevenapi.xyz/"&gt;isEven API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Jokes aside, this example aims to illustrate how you can make API calls from your Cloud Function which will enable you to build anything you’d like. &lt;/p&gt;

&lt;p&gt;Firstly, open the &lt;code&gt;java-example&lt;/code&gt; folder in your favorite IDE. Let’s start with a blank canvas and clean up our &lt;code&gt;src/Index.java&lt;/code&gt; file to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.HashMap&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RuntimeRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;json&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In order to deal with JSON objects more easily, we’ll make use of the popular &lt;a href="https://github.com/google/gson"&gt;&lt;code&gt;gson&lt;/code&gt;&lt;/a&gt; library. Include the following dependency in the &lt;code&gt;deps.gradle&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'com.google.code.gson:gson:2.9.0'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s write some code to read and parse a number sent as an argument to this function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.HashMap&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.Gson&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Gson&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Gson&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RuntimeRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;payloadString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPayload&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPayload&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; 
        &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"{}"&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPayload&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payloadString&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;containsKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;HashMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;
    &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;put&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Hello World!"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;json&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s go over the code we just wrote. From the functions documentation, we see that the &lt;code&gt;payload&lt;/code&gt; is available through the &lt;code&gt;request&lt;/code&gt; object and is a JSON string that needs to be converted to a JSON object to parse further. If the &lt;code&gt;payload&lt;/code&gt; is empty, we replace it with an empty JSON object. &lt;/p&gt;

&lt;p&gt;We then retrieve the &lt;code&gt;number&lt;/code&gt; that was passed to the function and default to the number &lt;code&gt;2&lt;/code&gt; in case it’s empty. We also import the &lt;code&gt;gson&lt;/code&gt; library and create an instance of it.&lt;/p&gt;

&lt;p&gt;Next, let’s make the call to the API using the native HTTP client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.Map&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.util.HashMap&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.net.HttpURLConnection&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.net.URL&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.BufferedReader&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.InputStreamReader&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.Gson&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;Gson&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Gson&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RuntimeRequest&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;payloadString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPayload&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPayload&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; 
        &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s"&gt;"{}"&lt;/span&gt; 
        &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;req&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getPayload&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payloadString&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;containsKey&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="no"&gt;URL&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="no"&gt;URL&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.isevenapi.xyz/api/iseven/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;number&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="nc"&gt;HttpURLConnection&lt;/span&gt; &lt;span class="n"&gt;con&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;HttpURLConnection&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;openConnection&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setRequestMethod&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"GET"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getResponseCode&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;BufferedReader&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;BufferedReader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;InputStreamReader&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getInputStream&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;
    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;inputLine&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="nc"&gt;StringBuilder&lt;/span&gt; &lt;span class="n"&gt;responseString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;StringBuilder&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="o"&gt;((&lt;/span&gt;&lt;span class="n"&gt;inputLine&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;readLine&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;responseString&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;append&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inputLine&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;in&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;close&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;disconnect&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Object&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;fromJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;responseString&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;json&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Awesome! We’re all set to test our function! If you remember the drill, all we need to do is deploy our function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite deploy &lt;span class="k"&gt;function&lt;/span&gt;
? Which functions would you like to deploy? java-example &lt;span class="o"&gt;(&lt;/span&gt;6286f6905af1e032e934&lt;span class="o"&gt;)&lt;/span&gt;
ℹ Info Deploying &lt;span class="k"&gt;function &lt;/span&gt;java-example &lt;span class="o"&gt;(&lt;/span&gt; 6286f6905af1e032e934 &lt;span class="o"&gt;)&lt;/span&gt;
ℹ Info Ignoring files using configuration from appwrite.json
✓ Success Deployed java-example &lt;span class="o"&gt;(&lt;/span&gt; 6286f6905af1e032e934 &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now head over to the Appwrite console and execute the function with the following payload. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8pvuzkwuydqc1t9yj3j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv8pvuzkwuydqc1t9yj3j.png" alt="Payload" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Head over to the &lt;strong&gt;Logs tab&lt;/strong&gt; to check the status and response from the function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfqgsr7mi9egoomhcceb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frfqgsr7mi9egoomhcceb.png" alt="Execution Logs" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfect! Looks like we’ve managed to solve one of the most pressing problems in Mathematics after all! Not to mention, the API also comes with a host of quirky Ads! &lt;/p&gt;

&lt;p&gt;And that brings us to the end of this tutorial. Feel free to modify the function to your liking and play around with the API. If you’re stuck or need any help, we’re always here to help. Simply head over to the &lt;code&gt;#support&lt;/code&gt; channels on our &lt;a href="https://appwrite.io/discord"&gt;Discord Server&lt;/a&gt; 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Resources
&lt;/h2&gt;

&lt;p&gt;Here are some handy links for more information&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/appwrite/blob/master/CONTRIBUTING.md"&gt;Appwrite Contribution Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/appwrite/appwrite"&gt;Appwrite Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs/functions"&gt;Functions Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/open-runtimes/examples"&gt;Cloud Function Examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>java</category>
      <category>opensource</category>
      <category>serverless</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Cloud Functions Using the New Kotlin Runtime</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Fri, 20 May 2022 12:02:18 +0000</pubDate>
      <link>https://dev.to/appwrite/cloud-functions-using-the-new-kotlin-runtime-3ejo</link>
      <guid>https://dev.to/appwrite/cloud-functions-using-the-new-kotlin-runtime-3ejo</guid>
      <description>&lt;p&gt;One of the highlights of Appwrite’s latest release is the addition of &lt;strong&gt;four&lt;/strong&gt; new Cloud Function runtimes! &lt;strong&gt;Java, Kotlin, .NET and C++&lt;/strong&gt; are now a part of our ever growing list of runtimes! 🤯&lt;/p&gt;

&lt;p&gt;In this article, we’ll take a look at writing Cloud Functions using the &lt;strong&gt;Kotlin runtime&lt;/strong&gt;. If you’re an Android developer, you could essentially build your app and write any necessary Cloud Functions without the need to learn any new language! 🤩&lt;/p&gt;

&lt;blockquote&gt;
&lt;h4&gt;
  
  
  🤔 New to Appwrite?
&lt;/h4&gt;

&lt;p&gt;Appwrite is &lt;strong&gt;open source backend-as-a-service&lt;/strong&gt; that abstracts all the complexity involved in building a modern application by providing you with a set of REST APIs for your core backend needs. Appwrite handles user authentication and authorization, realtime databases, file storage, cloud functions, webhooks and much more! If there is anything missing, you can extend Appwrite using your favorite backend language.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📝 Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before we get started, there are a couple of prerequisites. If you have the prerequisites setup already, you can skip to the following section. &lt;/p&gt;

&lt;p&gt;In order to follow along, you’ll need a few things beforehand.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🖥 &lt;strong&gt;An Appwrite instance&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you haven’t set up an Appwrite instance yet, you can follow the getting started guides to get up and running quickly. You can choose between &lt;a href="https://appwrite.io/docs/installation#one-click-setups"&gt;One-click installations&lt;/a&gt; on DigitalOcean or &lt;a href="https://appwrite.io/docs/installation#installWithDocker"&gt;Manual installations&lt;/a&gt; with Docker.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; - It's just a single command to install Appwrite&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--volume&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--volume&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;/appwrite:/usr/src/code/appwrite:rw &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--entrypoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"install"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    appwrite/appwrite:0.14.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once your server is up and running, head over to the Appwrite Dashboard on your server’s public IP address ( or localhost if you installed locally ) and create a new user account.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovsg3pabfkgxhwih4t4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fovsg3pabfkgxhwih4t4i.png" alt="Sign Up" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧑‍💻 &lt;strong&gt;The Appwrite CLI&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We’ll use the Appwrite CLI during this exercise as it makes the process super simple. If you have Node.js installed, the installation command is a simple&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; appwrite-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;npm&lt;/code&gt; is not your thing, we have numerous installation options you can find in the &lt;a href="https://appwrite.io/docs/command-line"&gt;getting started guide for the CLI&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  🏁 Getting Started
&lt;/h2&gt;

&lt;p&gt;With everything set up, we can now begin! Login to the Appwrite CLI using the following command and use the credentials we used when setting up the Appwrite server to login.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite login
? Enter your email &lt;span class="nb"&gt;test&lt;/span&gt;@test.com
? Enter your password &lt;span class="k"&gt;********&lt;/span&gt;
✓ Success
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we need to create a new Appwrite project to work with. We can use the following command to set it up&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite init project
? How would you like to start? Create a new Appwrite project
? What would you like to name your project? My Awesome Project
✓ Success
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can give your project any name of your choice. I’m going to stick to the defaults in this case. You’ll notice a new &lt;code&gt;appwrite.json&lt;/code&gt; file in the current directory which stores all the information about your project.&lt;/p&gt;

&lt;p&gt;It’s time to start writing our function! But wait, we don't need to start from scratch! The CLI can setup all the boilerplate for us using the following command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite init &lt;span class="k"&gt;function&lt;/span&gt;
? What would you like to name your &lt;span class="k"&gt;function&lt;/span&gt;? kotlin-example
? What runtime would you like to use? Kotlin &lt;span class="o"&gt;(&lt;/span&gt;kotlin-1.6&lt;span class="o"&gt;)&lt;/span&gt;
✓ Success
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Give your function a name and choose the &lt;strong&gt;Kotlin 1.6&lt;/strong&gt; runtime. This will create a new Appwrite Function in your project and set up all the boilerplate code necessary. Feel free to examine the files created in the &lt;code&gt;functions/kotlin-example&lt;/code&gt; directory. You’ll find the CLI created a simple Kotlin function that returns a very important JSON message&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"areDevelopersAwesome"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we go ahead and modify the function, let’s deploy it to get a feel of the end-to-end workflow from initializing the function to deploying it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite deploy &lt;span class="k"&gt;function&lt;/span&gt;
? Which functions would you like to deploy? kotlin-example &lt;span class="o"&gt;(&lt;/span&gt;62863924adaff7c88a10&lt;span class="o"&gt;)&lt;/span&gt;
ℹ Info Deploying &lt;span class="k"&gt;function &lt;/span&gt;kotlin-example &lt;span class="o"&gt;(&lt;/span&gt; 62863924adaff7c88a10 &lt;span class="o"&gt;)&lt;/span&gt;
ℹ Info Ignoring files using configuration from appwrite.json
✓ Success Deployed kotlin-example &lt;span class="o"&gt;(&lt;/span&gt; 62863924adaff7c88a10 &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;appwrite deploy function&lt;/code&gt; command packages your source code, uploads it to the Appwrite server and initiates the build process. During this time, all the function’s dependencies are installed and a &lt;code&gt;.jar&lt;/code&gt; file is generated for your function. &lt;/p&gt;

&lt;p&gt;You can head over to your Appwrite Dashboard to track the progress of your deployment.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqyk371l2aubfboisnbgz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqyk371l2aubfboisnbgz.png" alt="Kotlin Function" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the deployment completes, you can execute your function by clicking the &lt;strong&gt;Execute Now&lt;/strong&gt; button. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xed0ratqaaqw7ow565t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5xed0ratqaaqw7ow565t.png" alt="Execution Logs" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first execution results in what we call a &lt;strong&gt;Cold Start&lt;/strong&gt;. Essentially this is the first time a runtime is created, so it takes a bit longer. As you can see, the first execution took about &lt;strong&gt;450ms&lt;/strong&gt; and subsequent executions were around &lt;strong&gt;4ms&lt;/strong&gt;. Now that we have an idea of the complete workflow, we can start tinkering with the code and write some cool functions.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧮  Answering the Most Fundamental Question in Mathematics
&lt;/h2&gt;

&lt;p&gt;As the title suggests we’re going to write a cloud function to answer one of the most fundamental questions in Mathematics.&lt;/p&gt;

&lt;p&gt;Is the given number odd or even? I know what you’re thinking… It’s so easy! Why do I need a Cloud Function for it? I could just write&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;x&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
    &lt;span class="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="n"&gt;shr&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="n"&gt;shl&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;  &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But wait! We’re taking this to the next level. We’re going to decide if our number is even or odd using one of the most sophisticated and well written APIs out there! The &lt;a href="https://isevenapi.xyz/"&gt;isEven API&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Jokes aside, this example aims to illustrate how you can make API calls from your Cloud Function which will enable you to build anything you’d like. &lt;/p&gt;

&lt;p&gt;Firstly, open the &lt;code&gt;kotlin-example&lt;/code&gt; folder in your favorite IDE. Let’s start with a blank canvas and clean up our &lt;code&gt;src/Index.kt&lt;/code&gt; file to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nd"&gt;@Throws&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&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="nc"&gt;RuntimeRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mapOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"Hello, World!"&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 order to deal with JSON objects more easily, we’ll make use of the popular &lt;a href="https://github.com/google/gson"&gt;&lt;code&gt;gson&lt;/code&gt;&lt;/a&gt; library. Include the following dependency in the &lt;code&gt;deps.gradle&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'com.google.code.gson:gson:2.9.0'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, let’s write some code to read and parse a number sent as an argument to this function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.Gson&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;gson&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Gson&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@Throws&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&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="nc"&gt;RuntimeRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;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;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ifEmpty&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="nc"&gt;MutableMap&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;number&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mapOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="s"&gt;"Hello, World!"&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;Let’s go over the code we just wrote. From the &lt;a href="https://appwrite.io/docs/functions#writingYourOwnFunction"&gt;functions documentation&lt;/a&gt;, we see that the &lt;code&gt;payload&lt;/code&gt; is available through the &lt;code&gt;request&lt;/code&gt; object and is a JSON string that needs to be converted to a JSON object to parse further. If the &lt;code&gt;payload&lt;/code&gt; is empty, we replace it with an empty JSON object. &lt;/p&gt;

&lt;p&gt;We then retrieve the &lt;code&gt;number&lt;/code&gt; that was passed to the function and default to the number &lt;code&gt;2&lt;/code&gt; in case it’s empty. We also import the &lt;code&gt;gson&lt;/code&gt; library and create an instance of it.&lt;/p&gt;

&lt;p&gt;Next, let’s make the call to the API using the native HTTP client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.gson.Gson&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.BufferedReader&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.io.InputStreamReader&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.net.HttpURLConnection&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;java.net.URL&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;gson&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Gson&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="nd"&gt;@Throws&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&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="nc"&gt;RuntimeRequest&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;res&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;RuntimeResponse&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;payload&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;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;payload&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ifEmpty&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="nc"&gt;MutableMap&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;number&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"number"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;url&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.isevenapi.xyz/api/iseven/$number"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;con&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openConnection&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;HttpURLConnection&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;requestMethod&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"GET"&lt;/span&gt;
        &lt;span class="n"&gt;responseCode&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;responseString&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;buildString&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;BufferedReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;InputStreamReader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inputStream&lt;/span&gt;&lt;span class="p"&gt;)).&lt;/span&gt;&lt;span class="nf"&gt;useLines&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;lines&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;lines&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&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="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;con&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;disconnect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;gson&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fromJson&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;
        &lt;span class="n"&gt;responseString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nc"&gt;MutableMap&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&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;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&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;Awesome! We’re all set to test our function! If you remember the drill, all we need to do is deploy our function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite deploy &lt;span class="k"&gt;function&lt;/span&gt;
? Which functions would you like to deploy? kotlin-example &lt;span class="o"&gt;(&lt;/span&gt;62863924adaff7c88a10&lt;span class="o"&gt;)&lt;/span&gt;
ℹ Info Deploying &lt;span class="k"&gt;function &lt;/span&gt;kotlin-example &lt;span class="o"&gt;(&lt;/span&gt; 62863924adaff7c88a10 &lt;span class="o"&gt;)&lt;/span&gt;
ℹ Info Ignoring files using configuration from appwrite.json
✓ Success Deployed kotlin-example &lt;span class="o"&gt;(&lt;/span&gt; 62863924adaff7c88a10 &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can now head over to the Appwrite console and execute the function with the following payload. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkb3qj9dobz95adfgjsrx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkb3qj9dobz95adfgjsrx.png" alt="Payload" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Head over to the Logs tab to check the status and response from the function.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl8vssh39grickgfhlev2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl8vssh39grickgfhlev2.png" alt="Execution Logs" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Perfect! Looks like we’ve managed to solve one of the most pressing problems in Mathematics after all! Not to mention, the API also comes with a host of quirky Ads! Like this one to purchase old people 👴 &lt;/p&gt;

&lt;p&gt;And that brings us to the end of this tutorial. Feel free to modify the function to your liking and play around with the API. If you’re stuck or need any help, we’re always here to help. Simply head over to the &lt;code&gt;#support&lt;/code&gt; channels on our &lt;a href="https://appwrite.io/discord"&gt;Discord Server&lt;/a&gt; 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  📚 Resources
&lt;/h2&gt;

&lt;p&gt;Here are some handy links for more information&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/appwrite/blob/master/CONTRIBUTING.md"&gt;Appwrite Contribution Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://github.com/appwrite/appwrite"&gt;Appwrite Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs/functions"&gt;Functions Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/open-runtimes/examples"&gt;Cloud Function Examples&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kotlin</category>
      <category>opensource</category>
      <category>serverless</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Deploying Functions Just Got Easier with Appwrite CLI 2.0!</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Fri, 11 Mar 2022 14:04:34 +0000</pubDate>
      <link>https://dev.to/appwrite/deploying-functions-just-got-easier-with-appwrite-cli-20-2cmm</link>
      <guid>https://dev.to/appwrite/deploying-functions-just-got-easier-with-appwrite-cli-20-2cmm</guid>
      <description>&lt;p&gt;Appwrite 0.13 was just released and one of the biggest highlights this time around is the &lt;strong&gt;brand new Appwrite CLI!&lt;/strong&gt; The CLI underwent a major overhaul including a complete &lt;strong&gt;rewrite in Node.js&lt;/strong&gt;, &lt;strong&gt;easier creation and deployment of cloud functions&lt;/strong&gt;, the &lt;strong&gt;ability to manage your Appwrite projects&lt;/strong&gt;, &lt;strong&gt;collections&lt;/strong&gt;, &lt;strong&gt;CI support&lt;/strong&gt; and a lot more! &lt;/p&gt;

&lt;p&gt;In this article we’ll cover how you can get started with the Appwrite CLI and be on your way to deploying cloud functions!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What is Appwrite you may ask?&lt;/strong&gt; &lt;br&gt;
Appwrite is open source backend-as-a-service that abstracts all the complexity involved in building a modern application by providing you with a set of REST APIs for your core backend needs. Appwrite handles user authentication and authorization, databases, file storage, cloud functions, webhooks and much more! If there is anything missing, you can extend Appwrite using your favorite backend language.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ⚙️ Installation
&lt;/h2&gt;

&lt;p&gt;We’ve made sure developers have multiple installation options from an npm package to standalone binaries and even a Homebrew package. &lt;/p&gt;

&lt;p&gt;If you have npm installed, it's pretty simple&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; appwrite-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faacxcjcm59qqlpebgy2m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faacxcjcm59qqlpebgy2m.png" alt="Appwrite Install" width="800" height="764"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead if you prefer the standalone binary, you can install the CLI on Linux and MacOS using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-sL&lt;/span&gt; https://appwrite.io/cli/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Please note that the binary method of installing the CLI does not work with macOS on ARM. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re on a Windows system, we’ve got something for you as well!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;iwr &lt;span class="nt"&gt;-useb&lt;/span&gt; https://appwrite.io/cli/install.ps1 | iex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Homebrew is your thing, we have you covered too!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew tap appwrite/sdk-for-cli https://github.com/appwrite/sdk-for-cli
brew update
brew &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--HEAD&lt;/span&gt; appwrite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With installation now complete, it's time to verify your installation&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite &lt;span class="nt"&gt;-v&lt;/span&gt;
0.0.15
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will print the latest version of your CLI.&lt;br&gt;
Getting Started&lt;br&gt;
Before you can start using the CLI, you need to login to your Appwrite account with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite login
? Enter your email &lt;span class="nb"&gt;test&lt;/span&gt;@test.com
? Enter your password &lt;span class="k"&gt;********&lt;/span&gt;
? Enter the endpoint of your Appwrite server http://localhost/v1
✓ Success
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll be prompted to enter your email, password and the endpoint of your Appwrite server. If you’re running Appwrite locally, you can use the default value for the endpoint in the prompts. &lt;/p&gt;

&lt;p&gt;The CLI is designed to work with multiple Appwrite projects and you can configure the CLI to connect to your project using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite init project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can choose to create a new project or connect to an existing one associated with your account. The &lt;code&gt;init project&lt;/code&gt; command creates a new &lt;code&gt;appwrite.json&lt;/code&gt; file in the current directory with all the information about your current project like the ID, name, collection and function definitions and so on. &lt;/p&gt;

&lt;p&gt;You’re now all set to interact with the Appwrite CLI!&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡️ Deploying Functions
&lt;/h2&gt;

&lt;p&gt;One of the major highlights of the CLI are the new Function starters and easier ways to deploy the cloud functions. You can get started with your first cloud function using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite init &lt;span class="k"&gt;function&lt;/span&gt;
? What would you like to name your &lt;span class="k"&gt;function&lt;/span&gt;? My Awesome Function
? What runtime would you like to use? Node.js &lt;span class="o"&gt;(&lt;/span&gt;node-17.0&lt;span class="o"&gt;)&lt;/span&gt;
✓ Success
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command creates a new cloud function on your Appwrite server, and also clones some starter code to help you get going quickly. The starter code is designed to be simple enough to help you get started writing your own functions while being extensive enough to cover most common use cases like dependencies and accessing environment variables. Feel free to examine the code that was just created.&lt;/p&gt;

&lt;p&gt;Great! All that’s left now is to deploy your cloud function! Head back to your CLI and use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite deploy &lt;span class="k"&gt;function&lt;/span&gt;
? Which functions would you like to deploy? My Awesome Function &lt;span class="o"&gt;(&lt;/span&gt;6221eff3e289b17042b8&lt;span class="o"&gt;)&lt;/span&gt;
ℹ Info Deploying &lt;span class="k"&gt;function &lt;/span&gt;My Awesome Function &lt;span class="o"&gt;(&lt;/span&gt; 6221eff3e289b17042b8 &lt;span class="o"&gt;)&lt;/span&gt;
✓ Success Deployed My Awesome Function &lt;span class="o"&gt;(&lt;/span&gt; 6221eff3e289b17042b8 &lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the prompts and if everything goes well, your function should now be deployed! You can then head to the Functions section in the Appwrite console and execute your function. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsuqt2va48i0mwlpenar6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsuqt2va48i0mwlpenar6.png" alt="Deploy Function" width="800" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  ⬆️ Deploying Collections
&lt;/h2&gt;

&lt;p&gt;The CLI also serves a similar utility with your collection definitions. You can pull all your projects’ collection definitions into your appwrite.json file which you can later use to deploy to a different Appwrite project or server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite init collection
ℹ Info Found 1 collections
ℹ Info Fetching Millenium Problems ...
✓ Success
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re migrating to a new server, be sure to create a new Appwrite project and update the values of &lt;code&gt;projectId&lt;/code&gt; and &lt;code&gt;projectName&lt;/code&gt; in the &lt;code&gt;appwrite.json&lt;/code&gt; file. Don’t forget to update your server endpoint using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite client &lt;span class="nt"&gt;--endpoint&lt;/span&gt; https://endpoint.com/v1 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And also login to the CLI using your new server’s credentials using the &lt;code&gt;appwrite login&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Once the CLI is configured to connect to your new project, you can use the &lt;code&gt;deploy&lt;/code&gt; command to create all your collection definitions to the server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite deploy collection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  👩‍💻 Usage
&lt;/h2&gt;

&lt;p&gt;In the following section, we’ll cover the usage instructions of some common tasks. &lt;/p&gt;

&lt;p&gt;You can create a new user using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite &lt;span class="nb"&gt;users &lt;/span&gt;create &lt;span class="nt"&gt;--userId&lt;/span&gt; &lt;span class="s2"&gt;"unique()"&lt;/span&gt; &lt;span class="nt"&gt;--email&lt;/span&gt; hello@appwrite.io &lt;span class="nt"&gt;--password&lt;/span&gt; very_strong_password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To list users in your project, you can use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite &lt;span class="nb"&gt;users &lt;/span&gt;list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Oops. Looks like we forgot to give our first user a name! You can update user information using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite &lt;span class="nb"&gt;users &lt;/span&gt;updateName &lt;span class="nt"&gt;--userId&lt;/span&gt; 6222455985f1c3d14b35 &lt;span class="nt"&gt;--name&lt;/span&gt; &lt;span class="s2"&gt;"Awesome User"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s take a look at our users now.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwrvsfooxwgeexu2dh4m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqwrvsfooxwgeexu2dh4m.png" alt="Users List" width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you wish to parse the response further, you can print it in a more parser friendly JSON format using the &lt;code&gt;–json&lt;/code&gt; flag.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite &lt;span class="nb"&gt;users &lt;/span&gt;list –json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32n8cezymg6kok7o8mf8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F32n8cezymg6kok7o8mf8.png" alt="Users List JSON" width="800" height="324"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you plan to use the CLI in a CI environment, you need to authenticate using an API key. This can be done with the &lt;code&gt;appwrite client&lt;/code&gt; command. Everything else remains the same.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite client –key &amp;lt;YOUR_API_KEY&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The CLI also ships with a handy &lt;code&gt;–verbose&lt;/code&gt; flag that displays a more detailed error message in case you’re trying to debug something. &lt;/p&gt;

&lt;p&gt;The CLI is basically a reflection of the Appwrite API, so any methods you expect in the SDKs should be present as commands in the CLI. At any point, if you need to explore a command, you can do so using the &lt;code&gt;help&lt;/code&gt; command or its variants.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;appwrite &lt;span class="nb"&gt;users
&lt;/span&gt;appwrite &lt;span class="nb"&gt;users&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt;
appwrite &lt;span class="nb"&gt;users&lt;/span&gt; –help
appwrite &lt;span class="nb"&gt;users help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg9hlh8eihhh9vs97ikcs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg9hlh8eihhh9vs97ikcs.png" alt="Users Help" width="800" height="669"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🤩 What's next?
&lt;/h2&gt;

&lt;p&gt;We’ll continue to iterate on community feedback and be back with even better versions of the CLI packed with a lot more features! Eventually, the CLI will become the only tool you’ll need to install, migrate, manage and monitor your Appwrite server.&lt;/p&gt;

&lt;p&gt;Meanwhile, we’d love you to check it out and share your valuable feedback and hang out with us on our &lt;a href="https://appwrite.io/discord"&gt;Discord&lt;/a&gt;. If you like what we do at Appwrite, don’t forget to drop us a &lt;a href="http://github.com/appwrite/appwrite"&gt;tiny star on GitHub&lt;/a&gt;. It means a lot. &lt;/p&gt;

</description>
      <category>opensource</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>programming</category>
    </item>
    <item>
      <title>Send Welcome Emails using Appwrite's Swift Cloud Functions</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Fri, 22 Oct 2021 09:18:55 +0000</pubDate>
      <link>https://dev.to/appwrite/create-and-run-welcome-email-appwrite-cloud-function-with-swift-2m1h</link>
      <guid>https://dev.to/appwrite/create-and-run-welcome-email-appwrite-cloud-function-with-swift-2m1h</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faeofzxl2bcjq9t6dfe3g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faeofzxl2bcjq9t6dfe3g.png" alt="Cover Image" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For all the Swift developers out there, we have good news! We just announced our Swift SDK to work with server side APIs of Appwrite. You can learn more about our Swift SDK in our &lt;a href="https://dev.toswift-SDK-announcement-post"&gt;Swift SDK announcement post&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this tutorial however, we are going to write, deploy and run our very own &lt;strong&gt;Welcome Email Cloud Function&lt;/strong&gt; with Swift. Let's get started. &lt;/p&gt;

&lt;h2&gt;
  
  
  🤔 What are Appwrite Cloud Functions?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://appwrite.io/docs/functions"&gt;Appwrite Cloud Functions&lt;/a&gt; are a way for you to extend and customize your &lt;a href="https://appwrite.io"&gt;Appwrite BaaS&lt;/a&gt; functionality by allowing you to execute custom code. Appwrite can execute your function either explicitly or in response to any Appwrite system event like account creation, user login, database updates and much more. You can also schedule your functions to run according to a CRON schedule or trigger them manually by hitting an HTTP endpoint using the Appwrite client or server APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  🗒️ Prerequisites
&lt;/h2&gt;

&lt;p&gt;In order to continue with this tutorial, you'll need to have the latest version of Appwrite installed and an Appwrite project setup to test this function. If you have not already installed Appwrite, please do so. Installing Appwrite is really simple. Based on your operating system, run one of the following commands and installation should be complete in less than 2 minutes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unix
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--volume&lt;/span&gt; /var/run/docker.sock:/var/run/docker.sock &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--volume&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;/appwrite:/usr/src/code/appwrite:rw &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--entrypoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"install"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    appwrite/appwrite:0.11.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Windows CMD
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--rm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;^&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;--volume&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;//var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;^&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;--volume&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"%cd%"&lt;/span&gt;&lt;span class="n"&gt;/appwrite:/usr/src/code/appwrite:rw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;^&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;--entrypoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"install"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;^&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;appwrite/appwrite:0.11.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Windows PowerShell
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;docker&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-it&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--rm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;--volume&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;--volume&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;${pwd}&lt;/span&gt;&lt;span class="n"&gt;/appwrite:/usr/src/code/appwrite:rw&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nt"&gt;--entrypoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"install"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="n"&gt;appwrite/appwrite:0.11.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also find detailed installation instructions in the official Appwrite &lt;a href="https://appwrite.io/docs/installation"&gt;installation docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another requirement to follow along is that you have a &lt;a href="https://www.mailgun.com/"&gt;Mailgun account&lt;/a&gt; with a valid &lt;strong&gt;Mailgun Domain&lt;/strong&gt; and &lt;strong&gt;API Key&lt;/strong&gt;. With that aside, we're ready to get started. &lt;/p&gt;

&lt;h2&gt;
  
  
  🔓️ Activate Swift Functions Runtime
&lt;/h2&gt;

&lt;p&gt;The Swift runtime needs to be &lt;code&gt;enabled&lt;/code&gt; for you to be able to use it. This can be done easily using environment variables. The environment variables can be found in the &lt;code&gt;.env&lt;/code&gt; file located in the Appwrite installation folder. If it's not present already, you'll need to add the following key-value pair to the &lt;code&gt;.env&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;_APP_FUNCTIONS_RUNTIMES=swift-5.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, restart your stack using &lt;code&gt;docker-compose up -d&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔑 Initialize Your Swift Function
&lt;/h2&gt;

&lt;p&gt;First, create a project folder where you will create all the necessary files for your function. We will call this folder &lt;code&gt;welcome-email&lt;/code&gt;. Once inside this folder, you can create a new Swift project with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/app &lt;span class="nt"&gt;-w&lt;/span&gt; /app swift:5.5 swift package init WelcomeEmail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will initialize a new Swift package project. It should create bunch of files, important ones to notice are&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── Sources/WelcomeEmail/main.swift
└── Package.swift
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ➕ Add Appwrite Swift SDK dependency
&lt;/h2&gt;

&lt;p&gt;Open the &lt;code&gt;welcome-email&lt;/code&gt; folder in your favorite IDE and add the following code to your &lt;code&gt;Package.swift&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;PackageDescription&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;package&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"WelcomeEmail"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nv"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;package&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"https://github.com/swift-server/async-http-client.git"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="nv"&gt;targets&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;target&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"WelcomeEmail"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nv"&gt;dependencies&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;product&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"AsyncHTTPClient"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;package&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"async-http-client"&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="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we add the &lt;code&gt;async-http-client&lt;/code&gt; SDK for swift under dependencies as well as under the executable's target dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✍️  Write your Function
&lt;/h2&gt;

&lt;p&gt;Open &lt;code&gt;Sources/WelcomeEmail/main.swift&lt;/code&gt; and fill in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;AsyncHTTPClient&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;Foundation&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;sendSimpleMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;throws&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Welcome &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;!"&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;targetURL&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://api.mailgun.net/v3/&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="kt"&gt;MAILGUN_DOMAIN&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;/messages"&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s"&gt;"from"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Excited User &amp;lt;hello@appwrite.io&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"to"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"subject"&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s"&gt;"text"&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;var&lt;/span&gt; &lt;span class="nv"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;HTTPClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt;
    &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="kt"&gt;HTTPClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nv"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;targetURL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nv"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;RAW&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;value&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="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;auth&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"api:&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="kt"&gt;MAILGUN_API_KEY&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;using&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Encoding&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utf8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;!.&lt;/span&gt;&lt;span class="nf"&gt;base64EncodedString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"multipart/form-data"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Authorization"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Basic &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nf"&gt;buildMultipart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="n"&gt;httpClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;execute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;whenComplete&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;in&lt;/span&gt;
            &lt;span class="k"&gt;switch&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;case&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;failure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;error&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;success&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;response&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Message sent!"&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="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Error: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="se"&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="p"&gt;}&lt;/span&gt;

            &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;leave&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;catch&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;MAILGUN_DOMAIN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ProcessInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;processInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"MAILGUN_DOMAIN"&lt;/span&gt;&lt;span class="p"&gt;]&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="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;MAILGUN_API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ProcessInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;processInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"MAILGUN_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;]&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="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;APPWRITE_FUNCTION_EVENT_DATA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ProcessInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;processInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environment&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"APPWRITE_FUNCTION_EVENT_DATA"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;??&lt;/span&gt; &lt;span class="s"&gt;"{}"&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;httpClient&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;HTTPClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;eventLoopGroupProvider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;createNew&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;DispatchGroup&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

&lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;Data&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;APPWRITE_FUNCTION_EVENT_DATA&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;utf8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="kt"&gt;JSONSerialization&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;jsonObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;with&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as?&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Any&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="k"&gt;throw&lt;/span&gt; &lt;span class="s"&gt;"Unable to parse APPWRITE_FUNCTION_EVENT_DATA"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as?&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="s"&gt;"Unable to parse name"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;guard&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as?&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="s"&gt;"Unable to parse email"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enter&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="nf"&gt;sendSimpleMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;group&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;wait&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="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;error&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;error&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;The environment variables that we are accessing here are either already available or are later set in the Appwrite Function's settings.&lt;/p&gt;

&lt;p&gt;Next create a new file under &lt;code&gt;Sources/WelcomeEmail/File.swift&lt;/code&gt; that will house one of our helper classes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;NIO&lt;/span&gt;

&lt;span class="kd"&gt;open&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kt"&gt;File&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ByteBuffer&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;ByteBuffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
        &lt;span class="k"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;buffer&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;Lastly, we need to create one more file &lt;code&gt;Sources/WelcomeEmail/Utils.swift&lt;/code&gt; for some of our utility functions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight swift"&gt;&lt;code&gt;&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;AsyncHTTPClient&lt;/span&gt;
&lt;span class="kd"&gt;import&lt;/span&gt; &lt;span class="kt"&gt;NIO&lt;/span&gt;

&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;DASHDASH&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"--"&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;CRLF&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\r\n&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;boundaryChars&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"abcdefghijklmnopqrstuvwxyz1234567890"&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;randomBoundary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boundaryChars&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;randomElement&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&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;string&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;buildMultipart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="nv"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;inout&lt;/span&gt; &lt;span class="kt"&gt;HTTPClient&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="nv"&gt;params&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="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;?]&lt;/span&gt; &lt;span class="o"&gt;=&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="kd"&gt;func&lt;/span&gt; &lt;span class="nf"&gt;addPart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;DASHDASH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boundary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CRLF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Disposition: form-data; name=&lt;/span&gt;&lt;span class="se"&gt;\"\(&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="se"&gt;)\"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;as?&lt;/span&gt; &lt;span class="kt"&gt;File&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"; filename=&lt;/span&gt;&lt;span class="se"&gt;\"\(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="se"&gt;)\"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CRLF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Length: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readableBytes&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CRLF&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="kt"&gt;CRLF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CRLF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;describing&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CRLF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Content-Length: &lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;count&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CRLF&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="kt"&gt;CRLF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CRLF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;boundary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;randomBoundary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;var&lt;/span&gt; &lt;span class="nv"&gt;bodyBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;ByteBuffer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

    &lt;span class="k"&gt;for&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="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="nf"&gt;addPart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&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="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;let&lt;/span&gt; &lt;span class="nv"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="k"&gt;as?&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;listValue&lt;/span&gt; &lt;span class="k"&gt;in&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;addPart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\(&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="s"&gt;[]"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;listValue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;
                &lt;span class="k"&gt;continue&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
            &lt;span class="nf"&gt;addPart&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&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="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;!&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="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;DASHDASH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;boundary&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;DASHDASH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;writeString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;CRLF&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"content-type"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Content-Length"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;readableBytes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Content-Type"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"multipart/form-data;boundary=&lt;/span&gt;&lt;span class="se"&gt;\"\(&lt;/span&gt;&lt;span class="n"&gt;boundary&lt;/span&gt;&lt;span class="se"&gt;)\"&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;byteBuffer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bodyBuffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;extension&lt;/span&gt; &lt;span class="kt"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;Error&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ⚙️ Build the Function Binary
&lt;/h2&gt;

&lt;p&gt;In order to deploy our function, we need to first build the project. Our runtime is based on the &lt;code&gt;slim&lt;/code&gt; version of official &lt;strong&gt;Swift&lt;/strong&gt; docker image, so we'll use the official &lt;strong&gt;Swift&lt;/strong&gt; docker image to build our project.&lt;/p&gt;

&lt;p&gt;From the &lt;code&gt;welcome-email&lt;/code&gt; directory, run the following command&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="nv"&gt;$ &lt;/span&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/app &lt;span class="nt"&gt;-w&lt;/span&gt; /app swift:5.5 swift build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This should build the project. Ensure that your folder structure looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── .build/x86_64-unknown-linux-gnu/debug/WelcomeEmail
├── Package.swift
├── README.md
└── Sources
    └── WelcomeEmail
        ├── File.swift
        ├── main.swift
        └── Utils.swift
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;There could be other files and folders as well, but you can ignore those.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  ☁️ Create a Function in Your Appwrite Console
&lt;/h2&gt;

&lt;p&gt;Login to your Appwrite console and open the project of your choosing. On the sidebar, tap on the &lt;code&gt;Functions&lt;/code&gt; menu. In the following screen, tap the &lt;code&gt;Add Function&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp55xzrfjp6ztp0a57e4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkp55xzrfjp6ztp0a57e4.png" alt="Image description" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We'll call our Cloud function &lt;code&gt;WelcomeEmail&lt;/code&gt;. and select &lt;code&gt;swift-5.5&lt;/code&gt; for the environment. Then tap &lt;strong&gt;Create&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🧑‍💻 Deploy Tag
&lt;/h2&gt;

&lt;p&gt;Once your function is created, you'll be taken to the &lt;strong&gt;Function Overview&lt;/strong&gt; screen. Click the &lt;strong&gt;Deploy Tag&lt;/strong&gt; button at the bottom of the function overview page and then switch to the &lt;strong&gt;Manual&lt;/strong&gt; tab. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1l1gghjzmq0oh8jjkgoy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1l1gghjzmq0oh8jjkgoy.png" alt="Image description" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's first create a tarfile that contains our function.&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-zcvf&lt;/span&gt; code.tar.gz &lt;span class="nt"&gt;-C&lt;/span&gt; .build/x86_64-unknown-linux-gnu/ debug/WelcomeEmail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Head back to the &lt;strong&gt;Deploy a New Tag&lt;/strong&gt; dialog and upload the &lt;code&gt;code.tar.gz&lt;/code&gt; that we just created and use &lt;code&gt;./WelcomeEmail&lt;/code&gt; for the &lt;strong&gt;Command&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✅ Activate tag
&lt;/h2&gt;

&lt;p&gt;Once you deploy your tag, it will be listed under &lt;strong&gt;Tags&lt;/strong&gt; on the &lt;strong&gt;Overview&lt;/strong&gt; page. Activate your most recent tag ( if you have multiple versions ).&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Adding Triggers and Environment Variables
&lt;/h2&gt;

&lt;p&gt;On the &lt;strong&gt;Functions&lt;/strong&gt; page, switch to the &lt;strong&gt;Settings&lt;/strong&gt; tab. A function can be triggered based on an &lt;code&gt;event&lt;/code&gt; or a &lt;code&gt;schedule&lt;/code&gt; you choose. This particular function should be triggered by the &lt;code&gt;users.create&lt;/code&gt; and the &lt;code&gt;account.create&lt;/code&gt; events. Select these events from the events section.&lt;/p&gt;

&lt;p&gt;In the &lt;strong&gt;Variables&lt;/strong&gt; section, tap the &lt;strong&gt;Add Variable&lt;/strong&gt; button and add the following variables and click the &lt;strong&gt;Update&lt;/strong&gt; button.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;MAILGUN_API_KEY&lt;/strong&gt; - Your Mailgun API Key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MAILGUN_DOMAIN&lt;/strong&gt; - Your Mailgun domain.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  ✨️ Verify it's working
&lt;/h2&gt;

&lt;p&gt;It's about time to check if all our hard work has finally paid off! Let's create a user and verify that our Cloud Function has sent them a welcome email! &lt;/p&gt;

&lt;p&gt;Head to the &lt;strong&gt;Users&lt;/strong&gt; page from the Sidebar and click the &lt;strong&gt;Add User&lt;/strong&gt; button. Give your user a &lt;strong&gt;valid name&lt;/strong&gt; and &lt;strong&gt;email ID&lt;/strong&gt; and click &lt;strong&gt;Create&lt;/strong&gt;. Back in the &lt;strong&gt;Functions page&lt;/strong&gt;, you can now examine the logs of your function execution.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you're using a sandbox Mailgun account, ensure that the email ID is an &lt;a href="https://help.mailgun.com/hc/en-us/articles/217531258-Authorized-Recipients"&gt;Authorized Recipient&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  📚️ Resources
&lt;/h2&gt;

&lt;p&gt;Hope you enjoyed this article! We love contributions and encourage you to take a look at our &lt;a href="https://github.com/appwrite/appwrite/issues"&gt;open issues&lt;/a&gt; and &lt;a href="https://github.com/appwrite/rfc/pulls"&gt;ongoing RFCs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you get stuck anywhere, feel free to reach out to us on our &lt;a href="https://appwrite.io/discord"&gt;friendly support channels&lt;/a&gt; run by humans 👩‍💻.&lt;/p&gt;

&lt;p&gt;Here are some handy links for more information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/appwrite/blob/master/CONTRIBUTING.md"&gt;Appwrite Contribution Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite"&gt;Appwrite Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs"&gt;Appwrite Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>swift</category>
      <category>tutorial</category>
      <category>serverless</category>
      <category>cloud</category>
    </item>
    <item>
      <title>A guide to Maven Repositories</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Wed, 14 Jul 2021 18:17:13 +0000</pubDate>
      <link>https://dev.to/appwrite/a-guide-to-maven-repositories-1e9o</link>
      <guid>https://dev.to/appwrite/a-guide-to-maven-repositories-1e9o</guid>
      <description>&lt;p&gt;We at Appwrite recently published our Android SDK to Maven Central and we learnt a whole lot about the Gradle and Maven ecosystem in the process. &lt;/p&gt;

&lt;p&gt;In this series of articles, we'll aim to teach you how you can build and publish your own Android Libraries using Gradle. Before we dive into building and publishing artifacts with Gradle, we need to get familiar with Maven because after all, Gradle is a build tool for Java based projects ( among several others ).&lt;/p&gt;

&lt;p&gt;If you've worked on a Java project, it's highly likely that you would've heard of Maven, as it is the most popular build tool for Java projects. Most of us associate Maven with a &lt;code&gt;pom.xml&lt;/code&gt; file. However, there's much more to Maven than meets the eye and you can very quickly get lost in a sea of knowledge. This article will aim to walk you through the important concepts in Maven and introduce you to various terminologies in the Maven ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  🗃️ The POM file
&lt;/h2&gt;

&lt;p&gt;The POM file is the cornerstone of any Maven project. Think of it as an entry point to any Maven project. The POM file has all the information required to build the project; a recipe book of sorts. If you're familiar with the &lt;code&gt;package.json&lt;/code&gt; file in &lt;strong&gt;node&lt;/strong&gt; projects, &lt;code&gt;composer.json&lt;/code&gt; file in &lt;strong&gt;php&lt;/strong&gt; projects, &lt;code&gt;requirements.txt&lt;/code&gt; in &lt;strong&gt;python&lt;/strong&gt; projects and &lt;code&gt;build.gradle&lt;/code&gt; in other &lt;strong&gt;Java/Kotlin&lt;/strong&gt; projects, the POM file should seem familiar.&lt;/p&gt;

&lt;p&gt;Though we will be using Gradle for building and publishing artifacts, it's a good idea to learn about the structure of the POM file as these concepts can be extended to Gradle as well.&lt;/p&gt;

&lt;p&gt;Let's take a sample POM file to understand its structure. You can use the following command to create a simple Maven project if you want to test it out yourself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mvn &lt;span class="nt"&gt;-B&lt;/span&gt; archetype:generate &lt;span class="nt"&gt;-DgroupId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;com.mycompany.app &lt;span class="nt"&gt;-DartifactId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;my-app &lt;span class="nt"&gt;-DarchetypeArtifactId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;maven-archetype-quickstart &lt;span class="nt"&gt;-DarchetypeVersion&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have executed this command, you will notice a few things have happened. First, you will notice that a directory named &lt;code&gt;my-app&lt;/code&gt; has been created for the new project, and this directory contains a file named &lt;code&gt;pom.xml&lt;/code&gt; that should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;project&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0"&lt;/span&gt; &lt;span class="na"&gt;xmlns:xsi=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2001/XMLSchema-instance"&lt;/span&gt;
  &lt;span class="na"&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class="s"&gt;"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;modelVersion&amp;gt;&lt;/span&gt;4.0.0&lt;span class="nt"&gt;&amp;lt;/modelVersion&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.mycompany.app&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;my-app&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.0-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;my-app&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- FIXME change it to the project's website --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;http://www.example.com&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;properties&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;project.build.sourceEncoding&amp;gt;&lt;/span&gt;UTF-8&lt;span class="nt"&gt;&amp;lt;/project.build.sourceEncoding&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.source&amp;gt;&lt;/span&gt;1.7&lt;span class="nt"&gt;&amp;lt;/maven.compiler.source&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;maven.compiler.target&amp;gt;&lt;/span&gt;1.7&lt;span class="nt"&gt;&amp;lt;/maven.compiler.target&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/properties&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;junit&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;junit&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;4.11&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;scope&amp;gt;&lt;/span&gt;test&lt;span class="nt"&gt;&amp;lt;/scope&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;build&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;pluginManagement&amp;gt;&lt;/span&gt;&lt;span class="c"&gt;&amp;lt;!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --&amp;gt;&lt;/span&gt;
       ... lots of helpful plugins
    &lt;span class="nt"&gt;&amp;lt;/pluginManagement&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/build&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/project&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;pom.xml&lt;/code&gt; contains the &lt;strong&gt;Project Object Model (POM)&lt;/strong&gt; for this project. The POM is the most basic unit of work in Maven. This is important to remember because Maven is inherently &lt;strong&gt;project-centric&lt;/strong&gt; in that everything revolves around the notion of a project. In short, the &lt;strong&gt;POM&lt;/strong&gt; contains every important piece of information about your project and is the go-to place for finding anything related to your project.&lt;/p&gt;

&lt;p&gt;This is a very simple POM but still displays the key elements every POM contains, so let's walk through each of them to familiarize you with the POM essentials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;project&lt;/strong&gt; This is the top-level element in all Maven &lt;code&gt;pom.xml&lt;/code&gt; files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;modelVersion&lt;/strong&gt; This element indicates what version of the object model this POM is using. The version of the model itself changes very infrequently but it is mandatory in order to ensure stability of use if and when the Maven developers deem it necessary to change the model.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;groupId&lt;/strong&gt; This element indicates the unique identifier of the organization or group that created the project. The &lt;strong&gt;groupId&lt;/strong&gt; is one of the key identifiers of a project and is typically based on the fully qualified domain name of your organization. For example &lt;code&gt;org.apache.maven.plugins&lt;/code&gt; is the designated groupId for all Maven plugins.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;artifactId&lt;/strong&gt; This element indicates the unique base name of the &lt;strong&gt;primary artifact&lt;/strong&gt; being generated by this project. The primary artifact for a project is typically &lt;strong&gt;a JAR file&lt;/strong&gt;. Secondary artifacts like source bundles also use the artifactId as part of their final name. A typical artifact produced by Maven would have the form -. (for example, &lt;code&gt;myapp-1.0.jar&lt;/code&gt;).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;version&lt;/strong&gt; This element indicates the version of the artifact generated by the project. Maven goes a long way to help you with version management and you will often see a &lt;strong&gt;SNAPSHOT&lt;/strong&gt; designator in a version, which indicates that a project is in a state of development. We will discuss the use of snapshots and how they work further on in this guide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;name&lt;/strong&gt; - This element indicates the display name used for the project. This is often used in Maven's generated documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;url&lt;/strong&gt; This element indicates where the project's site can be found. This is often used in Maven's generated documentation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;properties&lt;/strong&gt; This element contains value placeholders accessible anywhere within a POM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;dependencies&lt;/strong&gt; This element's children list the dependencies. The cornerstone of the POM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;build&lt;/strong&gt; This element handles things like declaring your project's directory structure and managing plugins.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For a complete documentation of all the POM attributes, you can &lt;a href="https://maven.apache.org/ref/3.8.1/maven-model/maven.html"&gt;refer to the official docs&lt;/a&gt;. &lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 Artifacts
&lt;/h2&gt;

&lt;p&gt;An &lt;strong&gt;artifact&lt;/strong&gt; is something that is either produced or used by a project. Examples of artifacts produced by Maven for a project include: &lt;strong&gt;JARs ( Java Archives )&lt;/strong&gt;, &lt;strong&gt;source&lt;/strong&gt; and &lt;strong&gt;binary&lt;/strong&gt; distributions, &lt;strong&gt;WARs&lt;/strong&gt;, &lt;strong&gt;AARs&lt;/strong&gt; ( Android Archives ) etc. Each artifact is identified by a &lt;strong&gt;group id&lt;/strong&gt;, an &lt;strong&gt;artifact ID&lt;/strong&gt;, &lt;strong&gt;a version&lt;/strong&gt;, &lt;strong&gt;an extension&lt;/strong&gt; and a &lt;strong&gt;classifier&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Take a look at &lt;a href="https://repo1.maven.org/maven2/io/appwrite/sdk-for-android/0.0.1/"&gt;Appwrite's Android SDK&lt;/a&gt;. You will find the following artifacts ( and more ).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sdk-for-android-0.0.1-javadoc.jar                  2021-06-29 15:13       261            
sdk-for-android-0.0.1-sources.jar                  2021-06-29 15:13     18663      
sdk-for-android-0.0.1.aar                          2021-06-29 15:13     46437      
sdk-for-android-0.0.1.pom                          2021-06-29 15:13      3277
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will find a lot of &lt;code&gt;.md5&lt;/code&gt;, &lt;code&gt;.sha1&lt;/code&gt;, &lt;code&gt;.sha256&lt;/code&gt;, &lt;code&gt;.sha512&lt;/code&gt; and &lt;code&gt;.asc&lt;/code&gt; files which are all used by Maven Central and other consumers for verifying the signature and authenticity of your artifacts.&lt;/p&gt;

&lt;p&gt;You will notice that, these artifacts follow a naming convention as mentioned below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;artifactId&amp;gt;-&amp;lt;version&amp;gt;-&amp;lt;classifier&amp;gt;.&amp;lt;extension&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Note : &lt;strong&gt;classifier&lt;/strong&gt; is an optional field and is absent in the case of Primary Artifacts which in the case of our Android project are the aar and pom files.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In our case the following artifacts are the primary artifacts&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;sdk-for-android-0.0.1.aar&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sdk-for-android-0.0.1.pom&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our &lt;code&gt;aar&lt;/code&gt; file can contain &lt;strong&gt;Android resources&lt;/strong&gt; and a &lt;strong&gt;Manifest file&lt;/strong&gt;, which allows you to bundle in shared resources like layouts and drawables in addition to all the Java classes and methods. Our &lt;code&gt;pom&lt;/code&gt; file contains information about our library including all the dependencies we use internally. &lt;/p&gt;

&lt;p&gt;And the following are the secondary artifacts ( which are supplementary to the primary artifacts and are not necessarily required to build your project. )&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;sdk-for-android-0.0.1-javadoc.jar&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;sdk-for-android-0.0.1-sources.jar&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When we talk about publishing our project in the next article, we will be referring to all these artifacts.&lt;/p&gt;

&lt;h2&gt;
  
  
  🗺️ Maven Coordinates
&lt;/h2&gt;

&lt;p&gt;We've talked about the pom file and primary and secondary artifacts. In this section we will dive into the structure of a Maven repository and understand how Maven resolves dependencies when you build your project! &lt;/p&gt;

&lt;p&gt;What's a &lt;strong&gt;Maven dependency&lt;/strong&gt; you ask ? A &lt;strong&gt;Maven Dependency&lt;/strong&gt; is any artifact that your project depends on. A typical dependency declaration in a Maven project looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.appwrite&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;sdk-for-android&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.0.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Together, the &lt;strong&gt;groupID&lt;/strong&gt;, &lt;strong&gt;artifactID&lt;/strong&gt;, and &lt;strong&gt;version&lt;/strong&gt; make up the &lt;a href="https://maven.apache.org/pom.html#Maven_Coordinates"&gt;Maven Coordinates&lt;/a&gt;. Every Maven artifact is identified by these coordinates. &lt;/p&gt;

&lt;p&gt;The next question arises. &lt;strong&gt;Given the Maven coordinates, how does maven locate an artifact?&lt;/strong&gt; Maven uses the coordinates values for a given dependency to construct a URL according to the &lt;a href="https://cwiki.apache.org/confluence/display/MAVENOLD/Repository+Layout+-+Final"&gt;maven repository layout&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's take the example of &lt;strong&gt;Appwrite's Android SDK&lt;/strong&gt; with the following coordinates&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.appwrite&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;sdk-for-android&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.0.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;According to the &lt;a href="https://cwiki.apache.org/confluence/display/MAVENOLD/Repository+Layout+-+Final"&gt;official specification&lt;/a&gt;, the URL for primary artifacts looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/$groupId[0]/../${groupId[n]/$artifactId/$version/$artifactId-$version.$extension
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;groupId&lt;/strong&gt; array in the URL is formed from the &lt;code&gt;&amp;lt;groupId&amp;gt;&lt;/code&gt; element in the pom file as follows &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;$groupId is a array of strings made by splitting the groupId’s on “.” into directories.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So for the groupId value of &lt;code&gt;org.example.subdomain&lt;/code&gt;, our &lt;code&gt;$groupId&lt;/code&gt; array would be &lt;code&gt;[org, example, subdomain]&lt;/code&gt;, which when translated into directories, becomes &lt;code&gt;org/example/subdomain&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;In our case, the groupId &lt;code&gt;io.appwrite&lt;/code&gt; is translated to the following path &lt;code&gt;io/appwrite/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our next step is to build the URL for the &lt;strong&gt;primary&lt;/strong&gt; and &lt;strong&gt;secondary&lt;/strong&gt; artifacts.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 &lt;strong&gt;Primary Artifacts&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;One of the core features of Maven is its ability to handle &lt;a href="https://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Transitive_Dependencies"&gt;Transitive Dependencies&lt;/a&gt;. That is, to find and download the dependencies of your dependencies, and their dependencies and so on until all of dependencies are satisfied.&lt;/p&gt;

&lt;p&gt;Just how your own Maven project has a &lt;code&gt;pom.xml&lt;/code&gt; file listing its main dependencies, those dependencies also have a remote &lt;code&gt;pom&lt;/code&gt; file serving a similar purpose. Maven uses this file to figure out what other dependencies to download. When a coordinate does not contain a &lt;code&gt;&amp;lt;classifier&amp;gt;&lt;/code&gt;, it is considered a primary artifact and is expected to have a pom available.&lt;/p&gt;

&lt;p&gt;In our case, the primary artifacts are the &lt;code&gt;.pom&lt;/code&gt; file and the &lt;code&gt;.aar&lt;/code&gt; file.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;pom&lt;/strong&gt; - If we follow the URL convention above, the pom file for Appwrite's Android SDK can be located at
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;io/appwrite/sdk-for-android/0.0.1/sdk-for-android-0.0.1.pom
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;aar&lt;/strong&gt; - If we follow the URL convention above, the aar file for Appwrite's Android SDK can be located at
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;io/appwrite/sdk-for-android/0.0.1/sdk-for-android-0.0.1.aar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⛏️ &lt;strong&gt;Secondary Artifacts&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Secondary artifacts, or “attached artifacts” on the other hand are dependencies that you want Maven to download that are ancillary to your project. Most often they are used to download the &lt;code&gt;javadocs&lt;/code&gt; and/or &lt;code&gt;sources&lt;/code&gt; for a particular dependency. However, unlike a primary artifact, a secondary artifact is not expected to have a remote &lt;code&gt;pom&lt;/code&gt; and thus never has any dependencies.&lt;/p&gt;

&lt;p&gt;They can be specified in the &lt;code&gt;&amp;lt;dependencies&amp;gt;&lt;/code&gt; section just like primary artifacts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.appwrite&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;sdk-for-android&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.0.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;classifier&amp;gt;&lt;/span&gt;sources&lt;span class="nt"&gt;&amp;lt;/classifier&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The URL for secondary artifacts is similar to that of the primary artifacts except that they have an optional &lt;code&gt;$classifier&lt;/code&gt; variable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/$groupId[0]/../$groupId[n]/$artifactId/$version/$artifactId-$version-$classifier.$extension
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In our case, the secondary artifacts are the &lt;code&gt;javadocs&lt;/code&gt; and the &lt;code&gt;sources&lt;/code&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;javadoc&lt;/strong&gt; - If we follow the URL convention above, the &lt;code&gt;javadoc&lt;/code&gt; file for Appwrite's Android SDK can be located at
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;io/appwrite/sdk-for-android/0.0.1/sdk-for-android-0.0.1-javadoc.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;sources&lt;/strong&gt; - If we follow the URL convention above, the sources file for Appwrite's Android SDK can be located at
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;io/appwrite/sdk-for-android/0.0.1/sdk-for-android-0.0.1-sources.jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🏁 &lt;strong&gt;Checksums&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To verify the downloaded artifacts Maven computes the &lt;code&gt;md5&lt;/code&gt;, &lt;code&gt;sha1&lt;/code&gt;, &lt;code&gt;sha256&lt;/code&gt; and &lt;code&gt;sha512&lt;/code&gt; checksum for that artifact and compares it to the values found in the checksum files located at &lt;strong&gt;$ARTIFACT_URL.md5&lt;/strong&gt;, or &lt;strong&gt;$ARTIFACT_URL.sha1&lt;/strong&gt;, respectively.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This is strictly meant as a way to quickly verify downloads, and it is NOT meant to be used for authentication or security purposes. This is also NOT a substitute for using HTTPS, as checksums can be trivially intercepted and modified along with the modified artifacts.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;sha1&lt;/strong&gt; - the &lt;code&gt;sha1&lt;/code&gt; checksum for our aar artifacts for example, would be present at
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  io/appwrite/sdk-for-android/0.0.1/sdk-for-android-0.0.1.aar.sha1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;md5&lt;/strong&gt; - the &lt;code&gt;md5&lt;/code&gt; checksum for our aar artifacts for example, would be present at
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  io/appwrite/sdk-for-android/0.0.1/sdk-for-android-0.0.1.aar.md5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly for all other artifacts (javadoc.jar.md5, pom.md5, sources.jar.md5 and so on).&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 &lt;strong&gt;Signatures&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Maven Central&lt;/strong&gt; repository makes in mandatory to include a signature for all the uploaded artifacts and checksums. This ensures absolute confidence in the authenticity of the downloaded artifacts. Every &lt;strong&gt;artifact&lt;/strong&gt; and &lt;strong&gt;checksum&lt;/strong&gt; has a corresponding &lt;code&gt;.asc&lt;/code&gt; file that contains the signature of the author of the artifact.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;$artifacts.asc&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;For our &lt;code&gt;.aar&lt;/code&gt; file for example, the corresponding &lt;code&gt;.asc&lt;/code&gt; file would be located at&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;io/appwrite/sdk-for-android/0.0.1/sdk-for-android-0.0.1.aar.asc
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;$checksum.asc&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;For our &lt;code&gt;.md5&lt;/code&gt; ( sha1, sha256 etc.) files, the corresponding &lt;code&gt;.asc&lt;/code&gt; file would be located at&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;io/appwrite/sdk-for-android/0.0.1/sdk-for-android-0.0.1.aar.md5.asc
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📦 The Maven Repository
&lt;/h2&gt;

&lt;p&gt;A Repository is Maven holds artifacts and dependencies of all kinds. There are exactly two kinds of repositories &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Local &lt;br&gt;
The &lt;strong&gt;local repository&lt;/strong&gt; is a directory on the computer where Maven runs. It caches remote downloads and contains temporary build artifacts that you have not yet released. This is usually located in &lt;code&gt;$HOME/.m2/repository&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remote&lt;br&gt;
&lt;strong&gt;Remote repositories&lt;/strong&gt; refer to any other type of repository, accessed by a variety of protocols such as file:// and https://. These repositories might be a truly remote repository set up by a third party to provide their artifacts for downloading (for example, &lt;strong&gt;repo.maven.apache.org&lt;/strong&gt;). Other &lt;strong&gt;remote&lt;/strong&gt; repositories may be internal repositories set up on a file or HTTP server within your company, used to share private artifacts between development teams and for releases.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Local and remote repositories are structured the same way so that scripts can run on either side, or they can be synced for offline use. The layout of the repositories is completely transparent to the Maven user, however.&lt;/p&gt;

&lt;p&gt;The last topic that we'll discuss is the concept of a &lt;strong&gt;Release&lt;/strong&gt; repository and a &lt;strong&gt;SNAPSHOT&lt;/strong&gt; repository. &lt;/p&gt;

&lt;h3&gt;
  
  
  🏆 &lt;strong&gt;Release repository&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A release repository is where all the published artifacts are stored in Maven. Because caching plays a really important role in maven repositories, it is highly recommended to make the Release repositories immutable. i.e. artifacts once uploaded cannot be modified. Let's say you published &lt;code&gt;0.0.1&lt;/code&gt; of your library, you must not modify the existing version, instead publish the next version let's say &lt;code&gt;0.0.2&lt;/code&gt;. This is enforced by default in Maven Central. &lt;/p&gt;

&lt;p&gt;There is also the concept of a &lt;strong&gt;Staging repository&lt;/strong&gt; in Maven which serves as a staging area for you to verify all your artifacts before promoting it to the release repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧪 &lt;strong&gt;SNAPSHOT repository&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;A &lt;strong&gt;SNAPSHOT&lt;/strong&gt; variant of a library refers to the &lt;strong&gt;latest&lt;/strong&gt; code along a development branch, and provides no guarantee the code is stable or unchanging and these variants are published to the &lt;strong&gt;SNAPSHOT&lt;/strong&gt; repository. Conversely, the code in a &lt;strong&gt;Release&lt;/strong&gt; variant (any version value &lt;em&gt;without the suffix SNAPSHOT&lt;/em&gt;) is unchanging.&lt;/p&gt;

&lt;p&gt;In other words, a &lt;strong&gt;SNAPSHOT&lt;/strong&gt; version is the &lt;strong&gt;development&lt;/strong&gt; version before the final &lt;strong&gt;Release&lt;/strong&gt; version. The &lt;strong&gt;SNAPSHOT&lt;/strong&gt; is &lt;strong&gt;older&lt;/strong&gt; than its release.&lt;/p&gt;

&lt;p&gt;During the release process, a version of &lt;strong&gt;x.y.z-SNAPSHOT&lt;/strong&gt; changes to &lt;strong&gt;x.y.z&lt;/strong&gt;. The release process also increments the development version to &lt;strong&gt;x.y.(z+1)-SNAPSHOT&lt;/strong&gt;. For example, version &lt;strong&gt;1.0.0-SNAPSHOT&lt;/strong&gt; is released as version &lt;strong&gt;1.0.0&lt;/strong&gt;, and the new development version is version &lt;strong&gt;1.0.1-SNAPSHOT.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We already discussed that a &lt;strong&gt;Release&lt;/strong&gt; repository is immutable. So the idea behind a &lt;strong&gt;SNAPSHOT repository&lt;/strong&gt; is to allow mutability and easy development. You can continuously push your latest changes to &lt;strong&gt;1.0.0-SNAPSHOT&lt;/strong&gt; and anyone depending on it will get the latest changes every time they build their project. Then, after a few iterations, and everyone is happy the latest state of &lt;strong&gt;1.0.0-SNAPSHOT&lt;/strong&gt;, it can be permanently released as &lt;strong&gt;1.0.0&lt;/strong&gt;, and rapid development can continue on &lt;strong&gt;1.0.1-SNAPSHOT&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Sonatype's &lt;strong&gt;Open Source Software Repository Hosting (OSSRH)&lt;/strong&gt; service allows open source projects and individuals to create a Maven Central repository and publish artifacts for free! In the next article, we'll go through all the steps involved in publishing an Android library to Maven Central. So stay tuned 😉&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨️ Credits
&lt;/h2&gt;

&lt;p&gt;Hope you enjoyed this article! We love contributions and encourage you to take a look at our &lt;a href="https://github.com/appwrite/appwrite/issues"&gt;open isuses&lt;/a&gt; and &lt;a href="https://github.com/appwrite/rfc/pulls"&gt;ongoing RFCs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you get stuck anywhere, feel free to reach out to us on our &lt;a href="https://appwrite.io/discord"&gt;friendly support channels&lt;/a&gt; run by humans 👩‍💻.&lt;/p&gt;

&lt;p&gt;Here are some handy links for more information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/appwrite/blob/master/CONTRIBUTING.md"&gt;Appwrite Contribution Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite"&gt;Appwrite Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs"&gt;Appwrite Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>tutorial</category>
      <category>discuss</category>
      <category>java</category>
    </item>
    <item>
      <title>Clean up your storage using Appwrite Cloud functions!</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Wed, 14 Jul 2021 05:36:42 +0000</pubDate>
      <link>https://dev.to/appwrite/clean-up-your-storage-using-appwrite-cloud-functions-210i</link>
      <guid>https://dev.to/appwrite/clean-up-your-storage-using-appwrite-cloud-functions-210i</guid>
      <description>&lt;p&gt;&lt;strong&gt;Appwrite 0.9&lt;/strong&gt; adds support for both &lt;strong&gt;Java&lt;/strong&gt; and &lt;strong&gt;Kotlin&lt;/strong&gt; runtimes in Cloud Functions, growing the list of supported runtimes to &lt;strong&gt;over 15(!)&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This example will walk you through the process of creating and uploading a &lt;strong&gt;Kotlin cloud function.&lt;/strong&gt; In particular, we'll teach you how to use cloud functions to periodically clean up your storage and delete unnecessary files! This example also highlights how Appwrite can integrate seamlessly with 3rd party APIs and coexist with your existing stack. Without further ado, let's dive right in!&lt;/p&gt;

&lt;h2&gt;
  
  
  📝 Prerequisites
&lt;/h2&gt;

&lt;p&gt;At this stage, we assume that you already have an Appwrite instance up and running. If you do not have Appwrite setup yet, you can follow the super easy installation &lt;strong&gt;step&lt;/strong&gt; over at &lt;a href="https://appwrite.io/docs/installation" rel="noopener noreferrer"&gt;appwrite.io&lt;/a&gt;. It's not a typo. There really is only 1 step!&lt;/p&gt;

&lt;p&gt;You also need to create an &lt;strong&gt;API Key&lt;/strong&gt; from the Appwrite dashboard with the following scopes granted&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;files.read&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;
&lt;code&gt;files.write&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📽️ Create your project
&lt;/h2&gt;

&lt;p&gt;Create a new Kotlin project using IntelliJ ( or Eclipse ) and choose Maven as your build system. Set the artifact ID accordingly and click proceed. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ftcb8kzsxwy5u8g5zhv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3ftcb8kzsxwy5u8g5zhv.png" alt="create_project"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the project is created, we'll add our dependencies. For this example, we will be using two dependencies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Appwrite Kotlin SDK&lt;/strong&gt; (io.appwrite:sdk-for-kotlin:0.0.0-SNAPSHOT)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Google's GSON Library&lt;/strong&gt; (com.google.code.gson:gson:2.8.7)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add the following lines to the &lt;code&gt;&amp;lt;dependencies&amp;gt;&lt;/code&gt; section of your &lt;code&gt;pom.xml&lt;/code&gt; file. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.appwrite&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;sdk-for-kotlin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.0.0-SNAPSHOT&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.google.code.gson&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;gson&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;2.8.7&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Load the Maven changes from the UI or using the shortcut &lt;code&gt;Ctrl + Shift + O&lt;/code&gt; &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1tw2jngnt6zg11q16xhf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1tw2jngnt6zg11q16xhf.png" alt="refresh_maven"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  👩‍💻 Write some code
&lt;/h2&gt;

&lt;p&gt;Now that the dependencies are fetched, it's time to write some code.&lt;/p&gt;

&lt;p&gt;Create a new Kotlin file under &lt;code&gt;src/main/kotlin&lt;/code&gt; and name it &lt;code&gt;StorageCleaner.kt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, create a main function and initialize the Appwrite Client and Storage APIs. We'll be using environment variables to store our secrets and other configurable values. We will also store the file expiry date as an environment variable so that the cloud function can be configured without a redeployment. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.appwrite.Client&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.appwrite.services.Storage&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlin.system.exitProcess&lt;/span&gt;

&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&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="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"APPWRITE_ENDPOINT"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"APPWRITE_FUNCTION_PROJECT_ID"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"APPWRITE_API_KEY"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;storage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Storage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;daysToExpire&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getenv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"DAYS_TO_EXPIRE"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;toFloatOrNull&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;daysToExpire&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="nf"&gt;println&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Unable to parse DAYS_TO_EXPIRE."&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;exitProcess&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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;Before the next step, we need to create a few model classes to parse our JSON response. Create a new Kotlin file &lt;code&gt;Models.kt&lt;/code&gt; under &lt;code&gt;src/main/kotlin&lt;/code&gt; and add the following code.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;Permissions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;,&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;write&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;File&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="err"&gt;`$&lt;/span&gt;&lt;span class="py"&gt;id`&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="err"&gt;`$&lt;/span&gt;&lt;span class="py"&gt;permissions`&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Permissions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;dateCreated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;signature&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;mimeType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sizeOriginal&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;data class&lt;/span&gt; &lt;span class="nc"&gt;FileList&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Int&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;File&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;Next, let's fetch the last 100 files that were uploaded to storage. Add the following lines to &lt;code&gt;StorageCleaner.kt&lt;/code&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="gi"&gt;+import com.google.gson.Gson
&lt;/span&gt;&lt;span class="p"&gt;import io.appwrite.Client
import io.appwrite.services.Storage
import kotlin.system.exitProcess
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+suspend fun main(args: Array&amp;lt;String&amp;gt;) {
&lt;/span&gt;    val client = Client()
        .setEndpoint(System.getenv("APPWRITE_ENDPOINT"))
        .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
        .setKey(System.getenv("APPWRITE_API_KEY"))
    val storage = Storage(client)
&lt;span class="err"&gt;
&lt;/span&gt;    val daysToExpire = System.getenv("DAYS_TO_EXPIRE").toFloatOrNull()
    if (daysToExpire == null) {
        println("Unable to parse DAYS_TO_EXPIRE.")
        exitProcess(1)
    }
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+   val fileList = storage.listFiles("",100, 0, "DESC").body?.string() ?: ""
+   val files: FileList = Gson().fromJson(fileList, FileList::class.java)
&lt;/span&gt;}
&lt;span class="err"&gt;

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

&lt;/div&gt;

&lt;p&gt;Now, let's write the logic to delete files older than &lt;code&gt;daysToExpire&lt;/code&gt;. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="err"&gt;

&lt;/span&gt;&lt;span class="p"&gt;import com.google.gson.Gson
import io.appwrite.Client
import io.appwrite.services.Storage
&lt;/span&gt;&lt;span class="gi"&gt;+ import java.util.*
&lt;/span&gt;&lt;span class="p"&gt;import kotlin.system.exitProcess
&lt;/span&gt;&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="p"&gt;suspend fun main(args: Array&amp;lt;String&amp;gt;) {
&lt;/span&gt;    val client = Client()
        .setEndpoint(System.getenv("APPWRITE_ENDPOINT"))
        .setProject(System.getenv("APPWRITE_FUNCTION_PROJECT_ID"))
        .setKey(System.getenv("APPWRITE_API_KEY"))
    val storage = Storage(client)
&lt;span class="err"&gt;
&lt;/span&gt;    val daysToExpire = System.getenv("DAYS_TO_EXPIRE").toFloatOrNull()
    if (daysToExpire == null) {
        println("Unable to parse DAYS_TO_EXPIRE.")
        exitProcess(1)
    }
&lt;span class="err"&gt;
&lt;/span&gt;    val fileList = storage.listFiles("",100, 0, "DESC").body?.string() ?: ""
    val files: FileList = Gson().fromJson(fileList, FileList::class.java)
&lt;span class="err"&gt;
&lt;/span&gt;&lt;span class="gi"&gt;+   var deletedFiles =  0
+   for( file in files.files!!) {
+       val diff: Long = Date().time/1000 - file.dateCreated
+       if (diff &amp;gt; daysToExpire * 24 * 60 * 60) {
+           storage.deleteFile(file.`$id`)
+           println("Deleted ${file.`$id`}")
+           deletedFiles++
+       }
+   }
+   println("Total files deleted: $deletedFiles")
&lt;/span&gt;}
&lt;span class="err"&gt;

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

&lt;/div&gt;

&lt;p&gt;Now that we've written all the required code, we need to package our function as a &lt;code&gt;.jar&lt;/code&gt;. Fortunately, this can be done really easily using IntelliJ, so let's see how.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Configure artifacts.
&lt;/h2&gt;

&lt;p&gt;In this step, we will create the &lt;code&gt;.jar&lt;/code&gt; artifacts required to deploy our cloud function. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbj9m3owx3pkl3xwni33u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbj9m3owx3pkl3xwni33u.png" alt="configure_artifacts"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the following dialog, enter the name of your main class. In our case it is &lt;code&gt;StorageCleanerKt&lt;/code&gt;. Don't worry if it doesn't show up in the list. Just click OK. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznfyw3i3yn1taqfp1p7n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fznfyw3i3yn1taqfp1p7n.png" alt="configure_artifacts_2"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you don't see the main class, try to follow the steps in this answer &lt;a href="https://stackoverflow.com/questions/10654120/error-could-not-find-or-load-main-class-in-intellij-ide" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/10654120/error-could-not-find-or-load-main-class-in-intellij-ide&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the next dialog, click Apply and then OK.&lt;/p&gt;

&lt;p&gt;Confirm that a new file was created at &lt;code&gt;src/main/kotlin/META-INF/MANIFEST.MF&lt;/code&gt; with the following contents.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

Manifest-Version: 1.0
Main-Class: StorageCleanerKt


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

&lt;/div&gt;

&lt;p&gt;Now build your artifacts using &lt;code&gt;Build &amp;gt; Build Artifacts &amp;gt; Select your artifact from the list &amp;gt; Build&lt;/code&gt;. You will find the output of this step in &lt;code&gt;out/artifacts/mainModule_jar/mainModule.jar&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Test locally
&lt;/h2&gt;

&lt;p&gt;Great! Let's test if your function is working fine and doesn't have any compilation issues. Run the following command from the root directory of your Kotlin project. Make sure you replace the values of the required environment variables with those of your own setup. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APPWRITE_ENDPOINT&lt;/li&gt;
&lt;li&gt;APPWRITE_FUNCTION_PROJECT_ID&lt;/li&gt;
&lt;li&gt;APPWRITE_API_KEY&lt;/li&gt;
&lt;li&gt;DAYS_TO_EXPIRE&lt;/li&gt;
&lt;/ul&gt;

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

docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;--volume&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/usr/local/src:rw &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;APPWRITE_ENDPOINT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"http://192.168.1.35/v1"&lt;/span&gt;  &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;APPWRITE_FUNCTION_PROJECT_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"60d31170f368f"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;DAYS_TO_EXPIRE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"0.00001"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;APPWRITE_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"7e....879f"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    appwrite/runtime-for-java:11 &lt;span class="se"&gt;\&lt;/span&gt;
    java &lt;span class="nt"&gt;-jar&lt;/span&gt; out/artifacts/mainModule_jar/mainModule.jar


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

&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;The APPWRITE_ENDPOINT is &lt;strong&gt;NOT&lt;/strong&gt; localhost in this case since localhost is not accessible from the cloud functions runtime. You will need to set this to a publicly accessible IP of your Appwrite Server. You can find this by running &lt;code&gt;hostname -I&lt;/code&gt; in UNIX systems.  &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If everything goes well, you should see the following output&lt;/p&gt;

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

Total files deleted: 0


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

&lt;/div&gt;
&lt;h2&gt;
  
  
  🌩️ Create your cloud function
&lt;/h2&gt;

&lt;p&gt;Head over to the Appwrite Dashboard and navigate to the &lt;strong&gt;Functions&lt;/strong&gt; Tab on the sidebar and click on &lt;strong&gt;Add Function&lt;/strong&gt; . Give your function a Name, select an appropriate Java runtime and click &lt;code&gt;Create&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, head over to the &lt;strong&gt;Settings&lt;/strong&gt; tab in your cloud function and add the required environment variables and a suitable CRON schedule. In our case, we want to run it every hour (&lt;code&gt;0 * * * *&lt;/code&gt;).&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8ln5w814didlqpka0wf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fo8ln5w814didlqpka0wf.png" alt="configure_functions"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't forget to click &lt;strong&gt;Update&lt;/strong&gt; to save your settings.&lt;/p&gt;
&lt;h2&gt;
  
  
  ↗️ Deploying &amp;amp; Execute
&lt;/h2&gt;

&lt;p&gt;We're now ready to deploy our function. This step can be done either with the Appwrite CLI or manually.&lt;/p&gt;
&lt;h3&gt;
  
  
  👀 Deploying Manually
&lt;/h3&gt;

&lt;p&gt;Head over to the root directory of your Kotlin project and run the following commands to create a tarfile.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;out/artifacts

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-zcvf&lt;/span&gt; code.tar.gz mainModule_jar                                                  

mainModule_jar/
mainModule_jar/mainModule.jar

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;ls
&lt;/span&gt;code.tar.gz  mainModule_jar


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

&lt;/div&gt;

&lt;p&gt;This will create a new archive called &lt;code&gt;code.tar.gz&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With this created, head over to your &lt;code&gt;Appwrite Dashboard &amp;gt; Functions &amp;gt; Overview &amp;gt; Deploy Tag&lt;/code&gt;. In the dialog that pops up, upload the &lt;code&gt;tarfile&lt;/code&gt; we just created and &lt;code&gt;java -jar mainModule.jar&lt;/code&gt; for the entry point command. &lt;/p&gt;

&lt;p&gt;Once your function is successfully uploaded you need to activate your tag by clicking the Activate Button You can now go ahead and click &lt;strong&gt;Execute&lt;/strong&gt; and leave the data field empty.&lt;/p&gt;

&lt;p&gt;If everything goes well, you should be able to see the execution logs under the &lt;code&gt;Logs&lt;/code&gt; tab.&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wfhzh5tave1747p3x6t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8wfhzh5tave1747p3x6t.png" alt="logs"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ⌨️ Deploying with the CLI
&lt;/h3&gt;

&lt;p&gt;If using the Appwrite CLI, run the following commands from the root directory of your Kotlin project. Be sure to replace the IDs with your own values. &lt;/p&gt;

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

&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;out/artifacts/

&lt;span class="nv"&gt;$ &lt;/span&gt;appwrite functions createTag &lt;span class="nt"&gt;--functionId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60d41cdbec776 &lt;span class="nt"&gt;--command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"java -jar mainModule.jar"&lt;/span&gt; &lt;span class="nt"&gt;--code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;mainModule_jar

&lt;span class="nv"&gt;$id&lt;/span&gt; : 60d46ee4506d4
functionId : 60d41cdbec776
dateCreated : 1624534756
&lt;span class="nb"&gt;command&lt;/span&gt; : java &lt;span class="nt"&gt;-jar&lt;/span&gt; mainModule.jar
size : 4381381

&lt;span class="nv"&gt;$ &lt;/span&gt;appwrite functions updateTag &lt;span class="nt"&gt;--functionId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60d41cdbec776 &lt;span class="nt"&gt;--tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60d46ee4506d4

&lt;span class="nv"&gt;$id&lt;/span&gt; : 60d41cdbec776
&lt;span class="nv"&gt;$permissions&lt;/span&gt; : 
name : Storage Test
dateCreated : 1624513755
dateUpdated : 1624534608
status : disabled
runtime : java-11
tag : 60d46ee4506d4
vars : 
events : &lt;span class="o"&gt;{}&lt;/span&gt;
schedule : 0 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt;
scheduleNext : 
schedulePrevious : 1624532406
&lt;span class="nb"&gt;timeout&lt;/span&gt; : 15


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

&lt;/div&gt;

&lt;p&gt;Your Cloud Function is now active and will be triggered every 30 minutes based on our CRON schedule.&lt;/p&gt;

&lt;p&gt;Great! You've successfully deployed and executed your first Koltin Cloud Function! This is just the tip of the iceberg and the possibilities with Cloud Functions are endless! Stay tuned for more Cloud Function ideas from the Appwrite Team. If you'd like to learn more about Appwrite or how Appwrite works under the hood, we've just curated all the resources for you during &lt;a href="https://30days.appwrite.io/" rel="noopener noreferrer"&gt;30 Days of Appwrite&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨️ Credits
&lt;/h2&gt;

&lt;p&gt;Hope you enjoyed this article! You can find the complete code for this tutorial over at the &lt;a href="https://github.com/appwrite/demos-for-functions" rel="noopener noreferrer"&gt;Cloud Functions Demo&lt;/a&gt; repository where we have a lot more examples for various runtimes. We love contributions and encourage you to take a look at our &lt;a href="https://github.com/appwrite/appwrite/issues" rel="noopener noreferrer"&gt;open isuses&lt;/a&gt; and &lt;a href="https://github.com/appwrite/rfc/pulls" rel="noopener noreferrer"&gt;ongoing RFCs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you get stuck anywhere, feel free to reach out to us on our &lt;a href="https://appwrite.io/discord" rel="noopener noreferrer"&gt;friendly support channels&lt;/a&gt; run by humans.  &lt;/p&gt;

&lt;p&gt;Here are some handy links for more information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/appwrite/blob/master/CONTRIBUTING.md" rel="noopener noreferrer"&gt;Appwrite Contribution Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite" rel="noopener noreferrer"&gt;Appwrite Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs" rel="noopener noreferrer"&gt;Appwrite Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>opensource</category>
      <category>kotlin</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Send Welcome Emails using Appwrite's Java Cloud Functions!</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Mon, 12 Jul 2021 09:48:25 +0000</pubDate>
      <link>https://dev.to/appwrite/send-welcome-emails-using-appwrite-s-java-cloud-functions-lm9</link>
      <guid>https://dev.to/appwrite/send-welcome-emails-using-appwrite-s-java-cloud-functions-lm9</guid>
      <description>&lt;p&gt;&lt;strong&gt;Appwrite 0.9&lt;/strong&gt; adds support for both &lt;strong&gt;Java and Kotlin runtimes&lt;/strong&gt; in Cloud Functions, growing the list of supported runtimes to &lt;strong&gt;over 15(!)&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;This tutorial will walk you through the process of creating and uploading a Java Cloud Function. In particular, we'll teach you how to use Cloud Functions to send customized welcome emails to your users when they sign up! This example also highlights how Appwrite can integrate seamlessly with 3rd party APIs and coexist with your existing stack. Without further ado, let's dive right in!&lt;/p&gt;

&lt;h2&gt;
  
  
  📝 Prerequisites
&lt;/h2&gt;

&lt;p&gt;At this stage, we assume that you already have an Appwrite instance up and running. If you do not have Appwrite setup yet, you can follow the super easy installation &lt;strong&gt;step&lt;/strong&gt; over at &lt;a href="https://appwrite.io/docs/installation"&gt;appwrite.io&lt;/a&gt;. It's not a typo. There really is only 1 step! &lt;/p&gt;

&lt;p&gt;You also need to setup an &lt;a href="https://www.mailgun.com/"&gt;Mailgun&lt;/a&gt; or &lt;a href="https://sendgrid.com/"&gt;SendGrid&lt;/a&gt; account to be able to send emails. &lt;/p&gt;

&lt;h2&gt;
  
  
  📽️ Create your project
&lt;/h2&gt;

&lt;p&gt;Create a new Maven project using IntelliJ ( or any other IDE you're comfortable with ). Set the name and artifact ID accordingly and click &lt;strong&gt;Finish&lt;/strong&gt;. &lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1h20wfk6j7gmwbof5nl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm1h20wfk6j7gmwbof5nl.png" alt="create_project" width="800" height="601"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the project is created, we'll add our dependencies. For this example, we will need just one dependency to make our HTTP requests.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unirest Java&lt;/strong&gt; (com.mashape.unirest:unirest-java:1.4.9)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Add the following lines to the &lt;code&gt;&amp;lt;dependencies&amp;gt;&lt;/code&gt; section of your &lt;code&gt;pom.xml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;com.mashape.unirest&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;unirest-java&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;1.4.9&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update your Maven dependencies from the UI or using the shortcut &lt;code&gt;Ctrl + Shift + O&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgq0q8hwtgewib2kjbz7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgq0q8hwtgewib2kjbz7.png" alt="refresh_maven" width="800" height="419"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  👩‍💻 Write some code
&lt;/h2&gt;

&lt;p&gt;Now that the dependencies are fetched, it's time to write some code.&lt;/p&gt;

&lt;p&gt;Create a new Java class under &lt;code&gt;src/main/java&lt;/code&gt; and name it &lt;code&gt;WelcomeEmail.java&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Next, create a &lt;code&gt;main&lt;/code&gt; function that fetches all the environment variables and parses the JSON string stored in the environment variable &lt;code&gt;APPWRITE_FUNCTION_EVENT_DATA&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;APPWRITE_FUNCTION_EVENT_DATA&lt;/code&gt; is a special environment variable that is automatically passed to your Cloud Function when it is triggered by an event. In our case, the Cloud Function is triggered by a &lt;a href="https://appwrite.io/docs/server/users?sdk=nodejs#usersCreate"&gt;&lt;code&gt;users.create&lt;/code&gt;&lt;/a&gt; and &lt;a href="https://appwrite.io/docs/client/account?sdk=web#accountCreate"&gt;&lt;code&gt;account.create&lt;/code&gt;&lt;/a&gt; event, so the payload in &lt;code&gt;APPWRITE_FUNCTION_EVENT_DATA&lt;/code&gt; contains a &lt;a href="https://appwrite.io/docs/models/user"&gt;User Object&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We are interested in the name and email ID of the user so we can send a personalised email. We will extract those values here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.mashape.unirest.http.exceptions.UnirestException&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.json.JSONObject&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WelcomeEmail&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;YOUR_DOMAIN_NAME&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="no"&gt;API_KEY&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;UnirestException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="no"&gt;YOUR_DOMAIN_NAME&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MAILGUN_DOMAIN"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="no"&gt;API_KEY&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"MAILGUN_API_KEY"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getenv&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"APPWRITE_FUNCTION_EVENT_DATA"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Parse the JSON string into a JSON Object&lt;/span&gt;
                &lt;span class="nc"&gt;JSONObject&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;print&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[ERROR] There was an error"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[INFO] APPWRITE_FUNCTION_EVENT_DATA is empty"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Don't worry about the other environment variables yet, we will set them up in the Dashboard in the coming sections.&lt;/p&gt;

&lt;p&gt;Next, let's create a simple function that sends a POST request to the Mailgun API and sends out our email.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.mashape.unirest.http.HttpResponse&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.mashape.unirest.http.Unirest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;sendSimpleMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;UnirestException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Hi %s!"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="nc"&gt;HttpResponse&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Unirest&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;post&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://api.mailgun.net/v3/"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="no"&gt;YOUR_DOMAIN_NAME&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"/messages"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;basicAuth&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"api"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="no"&gt;API_KEY&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"from"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Your Awesome App &amp;lt;hello@yourawesomeapp.com&amp;gt;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"to"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"subject"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"Welcome Onboard"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;field&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
            &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;asString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getBody&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, call this function from our main function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;public static void main(String[] args) throws UnirestException {
&lt;/span&gt;        YOUR_DOMAIN_NAME = System.getenv("MAILGUN_DOMAIN");
        API_KEY = System.getenv("MAILGUN_API_KEY");
        String payload = System.getenv("APPWRITE_FUNCTION_EVENT_DATA");
&lt;span class="err"&gt;
&lt;/span&gt;        if (payload != null &amp;amp;&amp;amp; !payload.isEmpty()) {
            try {
                JSONObject json = new JSONObject(payload);
                String name = json.getString("name");
                String email = json.getString("email");
&lt;span class="gi"&gt;+               String response = sendSimpleMessage(name, email);
+               System.out.println(response);
&lt;/span&gt;            } catch (Exception e) {
                System.out.print("[ERROR] There was an error");
                System.out.println(e.getMessage());
            }
&lt;span class="err"&gt;
&lt;/span&gt;        } else {
            System.out.println("[INFO] APPWRITE_FUNCTION_EVENT_DATA is empty");
        }
&lt;span class="err"&gt;
&lt;/span&gt;    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we've written all the required code, we need to package our function as a &lt;code&gt;.jar&lt;/code&gt;. Fortunately, this can be done really easily using IntelliJ so let's see how.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚙️ Configure artifacts.
&lt;/h2&gt;

&lt;p&gt;In this step, we will create the &lt;code&gt;.jar&lt;/code&gt; artifacts required to deploy our Cloud Function. Select &lt;code&gt;File &amp;gt; Project Structure &amp;gt; Artifacts&lt;/code&gt; as seen in the screenshot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbrrz1vzo2q3rh6knzvmm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbrrz1vzo2q3rh6knzvmm.png" alt="configure_artifacts" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the following dialog, select your main class ( &lt;code&gt;WelcomeEmail&lt;/code&gt; ) as shown in the image.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flzfj7ffs62bw2zehmvag.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flzfj7ffs62bw2zehmvag.png" alt="configure_artifacts_2" width="800" height="436"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you don't see the main class, try to follow the steps in this answer &lt;a href="https://stackoverflow.com/questions/10654120/error-could-not-find-or-load-main-class-in-intellij-ide"&gt;https://stackoverflow.com/questions/10654120/error-could-not-find-or-load-main-class-in-intellij-ide&lt;/a&gt; &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the next dialog, click Apply and then OK.&lt;/p&gt;

&lt;p&gt;Confirm that a new file was created at &lt;code&gt;src/main/java/META-INF/MANIFEST.MF&lt;/code&gt; with the following contents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Manifest-Version: 1.0
Main-Class: WelcomeEmail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now build your artifacts using &lt;code&gt;Build &amp;gt; Build Artifacts &amp;gt; Select your artifact from the list &amp;gt; Build&lt;/code&gt;. You will find the output of this step in &lt;code&gt;out/artifacts/welcome_email_jar/welcome-email.jar&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🧪 Test locally
&lt;/h2&gt;

&lt;p&gt;Great! Let's test if your function is working fine and doesn't have any compilation issues. Run the following command from the root directory of your Java project. Make sure you replace the values of the required environment variables with those of your own setup. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;MAILGUN_API_KEY&lt;/li&gt;
&lt;li&gt;MAILGUN_DOMAIN &lt;/li&gt;
&lt;li&gt;APPWRITE_FUNCTION_EVENT_DATA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your &lt;strong&gt;MAILGUN_DOMAIN&lt;/strong&gt; should look something like &lt;strong&gt;sandboxee5d....b85.mailgun.org&lt;/strong&gt;. Also ensure that the email address is an &lt;a href="https://help.mailgun.com/hc/en-us/articles/217531258-Authorized-Recipients"&gt;authorized recipient&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;--volume&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;pwd&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;:/usr/local/src:rw &lt;span class="se"&gt;\ &lt;/span&gt;                                  
    &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;MAILGUN_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"YOUR_API_KEY"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;MAILGUN_DOMAIN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"sandboxee5d...b85.mailgun.org"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--env&lt;/span&gt; &lt;span class="nv"&gt;APPWRITE_FUNCTION_EVENT_DATA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"{ &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt; : &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Example&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;example@example.com&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    appwrite/runtime-for-java:11 &lt;span class="se"&gt;\&lt;/span&gt;
    java &lt;span class="nt"&gt;-jar&lt;/span&gt; out/artifacts/welcome_email_jar/welcome-email.jar 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If everything goes well, you should see the following output&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"&amp;lt;20210625073914.1.D719405DDA651887@sandboxee5d...b85.mailgun.org&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Queued. Thank you."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🌩️ Create your Cloud Function
&lt;/h2&gt;

&lt;p&gt;Head over to the Appwrite Dashboard and navigate to the &lt;strong&gt;Functions&lt;/strong&gt; Tab on the sidebar and click on &lt;strong&gt;Add Function&lt;/strong&gt; . Give your function a Name, select an appropriate Java runtime and click &lt;code&gt;Create&lt;/code&gt;. Keep a note of your function ID as we need this to deploy our function using the CLI.&lt;/p&gt;

&lt;p&gt;Next, head over to the &lt;strong&gt;Settings&lt;/strong&gt; tab in your Cloud Function and add the required environment variables and select the events that should trigger this function. In our case this would be &lt;code&gt;account.create&lt;/code&gt; and &lt;code&gt;users.create&lt;/code&gt;.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenewtpbyrdc5ewp5f839.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fenewtpbyrdc5ewp5f839.png" alt="configure_functions" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Don't forget to click &lt;strong&gt;Update&lt;/strong&gt; to save your settings.&lt;/p&gt;
&lt;h2&gt;
  
  
  ↗️ Deploying &amp;amp; Execute
&lt;/h2&gt;

&lt;p&gt;We're now ready to deploy our function. This step can be done either with the Appwrite CLI or manually.&lt;/p&gt;
&lt;h3&gt;
  
  
  👀 Deploying Manually
&lt;/h3&gt;

&lt;p&gt;Head over to the root directory of your Java project and run the following commands to create a &lt;code&gt;tarfile&lt;/code&gt;.&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;out/artifacts

&lt;span class="nv"&gt;$ &lt;/span&gt; &lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-zcvf&lt;/span&gt; code.tar.gz welcome_email_jar 

welcome_email_jar/
welcome_email_jar/welcome-email.jar

&lt;span class="nv"&gt;$ &lt;/span&gt; &lt;span class="nb"&gt;ls
&lt;/span&gt;code.tar.gz  welcome_email_jar
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new archive called &lt;code&gt;code.tar.gz&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With this created, head over to your &lt;code&gt;Appwrite Dashboard &amp;gt; Functions &amp;gt; Overview &amp;gt; Deploy Tag&lt;/code&gt;. In the dialog that pops up, upload the &lt;code&gt;tarfile&lt;/code&gt; we just created and use &lt;code&gt;java -jar welcome-email.jar&lt;/code&gt; for the entry point command. &lt;/p&gt;

&lt;p&gt;Once your function is successfully uploaded you need to activate your tag by clicking the &lt;strong&gt;Activate Button&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Great, in order to trigger our function, we need to create a user. Head over to the &lt;strong&gt;Users&lt;/strong&gt; section on the sidebar and create a new user using an email ID that is present in the list of authorized recipients. If everything goes well, you should be able to see the execution logs under the &lt;code&gt;Logs&lt;/code&gt; tab.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx3a6wv33ljklstozg9z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcx3a6wv33ljklstozg9z.png" alt="logs" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  ⌨️ Deploying with the CLI
&lt;/h3&gt;

&lt;p&gt;If using the Appwrite CLI, run the following commands from the root directory of your Java project. Be sure to replace the IDs with your own values. You can get your function ID from your Appwrite Dashboard.&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="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;out/artifacts/

&lt;span class="nv"&gt;$ &lt;/span&gt;appwrite functions createTag &lt;span class="nt"&gt;--functionId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60d5839682e94 &lt;span class="nt"&gt;--command&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"java -jar welcome-email.jar"&lt;/span&gt; &lt;span class="nt"&gt;--code&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;welcome_email_jar

&lt;span class="nv"&gt;$id&lt;/span&gt; : 60d58cacb0748
functionId : 60d5839682e94
dateCreated : 1624607916
&lt;span class="nb"&gt;command&lt;/span&gt; : java &lt;span class="nt"&gt;-jar&lt;/span&gt; welcome-email.jar
size : 1808608

&lt;span class="nv"&gt;$ &lt;/span&gt; appwrite functions updateTag &lt;span class="nt"&gt;--functionId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60d5839682e94 &lt;span class="nt"&gt;--tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60d58cacb0748

&lt;span class="nv"&gt;$id&lt;/span&gt; : 60d5839682e94
&lt;span class="nv"&gt;$permissions&lt;/span&gt; : 
name : Welcome Email Test
dateCreated : 1624605590
dateUpdated : 1624606138
status : disabled
runtime : java-11
tag : 60d58cacb0748
vars : 
events : 
schedule : 
scheduleNext : 
schedulePrevious : 0
&lt;span class="nb"&gt;timeout&lt;/span&gt; : 15
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your Cloud Function is now active and will be triggered whenever a new user is created. &lt;/p&gt;

&lt;p&gt;Great! You've successfully deployed and executed your first Java Cloud Function! This is just the tip of the iceberg, and the possibilities with Cloud Functions are endless! Stay tuned for more Cloud Function ideas from the Appwrite Team.&lt;/p&gt;

&lt;p&gt;If you'd like to learn more about Appwrite or how Appwrite works under the hood, we've just curated all the resources for you during &lt;a href="https://30days.appwrite.io/"&gt;30 Days of Appwrite&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨️ Credits
&lt;/h2&gt;

&lt;p&gt;Hope you enjoyed this article! You can find the complete code for this tutorial over at the &lt;a href="https://github.com/appwrite/demos-for-functions"&gt;Cloud Functions Demo&lt;/a&gt; repository where we have a lot more examples for various runtimes. We love contributions and encourage you to take a look at our &lt;a href="https://github.com/appwrite/appwrite/issues"&gt;open isuses&lt;/a&gt; and &lt;a href="https://github.com/appwrite/rfc/pulls"&gt;ongoing RFCs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you get stuck anywhere, feel free to reach out to us on our &lt;a href="https://appwrite.io/discord"&gt;friendly support channels&lt;/a&gt; run by humans.  &lt;/p&gt;

&lt;p&gt;Here are some handy links for more information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/appwrite/blob/master/CONTRIBUTING.md"&gt;Appwrite Contribution Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite"&gt;Appwrite Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs"&gt;Appwrite Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
      <category>cloud</category>
      <category>java</category>
      <category>serverless</category>
    </item>
    <item>
      <title>Getting started with Appwrite's Android SDK</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Fri, 09 Jul 2021 07:51:07 +0000</pubDate>
      <link>https://dev.to/appwrite/getting-started-with-appwrite-s-android-sdk-98l</link>
      <guid>https://dev.to/appwrite/getting-started-with-appwrite-s-android-sdk-98l</guid>
      <description>&lt;p&gt;One of the major highlights of Appwrite 0.9 is the official support for Android. We've also released a brand new Android SDK to go alongside it 😉!&lt;/p&gt;

&lt;p&gt;In this tutorial, we'll learn to setup Appwrite's Android SDK, interact with Appwrite's Accounts API and also learn to setup OAuth Logins in your App! We'll extensively use &lt;a href="https://developer.android.com/jetpack"&gt;JetPack components&lt;/a&gt; like Fragments, ViewModels, Data Binding, LiveData and Kotlin Coroutines! I hope you're as excited as I am! Let's get started!&lt;/p&gt;

&lt;h2&gt;
  
  
  📝 Prerequisites
&lt;/h2&gt;

&lt;p&gt;At this stage, we assume that you already have an Appwrite instance up and running. If you do not have Appwrite setup yet, you can follow the super easy installation &lt;strong&gt;step&lt;/strong&gt; over at &lt;a href="https://appwrite.io/docs/installation"&gt;appwrite.io&lt;/a&gt;. It's not a typo. There really is only 1 step!&lt;/p&gt;

&lt;p&gt;You should have also setup an OAuth provider with Appwrite to be able to follow the OAuth section of this tutorial. You can learn to setup OAuth providers in Appwrite by going through &lt;a href="https://dev.to/appwrite/30daysofappwrite-oauth-providers-3jf6"&gt;our tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠️ Create a new Android Project
&lt;/h2&gt;

&lt;p&gt;Setup your Android project and choose the &lt;strong&gt;Empty Activity&lt;/strong&gt; Template. Give your project a name, Choose &lt;strong&gt;Android 6.0 ( Marshmallow )&lt;/strong&gt; as your minimum SDK and click &lt;strong&gt;Finish&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zv8spzgx4e2d07kpun3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9zv8spzgx4e2d07kpun3.png" alt="create_project" width="800" height="623"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now is also a good time to add our Android App as a platform in the Appwrite Console. Head over to your &lt;code&gt;AndroidManifest.xml&lt;/code&gt; and locate the package name of your app. It should look something like &lt;code&gt;com.example.myapplication&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In your Appwrite dashboard, click on &lt;strong&gt;Add Platform&lt;/strong&gt; and select a &lt;strong&gt;New Android App&lt;/strong&gt;. Give your app a name, add the package name and click &lt;strong&gt;Register&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0ujb83ae99ei6dfe4lk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0ujb83ae99ei6dfe4lk.png" alt="add_platform" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once this is complete, it's time to head back to our Android project add our dependencies.&lt;/p&gt;

&lt;h2&gt;
  
  
  👷 Setup Appwrite's Android SDK
&lt;/h2&gt;

&lt;p&gt;Appwrite's Android SDK is hosted on Maven Central, so you'll first need to add the &lt;code&gt;mavenCentral()&lt;/code&gt; repository to your project's &lt;code&gt;build.gradle&lt;/code&gt; file ( if it's not already present ).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;allprojects&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;repositories&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;google&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="n"&gt;mavenCentral&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then add the Appwrite Android SDK to your app's &lt;code&gt;build.gradle&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ... Other dependencies&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt; &lt;span class="s1"&gt;'io.appwrite:sdk-for-android:0.0.1'&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We'll also be using &lt;a href="https://developer.android.com/topic/libraries/data-binding"&gt;Data Binding&lt;/a&gt; and we need to enable that in our app's &lt;code&gt;build.gradle&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;android&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="n"&gt;buildFeatures&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;dataBinding&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sync your gradle dependencies and if there are no errors, we're ready to proceed!&lt;/p&gt;

&lt;h2&gt;
  
  
  ⌨️ Create helper classes
&lt;/h2&gt;

&lt;p&gt;The first step is to initialise the &lt;code&gt;Client()&lt;/code&gt; class from the Appwrite SDK. For this, we will create a new file &lt;code&gt;utils/Client.kt&lt;/code&gt; where we will create a Singleton object to use across our App.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example.myapplication.utils&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.content.Context&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.appwrite.Client&lt;/span&gt;

&lt;span class="kd"&gt;object&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;client&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
             &lt;span class="c1"&gt;// Replace with your own endpoint and project ID&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://demo.appwrite.io/v1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"6070749e6acd4"&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;blockquote&gt;
&lt;p&gt;If your Appwrite setup is running on localhost, you will need to make sure localhost is accessible from your emulator by using a proxy. Else, you can replace &lt;code&gt;localhost&lt;/code&gt; with your private IP address which you can find using the command &lt;code&gt;hostname -I&lt;/code&gt; on UNIX systems.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you're using Appwrite on &lt;strong&gt;localhost&lt;/strong&gt;, you need to set the &lt;code&gt;setSelfSigned(true)&lt;/code&gt; flag to true.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://192.168.1.35/v1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"6070749e6acd4"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setSelfSigned&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&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're going to create another utility class called &lt;code&gt;utils/Event.kt&lt;/code&gt;. This utility class will allow us to handle &lt;strong&gt;LiveData Events&lt;/strong&gt; ( Changes that need to be observed only once ).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example.myapplication.utils&lt;/span&gt;

&lt;span class="cm"&gt;/**
 * Used as a wrapper for data that is exposed via a LiveData that represents an event.
 */&lt;/span&gt;
&lt;span class="k"&gt;open&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;hasBeenHandled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;
        &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="c1"&gt;// Allow external read but not write&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Returns the content and prevents its use again.
     */&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;getContentIfNotHandled&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;T&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hasBeenHandled&lt;/span&gt;&lt;span class="p"&gt;)&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="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;hasBeenHandled&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;
            &lt;span class="n"&gt;content&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="cm"&gt;/**
     * Returns the content, even if it's already been handled.
     */&lt;/span&gt;
    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;peekContent&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;T&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  🏗️ Create the layouts
&lt;/h2&gt;

&lt;p&gt;Now, we're going to update the layout in &lt;code&gt;activity_main.xml&lt;/code&gt; to allow us to host fragments. Replace the contents of &lt;code&gt;activity_main.xml&lt;/code&gt; with this snippet.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;androidx.constraintlayout.widget.ConstraintLayout&lt;/span&gt; &lt;span class="na"&gt;xmlns:android=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/apk/res/android"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:app=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/apk/res-auto"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:tools=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/tools"&lt;/span&gt;
    &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
    &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
    &lt;span class="na"&gt;tools:context=&lt;/span&gt;&lt;span class="s"&gt;".MainActivity"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;androidx.fragment.app.FragmentContainerView&lt;/span&gt;
        &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/fragment_container_view"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, create layout file for our Fragment at &lt;code&gt;layout/fragment_account.xml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;layout&lt;/span&gt; &lt;span class="na"&gt;xmlns:android=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/apk/res/android"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:app=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/apk/res-auto"&lt;/span&gt;
    &lt;span class="na"&gt;xmlns:tools=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/tools"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;ScrollView&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
        &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;androidx.constraintlayout.widget.ConstraintLayout&lt;/span&gt;
            &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/constraint_layout"&lt;/span&gt;
            &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
            &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
            &lt;span class="na"&gt;android:padding=&lt;/span&gt;&lt;span class="s"&gt;"16dp"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

            &lt;span class="nt"&gt;&amp;lt;EditText&lt;/span&gt;
                &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/responseTV"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"200dp"&lt;/span&gt;
                &lt;span class="na"&gt;android:background=&lt;/span&gt;&lt;span class="s"&gt;"@null"&lt;/span&gt;
                &lt;span class="na"&gt;android:enabled=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
                &lt;span class="na"&gt;android:fadeScrollbars=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
                &lt;span class="na"&gt;android:focusable=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
                &lt;span class="na"&gt;android:longClickable=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
                &lt;span class="na"&gt;android:scrollbars=&lt;/span&gt;&lt;span class="s"&gt;"vertical"&lt;/span&gt;
                &lt;span class="na"&gt;android:textIsSelectable=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintEnd_toEndOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintStart_toStartOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintTop_toTopOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

            &lt;span class="nt"&gt;&amp;lt;EditText&lt;/span&gt;
                &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/email"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_marginTop=&lt;/span&gt;&lt;span class="s"&gt;"16dp"&lt;/span&gt;
                &lt;span class="na"&gt;android:hint=&lt;/span&gt;&lt;span class="s"&gt;"Email"&lt;/span&gt;
                &lt;span class="na"&gt;android:inputType=&lt;/span&gt;&lt;span class="s"&gt;"textEmailAddress"&lt;/span&gt;
                &lt;span class="na"&gt;android:text=&lt;/span&gt;&lt;span class="s"&gt;"test@test.com"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintStart_toStartOf=&lt;/span&gt;&lt;span class="s"&gt;"@id/responseTV"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintTop_toBottomOf=&lt;/span&gt;&lt;span class="s"&gt;"@id/responseTV"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;


            &lt;span class="nt"&gt;&amp;lt;EditText&lt;/span&gt;
                &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/password"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_marginTop=&lt;/span&gt;&lt;span class="s"&gt;"16dp"&lt;/span&gt;
                &lt;span class="na"&gt;android:hint=&lt;/span&gt;&lt;span class="s"&gt;"password"&lt;/span&gt;
                &lt;span class="na"&gt;android:inputType=&lt;/span&gt;&lt;span class="s"&gt;"textPassword"&lt;/span&gt;
                &lt;span class="na"&gt;android:text=&lt;/span&gt;&lt;span class="s"&gt;"testtest"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintStart_toStartOf=&lt;/span&gt;&lt;span class="s"&gt;"@id/email"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintTop_toBottomOf=&lt;/span&gt;&lt;span class="s"&gt;"@id/email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

            &lt;span class="nt"&gt;&amp;lt;EditText&lt;/span&gt;
                &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/name"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"match_parent"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_marginTop=&lt;/span&gt;&lt;span class="s"&gt;"16dp"&lt;/span&gt;
                &lt;span class="na"&gt;android:hint=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;
                &lt;span class="na"&gt;android:inputType=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintStart_toStartOf=&lt;/span&gt;&lt;span class="s"&gt;"@id/password"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintTop_toBottomOf=&lt;/span&gt;&lt;span class="s"&gt;"@id/password"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

            &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt;
                &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/login"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_marginTop=&lt;/span&gt;&lt;span class="s"&gt;"8dp"&lt;/span&gt;
                &lt;span class="na"&gt;android:text=&lt;/span&gt;&lt;span class="s"&gt;"Login"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintEnd_toStartOf=&lt;/span&gt;&lt;span class="s"&gt;"@+id/signup"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintHorizontal_bias=&lt;/span&gt;&lt;span class="s"&gt;"0.5"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintHorizontal_chainStyle=&lt;/span&gt;&lt;span class="s"&gt;"spread"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintStart_toStartOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintTop_toBottomOf=&lt;/span&gt;&lt;span class="s"&gt;"@+id/name"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

            &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt;
                &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/signup"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_marginTop=&lt;/span&gt;&lt;span class="s"&gt;"8dp"&lt;/span&gt;
                &lt;span class="na"&gt;android:text=&lt;/span&gt;&lt;span class="s"&gt;"Signup"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintEnd_toStartOf=&lt;/span&gt;&lt;span class="s"&gt;"@id/getUser"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintHorizontal_bias=&lt;/span&gt;&lt;span class="s"&gt;"0.5"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintStart_toEndOf=&lt;/span&gt;&lt;span class="s"&gt;"@+id/login"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintTop_toBottomOf=&lt;/span&gt;&lt;span class="s"&gt;"@+id/name"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

            &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt;
                &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/getUser"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_marginTop=&lt;/span&gt;&lt;span class="s"&gt;"8dp"&lt;/span&gt;
                &lt;span class="na"&gt;android:text=&lt;/span&gt;&lt;span class="s"&gt;"Get User"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintEnd_toEndOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintHorizontal_bias=&lt;/span&gt;&lt;span class="s"&gt;"0.5"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintStart_toEndOf=&lt;/span&gt;&lt;span class="s"&gt;"@+id/signup"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintTop_toBottomOf=&lt;/span&gt;&lt;span class="s"&gt;"@+id/name"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

            &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt;
                &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/oAuth"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_marginTop=&lt;/span&gt;&lt;span class="s"&gt;"8dp"&lt;/span&gt;
                &lt;span class="na"&gt;android:text=&lt;/span&gt;&lt;span class="s"&gt;"Login with Facebook"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintEnd_toEndOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintEnd_toStartOf=&lt;/span&gt;&lt;span class="s"&gt;"@+id/logout"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintHorizontal_bias=&lt;/span&gt;&lt;span class="s"&gt;"0.5"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintHorizontal_chainStyle=&lt;/span&gt;&lt;span class="s"&gt;"spread"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintStart_toStartOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintTop_toBottomOf=&lt;/span&gt;&lt;span class="s"&gt;"@id/signup"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

            &lt;span class="nt"&gt;&amp;lt;Button&lt;/span&gt;
                &lt;span class="na"&gt;android:id=&lt;/span&gt;&lt;span class="s"&gt;"@+id/logout"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_width=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:layout_height=&lt;/span&gt;&lt;span class="s"&gt;"wrap_content"&lt;/span&gt;
                &lt;span class="na"&gt;android:text=&lt;/span&gt;&lt;span class="s"&gt;"Logout"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintEnd_toEndOf=&lt;/span&gt;&lt;span class="s"&gt;"parent"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintHorizontal_bias=&lt;/span&gt;&lt;span class="s"&gt;"0.5"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintStart_toEndOf=&lt;/span&gt;&lt;span class="s"&gt;"@+id/oAuth"&lt;/span&gt;
                &lt;span class="na"&gt;app:layout_constraintTop_toTopOf=&lt;/span&gt;&lt;span class="s"&gt;"@id/oAuth"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class="nt"&gt;&amp;lt;/androidx.constraintlayout.widget.ConstraintLayout&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/ScrollView&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/layout&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  🔨 Create the ViewModel
&lt;/h2&gt;

&lt;p&gt;Let's now create a ViewModel at &lt;code&gt;ui/accounts/AccountsViewModel.kt&lt;/code&gt; to manage our app state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example.myapplication.ui.accounts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.text.Editable&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.activity.ComponentActivity&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.lifecycle.*&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.example.myapplication.utils.Client.client&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.example.myapplication.utils.Event&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.appwrite.exceptions.AppwriteException&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.appwrite.services.Account&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.launch&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;org.json.JSONObject&lt;/span&gt;


&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AccountsViewModel&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ViewModel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;_error&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MutableLiveData&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;value&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="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;LiveData&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_error&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;_response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MutableLiveData&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;apply&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;value&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="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;LiveData&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_response&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;accountService&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="nf"&gt;lazy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Editable&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Editable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;viewModelScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&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="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accountService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&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;password&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="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
                &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&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="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&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;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AppwriteException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;_error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&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="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;fun&lt;/span&gt; &lt;span class="nf"&gt;onSignup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Editable&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Editable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Editable&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;viewModelScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&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="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accountService&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="n"&gt;email&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;password&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;name&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="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
                &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&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;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AppwriteException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;_error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&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="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;fun&lt;/span&gt; &lt;span class="nf"&gt;onGetUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;viewModelScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&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="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accountService&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="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;?:&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt;
                &lt;span class="n"&gt;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&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;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AppwriteException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;_error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&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="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;fun&lt;/span&gt; &lt;span class="nf"&gt;onLogout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;viewModelScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&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="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;accountService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;deleteSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"current"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;ifEmpty&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="n"&gt;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;JSONObject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&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="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;_response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;json&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;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AppwriteException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;_error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&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="p"&gt;}&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;Our ViewModel has 2 LiveData Objects: One to keep track of errors and one to keep track of the response.&lt;/p&gt;

&lt;p&gt;We also have 4 functions&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;onLogin - onClick handler for the Login Button&lt;/li&gt;
&lt;li&gt;onSignup - onClick handler for the Signup Button&lt;/li&gt;
&lt;li&gt;onLogout - onClick handler for the Logout Button&lt;/li&gt;
&lt;li&gt;onGetUser - onClick handler for the Get User Button&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  📝 Create the Fragment
&lt;/h2&gt;

&lt;p&gt;Awesome! Let's move on to create our Fragment at &lt;code&gt;ui/accounts/AccountsFragment.kt&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example.myapplication.ui.accounts&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.os.Bundle&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.view.LayoutInflater&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.view.View&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.view.ViewGroup&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.widget.Toast&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.activity.ComponentActivity&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.databinding.DataBindingUtil&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.fragment.app.Fragment&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.lifecycle.Observer&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.lifecycle.ViewModelProvider&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.example.myapplication.R&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.example.myapplication.databinding.FragmentAccountBinding&lt;/span&gt;


&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AccountsFragment&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Fragment&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;FragmentAccountBinding&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;lateinit&lt;/span&gt; &lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="py"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AccountsViewModel&lt;/span&gt;

    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;inflater&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;LayoutInflater&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ViewGroup&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;viewModel&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ViewModelProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&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="nc"&gt;AccountsViewModel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="k"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;binding&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;DataBindingUtil&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;inflate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;inflater&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_account&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="k"&gt;false&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lifecycleOwner&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;viewLifecycleOwner&lt;/span&gt;
        &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;login&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setOnClickListener&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;signup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setOnClickListener&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onSignup&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setOnClickListener&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onGetUser&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setOnClickListener&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onLogout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewLifecycleOwner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Observer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;getContentIfNotHandled&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Only proceed if the event has never been handled&lt;/span&gt;
                &lt;span class="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;makeText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;requireContext&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;it&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="nc"&gt;Toast&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;LENGTH_SHORT&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;show&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="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;observe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;viewLifecycleOwner&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Observer&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
            &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;getContentIfNotHandled&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;let&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responseTV&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setText&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;it&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;return&lt;/span&gt; &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;root&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;h2&gt;
  
  
  🔧 Update Main Activity
&lt;/h2&gt;

&lt;p&gt;Finally, let's update our MainActivity.kt, that will initialise our &lt;code&gt;Client&lt;/code&gt; singleton and add the &lt;code&gt;AccountsFragment&lt;/code&gt; to the &lt;strong&gt;FragmentContainerView&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;package&lt;/span&gt; &lt;span class="nn"&gt;com.example.myapplication&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.appcompat.app.AppCompatActivity&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.os.Bundle&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.fragment.app.add&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.fragment.app.commit&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.example.myapplication.utils.Client&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainActivity&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AppCompatActivity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;setContentView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;activity_main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nc"&gt;Client&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="n"&gt;applicationContext&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;savedInstanceState&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="n"&gt;supportFragmentManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;commit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nf"&gt;setReorderingAllowed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;AccountsFragment&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fragment_container_view&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="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;You should now be able to run your app and create users, login, logout and get information about the currently logged in user!&lt;/p&gt;

&lt;h2&gt;
  
  
  🔐 Adding OAuth Support
&lt;/h2&gt;

&lt;p&gt;You would have noticed that we have a &lt;strong&gt;Login With Facebook&lt;/strong&gt; button in our UI but it doesn't really do anything yet. So let's now add Facebook OAuth to our app!&lt;/p&gt;

&lt;p&gt;The first step is to add a callback activity in the &lt;code&gt;AndroidManifest.xml&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;manifest&lt;/span&gt; &lt;span class="na"&gt;xmlns:android=&lt;/span&gt;&lt;span class="s"&gt;"http://schemas.android.com/apk/res/android"&lt;/span&gt;
    &lt;span class="na"&gt;package=&lt;/span&gt;&lt;span class="s"&gt;"com.example.myapplication"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;application&lt;/span&gt;

        &lt;span class="err"&gt;&amp;lt;!--&lt;/span&gt; &lt;span class="err"&gt;Other&lt;/span&gt; &lt;span class="err"&gt;Activities&lt;/span&gt; &lt;span class="err"&gt;--&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;activity&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"io.appwrite.views.CallbackActivity"&lt;/span&gt; &lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;intent-filter&lt;/span&gt; &lt;span class="na"&gt;android:label=&lt;/span&gt;&lt;span class="s"&gt;"android_web_auth"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;action&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.action.VIEW"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.DEFAULT"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;category&lt;/span&gt; &lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.intent.category.BROWSABLE"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span class="nt"&gt;&amp;lt;data&lt;/span&gt; &lt;span class="na"&gt;android:scheme=&lt;/span&gt;&lt;span class="s"&gt;"appwrite-callback-6070749e6acd4"&lt;/span&gt;  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;/intent-filter&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/activity&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;/application&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/manifest&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure you replace the Project ID in &lt;code&gt;&amp;lt;data android:scheme="appwrite-callback-[PROJECT-ID]" /&amp;gt;&lt;/code&gt; with your own.&lt;/p&gt;

&lt;p&gt;Next, we'll add a function to our ViewModel to call the &lt;code&gt;createOAuth2Session()&lt;/code&gt; method of the Appwrite SDK.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;oAuthLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;activity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ComponentActivity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;viewModelScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&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="n"&gt;accountService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createOAuth2Session&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;activity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"facebook"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"appwrite-callback-6070749e6acd4://demo.appwrite.io/auth/oauth2/success"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"appwrite-callback-6070749e6acd4://demo.appwrite.io/auth/oauth2/failure"&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;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;_error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&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="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;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AppwriteException&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;_error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Event&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="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;The success and failure URLs take the following form&lt;br&gt;
&lt;code&gt;appwrite-callback-[PROJECT-ID]://[YOUR APPWRITE ENDPOINT]/auth/oauth2/[ success | failure ]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Make sure you replace the Project ID and Endpoint with that of your own.&lt;/p&gt;

&lt;p&gt;The last step is to invoke this function from &lt;code&gt;AccountsFragment.kt&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreateView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;inflater&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;LayoutInflater&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;container&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;ViewGroup&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt;
    &lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nc"&gt;View&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

        &lt;span class="c1"&gt;// ... Existing Methods&lt;/span&gt;

        &lt;span class="n"&gt;binding&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;oAuth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setOnClickListener&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;viewModel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;oAuthLogin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;activity&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;ComponentActivity&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;Re-run your app and you should now be able to trigger your Facebook OAuth Flow! With that, you now know how to interact with Appwrite's Accounts API in your Android Apps!&lt;/p&gt;

&lt;p&gt;We've built a complete app that interacts with all of Appwrite's APIs, which you can find over at our &lt;a href="https://github.com/appwrite/demo-getstarted-with-android"&gt;Github Repo&lt;/a&gt;. If you'd like to learn more about Appwrite or how Appwrite works under the hood, we've just curated all the resources for you during &lt;a href="https://30days.appwrite.io/"&gt;30 Days of Appwrite&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨️ Credits
&lt;/h2&gt;

&lt;p&gt;Hope you enjoyed this article! We love contributions and encourage you to take a look at our &lt;a href="https://github.com/appwrite/appwrite/issues"&gt;open isuses&lt;/a&gt; and &lt;a href="https://github.com/appwrite/rfc/pulls"&gt;ongoing RFCs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you get stuck anywhere, feel free to reach out to us on our &lt;a href="https://appwrite.io/discord"&gt;friendly support channels&lt;/a&gt; run by humans 👩‍💻.&lt;/p&gt;

&lt;p&gt;Here are some handy links for more information:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite/appwrite/blob/master/CONTRIBUTING.md"&gt;Appwrite Contribution Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite"&gt;Appwrite Github&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/docs"&gt;Appwrite Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>android</category>
      <category>tutorial</category>
      <category>opensource</category>
      <category>discuss</category>
    </item>
    <item>
      <title>Announcing Appwrite 0.9: The open source Firebase alternative</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Wed, 07 Jul 2021 14:27:41 +0000</pubDate>
      <link>https://dev.to/appwrite/announcing-appwrite-0-9-the-open-source-firebase-alternative-53ho</link>
      <guid>https://dev.to/appwrite/announcing-appwrite-0-9-the-open-source-firebase-alternative-53ho</guid>
      <description>&lt;p&gt;The last month was a crazy one. We've put together over &lt;strong&gt;250 commits&lt;/strong&gt;, &lt;strong&gt;20k lines of code&lt;/strong&gt; and countless hours to bring you the best Appwrite version ever! With that, we're incredibly excited to announce the release of &lt;strong&gt;Appwrite 0.9&lt;/strong&gt;, packed with a ton of cool new features like &lt;strong&gt;Android support&lt;/strong&gt;, &lt;strong&gt;Kotlin Server SDK&lt;/strong&gt;, &lt;strong&gt;Flutter Desktop Support&lt;/strong&gt;, and much more! Without spending any more time, let's dive in! 🤿&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Appwrite is an open-source, self-hosted Backend-as-a-Service that aims to make app development &lt;strong&gt;easier&lt;/strong&gt; with SDKs available in a variety of programming languages. Come hang out with us on &lt;a href="https://appwrite.io/discord"&gt;Discord&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  🤖 Android Support
&lt;/h2&gt;

&lt;p&gt;It's finally here 📌 Appwrite now has official support for Android! &lt;a href="https://github.com/appwrite/sdk-for-android"&gt;Our SDK&lt;/a&gt; has been out in the wild for over 2 weeks now - we've gathered some amazing feedback from the community, and we're now ready to present it to all of you! We've got all the setup instructions in our new &lt;a href="https://appwrite.io/docs/getting-started-for-android?"&gt;Getting Started Guide&lt;/a&gt;, but here's what you'll need to do, in a nutshell 🥜. &lt;/p&gt;

&lt;p&gt;Include the &lt;strong&gt;mavenCentral()&lt;/strong&gt; repository in your project's &lt;strong&gt;build.gradle(.kts)&lt;/strong&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;repositories&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;      
    &lt;span class="n"&gt;mavenCentral&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the Android SDK in your app's &lt;strong&gt;build.gradle(.kts)&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"io.appwrite:sdk-for-android:0.0.1"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🤩 Then make your first request using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;androidx.appcompat.app.AppCompatActivity&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;android.os.Bundle&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.GlobalScope&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;kotlinx.coroutines.launch&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.appwrite.Client&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.appwrite.services.Account&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MainActivity&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;AppCompatActivity&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;Bundle&lt;/span&gt;&lt;span class="p"&gt;?)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;savedInstanceState&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="nf"&gt;setContentView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;activity_main&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;applicationContext&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://[HOSTNAME_OR_IP]/v1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Your API Endpoint&lt;/span&gt;
            &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"5df5acd0d48c2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Your project ID&lt;/span&gt;

        &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;account&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Account&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

        &lt;span class="nc"&gt;GlobalScope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;launch&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;account&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="n"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"email@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"password"&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="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 also have some example apps to help you get started&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A bare minimum &lt;a href="https://github.com/appwrite/playground-for-android"&gt;Playground App&lt;/a&gt; to help you quickly start building apps.&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://github.com/appwrite/demo-getstarted-with-android"&gt;Getting Started App&lt;/a&gt; that has interactions with all of Appwrite's endpoints.&lt;/li&gt;
&lt;li&gt;A &lt;a href="https://github.com/appwrite/demo-quiz-with-android"&gt;Simple Quiz App&lt;/a&gt; built with Appwrite.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🦾 Kotlin Server SDK
&lt;/h2&gt;

&lt;p&gt;We also released a brand new &lt;a href="https://github.com/appwrite/sdk-for-kotlin"&gt;Kotlin Server SDK&lt;/a&gt; to go along with the Android one! Setting up the Kotlin SDK is a similar drill. You can check out our &lt;a href="https://appwrite.io/docs/getting-started-for-server"&gt;Getting Started Guide&lt;/a&gt; or follow along for a quick summary.&lt;/p&gt;

&lt;p&gt;Add the dependency to your &lt;strong&gt;pom.xml&lt;/strong&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;dependencies&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;dependency&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;groupId&amp;gt;&lt;/span&gt;io.appwrite&lt;span class="nt"&gt;&amp;lt;/groupId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;artifactId&amp;gt;&lt;/span&gt;sdk-for-kotlin&lt;span class="nt"&gt;&amp;lt;/artifactId&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;version&amp;gt;&lt;/span&gt;0.0.1&lt;span class="nt"&gt;&amp;lt;/version&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/dependency&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/dependencies&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or your &lt;strong&gt;build.gradle(.kts)&lt;/strong&gt; file if using &lt;strong&gt;Gradle&lt;/strong&gt; as your build system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight groovy"&gt;&lt;code&gt;&lt;span class="n"&gt;dependencies&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;implementation&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"io.appwrite:sdk-for-kotlin:0.0.1"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🚀 Then make your first request using&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.appwrite.Client&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;io.appwrite.services.Users&lt;/span&gt;

&lt;span class="k"&gt;suspend&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setEndpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"https://[HOSTNAME_OR_IP]/v1"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setProject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"5df5acd0d48c2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"919c2d18fb5d4...a2ae413da83346ad2"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;users&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Users&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;users&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="n"&gt;email&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"email@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"password"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;json&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;body&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;string&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 also have some example apps to help you get started&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A bare minimum &lt;a href="https://github.com/appwrite/playground-for-kotlin"&gt;Playground App&lt;/a&gt; to help you quickly start building apps.&lt;/li&gt;
&lt;li&gt;We also have some really cool &lt;a href="https://github.com/appwrite/demos-for-functions"&gt;Cloud Function demos&lt;/a&gt; using our Kotlin SDK. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🖥️ Flutter Desktop Support
&lt;/h2&gt;

&lt;p&gt;With Appwrite 0.9, we've enabled platform wide support for your Flutter Desktop Apps! You can now register your Linux, Windows and Mac apps from the Dashboard! &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcy3kn6js39mr4ebt59f0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcy3kn6js39mr4ebt59f0.png" alt="Flutter Desktop" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🏃 New Cloud Function Runtimes
&lt;/h2&gt;

&lt;p&gt;Our Cloud Function runtimes list continues to grow with over 20+ (!) runtimes. This time we've added support for &lt;strong&gt;deno-1.10&lt;/strong&gt;, &lt;strong&gt;deno-1.11&lt;/strong&gt;, &lt;strong&gt;dart 2.13&lt;/strong&gt;, &lt;strong&gt;node-16.0&lt;/strong&gt; , &lt;strong&gt;java-11.0&lt;/strong&gt; and &lt;strong&gt;java-16.0&lt;/strong&gt;. We've got you covered 💪 no matter what your favourite language is! If you're looking for some creative ways to get started with Cloud Functions, feel free to check out &lt;a href="https://github.com/appwrite/demos-for-functions"&gt;our demos&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚒️ Breaking Changes
&lt;/h2&gt;

&lt;p&gt;Breaking changes are hard, but unfortunately, they're a necessary evil! We've kept those nasty breaking changes to a bare minimum with this release and only made changes to our Server SDKs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;env&lt;/code&gt; has been renamed to &lt;code&gt;runtime&lt;/code&gt; in the &lt;code&gt;POST v1/functions&lt;/code&gt; endpoint. If you're using named parameters in your server SDKs, you will need to update them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;deleteUser&lt;/code&gt; has been replaced in favour of the &lt;code&gt;delete&lt;/code&gt; method in all our Server SDKs. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  🚀 Everything else
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Our Image Preview 📸 endpoint now let's you specify a gravity giving you much more control when cropping your images!  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;One of our community members &lt;a href="https://github.com/Meldiron"&gt;&lt;strong&gt;@Meldiron&lt;/strong&gt;&lt;/a&gt;, helped speed up our Cloud Function executions by upto a &lt;a href="https://github.com/appwrite/appwrite/pull/1308"&gt;&lt;strong&gt;whopping 4s 🤯&lt;/strong&gt;&lt;/a&gt; in some cases. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We revamped our &lt;strong&gt;User Sessions UI&lt;/strong&gt; in the Dashboard to give you more fine grained information about a user's session.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1wrsalkufc911a78pgjm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1wrsalkufc911a78pgjm.png" alt="sessions" width="800" height="404"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We've added some additional metadata in our &lt;strong&gt;File Preview Dialog&lt;/strong&gt; to make it easier to view your file types, file size and the creation date.&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fguwnzctwy968b7hjjauc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fguwnzctwy968b7hjjauc.png" alt="meta-data" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Internally, we've optimized our database connection pools for overall improved server performance 🤩&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Gone are the days of running multiple migration scripts to upgrade to the latest version of Appwrite! From Appwrite 0.9, it's just a single script! &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Based on popular demand, we've added a &lt;a href="https://appwrite.io/docs/client/account?sdk=web-default#accountGetSession"&gt;new endpoint&lt;/a&gt; to get a session by ID and another endpoint to force update the user verification status from Server Side SDKs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Last but not the least, we've &lt;a href="https://github.com/appwrite/appwrite/pull/1225"&gt;overhauled our Email Templates&lt;/a&gt; in an attempt to offer lot more customization in the future! &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Let's not forget, you also helped us reach a major milestone of &lt;strong&gt;10k Github stars&lt;/strong&gt; ⭐️ making us one of the &lt;strong&gt;top 2000&lt;/strong&gt; projects in Github history! We also crossed a landmark &lt;strong&gt;2.2M Docker pulls&lt;/strong&gt; and &lt;strong&gt;over 40k reads&lt;/strong&gt; on our blog posts! Thank you so much for all your support!&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcoo9vs3uxisxd2oubjhd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcoo9vs3uxisxd2oubjhd.png" alt="star" width="800" height="501"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  😍 And More!
&lt;/h2&gt;

&lt;p&gt;We still haven't covered everything! There's lots more bug fixes and other micro optimizations we made under the hood to make your experience with Appwrite better! To get all the details on Appwrite 0.9, check out all the changes in the &lt;a href="https://github.com/appwrite/appwrite/blob/master/CHANGES.md"&gt;changelog on GitHub&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;If you're upgrading from an older version of Appwrite, be sure to follow our &lt;a href="https://appwrite.io/docs/upgrade"&gt;Upgrading guide&lt;/a&gt; so that you don't loose your way in uncharted territories 😉.&lt;/p&gt;

&lt;p&gt;Are you curious about the big ideas we have up next, or have a great idea for Appwrite's future? Check out the &lt;a href="https://github.com/appwrite/rfc"&gt;RFC Repository&lt;/a&gt; for more details. Also, our &lt;a href="https://github.com/appwrite/awesome-appwrite"&gt;awesome-appwrite repository&lt;/a&gt; keeps growing with new tutorials, videos, and demos.&lt;/p&gt;

&lt;p&gt;If you've just discovered Appwrite and would like to get started, check out out our &lt;a href="https://30days.appwrite.io/"&gt;30 Days of Appwrite&lt;/a&gt; series where we explain step-by-step everything you need to know to build awesome Appwrite-powered apps. Follow us on &lt;a href="https://twitter.com/appwrite_io"&gt;Twitter&lt;/a&gt;, &lt;a href="https://dev.to/appwrite"&gt;Dev.to&lt;/a&gt;, or anywhere you find your friendly neighbourhood Appwrite. &lt;/p&gt;

</description>
      <category>flutter</category>
      <category>android</category>
      <category>kotlin</category>
      <category>opensource</category>
    </item>
    <item>
      <title>#30DaysOfAppwrite: Grafana Integration</title>
      <dc:creator>Christy Jacob</dc:creator>
      <pubDate>Sat, 29 May 2021 13:13:04 +0000</pubDate>
      <link>https://dev.to/appwrite/grafana-integration-50p9</link>
      <guid>https://dev.to/appwrite/grafana-integration-50p9</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Appwrite is an open-source, self-hosted Backend-as-a-Service that makes app development &lt;strong&gt;easier&lt;/strong&gt; with a suite of SDKs and APIs to accelerate app development. &lt;a href="http://30days.appwrite.io/"&gt;#30DaysOfAppwrite&lt;/a&gt; is a month-long event focused on giving developers a walkthrough of all of Appwrite's features, starting from the basics to more advanced features like Cloud Functions! Alongside we will also be building a fully-featured Medium clone to demonstrate how these concepts can be applied when building a real-world app. We also have some exciting prizes for developers who follow along with us!&lt;/p&gt;

&lt;h2&gt;
  
  
  Grafana Integration
&lt;/h2&gt;

&lt;p&gt;Welcome to Day 29 👋 - today marks the last day of #30DaysOfAppwrite, and we thought it would be a fun little exercise to show you how you can add external services to the Appwrite stack and make it work seamlessly! We love Dashboards, and we thought it would be great to add Grafana support to Appwrite. &lt;/p&gt;

&lt;p&gt;Appwrite doesn't come with Grafana out of the box for several reasons. First, you may already have your own set of monitoring tools in your stack, and we believe that our stack should be un-opinionated and allow you to work with the tools you feel comfortable with. The second reason is that we try to ship the Appwrite setup with minimal components to make Appwrite easy to start but still flexible enough to grow.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Add Grafana to Appwrite
&lt;/h2&gt;

&lt;p&gt;We will be creating two Dashboards: one for monitoring Appwrite's usage stats and one for monitoring your Server stats. &lt;/p&gt;

&lt;p&gt;The first step is to add the Grafana service to Appwrite's &lt;a href="https://github.com/appwrite/appwrite/blob/master/docker-compose.yml#L476"&gt;&lt;code&gt;docker-compose.yml&lt;/code&gt; file&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;grafana&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;grafana/grafana&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appwrite-grafana&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3000:3000"&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;appwrite&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;appwrite-grafana:/var/lib/grafana&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you need to add the &lt;code&gt;appwrite-grafana&lt;/code&gt; volume to the &lt;a href="https://github.com/appwrite/appwrite/blob/master/docker-compose.yml#L532"&gt;list of all volumes&lt;/a&gt;. This will allow your Grafana container to persist data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;appwrite-mariadb&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;appwrite-redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;appwrite-cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;appwrite-uploads&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;appwrite-certificates&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;appwrite-functions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;appwrite-influxdb&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;appwrite-config&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;appwrite-grafana&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker-compose up &lt;span class="nt"&gt;-d&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Dashboard #1 - Appwrite Metrics
&lt;/h2&gt;

&lt;p&gt;We don't need any additional configuration for your first Dashboard in our services. Now head over to &lt;code&gt;http://localhost:3000&lt;/code&gt; to configure Grafana. You can log in using the default credentials:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;username : admin
password : admin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will be prompted to enter a new password, and it is &lt;strong&gt;highly recommended&lt;/strong&gt; that you change the default password. Learn more about managing users and passwords in their &lt;a href="https://grafana.com/docs/grafana/latest/manage-users/user-admin/change-your-password/"&gt;official guide&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;The first step is to configure your Data Source. In our case, we will be using the InfluxDB plugin. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvi5ma8ubrqfm0p8fm2h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnvi5ma8ubrqfm0p8fm2h.png" alt="Add Datasource" width="800" height="408"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you add the InfluxDB data source, it's time to configure it. Here, you need to fill in the values of 2 fields, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;URL&lt;/strong&gt; - &lt;a href="http://influxdb:8086"&gt;http://influxdb:8086&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt; - telegraf&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, click &lt;strong&gt;Save and Test&lt;/strong&gt; to check your database connection. If all goes well, you will see a success message.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F490bpq9m7vgerh34f7oj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F490bpq9m7vgerh34f7oj.png" alt="Configure Datasource" width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The next step is to import the Dashboard we created for you. Head to the &lt;a href="https://grafana.com/grafana/dashboards/14508"&gt;Grafana's Dashboard Library&lt;/a&gt; and copy the ID of our Dashboard.&lt;/p&gt;

&lt;p&gt;You can then &lt;strong&gt;Import the Dashboard&lt;/strong&gt; in your Grafana instance like so. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgjns1oja5gywo3mxcte.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwgjns1oja5gywo3mxcte.png" alt="Importing Appwrite data" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's it! You should now see this fancy Dashboard&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0s5az7aspk879hngza2k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0s5az7aspk879hngza2k.png" alt="Appwrite Metrics" width="800" height="1176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dashboard #2 - Server Metrics
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://grafana.com/grafana/dashboards/5955"&gt;next Dashboard&lt;/a&gt; is one that will monitor our server metrics. This includes CPU usage, Disk I/O, Network I/O, and much more. This Dashboard requires some additional info, so we need to make a few changes in our &lt;code&gt;telegraf&lt;/code&gt; Docker image to make this information available.   &lt;/p&gt;

&lt;p&gt;We'll start by cloning Appwrite's &lt;code&gt;telegraf&lt;/code&gt; image&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/appwrite/docker-telegraf.git 
&lt;span class="nb"&gt;cd &lt;/span&gt;docker-telegraf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to make more metrics available to the collector. Add the following lines to &lt;a href="https://github.com/appwrite/docker-telegraf/blob/master/telegraf.conf#L83"&gt;line 83&lt;/a&gt;&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;[[&lt;/span&gt;inputs.cpu]]
    percpu &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true
    &lt;/span&gt;totalcpu &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;true
    &lt;/span&gt;collect_cpu_time &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false
    &lt;/span&gt;report_active &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;false&lt;/span&gt;
&lt;span class="o"&gt;[[&lt;/span&gt;inputs.disk]]
    ignore_fs &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"tmpfs"&lt;/span&gt;, &lt;span class="s2"&gt;"devtmpfs"&lt;/span&gt;, &lt;span class="s2"&gt;"devfs"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;[[&lt;/span&gt;inputs.io]]
&lt;span class="o"&gt;[[&lt;/span&gt;inputs.mem]]
&lt;span class="o"&gt;[[&lt;/span&gt;inputs.net]]
&lt;span class="o"&gt;[[&lt;/span&gt;inputs.system]]
&lt;span class="o"&gt;[[&lt;/span&gt;inputs.swap]]
&lt;span class="o"&gt;[[&lt;/span&gt;inputs.netstat]]
&lt;span class="o"&gt;[[&lt;/span&gt;inputs.processes]]
&lt;span class="o"&gt;[[&lt;/span&gt;inputs.kernel]]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we need to build a new Docker image using the changes we made.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker build &lt;span class="nt"&gt;-t&lt;/span&gt; telegraf-local &lt;span class="nb"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once this build is complete, we can make use of our new &lt;code&gt;telegraf-local&lt;/code&gt; image in the main Appwrite &lt;code&gt;docker-compose.yml&lt;/code&gt;. Replace the &lt;code&gt;appwrite/telegraf:1.1.0&lt;/code&gt; image in &lt;a href="https://github.com/appwrite/appwrite/blob/master/docker-compose.yml#L434"&gt;line 434&lt;/a&gt; with our &lt;code&gt;telegraf-local&lt;/code&gt; image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;telegraf&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;telegraf-local&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;appwrite-telegraf&lt;/span&gt;
    &lt;span class="na"&gt;networks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;appwrite&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now run &lt;code&gt;docker-compose up -d --remove-orphans&lt;/code&gt; from your &lt;code&gt;appwrite&lt;/code&gt; directory to restart your services.&lt;br&gt;
Now head over to your Grafana Dashboard and import &lt;a href="https://grafana.com/grafana/dashboards/5955"&gt;this new Dashboard&lt;/a&gt; the same way as you did the previous one, and if everything goes well, you should see the following Dashboard!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foz4shqwqquffliey1fb5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foz4shqwqquffliey1fb5.png" alt="System Metrics" width="800" height="2226"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And just like that, you now have access to all your server information in one place! This was just the tip of the iceberg! Grafana has many more amazing features. It's completely open-source, has support for over 30 Data Sources, has support for Alerting etc. You can set up custom alerts, and Grafana will continuously evaluate and send notifications to systems like Slack, PagerDuty, VictorOps, and OpsGenie. You can learn more about all of Grafana's features in their dedicated &lt;a href="https://grafana.com/tutorials/"&gt;tutorials section&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credits
&lt;/h2&gt;

&lt;p&gt;We hope you liked this write-up. You can follow &lt;a href="https://twitter.com/search?q=%2330daysofappwrite"&gt;#30DaysOfAppwrite&lt;/a&gt; on Social Media to keep up with all of our posts. The complete event timeline can be found &lt;a href="http://30days.appwrite.io"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://appwrite.io/discord"&gt;Discord Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://appwrite.io/"&gt;Appwrite Homepage&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/appwrite"&gt;Appwrite's Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feel free to reach out to us on Discord if you would like to learn more about Appwrite, Aliens, or Unicorns 🦄. Stay tuned for tomorrow's article! Until then 👋&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>flutter</category>
      <category>30daysofappwrite</category>
    </item>
  </channel>
</rss>
