How to email PDF results with Appwrite cloud, Mailgun and Flutter
Tags: cloud, appwrite, flutter, programming
Published: 2023-04-26 14:29:38

The **cloud:** a beautiful firmament containing "a visible mass of condensed water vapor floating in the atmosphere, typically high above the general level of the ground." Well, that’s what the Oxford Dictionary said, but the cloud is also a beautiful thing for developers. The cloud is a place of infinite possibilities and boundless opportunities, containing a global network of servers, all with a unique function.

That brings us to Appwrite. Isn't it great to have all the backend capabilities pushed to the web? With the Appwrite cloud, one can access all the standard backend features without installing anything. This tutorial demonstrates how to create and deploy an Appwrite function to email PDF results with Mailgun and Flutter.

- **What we are going to cover:**
    - How to create an Appwrite function
    - How to deploy the function to the cloud and locally (Appwrite cloud is still in private beta)
    - How to execute the function from the client side using the client SDK


## Prerequisites

To folllow along with this tutorial, the following are required:

- [Xcode](https://developer.apple.com/xcode/) (with developer account for Mac users).
- iOS Simulator, Android Studio, or Chrome web browser to run the application.
- [Appwrite CLI](https://appwrite.io/docs/command-line?utm_source=hackmamba&utm_medium=hackmamba-blog) installed.
- Appwrite [cloud](https://appwrite.io/cloud?utm_source=hackmamba&utm_medium=hackmamba-blog) access. It is currently in beta testing.
- Mailgun account access. [Here](https://signup.mailgun.com/new/signup?utm_source=hackmamba&utm_medium=hackmamba-blog) is a link to sign up.
- An Appwrite instance running on either Docker, [DigitalOcean droplet](https://marketplace.digitalocean.com/apps/appwrite), or [Gitpod](https://gitpod.io/#https://github.com/appwrite/integration-for-gitpod). You’ll need this because we will also show how to deploy the function locally.


## Account and project setup

In this section, we’ll cover how to set up the following:

1. Mailgun account
2. Appwrite cloud account
3. Appwrite project

**Setting up a Mailgun account**
To sign up for Mailgun, follow these steps:

- Start by [signing](https://signup.mailgun.com/new/signup?utm_source=hackmamba&utm_medium=hackmamba-blog) up for a new account
- Fill out the signup form (name, email address, password) and add the credit card information required
- Click on the `Create Account` button to submit the form
- Check your email inbox for a confirmation message from Mailgun
![Mailgun signup](https://paper-attachments.dropboxusercontent.com/s_43DBDC09534E0739E7C8C10CC0F42B993011AB266FDB05C08DF6644BC9354199_1679344138324_Screenshot+278.png)

- Follow the instructions in the email to verify the account and complete the signup process.

After completing the signing up and verification processes, we must add and verify our domain to send emails. Here are some places to purchase a domain:

- [Godaddy](https://sso.godaddy.com/v1/login?realm=idp&app=www&path=%2Fen-uk)
- [Hostinger](https://www.hostinger.com/)
- [nameCheap](https://www.namecheap.com/)

Next, follow the steps below to verify the DNS settings.

1. After adding the domain or subdomain, open your DNS provider and add the **two TXT DNS records** provided.
2. Next, add the **CNAME** record to allow Mailgun to track **clicks** and **opens****.**
3. Finally,  add the MX records.

Once we’ve added the records, our domain will be verified.

**Setting up an Appwrite cloud account**
To sign up for Appwrite, follow these steps:

- After registering for the Appwrite cloud beta, you will receive an invite via email.
- Click on the invite link and follow the registration process. That’s it!

**Setting up the Appwrite project**
After creating a cloud account, we'll create a platform and an Appwrite project. Let's start by doing the following:


> Note: This process is the same both locally and on the cloud


- For the Appwrite cloud, you’ll be redirected to the `Create project` page after successful sign-in, but locally, we will need to load up the Appwrite console. Thus, open your browser and enter the `IP address or hostname`.
- Next, choose the `Create Project` option and fill in the `name and ID` (ID can be automatically generated).
![Create database](https://paper-attachments.dropboxusercontent.com/s_7604AE644359B8A42B0CA41928E7FA82C1E3181DC0A806189A51D7006C234F5A_1675133088225_Screenshot+262.png)

- Next, we will create a collection to hold the URL string to an online PDF file. Thus, we will create one string attribute called `url`.


![Create collection](https://paper-attachments.dropboxusercontent.com/s_7604AE644359B8A42B0CA41928E7FA82C1E3181DC0A806189A51D7006C234F5A_1675133157888_Screenshot+263.png)

| url                                                                |
| ------------------------------------------------------------------ |
| https://www.w3.org/WAI/WCAG21/working-examples/pdf-table/table.pdf |


- Finally, set the collection-level `CRUD` permission for both collections to `Any` and select all the options.
![Set crud permission](https://paper-attachments.dropboxusercontent.com/s_7604AE644359B8A42B0CA41928E7FA82C1E3181DC0A806189A51D7006C234F5A_1675133182874_Screenshot+264.png)
![Set crud permission 2](https://paper-attachments.dropboxusercontent.com/s_7604AE644359B8A42B0CA41928E7FA82C1E3181DC0A806189A51D7006C234F5A_1675133218819_Screenshot+265.png)



## Creating an Appwrite project

Next, we’ll create two projects to achieve our desired result. For the first project, we will create an Appwrite function using the Appwrite CLI (command line interface). The second project will be a Flutter project to communicate with the function created earlier after deployment.

Thus, run the command below to create two directories for the projects, respectively:


```javascript
mkdir mailgun_function && mkdir mailgun_flutter_app
```

**Project** **o****ne (Creating a dart Appwrite function)**
We will start by enabling the Dart runtime in Appwrite, as it is not naturally included. Head to the default Appwrite directory (when installing locally) and make some edits to the `.env` file. Add `dart 2-17` to the `_APP_FUNCTIONS_RUNTIMES` and `_APP_FUNCTIONS_ENVS` variables like this:


```javascript
_APP_FUNCTIONS_RUNTIMES=node-16.0,php-8.0,python-3.9,ruby-3.0,dart-2.17
_APP_FUNCTIONS_ENVS=node-16.0,php-7.4,python-3.9,ruby-3.0,dart-2.17
```


![Adding dart SDK](https://paper-attachments.dropboxusercontent.com/s_43DBDC09534E0739E7C8C10CC0F42B993011AB266FDB05C08DF6644BC9354199_1679334380585_Screenshot+281.png)


After making the changes, we will run the command below from the default Appwrite directory in our terminal:


```javascript
docker compose up -d --force-recreate
```


> Note:  Make sure Docker is running before inputing the command above.

Next, we will head to the `mailgun_function` folder and log into the Appwrite server using its CLI.



```javascript
appwrite login
```

You will receive a prompt to add the email and password you used when registering the local instance. Next, create a new project or specify an existing one. We can do that using the following command:


```javascript
appwrite init project
```

We will then follow the prompt on how to set the project up.

Next, we must create an Appwrite function. Therefore, we will do that by running the command:


```javascript
appwrite init function
```

Similarly to the previous commands, you will receive a prompt directing you on how to set this up. Once done setting the function up, the command creates a starter project.

![Function folder](https://paper-attachments.dropboxusercontent.com/s_43DBDC09534E0739E7C8C10CC0F42B993011AB266FDB05C08DF6644BC9354199_1679335502671_Screenshot+282.png)


Now, head to the `pubspec.yaml` file and add the `http` package.


```javascript
http: ^0.13.3
```


![Depedencies](https://paper-attachments.dropboxusercontent.com/s_43DBDC09534E0739E7C8C10CC0F42B993011AB266FDB05C08DF6644BC9354199_1679337703317_Screenshot+284.png)


In the `main.dart` file, replace the existing code with the one below:

{% embed  https://gist.github.com/muyiwexy/d4396246c2847aeed0745cbdb429a5bb %}

The snippet above does the following:

- Imports the required dependencies
- Requests custom payload data when executing the function
- Passes the payload using `Uri.parse()`, converts it back to a file, and stores it in temporary storage
- Configures `http` mail client by specifying the **API Key**, and parses the domain URL, to emails, from emails, email content, and email subject
- Sends the email using the configured client

**Deploy the function**
For this tutorial, we will show how to deploy the functions both locally and on the cloud.


- **Cloud**

We need to create a function on the Appwrite cloud console to deploy on the cloud. Thus, head to the function section, click `Create Function`, fill in the `name` and `ID`, and select the preferred `runtime` (dart — 2.17). 


![Create function](https://paper-attachments.dropboxusercontent.com/s_43DBDC09534E0739E7C8C10CC0F42B993011AB266FDB05C08DF6644BC9354199_1679782621699_Screenshot+285.png)

Next, select `Create Deployment` and head to the manual deployment. In the manual deployment, we will need to add a `tar.gz` fileand specify the `entrypoint` for our project. So, head to the folder containing the `pubspec.lock` file and run the command below:

![Create deployment](https://paper-attachments.dropboxusercontent.com/s_43DBDC09534E0739E7C8C10CC0F42B993011AB266FDB05C08DF6644BC9354199_1679782708176_Screenshot+286.png)



```javascript
tar -czf code.tar.gz --exclude code.tar.gz .
```


This command will create a `tar.gz` file that can be uploaded to Appwrite. So we will head back to the cloud console, specify the entry point as `lib/main.dart`, then add the `tar.gz` file and click `create`.

- **Locally**

We can do this by navigating to the folder containing the `appwrite.json` file and then running the command below:


```javascript
appwrite deploy function
```


![Local deployment](https://paper-attachments.dropboxusercontent.com/s_43DBDC09534E0739E7C8C10CC0F42B993011AB266FDB05C08DF6644BC9354199_1679340096452_appwrite+deploy.webp)



> Note: Within the function section, head to the settings section and specify `Execute Access` to `any`.

**Project two (Creating a Flutter** **application)**

Head to the second folder we created earlier and run the following command


```javascript
git clone https://github.com/muyiwexy/Appwrite_Cloud_MailGun.git && cd Appwrite_Cloud_MailGun
```

This command will clone a flutter template within the current directory and change it to the `Appwrite_Cloud_MailGun` directory.

The template above contains the following:

- The `main.dart` file, which contains:
    - A button widget to execute the function on the client side
    - A `snackbar` to indicate success or failure
- The `utils.dart` file, which contains a `json` serialize to map the `JSON` object received from the database to a model class

Next, we must install and connect our Flutter application to Appwrite.

First, add `Appwrite` to the dependencies section of the `pubspec.yaml` file, like the image below:


![Dependencies](https://paper-attachments.dropboxusercontent.com/s_041BDED8DAB440A4B6CCF96EB23FFFC68E40117CE3B40D930FE7EEC37F7160D4_1675028904318_Screenshot+65.png)


Alternatively, we can use a terminal by typing the command below:


```javascript
flutter pub add appwrite
```

Here’s how to connect a Flutter project to Appwrite for Android and iOS devices.


- **iOS**

First, obtain the `bundle ID` by navigating to the `project.pbxproj` file (`ios > Runner.xcodeproj > project.pbxproj`) and searching for the `PRODUCT_BUNDLE_IDENTIFIER`.

Next, head to the `Runner.xcworkspace` folder in the application’s iOS folder in the project directory on [Xcode](https://developer.apple.com/xcode/). To select the runner target, choose the **Runner** project in the Xcode project navigator and find the `Runner target`. Next, select `General and IOS 11.0` in the deployment info section as the target.


![iOS](https://paper-attachments.dropboxusercontent.com/s_973FE6248EEDD7529E7A11435E297ADACD4E1B7483EB53A8303EEED9486C6A4E_1677590542497_file.jpeg)



- **Android**

For Android, copy the XML script below and paste it below the activity tag in the `Androidmanifest.xml` file (to find this file, head to `android > app > src > main`).

{% embed https://gist.github.com/muyiwexy/f1a0f6c59329d25d37c353f34a4fa9aa %}

> Note: change [PROJECT-ID] to the ID you used when creating the Appwrite project.

We will also need to set up a platform within the Appwrite console. Follow the steps below to do so.

- Within the Appwrite console, select `Create Platform` and choose `Flutter` for the platform type.
- Specify the operating system: in this case, Android.
- Finally, provide the application and package names (found in the app-level `build.gradle` file).


![Create platform](https://paper-attachments.dropboxusercontent.com/s_7604AE644359B8A42B0CA41928E7FA82C1E3181DC0A806189A51D7006C234F5A_1675132261190_Screenshot+259.png)
![Create platform](https://paper-attachments.dropboxusercontent.com/s_7604AE644359B8A42B0CA41928E7FA82C1E3181DC0A806189A51D7006C234F5A_1675132261213_Screenshot+260.png)


**Running the Flutter project**
Once we are done with the above, run the following command:


```javascript
flutter pub get
```

This command obtains all the dependencies in the `pubspec.yaml` file. Next, run the `flutter run` command to run the project on any desired platform.

Here is the result of the code:

![Result](https://paper-attachments.dropboxusercontent.com/s_43DBDC09534E0739E7C8C10CC0F42B993011AB266FDB05C08DF6644BC9354199_1679343517861_ezgif.com-video-to-gif+4.gif)



## Conclusion

In conclusion, emailing PDF results with Appwrite Cloud, Mailgun, and Flutter is a straightforward process that can be accomplished with simple steps. By using [Appwrite Cloud](https://appwrite.io/cloud?utm_source=hackmamba&utm_medium=hackmamba-blog) to generate and retrieve PDF results, Mailgun to send email notifications, and Flutter to handle the user interface and app logic, developers can easily create a robust and efficient system for emailing PDF results to users. 


## Resources
- [Appwrite official documentation](https://appwrite.io/docs?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Appwrite Flutter SDK](https://appwrite.io/docs/getting-started-for-flutter?utm_source=hackmamba&utm_medium=hackmamba-blog)
- [Appwrite Function](https://appwrite.io/docs/functions?utm_source=hackmamba&utm_medium=hackmamba-blog)