How to collect marketing campaign email leads with Mailgun and Appwrite in minutes
Published: 2024-01-08 16:22:31

Collecting marketing campaign email leads is fundamental to modern digital marketing strategies. It systematically gathers contact information, primarily email addresses, from individuals interested in a brand's products, services, or content.

This process is crucial for building and maintaining an email marketing list, a valuable tool for organizations to establish and nurture connections with their audience.

Various methods can be employed to collect email leads, such as utilizing web opt-in forms on websites and incorporating incentives like discounts or exclusive content. Web surveys, content or product upgrades, and online events like webinars or virtual summits can also capture email addresses during audience participation.

One of the significant challenges businesses face while setting up the collection of their email leads is the choice of technology. This choice can affect the speed at which organizations set up their campaign, the effectiveness of managing the email list, and the integration with their other existing platforms. This is where Appwrite, through [Appwrite Functions](https://appwrite.io/docs/products/functions?utm_source=hackmamba&utm_medium=hackmamba-blog) and [Mailgun](https://www.mailgun.com/?utm_source=hackmamba&utm_medium=hackmamba-blog) — a powerful email service provider — comes in.  

Appwrite provides ready-made function templates that allow businesses to set up applications easily. One of these templates is the **email contact form**. The email contact form template is designed to help gather email leads for marketing campaigns. It also includes a prebuilt contact form user interface that businesses can customize to meet their specific needs.

This tutorial demonstrates how you can set up the email leads collection system on your Next.js website using the email contact form provided by Appwrite and the Mailgun email service provider.

## Prerequisites

To follow along comfortably with this tutorial, you’ll need a few things: 
- Basic web development knowledge and a basic understanding of Next.js.
- An active [Appwrite cloud account](https://cloud.appwrite.io/register?utm_source=hackmamba&utm_medium=hackmamba-blog) and a [Mailgun account](https://signup.mailgun.com/new/signup?utm_source=hackmamba&utm_medium=hackmamba-blog).
- A code editor or Integrated Development Environment (IDE), preferably VScode.
- Basic knowledge of Git, a [GitHub account](https://github.com/signup), and a repository on that account.
- [Node.js](https://nodejs.org/en/download/current) installed.
- A CLI terminal.


## Repository

In case you want to view the repository of the entire Next.js leads collection website, check out this [link](https://github.com/Otrex/hackmamba-appwrite-nextjs-leads-page?utm_source=hackmamba&utm_medium=hackmamba-blog).



## Configuring Mailgun

To initiate email communications through Mailgun, you must retrieve the Simple Mail Transfer Protocol (SMTP) keys that Appwrite requires for sending emails through Mailgun.


> In this tutorial, you'll be using the sandbox environment. For instructions on using the live environment, refer to the detailed [guidelines](https://documentation.mailgun.com/en/latest/user_manual.html#verifying-your-domain).

**Retrieving the SMTP keys**
To perform this task, go to your Mailgun account dashboard. Once there, locate and click on the **Sending** menu.

![The sending menu on the Mailgun dashboard](https://lh7-us.googleusercontent.com/Y1NqJ_88Fdy7Q9LrQec1pepN8lDqvUVMYyG2vM0tK3PqQpASQkilgWPPtbtq9SzNmZwmF3dEFsJeJwYfIgVO87AcsgwyPRbM3mFGJ74nZKPATk2KE0vDUjV0SCxhlMFIAA6xa6x-KE4Oqh416u40E9k)


Next, select **Overview.**

![The overview option](https://lh7-us.googleusercontent.com/1XpcrNC7RA3X_x4AbwaNKS2TvdajCr3yQG37FV6C8XTtk1VQozZRfUlznKbye_SKFssg8Hp4m-0Qdc7cvcBksGC4YiMMTwaQ58IQY6PAs00Du7qM8kSSREQa0aPqjFUFK-45iVW6crlxxe-g-QcKzRI)


Afterward, navigate to the **SMTP** section and click **Select**.

![The screenshot showing the Select button](https://lh7-us.googleusercontent.com/uox08K6u-cBl47Nh0Aq395GKk4GNs1Ia5Y-UrwPGa_DUIvPMW5144a84xen7rMRiI7fbkwQ3c4rEErLE2odcFxBhJlMEpXGPldbJFjAhW_LH-a5-Y_azuHw_1VrfV3pBvRtvAPAFyg-WdmnAb-r7bKQ)


Once complete, you can retrieve the SMTP credentials from the section shown below. 

![The screenshot showing the SMTP credentials on Mailgun](https://lh7-us.googleusercontent.com/yQprq3vrai_V3Kdd1HLREZRLOzO-fm_8Lxgg8iRws-EpU0o2x3ooaaFiHviEBhfsxujgxrAauZ7QoeBArLCmKtVhE7Uebpq1au9ExtK-LlVm4aUhc4f0gILW65t2l_9C8W3PlInywSzTgudqoV7x7zQ)



## Configuring Appwrite

To proceed with the configuration, navigate to your Appwrite Cloud account dashboard, create a new project by entering the desired project name, and click **Create project,** as indicated below.

![A screenshot showing the create a new project on Appwrite](https://lh7-us.googleusercontent.com/0NeRH8dKVbvp7z_52z8M5XVDxMdEJcNJ2WltXANhPCF7k6TN56Mj9ZcpmygYrfebMIKnzh53wp7f1ACMuZOT5tOScOFohcSEcj8AJ-tFR-1kGoixdG3PviOzDbtvirfLNoXBFnoPw_klscha5x4m9-s)


After that, click on the **Functions** menu.

![A screenshot showing the Functions menu](https://lh7-us.googleusercontent.com/rMoMdRT-PqtJvOR-oyk5dqlMbQ7T8J1SAubC84XUkngvIqsdZOn1QXBWawnvUQ_QqgYdBtm9gD3o_-fhhiJFlutfCX2vMBgDhyvtnu7crQQh1DXFdl1lsxtcglS1kVveya6ZwqcYP_Au1mfRgKeF9O0)


Next, click the **templates** tab to view the available templates.

![A screenshot showing the Templates tab menu button](https://lh7-us.googleusercontent.com/uu7KaeZq9FcGks6qJArDNfx82T7X2Ra7qv5EJKyHwURE2Oum2ZzJzGutxW1ymU076I19WCuesGXHcOh_HGO7yra4zssXHzqNvIKTh63gwhf0XZQwepbHw4vWA5Z3pCp_RRSQHymaeDX7haonsnII3HI)


In the search field, enter **email contact form** to search for the template.

![A screenshot showing the template searching action](https://lh7-us.googleusercontent.com/rN9-cgWXD9hDFXH-7yueo5iXUay02lJlLJOd-3PHrW6lty76b5BL8hzwVwWjxINYCCyiKge56AqyYxdXAv6biy-0W36_Lal2Duxf78waXkheUbmp90C_APggR_PC_prtAw2fOi4qItw2tdaSNAxAcCA)


Afterward, click **Create function** to initiate the setup.

![A screenshot showing the Create function button](https://lh7-us.googleusercontent.com/yH8IcSi_2q4TCpBpe2x4ZC12QyO1XP41DqvUrPu3rZNkFpYIvRnxJ5ebVm1gLUVAApWjvyhtzcpR5QIHYVTMukXX4u4qTZ8X5QMGz8oF7L9W68W3Fi8pN_gXgMZg-yO4MLK5Wp4nuJfZi0jW_R5thXo)


**Setting up the email contact form**
This phase involves selecting a runtime environment, adding the credentials obtained from Mailgun, and setting up the GitHub repository. 

Select **Node.js - 16.0** as the runtime environment, then click **Next.**

![A screenshot showing the section to select the runtime environment for your email contact form](https://lh7-us.googleusercontent.com/CCJ6cauua5DG0B65Od3eTm9OI9pqbgWxOfkMxdG4H4ehM2VJvd1Ma7fjMVZIfffK_MZQeNTjuTJmgoLE0Z2068Zl7EeD8k3sy1ieES-SDy7Uf4gntC9xrfKUGZbf9gRSma7TBMaV0zqa9W9GiFmreo0)


After that, add the credentials obtained from Mailgun, as shown below.

![A screenshot showing the section to enter the credentials from Mailgun](https://lh7-us.googleusercontent.com/Xf5bdi-GsXZqRbLmp9zdM4lMXrC9r44wuUatPn_jASFX24mD6aZM1Y7opnuzGgOO93KumduVHszQ4jYUj_6e5s5ywtRvRkGJA-apH2pYpur_oCGc2ENM0l1VcYQ22Zp4TAvnX5dQBagjr-jugaqdRJI)


The template sends the email leads to the email address provided in the **SUBMIT_EMAIL** field. Add your preferred email to the field, and then click **Next**.


> When using Mailgun's sandbox environment, make sure the email address you provided in the **SUBMIT_EMAIL** field is authorized within Mailgun's system. For additional information, please visit this [link](https://help.mailgun.com/hc/en-us/articles/217531258-Authorized-Recipients?utm_source=hackmamba&utm_medium=hackmamba-blog). Also, note that emails sent using the sandbox environment are usually sent to the spam folder of the receiving email account.

**Connecting and setting up your GitHub repository**
At this point, you need to connect your GitHub repository to the platform. Appwrite pushes a copy of the template to your GitHub account, allowing you to personalize your version as required.

Click on the GitHub option as indicated below.

![](https://lh7-us.googleusercontent.com/IMkGAD9cc5Dd7PnV7bB4UzQojP9lSHFYFhWloZRo5gDHCY1uf9wpJYcy6zokHESW8VcCNkcsVv9JTlx6umQY-vW9Fl-LkLHiVfYp3eN9tM0uHYG1CoKbP2objdZU8Oi5NroEI_-8qXkK0WYZx7B0OP8)


If your GitHub account is not yet connected to Appwrite, you will be redirected to GitHub to complete the connection process.

![](https://lh7-us.googleusercontent.com/c_yGxEnkCnfCxYpUIvCion1D9rBDdNLS_pX13pA9eGwr4-WLipnryyjo67-V1iR3dAnnBtja3-AQYEasMqxQIIJ85NHTzlsEFulyzxL7NAmzWFWZbXZnohjZJMQK8xm_Rcbep3QOLtYu6rC0zOFlEtU)


Afterward, choose the repository that was created as part of the prerequisite.

If you already have a GitHub account connected to your Appwrite cloud account, select the **Add to existing repository** option instead of **Create a new repository** and click **Next**.

![A screenshot showing the add to existing repository option](https://lh7-us.googleusercontent.com/2K4r2EMrI3wz5WacjUoHhw15ZhTh90StyCJYFbV7ALjXIr0bFJueQhmyQHXNGrgI5XemHG6Ofr9B9u0-Eeuua1PpMZPlcpRNtMSrFW9o83JE4o0E0sKUp1jB1vX9u8Z6e4c2Dcup3jjZ5bePu_H5kpk)


Select the GitHub account and the repository of your choice, then click **Next**.

![](https://lh7-us.googleusercontent.com/0xOeXeEbxRMIlDyVIedwAhH5L2wqoKDSK138GXxiV_DViAVpxcDYDchHDY7zeR1T9HHAsuKRvEhSdZLCT-ezLNSV9XHDjycxIeT313kHk2946XO4oF4MNvdibzGHZ47XUOFcTwe-4On1qxj2GkXxQ8o)


After that, select the branch you want to use and add the root directory as **function/src,** then click **Create**.

![](https://lh7-us.googleusercontent.com/HOoNC_gi1tLQ3bgcZTCpuwXMCpknndtTd3xgUXIxvkY_KsbgoKsZf7Ggiz-HlttW2_m3KTyfmCS0RwPbbqtGGnFgul1PLuB72mVAfRPITSANHQwmJrdpWvQTfO1ysJcoHTvfTr_ZBNg8yVqVyfs-MNU)


Your email contact form template is set to deploy automatically once a copy of the template's code is successfully pushed to your repository. 

![A screenshot showing the content of the function on your GitHub repository](https://lh7-us.googleusercontent.com/V8N_TbbuekeAH3Bk5CWEadUQBg3L9TY8jlpLMkUhi3ni3l33zfyQRs0qXhJDniFLQrjJDR0Yhcr_g4J1r0iqImhUzV57nKkFC21fTsfrTqH1nbkz403Ry0zHAI9mvvAWacqTAtGEOtPCJZPXGlSzOEg)


Next, navigate to your Appwrite cloud dashboard to confirm the function was deployed successfully.

![A screenshot showing the successfully deployed function](https://lh7-us.googleusercontent.com/FrgVT0KuF3cgNQuXEUv7TC-MqWiKvzFTdyIlhLA_1rwGyEbIK_3NzmLwcNuOYlnnUPWmmuAfcu_fBhqeqCE-S5Q8TGtWGLFxOY1RatDHXf9wX38gLeg6g-TqeOpUknTIpiww_39JnIaXFR7tKqUHrPI)

## Setting up your leads collection Next.js website

For this step, you'll create your Next.js leads collection page and integrate Appwrite into the project.

To get started, navigate to your terminal and run the following command:

    npx create-next-app@latest leads_pages

This command prompts you to select other packages to be used by the project. Select the options as indicated in the screenshot below.

![A screenshot showing the selected options after running the create-project command](https://paper-attachments.dropboxusercontent.com/s_C6C9C51EF47D73CB8CC2DA4EEB9949FF62F13F6BF23DC92F40AC1C9A91C7F238_1702749843184_Screenshot+2023-12-16+at+18.51.14.png)


Once completed, run the command below to change the current working directory to the project's directory.

    cd leads_pages

Next, install your project's Appwrite SDK dependency by running this command:

    yarn add appwrite

Afterward, open the project on your code editor.

**Adding your environment variables.**
In the root directory of your project, create a file **.env,** then add the following:

    NEXT_PUBLIC_APPWRITE_FUNCTION_ID=<function_id>
    NEXT_PUBLIC_APPWRITE_BASE_URL=https://cloud.appwrite.io/v1
    NEXT_PUBLIC_APPWRITE_PROJECT_ID=<project_id>

You can retrieve your `<function_id>`  and `<project_id>` Appwrite credentials from the Appwrite dashboard. Replace the `<function_id>` and `<project_id>` with the corresponding credentials.

**Creating your leads collection custom hook**
To promote reusability and modularity, you'll need to create the logic that handles collecting and sending the user's input to Appwrite. 

To proceed, create a new folder, **hooks** in the **src/** directory. 
Next, create a file **useLeadCollector.tsx,** then add the following:

{% gist https://gist.github.com/Otrex/45ac69ede7a5a54be06e69d0b6c53a39
%}

In the snippet above, there are two states, which include:

- `request` state: This keeps track of the state of the asynchronous action when the collectLeads function is called.
- `form` state: This stores the value coming from the user input.

The **collectLeads** function handles requests to the Appwrite Function specified by the `process.env.NEXT_PUBLIC_APPWRITE_FUNCTION_ID` and `process.env.NEXT_PUBLIC_APPWRITE_FUNCTION_KEY`. The email contact form function requires the request body to be sent using the **content-type** `application/x-www-form-urlencoded.` Additionally, be sure to set the **referrer** header for proper functionality. 

Once the **collectLeads** function is called, the request state is toggled to **loading**, which changes the user interface to the loading interface. Next, the **throwErrorIfNot200** function handles errors returned from the Appwrite Function. If the request is successful, then the request state will be set to **completed**; otherwise, it will be set to **error**. After a 5-second delay on **error**, the state will be toggled to **idle**.

**Creating your page components**
To build the leads page, you'll be creating various components. Here's a breakdown:

- **Header:** This component houses the introductory content for the leads page.
- **About:** Offers additional information to capture the lead's interest.
- **JoinSteps:** Elaborates on the information discussed in the previous sections.
- **Footer:** Provides hyperlinks to different application sections and includes copywriter information.
- **Form:** An abstracted form interface for user interaction.
- **Contact:** The crucial section for collecting leads.

To organize your project, navigate to the **src/** directory and create a folder named **components** to store these page components.

Starting with the **Header** component, create a file **Header.tsx** in the **components** folder, then add the following code snippet.

{% gist https://gist.github.com/Otrex/a8dc4c170e8826757cef86fa0e05b6a0 %}


Next, create the About component by repeating the steps above, create the **About.tsx** file, and add the following:

{% gist https://gist.github.com/Otrex/d23b913412e12c7db73a205b26f2393b %}


After that, create the **Footer** component by creating the **Footer.tsx** file and adding the following:

{% gist https://gist.github.com/Otrex/109d61f4d102aab6ed548f95da045f1b
%}

Moving on to the **JoinSteps** component, create the **JoinSteps.tsx** file and add the code snippet below.

{% gist https://gist.github.com/Otrex/cd1014964247e863206aac19c2908a42
%}

Next, let's create the Form component. Start by creating a folder named **partials** within the **components** directory. Inside this **partials** folder, create a file **Form.tsx**. Copy and paste the following snippet into the **Form.tsx** file:

{% gist https://gist.github.com/Otrex/537cf99f68ae6ae831f71f9930e6bd99
%}

Last but not least is the **Contact** component. Create the **Contact.tsx** file and add the following:

{% gist https://gist.github.com/Otrex/effa073575c4dcaac264f12bb77bd906 %}

In the provided snippet, the Form component is rendered based on the value of the `request` state. If the request state is **idle**, then the Form component is rendered. Similarly, other request states are handled likewise.

The use of "use client" signifies that the Contact component is client-side. This is necessary because, by default, Next.js sets all components to server-side.

**Adding the components to the leads page**
Once the components are created successfully, you’ll need to add them to the leads landing page. 
To do so, open the **page.tsx** file in the **src/app** directory and add the following:
```ts
import About from "@/components/About";
import Contact from "@/components/Contact";
import Footer from "@/components/Footer";
import Header from "@/components/Header";
import JoinSteps from "@/components/JoinSteps";
export default function Home() {
  return (
    <main className="min-h-screen text-center px-24 py-10">
      <div className="max-w-[1000px] mx-auto pb-24 bg-white">
        <Header />
        <About />
        <JoinSteps />
        <Contact />
        <Footer />
      </div>
    </main>
 );
}
```
The above snippet renders the components for the user to interact with.

**Testing your leads page**
To display the page on the browser, navigate to your project's terminal and run the following:

    yarn dev

This command sets up a local server environment from the project.

![A screenshot showing the running environment for the project](https://paper-attachments.dropboxusercontent.com/s_C6C9C51EF47D73CB8CC2DA4EEB9949FF62F13F6BF23DC92F40AC1C9A91C7F238_1702958546594_Screenshot+2023-12-19+at+05.02.05.png)


Extract the URL (http://localhost:3000) from your terminal and visit the page on your browser. 

![](https://paper-attachments.dropboxusercontent.com/s_C6C9C51EF47D73CB8CC2DA4EEB9949FF62F13F6BF23DC92F40AC1C9A91C7F238_1702958609837_Screenshot+2023-12-19+at+05.03.17.png)


Here is a demonstration of the working system.

{% embed https://www.loom.com/share/77f6c30646764888b3f5b7e7b5f0a675?sid=f8609305-ab81-420b-94c9-f770ef9ef5ce %}

## Conclusion

By combining the capabilities of Appwrite and Mailgun, you can quickly set up your email marketing leads collector, streamline lead collection, and ultimately launch more successful marketing campaigns. The user-friendly setup and detailed instructions make this tutorial accessible even for those with minimal JavaScript and Git knowledge.

## Resources
- [How to automate Appwrite Functions deployment with GitHub](https://dev.to/hackmamba/how-to-automate-appwrite-functions-deployment-with-github-95e)
- [Appwrite Function documentation](https://appwrite.io/docs/products/functions?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Mailgun documentation](https://documentation.mailgun.com/en/latest/?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Git](https://docs.github.com/en)[H](https://docs.github.com/en)[ub documentation](https://docs.github.com/en)
- [Next.js documentation](https://nextjs.org/docs/)