From 8c89c3284b5347b15a6414c09e9079e21450b412 Mon Sep 17 00:00:00 2001 From: zeus2611 <28503393+zeus2611@users.noreply.github.com> Date: Mon, 2 Feb 2026 15:33:28 +0000 Subject: [PATCH 1/3] docs: update README table --- README.md | 93 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 907089f1..e6490a66 100644 --- a/README.md +++ b/README.md @@ -10,52 +10,53 @@ Templates for [Appwrite](https://appwrite.io/) Functions. These templates can be # List of Templates -| Template | Node.js | Python | PHP | Node.js (TypeScript) | Bun | Dart | Deno | Ruby | Kotlin | python-ml | C++ | .NET | Java | Swift | -| -------------------------------------- | ----------------------------------------------- | --------------------------------- | ------------------------------ |--------------------------------------------| ------------------------------ | ------------------------------ | ------------------------------- | ------------------------------- | --------------------------------- | --------------------------------------- | ---------------- | ------------------- | ----------------- | ------------------ | -| Starter | [✅](node/starter) | [✅](python/starter) | [✅](php/starter) | [✅](node-typescript/starter) | [✅](bun/starter) | [✅](dart/starter) | [✅](deno/starter) | [✅](ruby/starter) | [✅](kotlin/starter) | [✅](python-ml/starter) | [✅](cpp/starter) | [✅](dotnet/starter) | [✅](java/starter) | [✅](swift/starter) | -| Sync with Meilisearch | [✅](node/sync-with-meilisearch) | [✅](python/sync_with_meilisearch) | [✅](php/sync-with-meilisearch) | [✅](node-typescript/sync-with-meilisearch) | [✅](bun/sync-with-meilisearch) | 🏗️ | [✅](deno/sync-with-meilisearch) | [✅](ruby/sync_with_meilisearch) | [✅](kotlin/sync-with-meilisearch) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| WhatsApp with Vonage | [✅](node/whatsapp-with-vonage) | [✅](python/whatsapp_with_vonage) | [✅](php/whatsapp-with-vonage) | [✅](node-typescript/whatsapp-with-vonage) | [✅](bun/whatsapp-with-vonage) | [✅](dart/whatsapp_with_vonage) | [✅](deno/whatsapp-with-vonage) | [✅](ruby/whatsapp-with-vonage) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Sync with Qdrant | [✅](node/sync-with-qdrant) | [✅](python/sync_with_qdrant) | 🏗️ | [✅](node-typescript/sync-with-qdrant) | [✅](bun/sync-with-qdrant) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Prompt ChatGPT | [✅](node/prompt-chatgpt) | [✅](python/prompt_chatgpt) | [✅](php/prompt-chatgpt) | 🏗️ | 🏗️ | [✅](dart/prompt_chatgpt) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Censor with Redact | [✅](node/censor-with-redact) | [✅](python/censor_with_redact) | 🏗️ | 🏗️ | 🏗️ | [✅](dart/censor_with_redact) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Email Contact Form | [✅](node/email-contact-form) | [✅](python/email_contact_form) | [✅](php/email-contact-form) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Sync with Algolia | [✅](node/sync-with-algolia) | [✅](python/sync_with_algolia) | [✅](php/sync-with-algolia) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Discord Command Bot | [✅](node/discord-command-bot) | [✅](python/discord_command_bot) | 🏗️ | [✅](node-typescript/discord-command-bot)️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Github Issue Bot | [✅](node/github-issue-bot) | 🏗️ | 🏗️ | [✅](node-typescript/github-issue-bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Analyze with PerspectiveAPI | [✅](node/analyze-with-perspectiveapi) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Chat with Anyscale | [✅](node/chat-with-anyscale) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Chat with Perplexity Ai | [✅](node/chat-with-perplexity-ai) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Database Cleaner | [✅](node/database-cleaner) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Generate PDF | [✅](node/generate-pdf) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Generate with Fal.ai | [✅](node/generate-with-fal) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Generate with Replicate | [✅](node/generate-with-replicate) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Generate with Together Ai | [✅](node/generate-with-together-ai) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Image Classification with Hugging Face | [✅](node/image-classification-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Language Translation with Hugging Face | [✅](node/language-translation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Music Generation with Hugging Face | [✅](node/music-generation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Object Detection with Hugging Face | [✅](node/object-detection-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Password Expiry | [✅](node/password-expiry) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Payments with Lemon Squeezy | [✅](node/payments-with-lemon-squeezy) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Payments with Stripe | [✅](node/payments-with-stripe) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Push Notification with FCM | [✅](node/push-notification-with-fcm) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Query Mongo Atlas | [✅](node/query-mongo-atlas) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Query Neo4j Auradb | [✅](node/query-neo4j-auradb) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Query Neon Postgres | [✅](node/query-neon-postgres) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Query Redis Labs | [✅](node/query-redis-labs) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Query Upstash Vector | [✅](node/query-upstash-vector) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| RAG with LangChain | [✅](node/rag-with-langchain) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Slack Command Bot | [✅](node/slack-command-bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Speak with ElevenLabs | [✅](node/speak-with-elevenlabs) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Speak with Lmnt | [✅](node/speak-with-lmnt) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Speech Recognition with Hugging Face | [✅](node/speech-recognition-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Storage Cleaner | [✅](node/storage-cleaner) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Subscriptions with Lemon Squeezy | [✅](node/subscriptions-with-lemon-squeezy) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Subscriptions with Stripe | [✅](node/subscriptions-with-stripe) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Sync with Pinecone | [✅](node/sync-with-pinecone) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Text Generation with Hugging Face | [✅](node/text-generation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Text to Speech with Hugging Face | [✅](node/text-to-speech-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| URL Shortener | [✅](node/url-shortener) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Generate with Tensorflow | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | [✅](python-ml/generate_with_tensorflow) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Template | Node.js | Python | Node.js (TypeScript) | PHP | Dart | Bun | Deno | Ruby | Go | Kotlin | python-ml | C++ | .NET | Java | Swift | +| -------------------------------------- | ----------------------------------------------- | --------------------------------- | ------------------------------------------ | ------------------------------ | ------------------------------ | ------------------------------ | ------------------------------- | ------------------------------- | --------------------------- | --------------------------------- | --------------------------------------- | ---------------- | ------------------- | ----------------- | ------------------ | +| Starter | [✅](node/starter) | [✅](python/starter) | [✅](node-typescript/starter) | [✅](php/starter) | [✅](dart/starter) | [✅](bun/starter) | [✅](deno/starter) | [✅](ruby/starter) | [✅](go/starter) | [✅](kotlin/starter) | [✅](python-ml/starter) | [✅](cpp/starter) | [✅](dotnet/starter) | [✅](java/starter) | [✅](swift/starter) | +| Sync with Meilisearch | [✅](node/sync-with-meilisearch) | [✅](python/sync_with_meilisearch) | [✅](node-typescript/sync-with-meilisearch) | [✅](php/sync-with-meilisearch) | 🏗️ | [✅](bun/sync-with-meilisearch) | [✅](deno/sync-with-meilisearch) | [✅](ruby/sync_with_meilisearch) | 🏗️ | [✅](kotlin/sync-with-meilisearch) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| WhatsApp with Vonage | [✅](node/whatsapp-with-vonage) | [✅](python/whatsapp_with_vonage) | [✅](node-typescript/whatsapp-with-vonage) | [✅](php/whatsapp-with-vonage) | [✅](dart/whatsapp_with_vonage) | [✅](bun/whatsapp-with-vonage) | [✅](deno/whatsapp-with-vonage) | [✅](ruby/whatsapp-with-vonage) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Sync with Qdrant | [✅](node/sync-with-qdrant) | [✅](python/sync_with_qdrant) | [✅](node-typescript/sync-with-qdrant) | 🏗️ | 🏗️ | [✅](bun/sync-with-qdrant) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Prompt ChatGPT | [✅](node/prompt-chatgpt) | [✅](python/prompt_chatgpt) | 🏗️ | [✅](php/prompt-chatgpt) | [✅](dart/prompt_chatgpt) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Discord Command Bot | [✅](node/discord-command-bot) | [✅](python/discord_command_bot) | [✅](node-typescript/discord-command-bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | [✅](go/discord-command-bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Censor with Redact | [✅](node/censor-with-redact) | [✅](python/censor_with_redact) | 🏗️ | 🏗️ | [✅](dart/censor_with_redact) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Email Contact Form | [✅](node/email-contact-form) | [✅](python/email_contact_form) | 🏗️ | [✅](php/email-contact-form) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Sync with Algolia | [✅](node/sync-with-algolia) | [✅](python/sync_with_algolia) | 🏗️ | [✅](php/sync-with-algolia) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Github Issue Bot | [✅](node/github-issue-bot) | 🏗️ | [✅](node-typescript/github-issue-bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Sign in with Apple | 🏗️ | 🏗️ | 🏗️ | 🏗️ | [✅](dart/sign_in_with_apple) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Analyze with PerspectiveAPI | [✅](node/analyze-with-perspectiveapi) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Chat with Anyscale | [✅](node/chat-with-anyscale) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Chat with Perplexity Ai | [✅](node/chat-with-perplexity-ai) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Database Cleaner | [✅](node/database-cleaner) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Generate PDF | [✅](node/generate-pdf) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Generate with Fal.ai | [✅](node/generate-with-fal) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Generate with Replicate | [✅](node/generate-with-replicate) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Generate with Together Ai | [✅](node/generate-with-together-ai) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Image Classification with Hugging Face | [✅](node/image-classification-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Language Translation with Hugging Face | [✅](node/language-translation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Music Generation with Hugging Face | [✅](node/music-generation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Object Detection with Hugging Face | [✅](node/object-detection-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Password Expiry | [✅](node/password-expiry) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Payments with Lemon Squeezy | [✅](node/payments-with-lemon-squeezy) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Payments with Stripe | [✅](node/payments-with-stripe) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Push Notification with FCM | [✅](node/push-notification-with-fcm) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Query Mongo Atlas | [✅](node/query-mongo-atlas) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Query Neo4j Auradb | [✅](node/query-neo4j-auradb) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Query Neon Postgres | [✅](node/query-neon-postgres) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Query Redis Labs | [✅](node/query-redis-labs) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Query Upstash Vector | [✅](node/query-upstash-vector) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| RAG with LangChain | [✅](node/rag-with-langchain) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Slack Command Bot | [✅](node/slack-command-bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Speak with ElevenLabs | [✅](node/speak-with-elevenlabs) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Speak with Lmnt | [✅](node/speak-with-lmnt) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Speech Recognition with Hugging Face | [✅](node/speech-recognition-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Storage Cleaner | [✅](node/storage-cleaner) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Subscriptions with Lemon Squeezy | [✅](node/subscriptions-with-lemon-squeezy) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Subscriptions with Stripe | [✅](node/subscriptions-with-stripe) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Sync with Pinecone | [✅](node/sync-with-pinecone) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Text Generation with Hugging Face | [✅](node/text-generation-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Text to Speech with Hugging Face | [✅](node/text-to-speech-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| URL Shortener | [✅](node/url-shortener) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Generate with Tensorflow | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | [✅](python-ml/generate_with_tensorflow) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | ✅ = Done - Function is implemented in this runtime. From 972a36964bbabbbeeb0891a6edc41bc7ac981770 Mon Sep 17 00:00:00 2001 From: zeus2611 <28503393+zeus2611@users.noreply.github.com> Date: Wed, 4 Feb 2026 07:15:07 +0000 Subject: [PATCH 2/3] docs: update README table --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e6490a66..8c0e0246 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ Templates for [Appwrite](https://appwrite.io/) Functions. These templates can be | Email Contact Form | [✅](node/email-contact-form) | [✅](python/email_contact_form) | 🏗️ | [✅](php/email-contact-form) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | | Sync with Algolia | [✅](node/sync-with-algolia) | [✅](python/sync_with_algolia) | 🏗️ | [✅](php/sync-with-algolia) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | | Github Issue Bot | [✅](node/github-issue-bot) | 🏗️ | [✅](node-typescript/github-issue-bot) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | +| Storage Cleaner | [✅](node/storage-cleaner) | [✅](python/storage-cleaner) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | | Sign in with Apple | 🏗️ | 🏗️ | 🏗️ | 🏗️ | [✅](dart/sign_in_with_apple) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | | Analyze with PerspectiveAPI | [✅](node/analyze-with-perspectiveapi) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | | Chat with Anyscale | [✅](node/chat-with-anyscale) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | @@ -49,7 +50,6 @@ Templates for [Appwrite](https://appwrite.io/) Functions. These templates can be | Speak with ElevenLabs | [✅](node/speak-with-elevenlabs) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | | Speak with Lmnt | [✅](node/speak-with-lmnt) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | | Speech Recognition with Hugging Face | [✅](node/speech-recognition-with-huggingface) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | -| Storage Cleaner | [✅](node/storage-cleaner) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | | Subscriptions with Lemon Squeezy | [✅](node/subscriptions-with-lemon-squeezy) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | | Subscriptions with Stripe | [✅](node/subscriptions-with-stripe) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | | Sync with Pinecone | [✅](node/sync-with-pinecone) | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | 🏗️ | From 73da7c2be57f139235043333559ab6bd02868e74 Mon Sep 17 00:00:00 2001 From: Nischay Date: Sat, 7 Feb 2026 14:22:33 +0530 Subject: [PATCH 3/3] feat: add Python GitHub Issue Bot function for automated issue responses and webhook verification. --- python/github-issue-bot/.gitignore | 163 +++++++++++++++++++++++ python/github-issue-bot/README.md | 67 ++++++++++ python/github-issue-bot/requirements.txt | 1 + python/github-issue-bot/src/github.py | 94 +++++++++++++ python/github-issue-bot/src/main.py | 39 ++++++ python/github-issue-bot/src/utils.py | 23 ++++ 6 files changed, 387 insertions(+) create mode 100644 python/github-issue-bot/.gitignore create mode 100644 python/github-issue-bot/README.md create mode 100644 python/github-issue-bot/requirements.txt create mode 100644 python/github-issue-bot/src/github.py create mode 100644 python/github-issue-bot/src/main.py create mode 100644 python/github-issue-bot/src/utils.py diff --git a/python/github-issue-bot/.gitignore b/python/github-issue-bot/.gitignore new file mode 100644 index 00000000..beb0967e --- /dev/null +++ b/python/github-issue-bot/.gitignore @@ -0,0 +1,163 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# Directory used by Appwrite CLI for local development +.appwrite \ No newline at end of file diff --git a/python/github-issue-bot/README.md b/python/github-issue-bot/README.md new file mode 100644 index 00000000..1149b351 --- /dev/null +++ b/python/github-issue-bot/README.md @@ -0,0 +1,67 @@ +# 🤖 Python GitHub Issue Bot Function + +Automate the process of responding to newly opened issues on a GitHub repository. + +## 🧰 Usage + +### POST / + +Handles webhook and returns a verification response. + +**Parameters** + +| Name | Description | Location | Type | Sample Value | +| ------------------- | ------------------------- | -------- | ------ | ----------------------------------------------------------------------------------------------------- | +| x-hub-signature-256 | GitHub webhook signature | Header | String | `h74ba0jbla01lagudfo` | +| x-github-event | GitHub webhook event type | Header | String | `issues` | +| JSON Body | GitHub webhook payload | Body | Object | See [GitHub docs](https://docs.github.com/en/webhooks-and-events/webhooks/webhook-events-and-payload) | + +**Response** + +Sample `200` Response: + +Webhook verification successful. + +```json +{ "ok": true } +``` + +Sample `401` Response: + +Webhook verification failed. + +```json +{ "ok": false, "error": "Invalid signature" } +``` + +## ⚙️ Configuration + +| Setting | Value | +| ----------------- | --------------------------------- | +| Runtime | Python (3.9) | +| Entrypoint | `src/main.py` | +| Build Commands | `pip install -r requirements.txt` | +| Permissions | `any` | +| Timeout (Seconds) | 15 | + +## 🔒 Environment Variables + +### GITHUB_WEBHOOK_SECRET + +The secret used to verify that the webhook request comes from GitHub. + +| Question | Answer | +| ------------- | ----------------------------------------------------------------------------------------------- | +| Required | Yes | +| Sample Value | `d1efb...aec35` | +| Documentation | [GitHub Docs](https://docs.github.com/en/developers/webhooks-and-events/securing-your-webhooks) | + +### GITHUB_TOKEN + +A personal access token from GitHub with the necessary permissions to post comments on issues. + +| Question | Answer | +| ------------- | ---------------------------------------------------------------------------------------------------------- | +| Required | Yes | +| Sample Value | `ghp_1...` | +| Documentation | [GitHub Docs](https://docs.github.com/en/github/authenticating-to-github/creating-a-personal-access-token) | diff --git a/python/github-issue-bot/requirements.txt b/python/github-issue-bot/requirements.txt new file mode 100644 index 00000000..b393fb08 --- /dev/null +++ b/python/github-issue-bot/requirements.txt @@ -0,0 +1 @@ +PyGithub \ No newline at end of file diff --git a/python/github-issue-bot/src/github.py b/python/github-issue-bot/src/github.py new file mode 100644 index 00000000..7211a2c5 --- /dev/null +++ b/python/github-issue-bot/src/github.py @@ -0,0 +1,94 @@ +""" +GitHub service module to handle GitHub interactions. +""" + +import os +import json +import hashlib +import hmac +from github import Github + + +class GitHubService: + """ + Service class to interact with GitHub's Webhook. + """ + + def __init__(self): + self.github = Github(os.environ["GITHUB_TOKEN"]) + + def verify_webhook(self, context): + """ + Verify that the payload was sent from GitHub by validating SHA256. + + :param context: The Appwrite function execution context + :return: True if signature is valid, False otherwise + """ + signature_header = context.req.headers.get("x-hub-signature-256") + + if not signature_header or not isinstance(signature_header, str): + return False + + secret_token = os.environ["GITHUB_WEBHOOK_SECRET"] + + payload_body = context.req.body + + if not payload_body: + return False + + if isinstance(payload_body, dict): + payload_bytes = json.dumps(payload_body, separators=(',', ':')).encode('utf-8') + elif isinstance(payload_body, str): + payload_bytes = payload_body.encode('utf-8') + else: + payload_bytes = payload_body + + hash_object = hmac.new( + secret_token.encode('utf-8'), + msg=payload_bytes, + digestmod=hashlib.sha256 + ) + + expected_signature = "sha256=" + hash_object.hexdigest() + + return hmac.compare_digest(expected_signature, signature_header) + + def is_issue_opened_event(self, context): + """ + Checks if the event is an issue opened event. + + :param context: The Appwrite function execution context + :return: True if it is an issue opened event, False otherwise + """ + headers = context.req.headers + if isinstance(context.req.body, str): + body = json.loads(context.req.body) + else: + body = context.req.body + + return ( + headers.get("x-github-event") == "issues" and + body.get("issue") is not None and + body.get("action") == "opened" + ) + + def post_comment(self, repository, issue, comment): + """ + Post a comment on a GitHub issue. + + :param repository: The repository object from the webhook payload + :param issue: The issue object from the webhook payload + :param comment: The comment body to post + """ + owner = repository.get("owner", {}).get("login") + repo_name = repository.get("name") + issue_number = issue.get("number") + + if not owner or not repo_name or not issue_number: + print("Missing repository or issue information") + return + + repo = self.github.get_repo(f"{owner}/{repo_name}") + gh_issue = repo.get_issue(issue_number) + gh_issue.create_comment(comment) + diff --git a/python/github-issue-bot/src/main.py b/python/github-issue-bot/src/main.py new file mode 100644 index 00000000..faf5d5f1 --- /dev/null +++ b/python/github-issue-bot/src/main.py @@ -0,0 +1,39 @@ +import os +import json +from .utils import throw_if_missing +from .github import GitHubService + + +def main(context): + try: + throw_if_missing(os.environ, ["GITHUB_WEBHOOK_SECRET", "GITHUB_TOKEN"]) + except ValueError as e: + return context.res.json({"ok": False, "error": str(e)}, 500) + + github = GitHubService() + + if not github.verify_webhook(context): + context.error("Invalid signature") + return context.res.json({"ok": False, "error": "Invalid signature"}, 401) + + if not github.is_issue_opened_event(context): + context.log("Received non-issue event - ignoring") + return context.res.json({"ok": True}) + + if isinstance(context.req.body, str): + payload = json.loads(context.req.body) + else: + payload = context.req.body + + # Post a comment on the new issue + try: + github.post_comment( + payload["repository"], + payload["issue"], + f"Thanks for the issue report @{payload['issue']['user']['login']}! We will look into it as soon as possible." + ) + except Exception as e: + context.error(f"Failed to post comment: {e}") + return context.res.json({"ok": False, "error": "Failed to post comment"}, 500) + + return context.res.json({"ok": True}) diff --git a/python/github-issue-bot/src/utils.py b/python/github-issue-bot/src/utils.py new file mode 100644 index 00000000..5b0a4382 --- /dev/null +++ b/python/github-issue-bot/src/utils.py @@ -0,0 +1,23 @@ +""" +Utility functions for GitHub issue bot. +Includes function for validating required fields. +""" + +import os + + +def throw_if_missing(obj, keys): + """ + Throws an error if any of the keys are missing from the dictionary or None/0. + + :param obj: Dictionary to check + :param keys: List of required keys + :raises ValueError: If required keys are missing + """ + missing = [] + for key in keys: + if key not in obj or obj[key] is None or obj[key] == 0: + missing.append(key) + + if missing: + raise ValueError(f"Missing required fields: {', '.join(missing)}")