← Back to list

Create an Order Notification App using Spica and React

A Spica Tutorial for Trigger Spica Functions

Enes Buğra Çanak · 2022-12-06 13:56 · 77 claps · 6.2 min read
#spica #react #trigger #email-notifications #orders
Open on Medium ↗
Wiki topics: 🌐 · Web Development

BUILDING EMAIL NOTIFICATIONS WITH SPICA FUNCTIONS

Create an Order Notification App using Spica and React

A Spica Tutorial for Trigger Spica Functions

Emails are central to any successful business operation. Emails are widely used and accessible to a large audience. This makes emails the perfect solution for communication between businesses and consumers. Today we are going to create a Spica Function with a trigger, and with this function, we will send emails to product owners easily. This will be a basic application but you can improve it and use it in any kind of application.

Prerequisites

Setup

Since we won’t be focusing on React in this post, let’s begin by cloning the repository We set up on GitHub for the frontend. With the following code snippet, you can clone from CMD.

git clone https://github.com/enesbugrac/spica-email-notification-starter.git

To start, we can install npm packages and start coding for the Spica part.

cd spica-email-notification-starter/
npm install

To use Spica’s buckets, we must install the @spica-devkit/bucket library using npm.

npm install @spica-devkit/bucket

Setup Spica project

https://dashboard.spicaengine.com/register Let’s register via this link, then let’s start our process by creating a project. You can give any project name and information you want when you are creating the project.

After creating your project, go to Bucket from the left side navigation. Then click the +Add New Bucket. You can give Orders as Bucket name. After that click +Add new property button and select String on the property type modal. You can give product_name as the name of the new property. Then click the Save button for saving the property in Bucket. Also, you must create an owner_mail(String) property. You can do the same process we did for product_name.

Orders bucket

Orders bucket

Now we created our Orders bucket, the next step is creating Spica services in our client app so that we can access our bucket.

Order Service

As you can see we already have Order.service.tsx file under the src/services folder. We just need to get our API_KEY, BUCKET_ID, and API_URL from Spica.

Now go to the Bucket screen on the Spica website and copy your Bucket ID, then head over to the Access Management --> API Keys and click + Add New, you can give any name and description for your API Key, and after that click the Save button.

Spica API Key creation

Spica API Key creation

Now you are on this screen, you can attach any policies you want to your API Key but under this topic, we only need the Bucket Full Access policy, we will attach this policy by clicking the icon to the right. Finally, we created our API Key, and you can copy it.

After these copy operations, we can go back to our project and update our class as below.

Don’t forget to replace your API Key, Bucket ID, and Public URL!

import * as Bucket from "@spica-devkit/bucket";
export interface Order {
  product_name: string;
  owner_mail: string;
  _id: string;
}
class OrderService {
  private API_KEY = "<YOUR_API_KEY>";
  private BUCKET_ID = "<YOUR_BUCKET_ID>";
  constructor() {
    Bucket.initialize({
      apikey: this.API_KEY,
      publicUrl: "<YOUR_PUBLIC_URL>",
    });
  }
  addOrder = (object: object) => {
    return Bucket.data.insert(this.BUCKET_ID, object);
  };
  deleteOrder = (_id: string) => {
    return Bucket.data.remove(this.BUCKET_ID, _id);
  };
  getAllOrdersRealtime = () => {
    return Bucket.data.realtime.getAll(this.BUCKET_ID);
  };
}

export default new OrderService();

Create Function

After that click Functions on the left side menu, and click +Add New Function.

You can give any name you want to function. Select Javascript as Language. We will select Bucket as the Trigger type because we want to trigger our function via Bucket actions, also select ALL for the Operation type. Also, select the Orders bucket that we created before. With these specifications for our function, our function will trigger whenever an action happens in our Bucket. Now click the Save button and we are done. Let’s code!

Adding Dependency

We will use nodemailer for our emails in this project. Nodemailer is an email module for Node.js projects. We need to add nodemailer to our Dependencies. Write nodemailer as the Dependency name under Dependencies on the right side of the screen. Then click Enter to save Dependency.

After a short wait, nodemailer will be added to our Dependencies, and you will see it in the image below.

All set and we can import and use this package in our function.

Now head over to https://ethereal.email/ and click +Create Ethereal Account. We will use Ethereal for sending fake emails. Ethereal is a fake SMTP service, mostly aimed at Nodemailer and EmailEngine users (but not limited to). It’s a completely free anti-transactional email service where messages never get delivered. After that you will see your account credentials, don’t close this page and go back to the Spica function.

Adding Environment Variable

We will create our Environment Variables for this Ethereal account.

Click +Add New Environment Variable, write USERNAME as the key, and paste the Username that Ethereal gave you on the credentials. Now do the same operations for the password but this time write PASSWORD as the key. You can access these variables in your function, like the code snippet below.

We are done with creating environment variables and dependencies now, let’s code!

Function

As you can see we are getting a change object as the parameter. This object contains pieces of informations about the action in Bucket. You can check the example below.

{
  "operationType": "insert", // Type of the event
  "clusterTime": 1563732441, // Time of the event occurrence
  "fullDocument": {
    // The newly inserted document
    "_id": "5d34a9d957b31b06390788ec",
    "wysiwyg": {"en_US": "dqwdwd"},
    "relation": "5d132772d5869d9fd24c5985"
  },
  "ns": {
    // database name and collection name
    "db": "spica",
    "coll": "bucket_5d15d8244a23f73a2a453770"
  },
  "documentKey": {
    // the id of the inserted document (ObjectId string)
    "_id": "5d34a9d957b31b06390788ec"
  }
}

First, we must create our transporter for sendMail via nodemailer. You can create a transporter with credentials that we store in our Environment Variables.

Then we will check the change object and if we got an insert action, we will send an email with a different text via transporter.sendMail(), else if we got a delete action, we will send a different text. Also, we will get other variables such as owner_mail, product_name, and _id from the change object. We can log errors with console.error(). You can see the complete code below.

const nodemailer = require("nodemailer");

export default async function (change) {
    const transporter = nodemailer.createTransport({
        host: 'smtp.ethereal.email',
        port: 587,
        auth: {
            user: process.env.USERNAME,
            pass: process.env.PASSWORD
        }
    });
    if (change.kind === "insert") {
        await transporter.sendMail({
            from: '"Spica Tutorial" <spica@spica.com>',
            to: `${change.current.owner_mail}`,
            subject: "New Order for Your Product!",
            text: `Your product(${change.current.product_name}) just received a new order.`,
        }).catch(console.error);
        res.status(201).send({ message: "Email send success!" });
    } else if (change.kind === "delete") {
        await transporter.sendMail({
            from: '"Spica Tutorial" <spica@spica.com>',
            to: `${change.previous.owner_mail}`,
            subject: "Order canceled!",
            text: `Order with ${change.previous._id} id just canceled.`,
        }).catch(console.error);
        res.status(201).send({ message: "Email send success!" });
    }
}

Now we created our function and all needings. Let’s get back to our client project and add actions for our Bucket.

Using Spica service

First, go to the Products.tsx file and change the handleCreateOrder function as below, so that we can insert our new order object into the Orders Bucket.

  const handleCreateOrder = async () => {
    if (mailAddress && selectedItem?.title) {
      OrderService.addOrder({
        product_name: selectedItem.title,
        owner_mail: mailAddress,
      }).finally(() => alert("Succesful!"));
    } else {
      alert("Please fill mail address and select product!");
    }
    setSelectedItem(undefined);
  };

Now head over to the Orders.tsx file and fill useEffect() hook with the code snippet below. We are getting our orders in realtime with this code.

  useEffect(() => {
    const subs = OrderService.getAllOrdersRealtime().subscribe((res: any) =>
      setOrders(res)
    );
    return () => {
      subs.unsubscribe();
    };
  }, []);

Also, change the handleDeleteOrder() function as below, and now we can delete our orders.

  const handleDeleteOrder = (order: Order) => {
    OrderService.deleteOrder(order._id);
  };

You can create orders and delete them to test our function. As a result, you will receive fake emails in your fake Ethereal mail.

Conclusion

We created an order application that uses Spica Functions and Bucket trigger. We managed nodemailer on cloud function. You can check the final version of the application here and also Spica for more information.


메타데이터
post_id
f2b6a0c7d837
slug
create-a-order-notification-app-using-spica-and-react-f2b6a0c7d837
url
https://medium.com/@enesbugrac/create-a-order-notification-app-using-spica-and-react-f2b6a0c7d837
canonical_url
https://medium.com/@enesbugrac/create-a-order-notification-app-using-spica-and-react-f2b6a0c7d837
author_url
https://medium.com/@enesbugrac
status
ok
fetched_at
2026-07-26 09:46:03