{"id":23132494,"url":"https://github.com/merlinfuchs/embed-generator","last_synced_at":"2025-08-17T08:32:29.488Z","repository":{"id":38535388,"uuid":"498041489","full_name":"merlinfuchs/embed-generator","owner":"merlinfuchs","description":"Create rich embed messages for Discord (previously discord.club)","archived":false,"fork":false,"pushed_at":"2025-07-28T19:54:39.000Z","size":27463,"stargazers_count":521,"open_issues_count":57,"forks_count":48,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-07-28T20:22:46.413Z","etag":null,"topics":["discord","discord-bot","discord-embed","webhooks"],"latest_commit_sha":null,"homepage":"https://message.style","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/merlinfuchs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"merlinfuchs"}},"created_at":"2022-05-30T17:40:51.000Z","updated_at":"2025-07-28T19:54:42.000Z","dependencies_parsed_at":"2024-01-04T10:33:36.251Z","dependency_job_id":"10cdc0d2-12bd-49e6-bd99-1780561bedcd","html_url":"https://github.com/merlinfuchs/embed-generator","commit_stats":null,"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"purl":"pkg:github/merlinfuchs/embed-generator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/merlinfuchs%2Fembed-generator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/merlinfuchs%2Fembed-generator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/merlinfuchs%2Fembed-generator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/merlinfuchs%2Fembed-generator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/merlinfuchs","download_url":"https://codeload.github.com/merlinfuchs/embed-generator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/merlinfuchs%2Fembed-generator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270823300,"owners_count":24652085,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-17T02:00:09.016Z","response_time":129,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["discord","discord-bot","discord-embed","webhooks"],"created_at":"2024-12-17T11:18:57.884Z","updated_at":"2025-08-17T08:32:29.475Z","avatar_url":"https://github.com/merlinfuchs.png","language":"TypeScript","funding_links":["https://github.com/sponsors/merlinfuchs"],"categories":[],"sub_categories":[],"readme":"# Embed Generator\n\n[![Release](https://github.com/merlinfuchs/embed-generator/actions/workflows/release.yaml/badge.svg)](https://github.com/merlinfuchs/embed-generator/releases)\n[![Docker image](https://github.com/merlinfuchs/embed-generator/actions/workflows/docker-push.yaml/badge.svg)](https://hub.docker.com/r/merlintor/embed-generator)\n\n[![Release](https://img.shields.io/github/v/release/merlinfuchs/embed-generator)](https://github.com/merlinfuchs/embed-generator/releases/latest)\n[![MIT License](https://img.shields.io/github/license/merlinfuchs/embed-generator)](LICENSE)\n[![Uptime](https://img.shields.io/endpoint?url=https%3A%2F%2Fraw.githubusercontent.com%2Fmerlinfuchs%2Fembedg-uptime%2Fmaster%2Fapi%2Fembed-generator-api%2Fuptime.json)](https://status.kite.onl/)\n[![Discord Server](https://img.shields.io/discord/730045476459642900)](https://message.style/discord)\n\nA powerful tool for creating rich-embed Discord messages using webhooks.\n\nYou will usually want to use the hosted version at https://message.style. There is not much benefit in hosting this\nyourself.\n\n## YouTube tutorial\n\n[![Youtube Tutorial](./tutorial.png)](https://www.youtube.com/watch?v=DnFP0MRJPIg)\n\n## Self Hosting\n\nThis describes the easiest way to self host an instance of Embed Generator by creating a single binary that contains\nboth the backend and frontend.\n\nYou can find prebuilt binaries of the server with the frontend files included [here](https://github.com/merlinfuchs/embed-generator/releases/latest).\n\n### Configure the server\n\nTo configure the server you can create a file called `config.yaml` with the following fields:\n\n```yaml\ndiscord:\n  client_id: \"\"\n  client_secret: \"\"\n  token: \"\"\n\nopenai:\n  api_key: \"\" # for ChatGPT integration (optional)\n\npostgres:\n  host: \"localhost\"\n  port: 5432\n  dbname: \"embedg\"\n  user: \"postgres\"\n  password: \"\"\n\napp:\n  public_url: \"http://localhost:5173/app\"\n\napi:\n  # Make sure to add {public_url}/auth/callback to the OAuth2 Redirect URLs of your application in the Discord dev portal\n  public_url: \"http://localhost:5173/api\"\n\n  # Make sure to enable this when you don't have an SSL (HTTPS) certificate\n  insecure_cookies: true\n\n  host: \"localhost\"\n  port: 8080\n\n# These links are used in help commands and for redirects\nlinks:\n  discord: https://discord.gg/CpHwbKQKHA\n  source: https://github.com/merlinfuchs/embed-generator\n\nlog:\n  use_json: false # Enable to this to have easily parsable JSON log messages (you usually don't want this)\n\n# Here you can configure multiple tiers/plans which are linked to a Discord SKU\npremium:\n  plans:\n    # The default plan that all users automatically have\n    - id: default\n      default: true\n      features:\n        max_saved_messages: 25\n        max_actions_per_component: 3\n        advanced_action_types: false\n        ai_assistant: false\n        is_premium: false\n        custom_bot: false\n        max_custom_commands: 0\n        max_scheduled_messages: 5\n        periodic_scheduled_messages: false\n        max_template_ops: 1000\n        max_kv_keys: 10\n        components_v2: true\n        component_types: [1, 2, 3, 9, 10, 11, 12, 17]\n    # An additional premium plan that will apply when the user or guild has the SKU\n    - id: premium_server\n      sku_id: \"123\"\n      features:\n        max_saved_messages: 100\n        max_actions_per_component: 10\n        advanced_action_types: true\n        ai_assistant: true\n        is_premium: true # This is used for handing out cosmetics like a role on the support server\n        custom_bot: true\n        max_custom_commands: 25\n        max_image_upload_size: 8000000\n        max_scheduled_messages: 25\n        periodic_scheduled_messages: true\n        max_template_ops: 10000\n        max_kv_keys: 1000\n        components_v2: true\n        component_types: [1, 2, 3, 9, 10, 11, 12, 13, 14, 17]\n```\n\nYou can also set the config values using environment variables. For example `EMBEDG_DISCORD__TOKEN` will set the discord\ntoken.\n\n### Using Docker (docker-compose)\n\nInstall Docker and docker-compose and create a `docker-compose.yaml` file with the following contents:\n\n```yaml\nversion: \"3.8\"\n\nservices:\n  postgres:\n    image: postgres\n    restart: always\n    volumes:\n      - embedg-local-postgres:/var/lib/postgresql/data\n    environment:\n      POSTGRES_USER: postgres\n      POSTGRES_DB: embedg\n      PGUSER: postgres\n      PGDATA: /var/lib/postgresql/data/pgdata\n      POSTGRES_HOST_AUTH_METHOD: trust\n    healthcheck:\n      test: [\"CMD\", \"pg_isready\"]\n      interval: 3s\n      timeout: 30s\n      retries: 3\n\n  minio:\n    image: quay.io/minio/minio\n    command: server --console-address \":9001\" /data\n    ports:\n      - \"9000:9000\"\n      - \"9001:9001\"\n    environment:\n      MINIO_ROOT_USER: embedg\n      MINIO_ROOT_PASSWORD: 1234567890\n    volumes:\n      - embedg-local-minio:/data\n\n  embedg:\n    image: merlintor/embed-generator:latest\n    restart: always\n    ports:\n      - \"8080:8080\"\n    environment:\n      - EMBEDG_API__HOST=0.0.0.0\n      - EMBEDG_API__INSECURE_COOKIES=true\n      - EMBEDG_POSTGRES__HOST=postgres\n      - EMBEDG_POSTGRES__USER=postgres\n      - EMBEDG_POSTGRES__DB=embedg\n      - EMBEDG_S3__ENDPOINT=minio:9000\n      - EMBEDG_API__PUBLIC_URL=http://localhost:8080/api\n      - EMBEDG_APP__PUBLIC_URL=http://localhost:8080/app\n    volumes:\n      - ./config.yaml:/root/config.yaml\n    depends_on:\n      postgres:\n        condition: service_healthy\n\nvolumes:\n  embedg-local-postgres:\n  embedg-local-minio:\n```\n\nRun the file using `docker-compose up`. It will automatically mount the `config.yaml` file into the container. You should not configure postgres in your config file as it's using the postgres instance from the container.\n\nEmbed Generator should now be accessible in your browser at [http://localhost:8080](http://localhost:8080).\n\n### Build from source\n\n#### Build the app\n\nYou can download NodeJS and NPM from [nodejs.org](https://nodejs.org/en/download/).\n\n```sh\n# Switch to the embedg-app directory\ncd embedg-app\n\n# Install yarn globally\nnpm install -g yarn\n\n# Install dependencies\nyarn install\n\n# Start the development server (optional)\nyarn dev\n\n# Build for production use\nyarn build\n```\n\n#### Build the site (home page \u0026 docs)\n\n```sh\n# Switch to the embedg-app directory\ncd embedg-site\n\n# Install yarn globally\nnpm install -g yarn\n\n# Install dependencies\nyarn install\n\n# Start the development server (optional)\nyarn start\n\n# Build for production use\nyarn build\n```\n\n#### Build the server (backend)\n\nInstall Go `\u003e=1.21` from [go.dev](https://go.dev/doc/install).\n\n```sh\n# Switch to the backend directory\ncd embedg-server\n# or if you are in the frontend directoy\ncd ../embedg-server\n\n# Configure the server (see steps below)\n\n# Run database migrations\ngo run main.go migrate postgres up\n\n# Start the development server (optional)\ngo run --tags \"embedapp embedsite\" main.go server\n\n# Build and include the frontend files in the backend binary (build app and site first)\ngo build --tags  \"embedapp embedsite\"\n\n# Build without including the frontend files in the backend binary (you need to serve yourself)\ngo build\n```\n\n#### Install databases\n\nIf you are not using Docker you need to Install PostgreSQL on your device and create a user and database. I'm sure you can find instructions online!\n\n#### Run the binary\n\nYou should now be able to run the binary and host your own instance of Embed Generator. You usually want to deploy this\nbehind a reverse proxy like Nginx and terminate TLS there.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmerlinfuchs%2Fembed-generator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmerlinfuchs%2Fembed-generator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmerlinfuchs%2Fembed-generator/lists"}