{"id":20634160,"url":"https://github.com/samn/snacks","last_synced_at":"2025-04-15T19:36:03.881Z","repository":{"id":22558574,"uuid":"92103507","full_name":"samn/snacks","owner":"samn","description":"Contextless Photo Sharing","archived":false,"fork":false,"pushed_at":"2023-01-23T23:21:30.000Z","size":1434,"stargazers_count":4,"open_issues_count":15,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-04-14T10:53:32.898Z","etag":null,"topics":["firebase","firebase-functions","google-cloud","mailgun","nextjs"],"latest_commit_sha":null,"homepage":"https://snacksnacksnacksnacksnack.com","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/samn.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE.md","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-22T22:04:41.000Z","updated_at":"2021-09-01T17:38:05.000Z","dependencies_parsed_at":"2023-02-13T04:40:19.342Z","dependency_job_id":null,"html_url":"https://github.com/samn/snacks","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samn%2Fsnacks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samn%2Fsnacks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samn%2Fsnacks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/samn%2Fsnacks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/samn","download_url":"https://codeload.github.com/samn/snacks/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249139425,"owners_count":21219073,"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","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":["firebase","firebase-functions","google-cloud","mailgun","nextjs"],"created_at":"2024-11-16T14:24:05.269Z","updated_at":"2025-04-15T19:36:03.863Z","avatar_url":"https://github.com/samn.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# snacks\n\n[![Build Status](https://travis-ci.org/samn/snacks.svg?branch=master)](https://travis-ci.org/samn/snacks)\n\n## What it is\nhttps://snacksnacksnacksnacksnack.com/\n\nEmail a photo to `snack` at that domain and it'll get posted.\nThere's no metadata or attribution — post cool things and don't be a jerk.\n\nYou can run snacks on your own domain using Firebase, Google Cloud Platform, and Mailgun.\n\n\n## How it works\n\nMailgun is configured to call a webhook when emails are received.\nThat webhook (the `receiveEmail` function in this code base) downloads the attachments and processes them in another function (`receivedAttachmentsPubSub`).\nEXIF data is stripped, and images are resized and compressed.\nThe processed images are stored in a Google Cloud Storage bucket, and an index is stored in Google Cloud Datastore.\n\nThe `receiveEmail` function generates a BSON Object Id to identify the post.\nThis id is used throughout the system as a consistent key across functions (logs can be correlated this way).\nThe original post (at its original resolution but without EXIF data) is archived separately to facilitate reprocessing without recompression.\nObject Ids are naturally sorted by time which is convenient for sorting posts by when they were received.\n\nThe site is built with Next.js \u0026 React.\nPosts (a link to the image \u0026 its dimensions) are retrieved from the Datastore.\nThe inital render ocurrs server side, and additional posts are fetched as the page scrolls.\n\n\n## Additional Docs\n* [Firebase Functions Readme](functions/README.md)\n* [Production Setup](docs/production.md)\n* [Reprocessing Data](docs/reprocessing.md)\n\n\n## License\nCopyright 2017, Sam Neubardt.\n\n\u003ca rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\"\u003e\u003cimg alt=\"Creative Commons License\" style=\"border-width:0\" src=\"https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png\" /\u003e\u003c/a\u003e\u003cbr /\u003eThis work is licensed under a \u003ca rel=\"license\" href=\"http://creativecommons.org/licenses/by-nc-sa/4.0/\"\u003eCreative Commons Attribution-NonCommercial-ShareAlike 4.0 International License\u003c/a\u003e.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamn%2Fsnacks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamn%2Fsnacks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamn%2Fsnacks/lists"}