Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ Our Go runtime (just like our other runtimes) has been developed by our team and

## Event-driven nature

Appwrite Functions can be executed by various types of events, which allows you to integrate them into your applications in many different ways. These events include all HTTP actions (to consume like a REST API), CRON schedules (to run them on set time periods), and any events across the various Appwrite products in your project (for example, user creation, document deletion, or file upload).
Appwrite Functions can be executed by various types of events, which allows you to integrate them into your applications in many different ways. These events include all HTTP actions (to consume like a REST API), CRON schedules (to run them on set time periods), and any events across the various Appwrite products in your project (for example, user creation, row deletion, or file upload).

## Global environment variables

Aside from environment variables at the function level, Appwrite also allows you to environment variables at the project level so that they can be shared across multiple functions in a single project.
Aside from environment variables at the function level, Appwrite also allows you to environment variables at the project level so that they can be shared across multiple functions in a single project.

Comment on lines +32 to 33
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix grammar in “Global environment variables” section.

“…allows you to environment variables…” → “…allows you to define environment variables…”.

-Aside from environment variables at the function level, Appwrite also allows you to environment variables at the project level so that they can be shared across multiple functions in a single project.
+Aside from environment variables at the function level, Appwrite also allows you to define environment variables at the project level so they can be shared across multiple functions in a single project.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Aside from environment variables at the function level, Appwrite also allows you to environment variables at the project level so that they can be shared across multiple functions in a single project.
Aside from environment variables at the function level, Appwrite also allows you to define environment variables at the project level so they can be shared across multiple functions in a single project.
🤖 Prompt for AI Agents
In src/routes/blog/post/3-things-you-can-build-with-go-runtime/+page.markdoc
around lines 32-33, the sentence currently reads "Appwrite also allows you to
environment variables at the project level..."; change it to "Appwrite also
allows you to define environment variables at the project level so that they can
be shared across multiple functions in a single project." — replace the
incorrect phrase "allows you to environment variables" with "allows you to
define environment variables" and ensure the sentence punctuation and spacing
remain correct.

## Permissions system

Expand All @@ -51,7 +51,7 @@ Once your function is set up, we can try some examples:

## Example 1: AI Chatbot using GPT-3.5

The first example is a simple chatbot function that accepts a prompt in the request body and returns an answer in the response from the ChatGPT API.
The first example is a simple chatbot function that accepts a prompt in the request body and returns an answer in the response from the ChatGPT API.

To do this, we must first add the `go-openai` dependency to our project’s `mod` file.

Expand Down Expand Up @@ -138,7 +138,7 @@ You can then deploy this function using the `appwrite deploy function` command.

## Example 2: HTML Resume

The second example is an online HTML-based resume that you can deliver online through the function.
The second example is an online HTML-based resume that you can deliver online through the function.

For this, the first thing we do is create a `static` directory in the function folder and add a file, `resume.html` with the contents of our resume. You can [copy our template](https://github.com/appwrite-community/go-function-examples/blob/main/functions/go-resume/static/resume.html) if you’d like.

Expand Down Expand Up @@ -178,44 +178,44 @@ You can then deploy this function using the `appwrite deploy function` command.

## Example 3: URL Shortener

The third example is a personal URL shortener that stores your shortened URL path and long URL in an Appwrite Database and redirects the consumer to the appropriate long URL on pinging the shortened URL.
The third example is a personal URL shortener that stores your shortened URL path and long URL in an Appwrite Database and redirects the consumer to the appropriate long URL on pinging the shortened URL.

To build this function, create a `services` directory in the function folder and add a file `setup.go`. Here, we will add the necessary functions to initialize our Appwrite database.

```go
package services

import (
"github.com/appwrite/sdk-for-go/databases"
"github.com/appwrite/sdk-for-go/tablesdb"
"github.com/appwrite/sdk-for-go/permission"
"github.com/open-runtimes/types-for-go/v4/openruntimes"
)

func DoesDatabaseExist(dbs databases.Databases, dbId string) bool {
func DoesDatabaseExist(dbs tablesdb.TablesDB, dbId string) bool {
_, err := dbs.Get(dbId)
if err != nil {
return false
}
return true
}

func DoesCollectionExist(dbs databases.Databases, dbId string, collId string) bool {
_, err := dbs.GetCollection(dbId, collId)
func DoesTableExist(dbs tablesdb.TablesDB, dbId string, collId string) bool {
_, err := dbs.GetTable(dbId, collId)
if err != nil {
return false
}
return true
}

func DoesAttributeExist(dbs databases.Databases, dbId string, collId string, attribId string) bool {
_, err := dbs.GetAttribute(dbId, collId, attribId)
func DoesColumnExist(dbs tablesdb.TablesDB, dbId string, collId string, attribId string) bool {
_, err := dbs.GetColumn(dbId, collId, attribId)
if err != nil {
return false
}
return true
}

func InitialiseDatabase(Context openruntimes.Context, dbs databases.Databases, dbId string, collId string) {
func InitialiseDatabase(Context openruntimes.Context, dbs tablesdb.TablesDB, dbId string, collId string) {
doesDbExist := DoesDatabaseExist(dbs, dbId)
if !doesDbExist {
dbs.Create(
Expand All @@ -224,24 +224,24 @@ func InitialiseDatabase(Context openruntimes.Context, dbs databases.Databases, d
)
}

doesCollExist := DoesCollectionExist(dbs, dbId, collId)
doesCollExist := DoesTableExist(dbs, dbId, collId)
if !doesCollExist {
dbs.CreateCollection(
dbs.CreateTable(
dbId,
collId,
"URLs",
dbs.WithCreateCollectionPermissions([]string{permission.Read("any")}),
dbs.WithCreateTablePermissions([]string{permission.Read("any")}),
)
}

doesAttribExist := DoesAttributeExist(dbs, dbId, collId, "longUrl")
doesAttribExist := DoesColumnExist(dbs, dbId, collId, "longUrl")
if !doesAttribExist {
dbs.CreateUrlAttribute(
dbs.CreateUrlColumn(
dbId,
collId,
"longUrl",
true,
dbs.WithCreateUrlAttributeArray(false),
dbs.WithCreateUrlColumnArray(false),
)
}
}
Expand Down Expand Up @@ -276,12 +276,12 @@ func Main(Context openruntimes.Context) openruntimes.Response {
appwrite.WithKey(Context.Req.Headers["x-appwrite-key"]),
)

databases := appwrite.NewDatabases(client)
tablesDB := appwrite.NewTablesDB(client)

dbId := "urlDatabase"
collId := "urlCollection"
collId := "urlTable"

services.InitialiseDatabase(Context, *databases, dbId, collId)
services.InitialiseDatabase(Context, *tablesDB, dbId, collId)

if Context.Req.Method == "POST" {
var requestBody RequestBody
Expand All @@ -294,7 +294,7 @@ func Main(Context openruntimes.Context) openruntimes.Response {
}, Context.Res.WithStatusCode(400))
}

_, err = databases.CreateDocument(
_, err = tablesDB.CreateRow(
dbId,
collId,
requestBody.ShortId,
Expand Down Expand Up @@ -326,15 +326,15 @@ func Main(Context openruntimes.Context) openruntimes.Response {

shortId := path[1:]

document, err := databases.GetDocument(dbId, collId, shortId)
row, err := tablesDB.GetRow(dbId, collId, shortId)

if err != nil {
Context.Error(err)
return Context.Res.Text("URL not found", Context.Res.WithStatusCode(404))
}

var responseBody ResponseBody
document.Decode(&responseBody)
row.Decode(&responseBody)

return Context.Res.Redirect(responseBody.LongUrl, Context.Res.WithStatusCode(302))
}
Expand All @@ -345,7 +345,7 @@ func Main(Context openruntimes.Context) openruntimes.Response {

You can then deploy this function using the `appwrite deploy function` command.

After deployment, go to the Settings tab on the Function page in your Appwrite project and enable the following scopes for the dynamic API key: `databases.read`, `databases.write`, `collections.read`, `collections.write`, `attributes.read`, `attributes.write`, `documents.read`, `documents.write`,
After deployment, go to the Settings tab on the Function page in your Appwrite project and enable the following scopes for the dynamic API key: `databases.read`, `databases.write`, `tables.read`, `tables.write`, `columns.read`, `columns.write`, `rows.read`, `rows.write`,

# More resources

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ One such integration you can implement using Appwrite Functions is **Searching**

# Setting up the Template

Meilisearch is a flexible and powerful user-focused search engine that can be added to any website or application. The purpose of this function template is to sync documents in an Appwrite database collection to a Meilisearch index. Using this function template, users can explore, search, and retrieve information from the connected database collection. Through this template, documents from the Appwrite collection are systematically indexed within Meilisearch.
Meilisearch is a flexible and powerful user-focused search engine that can be added to any website or application. The purpose of this function template is to sync rows in an Appwrite database table to a Meilisearch index. Using this function template, users can explore, search, and retrieve information from the connected database table. Through this template, rows from the Appwrite table are systematically indexed within Meilisearch.

To use the function, you need the following set of keys:

- `APPWRITE_KEY` - API Key to talk to Appwrite backend APIs.To generate API Keys you can follow the documentation [here](https://appwrite.io/docs/getting-started-for-server#apiKey)
- `APPWRITE_ENDPOINT` - To get the Appwrite endpoint, you need to go to [Appwrite](https://cloud.appwrite.io/) and find it under “Settings”
- `APPWRITE_DATABASE_ID` - The ID of the Appwrite database that contains the collection to sync. You can find the documentation [here](https://appwrite.io/docs/databases).
- `APPWRITE_COLLECTION_ID` - The ID of the collection in the Appwrite database to sync.
- `APPWRITE_DATABASE_ID` - The ID of the Appwrite database that contains the table to sync. You can find the documentation [here](https://appwrite.io/docs/databases).
- `APPWRITE_TABLE_ID` - The ID of the table in the Appwrite database to sync.

To use Meilisearch, you can either self-host it using the command 👇

```bash
curl -L [https://install.meilisearch.com](https://install.meilisearch.com/) | sh
```

Or use [Meilisearch Cloud](https://www.meilisearch.com/cloud). For this example, we will assume that you are using Meilisearch Cloud.
Or use [Meilisearch Cloud](https://www.meilisearch.com/cloud). For this example, we will assume that you are using Meilisearch Cloud.

Here’s the keys you need:

Expand All @@ -40,7 +40,7 @@ Here’s the keys you need:

![Overview Meilisearch](/images/blog/add-a-search-function-to-your-app/functions.png)

- `MEILISEARCH_ADMIN_API_KEY` - This is the admin API key for Meilisearch. You will find it in the Meilisearch Console under “API Key”.
- `MEILISEARCH_ADMIN_API_KEY` - This is the admin API key for Meilisearch. You will find it in the Meilisearch Console under “API Key”.
- `MEILISEARCH_SEARCH_API_KEY` - This is the API Key for Meilisearch search operations. To get this, you need you create a new index from the Meilisearch Console. Once created you will find it under `Overview` as `Default Search API Key`


Expand All @@ -50,20 +50,20 @@ Here’s the keys you need:

![Keys](/images/blog/add-a-search-function-to-your-app/connect.png)

- `MEILISEARCH_INDEX_NAME` - Name of the Meilisearch index to which the documents will be synchronized. For e.g, in the above picture, the Index name is `Newindex`. You can also find it under `Settings` as `Index Name`.
- `MEILISEARCH_INDEX_NAME` - Name of the Meilisearch index to which the rows will be synchronized. For e.g, in the above picture, the Index name is `Newindex`. You can also find it under `Settings` as `Index Name`.


## Preparing the Function

The function template syncs documents in an Appwrite database collection to a Meilisearch index. It should get you up and running, but you will need to add real data to build a useful search index.
The function template syncs rows in an Appwrite database table to a Meilisearch index. It should get you up and running, but you will need to add real data to build a useful search index.

If you want to see the source code, you can find it on our [templates GitHub repository](https://github.com/appwrite/templates/tree/main/node/sync-with-meilisearch). Now, let’s navigate to our functions page on **[Appwrite](https://cloud.appwrite.io/)**. From there, we will select the **Templates** tab, search for and select the **Sync with Meilisearch** function template.



![templates](/images/blog/add-a-search-function-to-your-app/templates.png)

The function requires `APPWRITE_API_KEY`, `APPWRITE_DATABASE_ID`, `APPWRITE_COLLECTION_ID` , `MEILISEARCH_ENDPOINT`, `MEILISEARCH_ADMIN_API_KEY`, `MEILISEARCH_SEARCH_API_KEY`, `MEILISEARCH_INDEX_NAME`. Once you have added them you can proceed to the Connect step.
The function requires `APPWRITE_API_KEY`, `APPWRITE_DATABASE_ID`, `APPWRITE_TABLE_ID` , `MEILISEARCH_ENDPOINT`, `MEILISEARCH_ADMIN_API_KEY`, `MEILISEARCH_SEARCH_API_KEY`, `MEILISEARCH_INDEX_NAME`. Once you have added them you can proceed to the Connect step.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Unify API key env var name.

You use APPWRITE_KEY above and APPWRITE_API_KEY here. Pick one and use consistently (docs/Console show “API Key”).

-The function requires `APPWRITE_API_KEY`, `APPWRITE_DATABASE_ID`, `APPWRITE_TABLE_ID` , `MEILISEARCH_ENDPOINT`, ...
+The function requires `APPWRITE_KEY`, `APPWRITE_DATABASE_ID`, `APPWRITE_TABLE_ID`, `MEILISEARCH_ENDPOINT`, ...

Or replace earlier mention with APPWRITE_API_KEY—just be consistent across the post and template.


🏁 Script executed:

#!/bin/bash
file="src/routes/blog/post/add-a-search-function-to-your-app/+page.markdoc"

echo "Searching for APPWRITE_KEY..."
rg -n "APPWRITE_KEY" "$file" || echo "No occurrences of APPWRITE_KEY found."

echo
echo "Searching for APPWRITE_API_KEY..."
rg -n "APPWRITE_API_KEY" "$file" || echo "No occurrences of APPWRITE_API_KEY found."

Length of output: 510


Unify Appwrite API key env var name
Replace APPWRITE_API_KEY with APPWRITE_KEY in the env var list (line 66) to match the earlier definition at line 23.

-The function requires `APPWRITE_API_KEY`, `APPWRITE_DATABASE_ID`, `APPWRITE_TABLE_ID`, …
+The function requires `APPWRITE_KEY`,           `APPWRITE_DATABASE_ID`, `APPWRITE_TABLE_ID`, …
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
The function requires `APPWRITE_API_KEY`, `APPWRITE_DATABASE_ID`, `APPWRITE_TABLE_ID` , `MEILISEARCH_ENDPOINT`, `MEILISEARCH_ADMIN_API_KEY`, `MEILISEARCH_SEARCH_API_KEY`, `MEILISEARCH_INDEX_NAME`. Once you have added them you can proceed to the Connect step.
The function requires `APPWRITE_KEY`, `APPWRITE_DATABASE_ID`, `APPWRITE_TABLE_ID`, `MEILISEARCH_ENDPOINT`, `MEILISEARCH_ADMIN_API_KEY`, `MEILISEARCH_SEARCH_API_KEY`, `MEILISEARCH_INDEX_NAME`. Once you have added them you can proceed to the Connect step.
🤖 Prompt for AI Agents
In src/routes/blog/post/add-a-search-function-to-your-app/+page.markdoc around
line 66 (reference earlier definition at line 23), update the environment
variable list to use APPWRITE_KEY instead of APPWRITE_API_KEY so it matches the
previously defined name; change the single env var entry and verify any other
occurrences in this file use APPWRITE_KEY for consistency.


Select **Create a new repository** (this will generate a GitHub repository for you with the function), and leave the production branch and root settings as default to create this function.

Expand All @@ -84,13 +84,13 @@ Visit the **Domains** tab on the function page and copy the domain URL to test
We’ve added search functionality to our app and opened up many possibilities to improve the experience of our app’s users.

How can the *template* be extended ?
- Using events to automatically index new collections
- Using events to automatically index new tables
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

"tables" → "rows" (semantic fix).

Events will index new/changed rows, not new tables.

- Using events to automatically index new tables
+ Using events to automatically index new rows
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- Using events to automatically index new tables
- Using events to automatically index new rows
🤖 Prompt for AI Agents
In src/routes/blog/post/add-a-search-function-to-your-app/+page.markdoc around
line 87, the heading/text uses "tables" but is semantically incorrect; change
"Using events to automatically index new tables" to "Using events to
automatically index new rows" (or update any nearby occurrences of "tables" to
"rows" where the intent is indexing row-level changes) so the content accurately
states that events index new/changed rows rather than new tables.

- Using weights and other meilisearch features to optimise search such as excluding certain fields from indexing

Some examples are:

1. **Real-time Data Exploration:** It can be used to provide real-time search capabilities for datasets and data streams, allowing users to explore and analyze data in real-time.
2. **Content Management Systems:** The function template can be integrated into content management systems (CMS) to facilitate efficient content retrieval for editors and site visitors.
2. **Content Management Systems:** The function template can be integrated into content management systems (CMS) to facilitate efficient content retrieval for editors and site visitors.

Be sure to check out the other available Function Templates. We’ve created multiple that could be of use in your projects. You can find the [templates GitHub repository here](https://github.com/appwrite/templates).

Expand Down
Loading
Loading