DEV Community

loading...
Cover image for #30DaysOfAppwrite : Our First Cloud Function
Appwrite

#30DaysOfAppwrite : Our First Cloud Function

Torsten Dittmann
Fullstack Engineer
・3 min read

Intro

#30DaysOfAppwrite is a month long event focused at giving developers a walk through 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!

Reading Time

The first Cloud Function we are going to implement in our Medium Clone will be a function, that will calculate the reading time of a post. Calculating the reading time of a post can be quite the extensive task, depending on the length of the content. In order not to slow down your application unnecessarily, we will run this process on our server.

We are going to use a formula suggested in this blog post from Infusion Media.

First of all, we are going to add following rule to our Posts collection:

  • Label: Reading Time
  • Key: readingTime
  • Rule Type: Text

Rules

Now that the Database is prepared, let's start with our cloud function. For this we are going to create a Cloud function with Node.js runtime. In your Function Dashboard under the Settings Tab we need to enable the trigger for the events database.documents.create and database.documents.update. As environment variables we are going to add the following:

  • APPWRITE_PROJECT_ID: Insert your project ID.
  • APPWRITE_ENDPOINT: Insert your appwrite endpoint.
  • APPWRITE_API_KEY: Insert an API key that has documents.write permission.
  • POSTS_COLLECTION: Insert the ID of the Posts collection.

To stay true to the language of our demo project, we will write it in Node.js.

Create a Node.js package using npm:

mkdir calculate-reading-time
cd calculate-reading-time
npm init -y
Enter fullscreen mode Exit fullscreen mode

Now adding node-appwrite as a dependency:

npm install node-appwrite
Enter fullscreen mode Exit fullscreen mode

Create index.js file and put in following content:

const DATA = JSON.parse(process.env.APPWRITE_FUNCTION_EVENT_DATA);
const POSTS_COLLECTION = process.env.POSTS_COLLECTION;

const { $id, $collection, text, published } = DATA;

// Stop if it's not the Posts Collection or not published
if ($collection !== POSTS_COLLECTION || !published) {
    return;
}

// Initialise the client SDK
const appwrite = require("node-appwrite");
const client = new appwrite.Client();
const database = new appwrite.Database(client);

client
    .setEndpoint(process.env.APPWRITE_ENDPOINT) // Your API Endpoint
    .setProject(process.env.APPWRITE_PROJECT_ID) // Your project ID
    .setKey(process.env.APPWRITE_API_KEY) // Your secret API key
;

// Get word count
let words = text.match(
    /[A-Za-z\u00C0-\u017F]+|[\u0400-\u04FF\u0500–\u052F]+|[\u0370-\u03FF\u1F00-\u1FFF]+|[\u4E00–\u9FFF]|\d+/g
);

words = words ? words.length : 0;

let minutes = words / 200;
let seconds = (minutes % 1) * 60;
let readingTime = `${Math.floor(minutes)}m ${Math.floor(seconds)}s`;

// Don't update Post if reading time has not changed
if (readingTime === DATA.readingTime) {
    return;
}

database.updateDocument($collection, $id, {
    readingTime: readingTime
}).then(console.log).catch(console.error)
Enter fullscreen mode Exit fullscreen mode

This function is triggered on every document write and update events, calculates the reading time and saves it to the readingTime attribute. We are also checking if the reading time changes - this is necessary to not create an infinite loop and unnecessarily hit the API with our Cloud Function.

We can upload the Function very easily using the Appwrite CLI (or upload it manually in the dashboard):

appwrite functions createTag --code=. --functionId=[YOUR_FUNCTION_ID] --command='node index.js'
Enter fullscreen mode Exit fullscreen mode

Don't forget to activate the tag we just created!
We covered both the CLI method and Manual method on Day 23. So feel free to check it out if you get stuck.

Testing Our Cloud Function

We can easily test out our reading time calculation now, when navigating to the Posts collection and edit the text of a published post. You can either navigate to the Functions Dashboard and check the log, or just refresh the document we just updated and see how the readingTime attribute has magically been updated!

Alt Text

The only thing left for us is, to add the reading time to our Medium Clone at the top of each post:

// src/routes/Post.svelte

//...
<i>
  {post.readingTime}
</i>
//...
Enter fullscreen mode Exit fullscreen mode

Credits

We hope you liked this write up. You can follow #30DaysOfAppwrite on Social Media to keep up with all of our posts. The complete event timeline can be found here

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 👋

Discussion (0)