{"id":19030329,"url":"https://github.com/chmouel/gosmee","last_synced_at":"2025-08-21T11:32:38.761Z","repository":{"id":38299417,"uuid":"483424407","full_name":"chmouel/gosmee","owner":"chmouel","description":"Command line server and client for webhooks deliveries (and https://smee.io)","archived":false,"fork":false,"pushed_at":"2025-08-11T14:11:25.000Z","size":9210,"stargazers_count":50,"open_issues_count":8,"forks_count":17,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-08-11T15:06:15.718Z","etag":null,"topics":["developer-tools","forwarder","golang","webhooks-catcher"],"latest_commit_sha":null,"homepage":"https://hook.pipelinesascode.com","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chmouel.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}},"created_at":"2022-04-19T22:10:09.000Z","updated_at":"2025-08-11T13:19:03.000Z","dependencies_parsed_at":"2023-10-01T22:03:28.697Z","dependency_job_id":"17124231-e90d-42a4-984a-fd03ed81935a","html_url":"https://github.com/chmouel/gosmee","commit_stats":{"total_commits":369,"total_committers":7,"mean_commits":"52.714285714285715","dds":0.4254742547425474,"last_synced_commit":"5b712f19c5babfcd570aba8002254571a6b6d9bc"},"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"purl":"pkg:github/chmouel/gosmee","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fgosmee","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fgosmee/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fgosmee/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fgosmee/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chmouel","download_url":"https://codeload.github.com/chmouel/gosmee/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chmouel%2Fgosmee/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271470251,"owners_count":24765357,"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-21T02:00:08.990Z","response_time":74,"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":["developer-tools","forwarder","golang","webhooks-catcher"],"created_at":"2024-11-08T21:17:30.860Z","updated_at":"2025-08-21T11:32:38.754Z","avatar_url":"https://github.com/chmouel.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🔄 gosmee - A webhook forwarder/relayer and replayer\n\n\u003cp align=\"center\"\u003e\n\u003cimg alt=\"gosmee logo\" src=\"https://github.com/chmouel/gosmee/assets/98980/c0625494-c07e-4e05-82ac-6d96c1491f62\" width=\"25%\" height=\"25%\"\u003e\n\u003c/p\u003e\n\n✨ Gosmee is a powerful webhook relayer that runs anywhere with ease!\n📡 It also serves as a GitHub Hooks replayer using the GitHub API.\n\n## 📝 Description\n\nGosmee enables you to relay webhooks from itself (as a server) or from\n\u003chttps://smee.io\u003e to your local laptop or infrastructure hidden from the public\ninternet.\n\nIt makes exposing services on your local network (like localhost) or behind\na VPN simple and secure. This allows public services, such as GitHub, to push\nwebhooks directly to your local environment.\n\nHere's how it works:\n\n1. Configure your Webhook to send events to a \u003chttps://smee.io/\u003e URL or to\n   your publicly accessible Gosmee server.\n2. Run the Gosmee client on your local machine to fetch these events and\n   forward them to your local service.\n\nThis creates a seamless bridge between GitHub webhooks and your local\ndevelopment environment!\n\nAlternatively, if you prefer not to use a relay server, you can use the\nGitHub API to replay webhook deliveries.\n\n### Diagram\n\nFor those who prefer a visual explanation of how gosmee works:\n\n#### Simple\n\n![diagram](./.github/gosmee-diag.png)\n\n#### Detailed\n\n```mermaid\nsequenceDiagram\n    participant SP as Service Provider (e.g., GitHub)\n    participant GS as Gosmee Server (Public URL / smee.io)\n    participant GC as Gosmee Client (Local / Private Network)\n    participant LS as Local Service (e.g., localhost:3000)\n\n    Note over GC, LS: Runs in private network/local machine\n    Note over SP, GS: Accessible on the public internet\n\n    GC-\u003e\u003e+GS: 1. Connect \u0026 Listen via SSE\n    SP-\u003e\u003e+GS: 2. Event triggers -\u003e Sends Webhook Payload (HTTP POST)\n    GS-\u003e\u003e-GC: 3. Relays Webhook Payload (via SSE connection)\n    GC-\u003e\u003e+LS: 4. Forwards Webhook Payload (HTTP POST)\n    LS--\u003e\u003e-GC: 5. (Optional) HTTP Response\n    GS--\u003e\u003e-SP: 6. (Optional) HTTP Response (e.g., 200 OK)\n```\n\n## Blog Post\n\nLearn more about the background and features of this project in this blog\npost: \u003chttps://blog.chmouel.com/posts/gosmee-webhook-forwarder-relayer\u003e\n\n## 🖥️ Screenshot\n\n![Screenshot](./.github/screenshot.png)\n\n### Live Event Feed\n\nThe web interface of the gosmee server features a live event feed that shows webhook events in real-time:\n\n- 🔴 Live status indicator showing connection state\n- Event counter showing number of received events\n- JSON tree viewer for easy payload inspection\n- Copy buttons for headers and payloads\n- 🔄 Replay functionality to resend events to your endpoint\n- Clear button to remove all events from the feed\n\nEach event in the feed shows:\n\n- Event ID and timestamp\n- Headers with copy functionality\n- Payload in both tree view and raw JSON formats\n- Option to replay individual events\n\n## 🛠️ Replay Viewer Utility\n\n\u003chttps://github.com/user-attachments/assets/dbd0978a-a8ef-4e77-b498-672497567b39\u003e\n\nGosmee includes a helper script [`misc/replayview`](./misc/replayview) for\ninteractively browsing, previewing, and replaying webhook events saved by the\nclient (`--saveDir`). This tool lets you:\n\n- Fuzzy-find replay shell scripts and their JSON payloads\n- Preview event metadata, headers, and payloads\n- Copy replay script paths to clipboard\n- Create symlinks for quick access\n- Run replay scripts directly\n- Interactively inspect JSON payloads (requires [`fx`](https://github.com/antonmedv/fx))\n\n**Usage:**\n\n```sh\n./misc/replayview -h\n```\n\nBy default, it looks for replay files in `/tmp/save` or `/tmp/replay`. Use `-d\n\u003cdir\u003e` to specify a different directory.\n\nIt will make a symlink of the chosen replay event to the file `/tmp/run.sh`,\nthis redirect the event to the local service where to replay the payload\neasily.\n\n**Requirements:** `fzf`, `jq`, `fd`, and optionally [fx](https://fx.wtf/) for interactive JSON\nviewing.\n\nSee the script header or run with `-h` for full options and details.\n\n## 📥 Install\n\n### Release\n\nGo to the [release](https://github.com/chmouel/gosmee/releases) page and\nchoose the appropriate archive or package for your platform.\n\n## 🍺 Homebrew\n\n```shell\nbrew tap chmouel/gosmee https://github.com/chmouel/gosmee\nbrew install gosmee\n```\n\n## [Arch](https://aur.archlinux.org/packages/gosmee-bin)\n\n```shell\nyay -S gosmee-bin\n```\n\n### 🐳 Docker\n\n#### Gosmee client with Docker\n\n```shell\ndocker run ghcr.io/chmouel/gosmee:latest\n```\n\n#### Gosmee server with Docker\n\n```shell\ndocker run -d -p 3026:3026 --restart always --name example.org ghcr.io/chmouel/gosmee:latest server --port 3026 --address 0.0.0.0 --public-url https://example.org\n```\n\n### GO\n\n```shell\ngo install -v github.com/chmouel/gosmee@latest\n```\n\n### 📂 Git\n\nClone the repository and use:\n\n```shell\n-$ make build\n-$ ./bin/gosmee --help\n```\n\n### ❄️ [Nix/NixOS](https://nixos.org/)\n\nGosmee is available from [`nixpkgs`](https://github.com/NixOS/nixpkgs).\n\n```shell\nnix-env -iA gosmee\nnix run nixpkgs#gosmee -- --help # your args are here\n```\n\n### System Services\n\nSystem Service example files for macOS and Linux are available in the\n[misc](./misc) directory.\n\n### ☸️ Kubernetes\n\nYou can deploy gosmee on Kubernetes to relay webhooks to your internal services.\n\nTwo deployment yaml are available:\n\n- [gosmee-server-deployment.yaml](./misc/gosmee-server-deployment.yaml) - For deploying the public-facing server component\n- [gosmee-client-deployment.yaml](./misc/gosmee-client-deployment.yaml) - For deploying the client component that forwards to internal services\n\n#### Server Deployment\n\nThe server deployment exposes a public webhook endpoint to receive incoming webhook events:\n\n```shell\nkubectl apply -f misc/gosmee-server-deployment.yaml\n```\n\nKey configuration:\n\n- Set `--public-url` to your actual domain where the service will be exposed\n- Configure an Ingress with TLS or use a service mesh for production use\n- For security, consider using `--webhook-signature` and `--allowed-ips` options\n\n#### Client Deployment\n\nThe client deployment connects to a gosmee server (either your own or smee.io) and forwards webhook events to internal services:\n\n```shell\nkubectl apply -f misc/gosmee-client-deployment.yaml\n```\n\nKey configuration:\n\n- Adjust the first argument to your gosmee server URL or smee.io channel\n- Change the second argument to your internal service URL (e.g., `http://service.namespace:8080`)\n- The `--saveDir` flag enables saving webhook payloads to `/tmp/save` for later inspection\n\nFor detailed configuration options, refer to the documentation comments in each deployment file.\n\n### Shell completion\n\nShell completions are available for gosmee:\n\n```shell\n# BASH\nsource \u003c(gosmee completion bash)\n\n# ZSH\nsource \u003c(gosmee completion zsh)\n```\n\n## 🚀 Usage\n\n### 💻 Client\n\nIf you plan to use \u003chttps://smee.io\u003e, you can generate your own smee URL by\nvisiting \u003chttps://smee.io/new\u003e.\n\nIf you want to use \u003chttps://hook.pipelinesascode.com\u003e then you can directly\ngenerate a URL with  the `-u / --new-url` flag to generate one.\n\nOnce you have it, the basic usage is:\n\n```shell\ngosmee client https://smee.io/aBcDeF https://localhost:8080\n```\n\nThis command will relay all payloads received by the smee URL to a service\nrunning on \u003chttp://localhost:8080\u003e.\n\nYou can also save all relays as shell scripts for easy replay:\n\n```shell\ngosmee client --saveDir /tmp/savedreplay https://smee.io/aBcDeF https://localhost:8080\n```\n\nThis command saves the JSON data of new payloads to\n`/tmp/savedreplay/timestamp.json` and creates shell scripts with cURL options\nat `/tmp/savedreplay/timestamp.sh`. Replay webhooks easily by running these\nscripts!\n\nYou can configure the SSE client buffer size (in bytes) with the `--sse-buffer-size` flag. The default is `1048576` (1MB).\n\nFor those who prefer [HTTPie](https://httpie.io) over cURL, you can generate HTTPie-based replay scripts:\n\n```shell\ngosmee client --httpie --saveDir /tmp/savedreplay https://smee.io/aBcDeF https://localhost:8080\n```\n\nThis will create replay scripts that use `http` command instead of `curl`. The\ngenerated scripts support the same features as cURL scripts the output will be\na bit nicer and colorful to read.\n\nYou can ignore certain events (identified by GitLab/GitHub/Bitbucket) with one or more `--ignore-event` flags.\n\nIf you only want to save payloads without replaying them, use `--noReplay`.\n\nBy default, you'll get colorful output unless you specify `--nocolor`.\n\nOutput logs as JSON with `--output json` (which implies `--nocolor`).\n\n#### Replay scripts\n\nBoth cURL and HTTPie replay scripts include those command-line options:\n\n- `-l, --local`: Use local debug URL\n- `-t, --target URL`: Specify target URL directly  \n- `-h, --help`: Show help message\n- `-v, --verbose`: Enable verbose output\n\n**Examples:**\n\n```shell\n# Use local debug endpoint\n./timestamp.sh -l\n\n# Specify custom target URL\n./timestamp.sh -t http://custom-service:8080\n\n# Use verbose mode for debugging\n./timestamp.sh -v\n\n# Show help\n./timestamp.sh -h\n```\n\nScripts also respect the `GOSMEE_DEBUG_SERVICE` environment variable for\nalternative target URLs.\n\n### 🖥️ Server\n\nWith `gosmee server` you can run your own relay server instead of using\n\u003chttps://smee.io\u003e.\n\nBy default, `gosmee server` binds to `localhost` on port `3333`. For practical\nuse, you'll want to expose it to your public IP or behind a proxy using the\n`--address` and `--port` flags.\n\nFor security, you can use Let's Encrypt certificates with the `--tls-cert`\nand `--tls-key` flags.\n\nThere are many customization options available - check them with `gosmee server\n--help`.\n\nTo use your server, access it with a URL format like:\n\n\u003chttps://myserverurl/RANDOM_ID\u003e\n\nThe random ID must be 12 characters long with characters from `a-zA-Z0-9_-`.\n\nGenerate a random ID easily with the `/new` endpoint:\n\n```shell\n% curl http://localhost:3333/new\nhttp://localhost:3333/NqybHcEi\n```\n\n#### Caddy\n\n[Caddy](https://caddyserver.com/) is the ideal way to run gosmee server:\n\n```caddyfile\nhttps://webhook.mydomain {\n    reverse_proxy http://127.0.0.1:3333 {\n        header_up X-Real-IP {remote_host}\n        header_up X-Forwarded-For {remote_host}\n    }\n}\n```\n\nIt automatically configures Let's Encrypt certificates for you!\n\n#### Nginx\n\nRunning gosmee server behind nginx requires some configuration:\n\n```nginx\n    location / {\n        proxy_pass         http://127.0.0.1:3333;\n        proxy_set_header Connection '';\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_http_version 1.1;\n        chunked_transfer_encoding off;\n        proxy_read_timeout 372h;\n    }\n```\n\n⚠️ Long-running connections may occasionally cause errors with nginx.\nContributions to debug this are welcome!\n\n#### 🔒 Security\n\n##### Webhook IP Restrictions\n\nTo enhance security, gosmee server supports IP address restrictions for webhook POST requests. This feature allows you to:\n\n- Restrict webhook POST requests to specific IP addresses or CIDR ranges\n- Support both IPv4 and IPv6 addresses\n- Trust X-Forwarded-For and X-Real-IP headers when behind a proxy\n- Log rejected IP addresses for monitoring\n- Only affects POST requests - UI access remains unrestricted\n\nExample usage with Git hosting providers' IP ranges:\n\n```shell\n# GitHub webhook IP ranges\ngosmee server --allowed-ips 192.30.252.0/22 --allowed-ips 185.199.108.0/22 --allowed-ips 140.82.112.0/20 --trust-proxy\n\n# GitLab.com webhook IP ranges\ngosmee server --allowed-ips 35.231.145.151 --allowed-ips 34.74.90.64 --allowed-ips 34.74.226.93 --trust-proxy\n\n# Bitbucket Cloud webhook IP ranges\ngosmee server --allowed-ips 34.199.54.113 --allowed-ips 34.232.119.183 --allowed-ips 34.236.25.177 --allowed-ips 35.171.175.212 --trust-proxy\n\n# Multiple providers can be combined\ngosmee server --allowed-ips 192.30.252.0/22 --allowed-ips 35.231.145.151 --allowed-ips 34.199.54.113 --trust-proxy\n```\n\nOfficial IP ranges documentation:\n\n- GitHub: [IP Documentation](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/about-githubs-ip-addresses)\n- GitLab.com: [IPv4 Addresses](https://docs.gitlab.com/ee/user/gitlab_com/index.html#ipv4-addresses)\n- Bitbucket Cloud: [IP Ranges Documentation](https://support.atlassian.com/bitbucket-cloud/docs/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall/)\n\nEnvironment variables:\n\n- `GOSMEE_ALLOWED_IPS`: Comma-separated list of allowed IPs/CIDR ranges\n- `GOSMEE_TRUST_PROXY`: Set to any value to trust proxy headers\n\nThe server logs will show:\n\n- Rejected POST requests with the client's IP address\n- Whether the IP was obtained from proxy headers (when --trust-proxy is enabled)\n- Standard request logging including status code 403 for rejected IPs\n\nNote: If no IP restrictions are configured, all POST requests will be allowed.\n\n##### 📦 Payload Size and Memory Management\n\n###### Server-Side\n\nTo protect server resources, `gosmee server` enforces a maximum payload size for incoming webhooks. By default, this limit is 25MB, matching GitHub's standard. You can configure this limit using the `--max-body-size` flag (value is in bytes).\n\nExample:\n\n```shell\n# Set a custom 10MB limit\ngosmee server --max-body-size 10485760\n```\n\n###### Client-Side\n\nThe `gosmee client` also has a buffer for receiving messages from the server. If you are forwarding payloads larger than the default, you will need to increase this buffer.\n\n- **Flag**: `--sse-buffer-size`\n- **Default**: `1048576` (1MB)\n- **Description**: Sets the maximum buffer size in bytes for the client's connection.\n\nExample:\n\n```shell\n# Set a 5MB buffer for the client\ngosmee client --sse-buffer-size 5242880 \u003cSMEE_URL\u003e \u003cTARGET_URL\u003e\n```\n\n###### ⚠️ Important Caveats\n\nIncreasing payload and buffer sizes has security and performance implications:\n\n- **Increased Memory Consumption**: Both the client and server will consume more memory when these limits are raised. A server handling many simultaneous large webhooks, or a client with a large buffer, can use a significant amount of RAM.\n- **Denial-of-Service (DoS) Risk**: Exposing a server with a very large `max-body-size` can make it a target for DoS attacks, where an attacker sends huge payloads to exhaust server memory.\n- **Kubernetes Deployments**: If you are running `gosmee` in Kubernetes and increase these limits, you **must** update the memory `requests` and `limits` in the `gosmee-server-deployment.yaml` and `gosmee-client-deployment.yaml` files. Failure to do so may cause your Pods to be OOMKilled (Out Of Memory) by Kubernetes.\n\nAlways set these values to the lowest practical limit that still accommodates your expected webhook sizes.\n\n##### Channel Name Protection\n\nTo prevent potential DoS attacks and ensure system stability:\n\n- Channel names are limited to 64 characters maximum\n- All route handlers (`/`, `/events/{channel}`, `/replay/{channel}`, POST `/{channel}`) enforce this limit\n- Built-in validation for all endpoints that handle channel names\n- Protects against resource exhaustion attacks that could be caused by excessive channel name lengths\n\n##### 🔐 Webhook Signature Validation\n\nWhen running gosmee server, you can enable webhook signature validation for multiple providers with multiple secrets:\n\n```shell\ngosmee server --webhook-signature=SECRET1 --webhook-signature=SECRET2\n```\n\nWhen enabled:\n\n- For GitHub: Validates X-Hub-Signature-256 header using HMAC SHA-256\n- For GitLab: Validates X-Gitlab-Token header using secure token comparison\n- For Bitbucket Cloud/Server: Validates X-Hub-Signature header using HMAC SHA-256\n- For Gitea/Forge: Validates X-Gitea-Signature header using HMAC SHA-256\n- Supports multiple secrets - useful when receiving webhooks from different sources\n- Rejects requests with missing or invalid signatures with HTTP 401 Unauthorized\n- Each secret is tried for validation, webhook is accepted if any secret matches\n- Performance impact is minimal: ~2μs per validation with negligible memory usage\n\nYou can also set multiple secrets via the `GOSMEE_WEBHOOK_SIGNATURE` environment variable by separating them with commas.\n\n## 🔁 Replay webhook deliveries via the GitHub API (beta)\n\nIf you prefer not to use a relay server with GitHub, you can replay webhook deliveries directly via the GitHub API.\n\nThis method is more reliable as you don't depend on relay server availability.\nYou'll need a GitHub token with appropriate scopes:\n\n- For repository webhooks: `read:repo_hook` or `repo` scope\n- For organization webhooks: `admin:org_hook` scope\n\nCurrently supports replaying webhooks from Repositories and Organizations (GitHub Apps webhooks not supported).\n\nFirst, find the Hook ID:\n\n```shell\ngosmee replay --github-token=$GITHUB_TOKEN --list-hooks org/repo\n```\n\nList hooks for an organization:\n\n```shell\ngosmee replay --github-token=$GITHUB_TOKEN --list-hooks org\n```\n\nStart listening and replaying events on a local server:\n\n```shell\ngosmee replay --github-token=$GITHUB_TOKEN org/repo HOOK_ID http://localhost:8080\n```\n\nThis will listen to all **new** events and replay them to \u003chttp://localhost:8080\u003e.\n\nReplay all events received since a specific time (UTC format `2023-12-19T12:31:12`):\n\n```shell\ngosmee replay --time-since=2023-12-19T09:00:00 --github-token=$GITHUB_TOKEN org/repo HOOK_ID http://localhost:8080\n```\n\nTo find the right date, list all deliveries:\n\n```shell\ngosmee replay --github-token=$GITHUB_TOKEN --list-deliveries org/repo HOOK_ID\n```\n\n\u003e[!NOTE]\n\u003e`gosmee replay` doesn't support paging yet and lists only the last\n\u003e100 deliveries. Specifying a date older than the last 100\n\u003edeliveries won't work.\n\u003e\n\u003eWhen rate limited, gosmee will fail without recovery mechanisms.\n\n## 🌐 Beyond Webhook\n\nGosmee is webhook-specific. For other tunneling solutions, check\n\u003chttps://github.com/anderspitman/awesome-tunneling\u003e. Recommended alternatives\ninclude [go-http-tunnel](https://github.com/mmatczuk/go-http-tunnel) or\n[tailscale](https://tailscale.com/).\n\n## ⚠️ Caveats\n\nThis tool is intended for local development and testing environments only!\nIt hasn't undergone thorough security and performance reviews and\nshould not be deployed in production systems.\n\n[smee-sidecar](https://github.com/konflux-ci/smee-sidecar) is a service intended for\nmonitoring gosmee deployments. It provides active health checks to verify that gosmee\nis serving requests.\n\n## 🙏 Thanks\n\n- Most of the work is powered by the [go-sse](https://github.com/r3labs/sse) library.\n- Previously used [pysmee](https://github.com/akrog/pysmee) but its underlying\nSSE library had issues with chunked transfers.\n\n## 📜 Copyright\n\n[Apache-2.0](./LICENSE)\n\n## 👥 Authors\n\n### Chmouel Boudjnah\n\n- 🐘 Fediverse - \u003c[@chmouel@chmouel.com](https://fosstodon.org/@chmouel)\u003e\n- 🐦 Twitter - \u003c[@chmouel](https://twitter.com/chmouel)\u003e\n- 📝 Blog  - \u003c[https://blog.chmouel.com](https://blog.chmouel.com)\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchmouel%2Fgosmee","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchmouel%2Fgosmee","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchmouel%2Fgosmee/lists"}