Remember when I wrote about using push without notifications? Sebastiaan has written up the details of the experiment he conducted at Indie Web Camp Berlin.
{ "type": "entry", "published": "2018-11-24T13:47:38Z", "url": "https://adactio.com/links/14554", "category": [ "push", "api", "serviceworkers", "notifications", "caching", "javascript", "permissions", "frontend", "development", "indiewebcamp", "demo" ], "bookmark-of": [ "https://seblog.nl/2018/11/13/3/pushapi-without-notifications" ], "content": { "text": "PushAPI without Notifications | Seblog\n\n\n\nRemember when I wrote about using push without notifications? Sebastiaan has written up the details of the experiment he conducted at Indie Web Camp Berlin.", "html": "<h3>\n<a class=\"p-name u-bookmark-of\" href=\"https://seblog.nl/2018/11/13/3/pushapi-without-notifications\">\nPushAPI without Notifications | Seblog\n</a>\n</h3>\n\n<p>Remember when I wrote about using <a href=\"https://adactio.com/journal/14511\">push without notifications</a>? Sebastiaan has written up the details of the experiment he conducted at Indie Web Camp Berlin.</p>" }, "author": { "type": "card", "name": "Jeremy Keith", "url": "https://adactio.com/", "photo": "https://aperture-proxy.p3k.io/bbbacdf0a064621004f2ce9026a1202a5f3433e0/68747470733a2f2f6164616374696f2e636f6d2f696d616765732f70686f746f2d3135302e6a7067" }, "post-type": "bookmark", "_id": "1478425", "_source": "2", "_is_read": true }
{ "type": "entry", "published": "2018-11-22T10:58:41+01:00", "summary": "In den letzten 4…5 Jahren hab ich immer wieder mit dem Gedanken gespielt meinen facebook Account zu l\u00f6schen. Mein Account hatte wirklich wenig pers\u00f6nliches und ich habe ihn fast ausschlie\u00dflich dazu benutzt, meine Blogposts zu teilen. Der einzig plausible Grund der mich noch daraun gehindert hat ihn zu l\u00f6schen, ist mein Beruf. Mittlerweile bin ich […]", "url": "https://notiz.blog/2018/11/22/facebook/", "featured": "https://notiz.blog/wp-content/uploads/2018/11/facebook-profile-not-found.png", "name": "facebook", "content": { "text": "In den letzten 4...5 Jahren hab ich immer wieder mit dem Gedanken gespielt meinen facebook Account zu l\u00f6schen. Mein Account hatte wirklich wenig pers\u00f6nliches und ich habe ihn fast ausschlie\u00dflich dazu benutzt, meine Blogposts zu teilen. Der einzig plausible Grund der mich noch daraun gehindert hat ihn zu l\u00f6schen, ist mein Beruf. Mittlerweile bin ich aber der \u00dcberzeugung, dass daf\u00fcr auch ein ... nennen wir es mal \"Test-Account\" ... ausreicht.\n\n\n\nGl\u00fccklicherweise geh\u00f6re ich zu einer Generation die auch ganz gut ohne facebook auskommt, weshalb ich das \"Privileg\" habe, meinen Account zu l\u00f6schen.\n\n\n\nAlso dann: Ciao facebook!\n\n\n\n\nWer mich erreichen, mir folgen, mit mir diskutieren, oder einfach nur \"hallo\" sagen will, ist (bzw. \"war schon immer\") hier auf notiz.blog am besten aufgehoben. Mein Blog hat RSS, ATOM, JSON, Microformats(2), Schema.org und ActivityStream Feeds, er unterst\u00fctzt Kommentare, Salmons, Webmentions und Pingbacks, ihr k\u00f6nnt mir auf Mastodon, Friendi.ca, GNU.social, STATUS.net, Diaspora (WIP) ((@)pfefferle@notiz.blog), Micro.blog (\u00fcber irgend einen der oben erw\u00e4hnten Feeds) oder \u00fcber Telegram folgen (@notizblog).\n\n\n\nAu\u00dferdem bin ich weiterhin \u00fcber Twitter, GitHub und diverse Slack Channels (IndieWeb, WordPress, ...) zu erreichen.\n\n\n\nAls n\u00e4chstes w\u00fcrde ich \u00fcbrigens auch gerne auf Whatsapp verzichten... Also bitte nur noch Telegram verwenden!", "html": "<p>In den letzten 4...5 Jahren hab ich immer wieder mit dem Gedanken gespielt meinen facebook Account zu l\u00f6schen. Mein Account hatte wirklich wenig pers\u00f6nliches und ich habe ihn fast ausschlie\u00dflich dazu benutzt, meine Blogposts zu teilen. Der einzig plausible Grund der mich noch daraun gehindert hat ihn zu l\u00f6schen, ist mein Beruf. Mittlerweile bin ich aber der \u00dcberzeugung, dass daf\u00fcr auch ein ... nennen wir es mal \"Test-Account\" ... ausreicht.</p>\n\n\n\n<p>Gl\u00fccklicherweise geh\u00f6re ich zu einer Generation die auch ganz gut ohne facebook auskommt, weshalb ich das \"<a href=\"https://medium.com/@ginahelfrich/deleting-facebook-is-a-privilege-you-should-do-it-anyway-fb299396fd70\">Privileg</a>\" habe, meinen Account zu l\u00f6schen.</p>\n\n\n\n<p>Also dann: Ciao facebook!<br /></p>\n\n\n\n<p>Wer mich erreichen, mir folgen, mit mir diskutieren, oder einfach nur \"hallo\" sagen will, ist (bzw. \"war schon immer\") hier auf <strong>notiz.blog</strong> am besten aufgehoben. Mein Blog hat RSS, ATOM, JSON, Microformats(2), Schema.org und ActivityStream Feeds, er unterst\u00fctzt Kommentare, Salmons, Webmentions und Pingbacks, ihr k\u00f6nnt mir auf Mastodon, Friendi.ca, GNU.social, STATUS.net, Diaspora (<a href=\"https://github.com/pfefferle/wordpress-diaspora\"><abbr title=\"work in progress\">WIP</abbr></a>) (<code>(@)pfefferle@notiz.blog</code>), Micro.blog (\u00fcber irgend einen der oben erw\u00e4hnten Feeds) oder \u00fcber Telegram folgen (<code><a href=\"https://t.me/notizblog\">@notizblog</a></code>).</p>\n\n\n\n<p>Au\u00dferdem bin ich weiterhin \u00fcber <a href=\"https://twitter.com/pfefferle\">Twitter</a>, <a href=\"https://github.com/pfefferle\">GitHub</a> und diverse Slack Channels (IndieWeb, WordPress, ...) zu erreichen.</p>\n\n\n\n<p>Als n\u00e4chstes w\u00fcrde ich \u00fcbrigens auch gerne auf Whatsapp verzichten... Also bitte nur noch <a href=\"https://t.me/pfefferle\">Telegram</a> verwenden!<br /></p>" }, "author": { "type": "card", "name": "Matthias Pfefferle", "url": "https://pfefferle.org/", "photo": "https://secure.gravatar.com/avatar/75512bb584bbceae57dfc503692b16b2?s=96&d=https://notiz.blog/wp-content/plugins/semantic-linkbacks/img/mm.jpg&r=g" }, "post-type": "note", "_id": "1467732", "_source": "206", "_is_read": true }
{ "type": "entry", "published": "2018-11-20 23:03-0800", "url": "http://tantek.com/2018/324/t1/five-years-homebrew-website-club", "content": { "text": "Five years ago Homebrew Website Club (HWC) met for the first time: http://tantek.com/2013/332/b1/homebrew-website-club-newsletter\n\nSince then:\n* HWC has grown, meets in many cities^1\n* Path (noted in linked post) shutdown^2\n\nNext HWC meeting 2018-11-28^3\nJoin us, share, inspire, be inspired \u00a0\n\n^1. https://indieweb.org/Homebrew_Website_Club#Regular_Meetings\n^2. https://indieweb.org/Path\n^3. https://indieweb.org/next-hwc", "html": "Five years ago Homebrew Website Club (HWC) met for the first time: <a href=\"http://tantek.com/2013/332/b1/homebrew-website-club-newsletter\">http://tantek.com/2013/332/b1/homebrew-website-club-newsletter</a><br /><br />Since then:<br />* HWC has grown, meets in many cities^1<br />* Path (noted in linked post) shutdown^2<br /><br />Next HWC meeting 2018-11-28^3<br />Join us, share, inspire, be inspired \u00a0<br /><br />^1. <a href=\"https://indieweb.org/Homebrew_Website_Club#Regular_Meetings\">https://indieweb.org/Homebrew_Website_Club#Regular_Meetings</a><br />^2. <a href=\"https://indieweb.org/Path\">https://indieweb.org/Path</a><br />^3. <a href=\"https://indieweb.org/next-hwc\">https://indieweb.org/next-hwc</a>" }, "author": { "type": "card", "name": "Tantek \u00c7elik", "url": "http://tantek.com/", "photo": "https://aperture-media.p3k.io/tantek.com/acfddd7d8b2c8cf8aa163651432cc1ec7eb8ec2f881942dca963d305eeaaa6b8.jpg" }, "post-type": "note", "_id": "1460316", "_source": "1", "_is_read": true }
{ "type": "entry", "published": "2018-11-20 22:18:56.314473", "summary": "I talk about what-you-see-is-what-you-get posting system for my #indieweb site and how it improved my post quality.", "url": "https://kongaloosh.com/e/2018/11/20/indie-wysi", "photo": [ "https://aperture-proxy.p3k.io/1c481c72f7b0c4011a8a756058c6a6100e659273/68747470733a2f2f6b6f6e67616c6f6f73682e636f6d2f646174612f323031382f31312f32302f696e6469652d777973692e706e67" ], "syndication": [ "https://kongaloosh.com/" ], "name": "Indie WYSIWYG: How I Fixed My Instagram Problem", "content": { "text": "I talk about what-you-see-is-what-you-get posting system for my #indieweb site and how it improved my post quality.\n \n \n \n \n \n \n \n \n \n dev\n \n indieweb\n \n wysiwyg\n \n cms\n \n article", "html": "<a href=\"https://kongaloosh.com/e/2018/11/20/indie-wysi\">\n </a>\n \n \n \n <p>\n <i>\n I talk about what-you-see-is-what-you-get posting system for my #indieweb site and how it improved my post quality.\n </i>\n </p>\n \n \n \n \n \n <i></i>\n \n <a href=\"https://kongaloosh.com/t/dev\">dev</a>\n \n <a href=\"https://kongaloosh.com/t/indieweb\">indieweb</a>\n \n <a href=\"https://kongaloosh.com/t/wysiwyg\">wysiwyg</a>\n \n <a href=\"https://kongaloosh.com/t/cms\">cms</a>\n \n <a href=\"https://kongaloosh.com/t/article\">article</a>" }, "author": { "type": "card", "name": "Alex Kearney", "url": "http://kongaloosh.com", "photo": null }, "post-type": "photo", "_id": "1459819", "_source": "228", "_is_read": true }
Another year is wrapping up (how?!), so time for my #indieweb #newwwyear resolutions for my website.
By 2019-01-01 I would like to:
As a stretch goal, I would like to work on my channels more. I would like to set up one to feed into my micro.blog that excludes replies to non-micro.blog posts. I would like to start treating micro.blog as my primary, external social network instead of Twitter.
{ "type": "entry", "published": "2018-11-20 15:31-0800", "url": "https://gregorlove.com/2018/11/another-year-is-wrapping-up/", "syndication": [ "https://twitter.com/gRegorLove/status/1065028111694102528" ], "content": { "text": "Another year is wrapping up (how?!), so time for my #indieweb #newwwyear resolutions for my website.\n\nBy 2019-01-01 I would like to:\n\nUpdate my archive pages to cover more post types, not just articles\n\tAdd back the next/previous article navigation. I lost those as part of updates to the footer\n\nAs a stretch goal, I would like to work on my channels more. I would like to set up one to feed into my micro.blog that excludes replies to non-micro.blog posts. I would like to start treating micro.blog as my primary, external social network instead of Twitter.\n\nPreviously: 2017, 2016, 2015", "html": "<p>Another year is wrapping up (how?!), so time for my #indieweb #newwwyear resolutions for my website.</p>\n\n<p>By 2019-01-01 I would like to:</p>\n\n<ul><li>Update my archive pages to cover more post types, not just articles</li>\n\t<li>Add back the next/previous article navigation. I lost those as part of <a href=\"https://gregorlove.com/2018/03/ive-launched-this-on-both/\">updates to the footer</a>\n</li>\n</ul><p>As a stretch goal, I would like to work on my <a href=\"https://gregorlove.com/channels/\">channels</a> more. I would like to set up one to feed into <a href=\"https://micro.blog/gregorlove\">my micro.blog</a> that excludes replies to non-micro.blog posts. I would like to start treating micro.blog as my primary, external social network instead of Twitter.</p>\n\n<p>Previously: <a href=\"https://gregorlove.com/2017/12/my-newwwyear-resolution/\">2017</a>, <a href=\"https://gregorlove.com/2016/11/my-indieweb-commitment-is-finish/\">2016</a>, <a href=\"https://gregorlove.com/2015/12/my-indieweb-commitment-is/\">2015</a></p>" }, "author": { "type": "card", "name": "gRegor Morrill", "url": "https://gregorlove.com/", "photo": "https://aperture-proxy.p3k.io/929c8777d059069a2a16a064d96f4c29b65548f8/68747470733a2f2f677265676f726c6f76652e636f6d2f736974652f6173736574732f66696c65732f333437332f70726f66696c652d323031362d6d65642e6a7067" }, "post-type": "note", "_id": "1459058", "_source": "95", "_is_read": true }
{ "type": "entry", "published": "2018-11-19T19:39:20-05:00", "url": "https://eddiehinkle.com/2018/11/19/17/note/", "category": [ "indieweb", "indiewebcamp", "tech" ], "syndication": [ "https://micro.blog/EddieHinkle", "https://news.indieweb.org/en" ], "content": { "text": "Thinking through planning the IndieWebCamp Online event. Right now, it looks like we might be scheduling it for the weekend of March 9 and 10, 2019. Anyone who is thinking about participating have any huge conflicts with that weekend? If so, let me know!", "html": "Thinking through planning the <a href=\"https://indieweb.org/IndieWebCamps\">IndieWebCamp</a> Online event. Right now, it looks like we might be scheduling it for the weekend of March 9 and 10, 2019. Anyone who is thinking about participating have any huge conflicts with that weekend? If so, let me know!" }, "author": { "type": "card", "name": "Eddie Hinkle", "url": "https://eddiehinkle.com/", "photo": "https://aperture-proxy.p3k.io/cc9591b69c2c835fa2c6e23745b224db4b4b431f/68747470733a2f2f656464696568696e6b6c652e636f6d2f696d616765732f70726f66696c652e6a7067" }, "post-type": "note", "_id": "1451225", "_source": "226", "_is_read": true }
{ "type": "entry", "published": "2018-11-18 21:38-0800", "url": "https://gregorlove.com/2018/11/xoxo-yes-you-do-belong-here/", "name": "XOXO: Yes, you do belong here", "content": { "text": "In September I attended XOXO Festival for the first time. I\u2019ve heard great things about the festival over the years. I almost attended in 2016 but I couldn\u2019t quite make it work and decided I would go the following year. Then they announced they were going on hiatus, so there would be no XOXO 2017. I was really glad to hear they were coming back this year, so I was determined to attend.\n\nXOXO bills itself as an \u201cexperimental festival for independent artists and creators who work on the internet.\u201d The organizers are intentional about having a diverse and inclusive event, both speakers and attendees. Potential attendees fill out a brief survey about themselves and something they have recently created that they are proud of. This allows the organizers to invite a more diverse group of attendees instead of just having first-come, first-serve ticket sales. They also subsidized 20% of the attendees this year, which meant 400 free tickets.\n\nHere\u2019s a good little intro video with some footage from this year:\n\n\n\nSo what was my XOXO experience like?\n\nI was struck by how friendly everyone was. There was a large pavilion outside the venue with standing tables and a many people would readily walk up to you and introduce themselves. There was very little \u201cwhere do you work?\u201d in the conversations and a lot of \u201cwhat are you excited/passionate about?\u201d It felt like a gathering of soon-to-be friends and not a schmoozy networking event.\n\nThe opening keynote Thursday night by Cameron Esposito was funny and powerful. One of the best lines included in that video above was \u201cart dismantles power, otherwise it is propaganda.\u201d You should check out her stand-up special, Rape Jokes, which deals with her experience of sexual assault. It\u2019s free to watch on her site and she\u2019s collecting donations for RAINN. As of this writing, over $80k has been raised.\n\nIn the weeks prior to the festival, attendees were invited to join the XOXO Slack group chat. There are a bunch of different topical channels in there to help you connect with each other. Friday at the festival was largely reserved for social meetups. The Slack channels organized over 30 meetups around Portland. It ended up being a great way to ease into the festival by meeting people and exploring Portland.\n\nI attended the #indieweb/#mastodon meetup in the morning and the #mcelroy meetup in the afternoon. If you\u2019re not familiar with the McElroy brothers, they\u2019re best known for their hilarious advice podcast: My Brother, My Brother and Me. They have a segment within that show, \u201cMunch Squad,\u201d where they read fast food companies\u2019 earnest, actual press releases for their new food abominations. It seemed only appropriate that if we were going to have an XOXO #mcelroy meetup, it should be somewhere like Taco Bell. So that\u2019s what we did. We had some good, good (bad) food and lots of laughs. I kid you not, my total came to $6.69 (hashtag nice, hashtag blessed). For two people there, it was their first time ever eating Taco Bell, so it was a treat to introduce them to it.\n\nI might have bought munchsquad dot club after that meetup.\n\nFriday night the festival portion started, aka the Paradox of Choice. The main auditorium had Film and Animation. Another room had Art+Code. There was also the Arcade room and the Tabletop room. I went to Art+Code first and saw Jenn Schiffer\u2019s introduction, including some attendee\u2019s retro websites. I also saw Baratunde Thurston\u2019s talk about racialized news headlines and his quiz web app, Living While Black. Try it out and see if you can tell which headlines are real or fake.\n\nI decided to bop around to some of the other things going on at the same time, thinking that anything I missed in Art+Code would be recorded and posted online later. Unfortunately I was mistaken. I wish I had stayed in Art+Code longer, but oh well. I was glad to catch the Bill Wurtz segment of Film and Animation. If you\u2019re not familiar with him, start with \u201cand the day goes on.\u201d\n\nOn Saturday the conference portion started. These were the main speakers and there was only one track, so no worries about missing anything. They were also recorded and many are now posted. Check out some of my favorites:\n\nDemi Adejuyigbe\n\tOpen Mike Eagle\n\tJean Grae\n\tNatalie Wynn (ContraPoints)\nThere\u2019s several more posted on the XOXO YouTube.\n\nA recurring theme from both attendees and speakers was experiencing impostor syndrome. Some attendees even made an XOXO Bingo game where the free spot was \u201chave impostor syndrome.\u201d There was a recurring encouragement, though: yes, you do belong here.\n\nThe Slack chat was an interesting component throughout the event. I was impressed that organizers and volunteers were on it regularly to answer questions and respond to feedback. Day-to-day, improvements were made based on feedback, like adding more lighting to the picnic tables outside at night. The organizers were very receptive to feedback and criticism; it was a transparent process since all the attendees could see it. It was also great to connect with other attendees through it. I used it to meet up with people for meals and even at the airport on my way home.\n\nI went in to XOXO with pretty high expectations and was not disappointed. It\u2019s a fantastic community. I highly recommend it if you\u2019re involved in anything creative online. Hopefully I will see you there in 2019!\n\nCheck out some other attendee\u2019s blog posts:\n\n\u201cLook After Each Other(tm)\u201d by Doug Hanke\n\n\t\u201cXOXO\u201d by Jess Driscoll\n\n\t\u201cDear XOXO\u201d by Georgie\n\n\t\u201cXOXO 2018\u201d by Kanane\n\n\t\u201cWhat XOXO 2018 taught me about running events\u201d by Brandon Johnson\n\n\t\u201cXOXO 2018 Monday Thoughts\u201d by Brook Shelley\n\n\t\u201cXOXO and the Shimmering \u201dDistortion Field\u201d by Julia Skott", "html": "<p>In September I attended <a href=\"https://2018.xoxofest.com/\">XOXO Festival</a> for the first time. I\u2019ve heard great things about the festival over the years. I almost attended in 2016 but I couldn\u2019t quite make it work and decided I would go the following year. Then they announced they were going on hiatus, so there would be no XOXO 2017. I was really glad to hear they were coming back this year, so I was determined to attend.</p>\n\n<p>XOXO bills itself as an \u201cexperimental festival for independent artists and creators who work on the internet.\u201d The organizers are intentional about having a diverse and inclusive event, both speakers and attendees. Potential attendees fill out a brief survey about themselves and something they have recently created that they are proud of. This allows the organizers to invite a more diverse group of attendees instead of just having first-come, first-serve ticket sales. They also subsidized 20% of the attendees this year, which meant 400 free tickets.</p>\n\n<p>Here\u2019s a good little intro video with some footage from this year:</p>\n\n\n\n<p>So what was my XOXO experience like?</p>\n\n<p>I was struck by how friendly everyone was. There was a large pavilion outside the venue with standing tables and a many people would readily walk up to you and introduce themselves. There was very little \u201cwhere do you work?\u201d in the conversations and a lot of \u201cwhat are you excited/passionate about?\u201d It felt like a gathering of soon-to-be friends and not a schmoozy networking event.</p>\n\n<p>The opening keynote Thursday night by <a class=\"h-card\" href=\"https://www.cameronesposito.com/\">Cameron Esposito</a> was funny and powerful. One of the best lines included in that video above was \u201cart dismantles power, otherwise it is propaganda.\u201d You should check out her stand-up special, Rape Jokes, which deals with her experience of sexual assault. It\u2019s free to watch on her site and she\u2019s collecting donations for <a href=\"https://www.rainn.org\"><abbr title=\"Rape, Abuse & Incest National Network\">RAINN</abbr></a>. As of this writing, over $80k has been raised.</p>\n\n<p>In the weeks prior to the festival, attendees were invited to join the XOXO Slack group chat. There are a bunch of different topical channels in there to help you connect with each other. Friday at the festival was largely reserved for social meetups. The Slack channels organized over 30 meetups around Portland. It ended up being a great way to ease into the festival by meeting people and exploring Portland.</p>\n\n<p>I attended the #indieweb/#mastodon meetup in the morning and the #mcelroy meetup in the afternoon. If you\u2019re not familiar with the McElroy brothers, they\u2019re best known for their hilarious advice podcast: <a href=\"https://www.maximumfun.org/shows/my-brother-my-brother-and-me\">My Brother, My Brother and Me</a>. They have a segment within that show, \u201cMunch Squad,\u201d where they read fast food companies\u2019 earnest, actual press releases for their new food abominations. It seemed only appropriate that if we were going to have an XOXO #mcelroy meetup, it should be somewhere like Taco Bell. So that\u2019s what we did. We had some good, good (bad) food and lots of laughs. I kid you not, my total came to $6.69 (hashtag nice, hashtag blessed). For two people there, it was their first time ever eating Taco Bell, so it was a treat to introduce them to it.</p>\n\n<p><i>I might have bought <a href=\"http://munchsquad.club\">munchsquad dot club</a> after that meetup.</i></p>\n\n<p>Friday night the festival portion started, aka the Paradox of Choice. The main auditorium had Film and Animation. Another room had Art+Code. There was also the Arcade room and the Tabletop room. I went to Art+Code first and saw <a href=\"https://www.youtube.com/watch?v=fvaWAkqlJPE\">Jenn Schiffer\u2019s introduction</a>, including some attendee\u2019s retro websites. I also saw Baratunde Thurston\u2019s talk about racialized news headlines and his quiz web app, <a href=\"https://livingwhileblack.glitch.me/\">Living While Black</a>. Try it out and see if you can tell which headlines are real or fake.</p>\n\n<p>I decided to bop around to some of the other things going on at the same time, thinking that anything I missed in Art+Code would be recorded and posted online later. Unfortunately I was mistaken. I wish I had stayed in Art+Code longer, but oh well. I was glad to catch the Bill Wurtz segment of Film and Animation. If you\u2019re not familiar with him, start with \u201c<a href=\"https://www.youtube.com/watch?v=NHZr6P1csiY\">and the day goes on</a>.\u201d</p>\n\n<p>On Saturday the conference portion started. These were the main speakers and there was only one track, so no worries about missing anything. They were also recorded and many are now posted. Check out some of my favorites:</p>\n\n<ul><li><a href=\"https://www.youtube.com/watch?v=G39U1Z1d7qI\">Demi Adejuyigbe</a></li>\n\t<li><a href=\"https://www.youtube.com/watch?v=LrrLT5l8DvU\">Open Mike Eagle</a></li>\n\t<li><a href=\"https://www.youtube.com/watch?v=GrSm3HyHbqQ\">Jean Grae</a></li>\n\t<li><a href=\"https://www.youtube.com/watch?v=0Ix9jxid2YU\">Natalie Wynn (ContraPoints)</a></li>\n</ul><p>There\u2019s several more posted on the <a href=\"https://www.youtube.com/user/xoxofest\">XOXO YouTube</a>.</p>\n\n<p>A recurring theme from both attendees and speakers was experiencing <a href=\"https://en.wikipedia.org/wiki/Impostor_syndrome\">impostor syndrome</a>. Some attendees even made an XOXO Bingo game where the free spot was \u201chave impostor syndrome.\u201d There was a recurring encouragement, though: yes, you do belong here.</p>\n\n<p>The Slack chat was an interesting component throughout the event. I was impressed that organizers and volunteers were on it regularly to answer questions and respond to feedback. Day-to-day, improvements were made based on feedback, like adding more lighting to the picnic tables outside at night. The organizers were very receptive to feedback and criticism; it was a transparent process since all the attendees could see it. It was also great to connect with other attendees through it. I used it to meet up with people for meals and even at the airport on my way home.</p>\n\n<p>I went in to XOXO with pretty high expectations and was not disappointed. It\u2019s a fantastic community. I highly recommend it if you\u2019re involved in anything creative online. Hopefully I will see you there in 2019!</p>\n\n<p>Check out some other attendee\u2019s blog posts:</p>\n\n<ul><li class=\"h-cite\">\u201c<a class=\"p-name u-url\" href=\"https://www.doug-hanke.com/blog/2018/9/10/xoxo-2018\">Look After Each Other(tm)</a>\u201d by <a class=\"u-author h-card\" href=\"https://www.doug-hanke.com/\">Doug Hanke</a>\n</li>\n\t<li class=\"h-cite\">\u201c<a class=\"p-name u-url\" href=\"https://jessdriscoll.github.io/blog/2018/09/09/xoxo\">XOXO</a>\u201d by <a class=\"u-author h-card\" href=\"http://jessdriscoll.com/\">Jess Driscoll</a>\n</li>\n\t<li class=\"h-cite\">\u201c<a class=\"p-name u-url\" href=\"https://hey.georgie.nu/xoxo/\">Dear XOXO</a>\u201d by <a class=\"u-author h-card\" href=\"https://hey.georgie.nu/\">Georgie</a>\n</li>\n\t<li class=\"h-cite\">\u201c<a class=\"p-name u-url\" href=\"http://www.spideyj.com/xoxo-2018/\">XOXO 2018</a>\u201d by <a class=\"u-author h-card\" href=\"http://www.spideyj.com\">Kanane</a>\n</li>\n\t<li class=\"h-cite\">\u201c<a class=\"p-name u-url\" href=\"http://brandon.mn/posts/2018-10-01-xoxo/\">What XOXO 2018 taught me about running events</a>\u201d by <a class=\"u-author h-card\" href=\"http://brandon.mn\">Brandon Johnson</a>\n</li>\n\t<li class=\"h-cite\">\u201c<a class=\"p-name u-url\" href=\"https://www.brookshelley.com/blog/2018/09/10/xoxo-thoughts.html\">XOXO 2018 Monday Thoughts</a>\u201d by <a class=\"u-author h-card\" href=\"https://www.brookshelley.com\">Brook Shelley</a>\n</li>\n\t<li class=\"h-cite\">\u201c<a class=\"p-name u-url\" href=\"https://www.juliaskott.com/blog/2018/9/28/xoxo-and-the-distortion-field\">XOXO and the Shimmering \u201dDistortion Field</a>\u201d by <a class=\"u-author h-card\" href=\"https://www.juliaskott.com\">Julia Skott</a>\n</li>\n</ul>" }, "post-type": "article", "_id": "1445706", "_source": "179", "_is_read": true }
I think a read post primarily indicates an action related to reading it. “I want to read this,” “I am currently reading this,” or “I finished reading this.” I think any of those could include an optional comment. The Goodreads status update UI is a good example of this: you can update your reading progress and include a comment each time. Once you’ve marked a book as finished, you have a separate UI to enter a review and a rating, independent of your previous status updates and comments.
I think the general indieweb workflow for this would be several posts:
Personally I don't think updating existing posts is a great idea in this workflow, but I'm open to ideas. These are my suggestions based on experience with Goodreads.
{ "type": "entry", "published": "2018-11-18 17:28-0800", "url": "https://gregorlove.com/2018/11/i-think-a-read-post/", "in-reply-to": [ "https://quickthoughts.jgregorymcverry.com/2018/11/19/though-now-gregorlove-i-am-really-confused" ], "content": { "text": "I think a read post primarily indicates an action related to reading it. \u201cI want to read this,\u201d \u201cI am currently reading this,\u201d or \u201cI finished reading this.\u201d I think any of those could include an optional comment. The Goodreads status update UI is a good example of this: you can update your reading progress and include a comment each time. Once you\u2019ve marked a book as finished, you have a separate UI to enter a review and a rating, independent of your previous status updates and comments.\n\nI think the general indieweb workflow for this would be several posts:\n\nA read post with status to-read\n\n\tread post(s) with status reading (one or more)\n\tA read post with status finished\n\n\tAn h-review post\nPersonally I don't think updating existing posts is a great idea in this workflow, but I'm open to ideas. These are my suggestions based on experience with Goodreads.", "html": "<p>I think a <i>read</i> post primarily indicates an action related to reading it. \u201cI want to read this,\u201d \u201cI am currently reading this,\u201d or \u201cI finished reading this.\u201d I think any of those could include an optional comment. The Goodreads status update UI is a good example of this: you can update your reading progress and include a comment each time. Once you\u2019ve marked a book as finished, you have a separate UI to enter a review and a rating, independent of your previous status updates and comments.</p>\n\n<p>I think the general indieweb workflow for this would be several posts:</p>\n\n<ol><li>A read post with status <i>to-read</i>\n</li>\n\t<li>read post(s) with status <i>reading</i> (one or more)</li>\n\t<li>A read post with status <i>finished</i>\n</li>\n\t<li>An h-review post</li>\n</ol><p>Personally I don't think updating existing posts is a great idea in this workflow, but I'm open to ideas. These are my suggestions based on experience with Goodreads.</p>" }, "author": { "type": "card", "name": "gRegor Morrill", "url": "https://gregorlove.com/", "photo": "https://aperture-proxy.p3k.io/929c8777d059069a2a16a064d96f4c29b65548f8/68747470733a2f2f677265676f726c6f76652e636f6d2f736974652f6173736574732f66696c65732f333437332f70726f66696c652d323031362d6d65642e6a7067" }, "post-type": "reply", "refs": { "https://quickthoughts.jgregorymcverry.com/2018/11/19/though-now-gregorlove-i-am-really-confused": { "type": "entry", "url": "https://quickthoughts.jgregorymcverry.com/2018/11/19/though-now-gregorlove-i-am-really-confused", "content": { "text": "Though now @gRegorLove I am really confused on the difference between a read post and an h-review of a book. Is a read, either want-to, reading, done just an action with no summary? Does a red post become a review once you make a recommendation?" }, "author": { "type": "card", "name": "Greg McVerry", "url": false, "photo": "https://gregorlove.com/site/assets/files/3540/d7f505f3722cfa6a6a98692773b7cb84219c7441887bb8116f880ea634e5c2d7.jpg" }, "post-type": "note" } }, "_id": "1445398", "_source": "95", "_is_read": true }
{ "type": "entry", "published": "2018-11-18T09:47:53-08:00", "summary": "Listen to a summary of all the sessions at IndieWebCamp Berlin 2018!", "url": "https://aaronparecki.com/2018/11/18/7/indiewebcamp-berlin", "category": [ "indieweb", "this-week", "indiewebcamp", "podcast" ], "audio": [ "https://aperture-media.p3k.io/aaronparecki.com/95cd22171acfdf1fd7f3b470872f106536be5041ae0d6b54016c3703ddab40bc.mp3" ], "name": "IndieWebCamp Berlin 2018", "content": { "text": "Listen to a summary of all the sessions at IndieWebCamp Berlin 2018!\nSession notes:\u00a0https://indieweb.org/2018/Berlin/Sessions\n\n Narration by Marty McGuire\n\n Edited by Aaron Parecki", "html": "<p class=\"p-summary\">Listen to a summary of all the sessions at IndieWebCamp Berlin 2018!</p>\n<p>Session notes:\u00a0<a href=\"https://indieweb.org/2018/Berlin/Sessions\">https://indieweb.org/2018/Berlin/Sessions</a></p>\n<p>\n Narration by <a href=\"https://martymcgui.re\">Marty McGuire</a><br />\n Edited by <a href=\"https://aaronparecki.com\">Aaron Parecki</a>\n</p>" }, "author": { "type": "card", "name": "Aaron Parecki", "url": "https://aaronparecki.com/", "photo": "https://aperture-media.p3k.io/aaronparecki.com/2b8e1668dcd9cfa6a170b3724df740695f73a15c2a825962fd0a0967ec11ecdc.jpg" }, "post-type": "audio", "_id": "1442227", "_source": "16", "_is_read": true }
{ "type": "entry", "published": "2018-11-18T14:30:00+01:00", "summary": "Should I be beating myself up because we're more than halfway to the end of November? I don't think so. October was a good month, but not standout good. Maybe if it had been I would have written it up more rapidly. The high spot was definitely IndieWeb Camp in N\u00fcrnberg, and I did write that up reasonably quickly. No need to repeat here.\nMore this way ...", "url": "https://www.jeremycherfas.net/blog/monthly-report-2018-10", "in-reply-to": [ "https://www.jeremycherfas.net/blog/indiewebcamp-nurnberg-2018" ], "name": "Monthly report: October 2018", "content": { "text": "Should I be beating myself up because we're more than halfway to the end of November? I don't think so. October was a good month, but not standout good. Maybe if it had been I would have written it up more rapidly. The high spot was definitely IndieWeb Camp in N\u00fcrnberg, and I did write that up reasonably quickly. No need to repeat here.\n\n More this way ...", "html": "<p>Should I be beating myself up because we're more than halfway to the end of November? I don't think so. October was a good month, but not standout good. Maybe if it had been I would have written it up more rapidly. The high spot was definitely <a class=\"u-in-reply-to\" href=\"https://www.jeremycherfas.net/blog/indiewebcamp-nurnberg-2018\">IndieWeb Camp in N\u00fcrnberg</a>, and I did write that up reasonably quickly. No need to repeat here.</p>\n\n <p><a href=\"https://www.jeremycherfas.net/blog/monthly-report-2018-10\">More this way ...</a></p>" }, "author": { "type": "card", "name": "Jeremy Cherfas", "url": "https://jeremycherfas.net", "photo": "https://aperture-proxy.p3k.io/d86af7b89af940fd08d45409035f1d24a547840a/68747470733a2f2f7777772e6a6572656d79636865726661732e6e65742f757365722f706c7567696e732f61626f75746d652f6173736574732f617661746172732f7a6f6f742e6a7067" }, "post-type": "reply", "_id": "1441082", "_source": "202", "_is_read": true }
{ "type": "entry", "published": "2018-11-17T16:44:50+00:00", "url": "https://cleverdevil.io/2018/new-podcast-two-dads-talking", "syndication": [ "https://twitter.com/cleverdevil/status/1063868512534503426" ], "name": "New Podcast: Two Dads Talking", "content": { "text": "I am not ashamed to admit that I love podcasts. In the early 2000s, blogs were the hot thing: an open publishing medium that allowed people to exchange ideas, converse, and share. Since then, blogs have faded, as increasingly toxic social media walled gardens have moved people off the open web. It\u2019s a shame, really. I\u2019m hopeful that blogs will rise again, but it\u2019s going to take time.Podcasts, on the other hand, have only grown in popularity, and are still blissfully free of central control from creepy ad-driven social media giants. We are in the golden age of podcasting!I\u2019ve had a personal microcast for a while now, and I\u2019ve been pretty undisciplined about publishing it. Still, it has been a fun exercise, and I plan to keep at it for years to come.Today, however, I\u2019m excited to announce a new podcast project: Two Dads Talking. TDT is a longer form podcast featuring myself and my co-host Eddie Hinkle. Eddie and I have known each other for a few years now through the IndieWeb community, and we\u2019ve found that we both have a lot in common, but also a significant amount of differences. This podcast is an opportunity for us to get to know each other better, and for our listeners to join us in that discovery.Eddie and I are both parents, though at very different life stages, and both are people of faith, and technologists. I\u2019m really looking forward to getting to know Eddie better, and I hope you\u2019ll all join us in our journey of Two Dads Talking.To subscribe, visit the Two Dads Talking website, follow us on Micro.blog, or subscribe in your favorite podcast client.", "html": "<p><img src=\"https://aperture-proxy.p3k.io/2b6209d1977de1a53bc8a21d76bac6a65fe9519c/68747470733a2f2f636c65766572646576696c2e696f2f66696c652f3739366565326664303832643631633538366634653762636361653130646331\" alt=\"\" /></p><p>I am not ashamed to admit that I love podcasts. In the early 2000s, blogs were the hot thing: an open publishing medium that allowed people to exchange ideas, converse, and share. Since then, blogs have faded, as increasingly toxic social media walled gardens have moved people off the open web. It\u2019s a shame, really. I\u2019m hopeful that blogs will rise again, but it\u2019s going to take time.</p><p>Podcasts, on the other hand, have only grown in popularity, and are still blissfully free of central control from creepy ad-driven social media giants. We are in the golden age of podcasting!</p><p>I\u2019ve had <a href=\"http://cleverca.st\">a personal microcast</a> for a while now, and I\u2019ve been pretty undisciplined about publishing it. Still, it has been a fun exercise, and I plan to keep at it for years to come.</p><p>Today, however, I\u2019m excited to announce a new podcast project: <a href=\"https://twodads.fm\">Two Dads Talking</a>. TDT is a longer form podcast featuring myself and my co-host <a href=\"https://eddiehinkle.com\">Eddie Hinkle</a>. Eddie and I have known each other for a few years now through the <a href=\"https://Indieweb.org\">IndieWeb</a> community, and we\u2019ve found that we both have a lot in common, but also a significant amount of differences. This podcast is an opportunity for us to get to know each other better, and for our listeners to join us in that discovery.</p><p>Eddie and I are both parents, though at very different life stages, and both are people of faith, and technologists. I\u2019m really looking forward to getting to know Eddie better, and I hope you\u2019ll all join us in our journey of Two Dads Talking.</p><p>To subscribe, visit the <a href=\"https://twodads.fm\">Two Dads Talking website</a>, <a href=\"https://micro.blog/twodads\">follow us on Micro.blog</a>, or subscribe in your favorite podcast client.</p>" }, "author": { "type": "card", "name": "Jonathan LaCour", "url": "https://cleverdevil.io/profile/cleverdevil", "photo": "https://aperture-proxy.p3k.io/77e5d6e5871324c43aebf2e3e7a5553e14578f66/68747470733a2f2f636c65766572646576696c2e696f2f66696c652f66646263373639366135663733383634656131316138323863383631653133382f7468756d622e6a7067" }, "post-type": "article", "_id": "1437220", "_source": "71", "_is_read": true }
Just implemented a Siri Shortcut for IndieAuth! Now let’s see if I can integrate it with my Micropub shortcut.
{ "type": "entry", "published": "2018-11-16T23:17:56+0000", "url": "https://seblog.nl/2018/11/16/2/just-implemented-a-siri", "category": [ "indieweb" ], "content": { "text": "Just implemented a Siri Shortcut for IndieAuth! Now let\u2019s see if I can integrate it with my Micropub shortcut.", "html": "<p>Just implemented a Siri Shortcut for IndieAuth! Now let\u2019s see if I can integrate it with my Micropub shortcut.</p>" }, "author": { "type": "card", "name": "Sebastiaan Andeweg", "url": "https://seblog.nl/", "photo": "https://aperture-proxy.p3k.io/10e8aeca31d1cd146999fcacc07a8eb9ad47c813/68747470733a2f2f7365626c6f672e6e6c2f70686f746f2e6a7067" }, "post-type": "note", "_id": "1434215", "_source": "1366", "_is_read": true }
{ "type": "entry", "published": "2018-11-16T01:15:20-05:00", "url": "https://eddiehinkle.com/2018/11/16/1/note/", "category": [ "colophon", "indieweb-goals", "newwwyear" ], "syndication": [ "https://micro.blog/EddieHinkle", "https://news.indieweb.org/en", "https://twitter.com/eddiehinkle" ], "content": { "text": "I just added support for the Micropub Category List query to my website. Looking forward to adding support to Indigenous for iOS in the near future as well. This is the first of many goals completed for #newwwyear 2019.", "html": "I just added support for the <a href=\"https://indieweb.org/Micropub-extensions#Query_for_Category.2FTag_List\">Micropub Category List query</a> to my website. Looking forward to adding support to Indigenous for iOS in the near future as well. This is the first of many goals completed for #newwwyear 2019." }, "author": { "type": "card", "name": "Eddie Hinkle", "url": "https://eddiehinkle.com/", "photo": "https://aperture-proxy.p3k.io/cc9591b69c2c835fa2c6e23745b224db4b4b431f/68747470733a2f2f656464696568696e6b6c652e636f6d2f696d616765732f70726f66696c652e6a7067" }, "post-type": "note", "_id": "1428263", "_source": "226", "_is_read": true }
{ "type": "entry", "published": "2018-11-15T20:41:02+0000", "url": "https://seblog.nl/2018/11/15/1/enhancing-the-micropub-experience", "category": [ "indieweb", "micropub" ], "syndication": [ "https://news.indieweb.org/en/seblog.nl/2018/11/15/1/enhancing-the-micropub-experience" ], "name": "Enhancing the Micropub experience with services", "content": { "text": "At IndieWebCamp Berlin this year, at the session about Workflow, we came up with an idea, how to enhance your blogposts with an external service using Micropub. I\u2019ve thought of a few variants, and in spirit of the IndieWeb I should first build them and then show it, but I haven\u2019t got around it yet.\nSo y\u2019all will have to do with just a description. I might implement it at some point, if I have a real use case for it. I don\u2019t actually want weather on my posts. \nBut let\u2019s start at an idea I first had at IndieWebCamp N\u00fcrnberg.\nThe Syndication Button Hack\nMicropub is an open API standard that allows clients to post to servers. In the spec, there is a mechanism for clients to show buttons for syndication targets. The client asks the server what targets there are, and the server responds with a list of names and UIDs. The client then shows the names on buttons (or near checkboxes) and if the user selects one, the UID is set as the mp-syndicate-to field of the post. The server is then responsible for syndicating the post to, say, Twitter or Facebook.\nThis mechanism is widely supported among clients. And since the client does not have to do any work actually related to the syndication, it can also be used for other things.\nImagine the server implementing private posts. The support for private posts in Micropub clients is not really existing at the moment of writing. But we can get a button to toggle the state of the post created, quite easily:\nGET /micropub?q=syndicate-to\nAuthorization: Bearer xxxxxxxxx\nAccept: application/json\n\nHTTP/1.1 200 OK\nContent-type: application/json\n\n{\n \"syndicate-to\": [\n {\n \"uid\": \"private-post\",\n \"name\": \"Private post\"\n }\n ]\n}\nSince it\u2019s up to the server to syndicate to private-post, it can decide not to syndicate it, but to mark it private. There are a number of possibilities with this: toggle audiences, mark the post as draft. All these things could have their own queries at some point, but until then, this will work in almost all the clients.\nAlso notice the Bearer token. The server can know which client is asking, so it could show a different set of buttons, depending on the client. Quill supports draft posts? Don\u2019t show that button in Quill.\nEnter the Weather Service\nBack to the idea of Berlin, which takes this one step further. If we have the Syndication Button Hack in place, we can also hook up external services to enhance our blog posts.\nSay I display a location with every entry I post. I could have a button that says: \u2018Weather Service\u2019. Activating that button would instruct my server to ping the Weather Service about the existance of this new post. This could be done by WebSub or some other mechanism.\nBack when I signed up for the Weather Service, I gave it access to my Micropub endpoint as well. The Weather Service waits for new posts to arrive, reads their location, fetches the weather for that location, and sends a Micropub update request.\nThe only new part this requires, is the button and the ping to the Weather Service. All the other parts exist in clients and servers. Ah, and someone will need to build that Weather Service.\nExternal services in general\nThe nice thing about this model, is that the heavy lifting is on neither the Micropub client nor the server. It\u2019s on the external service. And it\u2019s not that heavy of a lifting, because the external service does only one thing and does one thing well. It can give superpowers to both Wordpress blogs and static generated sites.\nThe external service could provide information about the weather, but think of Aaron\u2019s Overland and Compass: it could also provide the location of the post given a point in time. There might be more. Expanding venue info?\nOne thing to watch out for, is concurrent processing of these Micropub requests. This might not be a problem for you, but I store my posts as flat files. If two services send an update request for the same post, one might start, and the other might overwrite the first one. (I really need to check how my blog handles this case.)\nWhen you are using a database like MySQL, you should be safe for this kind of stuff, but it still depends on the implementation of your Micropub endpoint.\nOther ways of doing it\nPeter did not like this first approach, because his post would have multiple visible states (first a few seconds without weather, then with it).\nAnother appreach would be a sort of Russian doll Micropub request, where you sign in to an external service which signs in to your Micropub endpoint. This would mean that quill.p3k.io posts to weather.example/micropub which intercepts the request, and sends the same request with weather info added to seblog.nl/micropub. \nI don\u2019t like that approach either, because now I have to trust the Weather Service with my tokens. In the first approach, every service gets their own scoped token, which is safer.\nSince the server knows how many services it has asked to enhance the post, it could also keep it in draft until the last update request comes in. This would require more work on the server\u2019s side of things, and there has to be a timeout on it, but it could be a way to mitigate Peter\u2019s problem.\nAs always: feel free to steal or improve, but please let me know.", "html": "<p>At IndieWebCamp Berlin this year, at the session about Workflow, we came up with an idea, how to enhance your blogposts with an external service using Micropub. I\u2019ve thought of a few variants, and in spirit of the IndieWeb I should first build them and then show it, but I haven\u2019t got around it yet.</p>\n<p>So y\u2019all will have to do with just a description. I might implement it at some point, if I have a real use case for it. I don\u2019t actually want weather on my posts. </p>\n<p>But let\u2019s start at an idea I first had at IndieWebCamp N\u00fcrnberg.</p>\n<h2>The Syndication Button Hack</h2>\n<p>Micropub is an open API standard that allows clients to post to servers. In <a href=\"https://www.w3.org/TR/micropub/#syndication-targets\">the spec</a>, there is a mechanism for clients to show buttons for syndication targets. The client asks the server what targets there are, and the server responds with a list of names and UIDs. The client then shows the names on buttons (or near checkboxes) and if the user selects one, the UID is set as the <code>mp-syndicate-to</code> field of the post. The server is then responsible for syndicating the post to, say, Twitter or Facebook.</p>\n<p>This mechanism is widely supported among clients. And since the client does not have to do any work actually related to the syndication, it can also be used for other things.</p>\n<p>Imagine the server implementing private posts. The support for private posts in Micropub clients is not really existing at the moment of writing. But we can get a button to toggle the state of the post created, quite easily:</p>\n<pre><code>GET /micropub?q=syndicate-to\nAuthorization: Bearer xxxxxxxxx\nAccept: application/json\n\nHTTP/1.1 200 OK\nContent-type: application/json\n\n{\n \"syndicate-to\": [\n {\n \"uid\": \"private-post\",\n \"name\": \"Private post\"\n }\n ]\n}</code></pre>\n<p>Since it\u2019s up to the server to syndicate to <code>private-post</code>, it can decide not to syndicate it, but to mark it private. There are a number of possibilities with this: toggle audiences, mark the post as draft. All these things could have their own queries at some point, but until then, this will work in almost all the clients.</p>\n<p>Also notice the <code>Bearer</code> token. The server can know which client is asking, so it could show a different set of buttons, depending on the client. Quill supports draft posts? Don\u2019t show that button in Quill.</p>\n<h2>Enter the Weather Service</h2>\n<p>Back to the idea of Berlin, which takes this one step further. If we have the Syndication Button Hack in place, we can also hook up external services to enhance our blog posts.</p>\n<p>Say I display a location with every entry I post. I could have a button that says: \u2018Weather Service\u2019. Activating that button would instruct my server to ping the Weather Service about the existance of this new post. This could be done by WebSub or some other mechanism.</p>\n<p>Back when I signed up for the Weather Service, I gave it access to my Micropub endpoint as well. The Weather Service waits for new posts to arrive, reads their location, fetches the weather for that location, and sends a Micropub update request.</p>\n<p>The only new part this requires, is the button and the ping to the Weather Service. All the other parts exist in clients and servers. Ah, and someone will need to build that Weather Service.</p>\n<h2>External services in general</h2>\n<p>The nice thing about this model, is that the <a href=\"https://chat.indieweb.org/dev/2018-11-15#t1542309128941000\">heavy lifting</a> is on neither the Micropub client nor the server. It\u2019s on the external service. And it\u2019s not that heavy of a lifting, because the external service does only one thing and does one thing well. It can give superpowers to both Wordpress blogs and static generated sites.</p>\n<p>The external service could provide information about the weather, but think of <a href=\"https://aaronpk.com\">Aaron</a>\u2019s <a href=\"https://overland.p3k.app/\">Overland</a> and <a href=\"https://github.com/aaronpk/Compass\">Compass</a>: it could also provide the location of the post given a point in time. There might be more. Expanding venue info?</p>\n<p>One thing to watch out for, is concurrent processing of these Micropub requests. This might not be a problem for you, but I store my posts as flat files. If two services send an update request for the same post, one might start, and the other might overwrite the first one. (I really need to check how my blog handles this case.)</p>\n<p>When you are using a database like MySQL, you should be safe for this kind of stuff, but it still depends on the implementation of your Micropub endpoint.</p>\n<h2>Other ways of doing it</h2>\n<p><a href=\"https://petermolnar.net\">Peter</a> did not like this first approach, because his post would have multiple visible states (first a few seconds without weather, then with it).</p>\n<p>Another appreach would be a sort of Russian doll Micropub request, where you sign in to an external service which signs in to your Micropub endpoint. This would mean that <code>quill.p3k.io</code> posts to <code>weather.example/micropub</code> which intercepts the request, and sends the same request with weather info added to <code>seblog.nl/micropub</code>. </p>\n<p>I don\u2019t like that approach either, because now I have to trust the Weather Service with my tokens. In the first approach, every service gets their own scoped token, which is safer.</p>\n<p>Since the server knows how many services it has asked to enhance the post, it could also keep it in draft until the last update request comes in. This would require more work on the server\u2019s side of things, and there has to be a timeout on it, but it could be a way to mitigate Peter\u2019s problem.</p>\n<p>As always: feel free to steal or improve, but please let me know.</p>" }, "author": { "type": "card", "name": "Sebastiaan Andeweg", "url": "https://seblog.nl/", "photo": "https://aperture-proxy.p3k.io/10e8aeca31d1cd146999fcacc07a8eb9ad47c813/68747470733a2f2f7365626c6f672e6e6c2f70686f746f2e6a7067" }, "post-type": "article", "_id": "1426067", "_source": "1366", "_is_read": true }
{ "type": "entry", "published": "2018-11-15T04:50:53-05:00", "url": "https://eddiehinkle.com/2018/11/15/10/note/", "category": [ "indieweb-goals" ], "syndication": [ "https://micro.blog/EddieHinkle", "https://news.indieweb.org/en", "https://twitter.com/eddiehinkle" ], "content": { "text": "I posted my #newwwyear 2019 #indieweb goals, it\u2019s quite ambitious. But if I complete all of them, my bonus goal is getting some movement on tracking my books and reading in my website. https://eddiehinkle.com/2018/11/15/5/article/", "html": "I posted my #newwwyear 2019 #indieweb goals, it\u2019s quite ambitious. But if I complete all of them, my bonus goal is getting some movement on tracking my books and reading in my website. <a href=\"https://eddiehinkle.com/2018/11/15/5/article/\">https://eddiehinkle.com/2018/11/15/5/article/</a>" }, "post-type": "note", "_id": "1421613", "_source": "226", "_is_read": true }
{ "type": "entry", "published": "2018-11-14 14:42-0800", "url": "http://tantek.com/2018/318/t1/2019-indieweb-commitment", "category": [ "indieweb" ], "content": { "text": "My 2019-001 #indieweb commitment: build on my @IndieWebCamp Berlin coding, improve archive pages, more nav & pagination, e.g. home stream to prev day(s).\nDetails: https://indieweb.org/Falcon#archive_pages\n\nWhat\u2019s your 2019-01-01 personal site commitment?\nhttps://indieweb.org/2019-01-01-commitments\n\nPreviously: \n* http://tantek.com/2018/308/t2/indiewebcamp-archive-navigation-day-archives\n* http://tantek.com/2016/330/b1/2017-01-01-indieweb-commitment-own-my-rsvps\n\nMore on archives, navigation, pagination:\n* https://indieweb.org/archive\n* https://indieweb.org/navigation\n* https://indieweb.org/archive_navigation\n* https://indieweb.org/pagination", "html": "My 2019-001 #<span class=\"p-category\">indieweb</span> commitment: build on my <a class=\"h-cassis-username\" href=\"https://twitter.com/IndieWebCamp\">@IndieWebCamp</a> Berlin coding, improve archive pages, more nav & pagination, e.g. home stream to prev day(s).<br />Details: <a href=\"https://indieweb.org/Falcon#archive_pages\">https://indieweb.org/Falcon#archive_pages</a><br /><br />What\u2019s your 2019-01-01 personal site commitment?<br /><a href=\"https://indieweb.org/2019-01-01-commitments\">https://indieweb.org/2019-01-01-commitments</a><br /><br />Previously: <br />* <a href=\"http://tantek.com/2018/308/t2/indiewebcamp-archive-navigation-day-archives\">http://tantek.com/2018/308/t2/indiewebcamp-archive-navigation-day-archives</a><br />* <a href=\"http://tantek.com/2016/330/b1/2017-01-01-indieweb-commitment-own-my-rsvps\">http://tantek.com/2016/330/b1/2017-01-01-indieweb-commitment-own-my-rsvps</a><br /><br />More on archives, navigation, pagination:<br />* <a href=\"https://indieweb.org/archive\">https://indieweb.org/archive</a><br />* <a href=\"https://indieweb.org/navigation\">https://indieweb.org/navigation</a><br />* <a href=\"https://indieweb.org/archive_navigation\">https://indieweb.org/archive_navigation</a><br />* <a href=\"https://indieweb.org/pagination\">https://indieweb.org/pagination</a>" }, "author": { "type": "card", "name": "Tantek \u00c7elik", "url": "http://tantek.com/", "photo": "https://aperture-media.p3k.io/tantek.com/acfddd7d8b2c8cf8aa163651432cc1ec7eb8ec2f881942dca963d305eeaaa6b8.jpg" }, "post-type": "note", "_id": "1420707", "_source": "1", "_is_read": true }
{ "type": "entry", "published": "2018-11-13T20:05:34-05:00", "url": "https://martymcgui.re/2018/11/13/200534/", "featured": "https://martymcgui.re/imageproxy/960,fit,s3XR-DoqI1vPJFsKdNSfC3Db47FnlmmtoOFLnv-RkeaI=/https://media.martymcgui.re/5c/8c/e6/23/fbc1f119c93947469e36dd7578cd5527b7a030102570f65162780c7a.jpg", "category": [ "HWC", "IndieWeb", "Baltimore", "wrap-up" ], "name": "HWC Baltimore 2018-11-13 Wrap-Up", "content": { "text": "Baltimore's first Homebrew Website Club of November met at the Digital Harbor Foundation Tech Center on November 13th.\nHere are some notes from the \"broadcast\" portion of the meetup:\n\n jonathanprozzi.net \u2014 Ran into an issue with his homepage. Some nginx rule was falling back to a default site. Got it fixed, though. Been doing lots of web dev for work, but none for his personal site.\n \n\n\n martymcgui.re \u2014 Been traveling a lot! Went to IWC Berlin and Accessibility Club and had a great time! Grateful to catch up with and meet new people in the IndieWeb community. Worked on month/year archive navigation for the new Hugo version of his site, which is very close to being feature-complete compared to his Jekyll site.\n \n\nOther discussion:\nIWC Berlin! Marty went and there were many good sessions.\n Changes in organizing HWCs (wiki stuff) and related events (travel sponsorships for IWCs, peripheral events that could bring people into the IndieWeb community).\n \nReplacing Flickr. Flickr dumping free content beyond the latest 1000 images. DHF relies heavily on Flickr albums, including using them for the homepage of their site. Will probably get a Flickr Pro account now, request an export to make sure their photos are safe.\n Web accessibility! So many fresh new JavaScript-based things refuse to use semantic markup, or otherwise break navigation or readability, making them unusable. Accessibility Club had a lot of good lessons. Hopefully the videos of the talks will go up soon!\n \n WordPress accessibility issues around the new Gutenberg editor, the problems with Automattic pushing it through without listening to community. Yikes.\n \n\nLeft-to-right: martymcgui.re, jonathanprozzi.netThanks to everyone who came out! We look forward to seeing you at our next meetup on Tuesday, November 27th at 7:30pm!", "html": "<p>Baltimore's first <a href=\"https://indieweb.org/events/2018-11-13-homebrew-website-club-baltimore\">Homebrew Website Club of November</a> met at the <a href=\"https://digitialharbor.org/\">Digital Harbor Foundation Tech Center</a> on November 13th.</p>\n<p>Here are some notes from the \"broadcast\" portion of the meetup:</p>\n<p>\n jonathanprozzi.net \u2014 Ran into an issue with his homepage. Some nginx rule was falling back to a default site. Got it fixed, though. Been doing lots of web dev for work, but none for his personal site.\n <br /></p>\n<p>\n martymcgui.re \u2014 Been traveling a lot! Went to <a href=\"https://indieweb.org/2018/Berlin\">IWC Berlin</a> and <a href=\"https://accessibility-club.org/\">Accessibility Club</a> and had a great time! Grateful to catch up with and meet new people in the IndieWeb community. Worked on month/year archive navigation for the new Hugo version of his site, which is very close to being feature-complete compared to his Jekyll site.\n <br /></p>\n<p>Other discussion:</p>\n<ul><li>IWC Berlin! Marty went and there were many good sessions.</li>\n <li>Changes in organizing HWCs (wiki stuff) and related events (travel sponsorships for IWCs, peripheral events that could bring people into the IndieWeb community).</li>\n <li>\n<a href=\"https://indieweb.org/2018/Berlin/photos\">Replacing Flickr</a>. Flickr dumping free content beyond the latest 1000 images. DHF relies heavily on Flickr albums, including using them for the homepage of their site. Will probably get a Flickr Pro account now, request an export to make sure their photos are safe.</li>\n <li>Web accessibility! So many fresh new JavaScript-based things refuse to use semantic markup, or otherwise break navigation or readability, making them unusable. Accessibility Club had a lot of good lessons. Hopefully the videos of the talks will go up soon!</li>\n <li>\n WordPress accessibility issues around the new Gutenberg editor, the problems with Automattic pushing it through without listening to community. Yikes.\n <br /></li>\n</ul><img class=\"u-featured\" src=\"https://martymcgui.re/imageproxy/960,fit,s3XR-DoqI1vPJFsKdNSfC3Db47FnlmmtoOFLnv-RkeaI=/https://media.martymcgui.re/5c/8c/e6/23/fbc1f119c93947469e36dd7578cd5527b7a030102570f65162780c7a.jpg\" alt=\"fbc1f119c93947469e36dd7578cd5527b7a030102570f65162780c7a.jpg\" />Left-to-right: martymcgui.re, jonathanprozzi.net<p>Thanks to everyone who came out! We look forward to seeing you at our next meetup on Tuesday, November 27th at 7:30pm!</p>" }, "author": { "type": "card", "name": "Marty McGuire", "url": false, "photo": "https://aperture-proxy.p3k.io/8275f85e3a389bd0ae69f209683436fc53d8bad9/68747470733a2f2f6d617274796d636775692e72652f696d616765732f6c6f676f2e6a7067" }, "post-type": "article", "_id": "1413346", "_source": "175", "_is_read": true }
Rolled out several fixes today for receiving Webmentions, parsing different kinds of usernames, and notifying Mastodon instances. Hopefully all these cross-site interactions will be a little bit more seamless now.
{ "type": "entry", "author": { "name": "Manton Reece", "url": "https://www.manton.org/", "photo": "https://aperture-proxy.p3k.io/907926e361383204bd1bc913c143c23e70ae69bb/68747470733a2f2f6d6963726f2e626c6f672f6d616e746f6e2f6176617461722e6a7067" }, "url": "https://www.manton.org/2018/11/13/rolled-out-several.html", "content": { "html": "<p>Rolled out several fixes today for receiving Webmentions, parsing different kinds of usernames, and notifying Mastodon instances. Hopefully all these cross-site interactions will be a little bit more seamless now.</p>", "text": "Rolled out several fixes today for receiving Webmentions, parsing different kinds of usernames, and notifying Mastodon instances. Hopefully all these cross-site interactions will be a little bit more seamless now." }, "published": "2018-11-13T17:16:31-06:00", "post-type": "note", "_id": "1412826", "_source": "12", "_is_read": true }
{ "type": "entry", "published": "2018-11-13T21:25:01+0000", "url": "https://seblog.nl/2018/11/13/3/pushapi-without-notifications", "category": [ "indieweb", "PushAPI", "notifications" ], "syndication": [ "https://news.indieweb.org/en/seblog.nl/2018/11/13/3/pushapi-without-notifications" ], "name": "PushAPI without Notifications", "content": { "text": "Recently I\u2019ve been to IndieWebCamp Berlin, where I spend the Hack\u00a0Day on abusing the PushAPI to update ServiceWorker caches.\nI would like to start with a small section on what and why, but while I was procrastinating on writing this blog post (the pressure is high), no one less than Jeremy Keith wrote a blog post about it. Since that\u2019s a perfect what and why, there are just two things to do for me here: demo and how.\nDemo\nI did a demo in Berlin, but the demo-gods where unforgiving. It did not work at all, but when I got back to my seat, it started working again. What happened? My Mac tried to be nice and turned off notifications while I was presenting.\nBut, as to make up for it, the new macOS Mojave shipped with a screen capturing tool. So here is a retry of the demo in under 5 minutes:\nThe how\nThis might not be the most interesting part of it, but it\u2019s nice to share work. It\u2019s not a full comprehensive guide on how to do this stuff, because that would just take way too long. See it as a quick guide behind the different API\u2019s involved. \nI googled it all anyway. You can google along.\nOh and if you want to skip ahead: there are some use cases at the end.\nShowing a local notification\nLike with any Javascript, you should check support before you ask something. There is a list of things to ask in the below code example: we want Notifications, it should not be denied, there has to be ServiceWorker support, and for the part later on, there should be a PushManager too. \nOnce we prompted the user and got permission, it\u2019s as simple as getting our ServiceWorker registration and ask it to show a notification. As you can see: this involves the ServiceWorker, but it does not involve any other servers.\nfunction activateNotifications() {\n Notification.requestPermission()\n .then(status => this.status = status)\n},\n\nfunction supportsNotifications() {\n return ('Notification' in window) && (this.status !== 'denied') &&\n ('serviceWorker' in navigator) && ('PushManager' in window)\n}\n\nasync function sendTestNotification() {\n const reg = await navigator.serviceWorker.getRegistration()\n\n return reg.showNotification('Hallo, test!')\n}\nNote: the demo code is using Vue, which I leave out in this blog post to simplify things. But that\u2019s where this points to: a collection of variables on the Vue instance.\nSubscribing for the PushAPI\nOnce the user clicks the button \u2018Subscribe\u2019, the following function gets triggered. In here, we again get the ServiceWorker registration, and then access the PushManager on it, which we tell to subscribe.\nasync function subscribe() {\n const reg = await navigator.serviceWorker.getRegistration()\n const sub = await reg.pushManager.subscribe({\n userVisibleOnly: true, // required for Chrome\n applicationServerKey: urlB64ToUint8Array(this.publicVapidKey)\n })\n\n this.notifications = true\n const key = sub.getKey('p256dh')\n const token = sub.getKey('auth')\n\n await this.$http.post('/subscriptions', {\n endpoint: sub.endpoint,\n key: key ? btoa(String.fromCharCode.apply(null, new Uint8Array(key))) : null,\n token: token ? btoa(String.fromCharCode.apply(null, new Uint8Array(token))) : null\n })\n\n this.subscribed = sub !== null\n},\nSome browsers have their own way of doing authentication, but the most universal is with a Vapid key pair. The package I use for the backend came with a way of creating them. We give the public key to the PushManager, which will give us a Subscription object.\nIn the end, we send the Subscription\u2019s key, token and endpoint to the server via a POST request.\nNote: my HTTP library of choice is axios and the urlB64ToUint8Array() function can be found here\nStoring the Subscription\nFor the backend, I\u2019m using a Laravel package for WebPush, which allows me to save the endpoint with very minimal code:\npublic function update(Request $request)\n{\n $this->validate($request, ['endpoint' => 'required']);\n $request->user()->updatePushSubscription(\n $request->endpoint,\n $request->key,\n $request->token\n );\n return response()->json(null, 201);\n}\nAs you can see, it is using the user to associate the data with. (I fake the auth in the demo, which I do not recommend.) It ends up in a database, with four main columns: user_id, endpoint, public_key, auth_token.\nIn theory, you can go without users, but you will need to store the other parts. The token and key look like random strings, but the endpoint is an actual URL, on a subdomain of either Mozilla or Google, depending on the browser. (No support on Safari yet, mind you.)\nThese endpoints and tokens can expire, so you will need to keep an eye on the table.\nSending the notification\nI can be short about this part: I have no idea. The following code is all it takes to trigger it:\nNotification::send(\n User::all(), \n new NewBlogPostCreated($content, $notify)\n);\n... where $content is the content of the post, and $notify a boolean, telling my ServiceWorker whether or not to show a notification (we\u2019ll get to that).\nThe NewBlogPostCreated class extends Laravel\u2019s build-in Notification class and has these two methods:\npublic function via($notifiable)\n{\n return [WebPushChannel::class];\n}\n\npublic function toWebPush($notifiable, $notification)\n{\n return (new WebPushMessage)\n ->title($this->notify ? 'notify' : 'update-cache')\n ->body($this->content);\n}\nThere is a lot of magic behind the scenes here. I have no idea. In the end, they send a POST request to the endpoints of those users, after signing the right things with the right keys.\nReceiving the notification and then don\u2019t\nNext, we\u2019re back in Javascript-land, however, this is the ServiceWorker-province. The ServiceWorker, once installed, is a script, written in Javascript, but completely decoupled from any window. It lives in your browser and represents not one page, but your whole website. \nIt\u2019s quite hard to wrap your head around at first, but, I think the PushAPI makes it easier: there is no window involved with a push message, and there is no page involved with a push message. There is only your ServiceWorker, which acts for your whole website.\nThe ServiceWorker script itself consists of a series of callbacks, that are executed whenever things happen. In the case of a push message, the 'push' event is triggered:\n(function() {\n 'use strict';\n\n self.addEventListener('push', function (e) {\n const data = e.data.json()\n\n self.caches.open('manual')\n .then(cache => cache.put('hello', new Response(data.body)))\n\n if (data.title == 'notify') {\n e.waitUntil(\n self.registration.showNotification(\n 'New content!', \n {body: data.body}\n )\n );\n }\n });\n\n})();\nThat\u2019s all I need for receiving push notifications. I first retrieve the data from the message. Then I open the cache named \u2018manual\u2019 and I put the body of the message in that cache as the content of a URL (in this case \u2018offline.test/hello\u2019). It is made for pages, but I use it as a key-value store here.\nThen I check the title field, which I have abused for this purpose. If it is set to the magic string \u2018notify\u2019, I will trigger the notification. If it\u2019s something else I will do nothing.\nThis shows that I don\u2019t have to: I can leave the notification out, but I still get a ServiceWorker activation and I can do whatever I want with it.\nUse cases\nI think this can be used for creepy things (can I occasionally ping my ServiceWorkers and ask for data like \u2018how many windows are open?\u2019 and phone that home?), but I also think there are nice uses for this as well.\nAs Jeremy wrote: this can be used for magazines, podcasts and blogs to push new content to my phone, to read on a plane or in the subway when I\u2019m offline. I see a nice feature for a web-based IndieWeb Reader too: it can push me copies of posts it collected.\nI think the Reader is a nice place to use this. With great power comes great responsibility. Do I want to grand that great power to that weird magazine, that dubious podcast, that blog I visit once or twice a month? I might know you well, I might not. Do I trust you, pushing megabytes on my phone without me noticing?\nWeb apps like a Reader are easier to bond with. Plus: once I know my Reader supports reading offline, I might visit it in the subway. Will I remember the magazine? \nThe last bonus of the IndieWeb Reader specifically: it can send me posts from any magazine or podcast or blog, whether they support offline reading or not. But that\u2019s more specific to the Reader than it is to Push.\nI\u2019m also very curious to know how things will evolve if ServiceWorkers get even more superpowers. How well will those pair with a free ServiceWorker activation? Lot\u2019s of exploring to do!", "html": "<p>Recently I\u2019ve been to IndieWebCamp Berlin, where I spend the Hack\u00a0Day on abusing the PushAPI to update ServiceWorker caches.</p>\n<p>I would like to start with a small section on what and why, but while I was procrastinating on writing this blog post (the pressure is high), no one less than Jeremy Keith wrote <a href=\"https://adactio.com/journal/14511\">a blog post about it</a>. Since that\u2019s a perfect what and why, there are just two things to do for me here: demo and how.</p>\n<h2>Demo</h2>\n<p>I did a demo in Berlin, but the demo-gods where unforgiving. It did not work at all, but when I got back to my seat, it started working again. What happened? My Mac tried to be nice and turned off notifications while I was presenting.</p>\n<p>But, as to make up for it, the new macOS Mojave shipped with a screen capturing tool. So here is a retry of the demo in under 5 minutes:</p>\n<h2>The how</h2>\n<p>This might not be the most interesting part of it, but it\u2019s nice to share work. It\u2019s not a full comprehensive guide on how to do this stuff, because that would just take way too long. See it as a quick guide behind the different API\u2019s involved. </p>\n<p>I googled it all anyway. You can google along.</p>\n<p><em>Oh and if you want to skip ahead: there are some use cases at the end.</em></p>\n<h3>Showing a local notification</h3>\n<p>Like with any Javascript, you should check support before you ask something. There is a list of things to ask in the below code example: we want Notifications, it should not be denied, there has to be ServiceWorker support, and for the part later on, there should be a PushManager too. </p>\n<p>Once we prompted the user and got permission, it\u2019s as simple as getting our ServiceWorker registration and ask it to show a notification. As you can see: this involves the ServiceWorker, but it does not involve any other servers.</p>\n<pre><code>function activateNotifications() {\n Notification.requestPermission()\n .then(status => this.status = status)\n},\n\nfunction supportsNotifications() {\n return ('Notification' in window) && (this.status !== 'denied') &&\n ('serviceWorker' in navigator) && ('PushManager' in window)\n}\n\nasync function sendTestNotification() {\n const reg = await navigator.serviceWorker.getRegistration()\n\n return reg.showNotification('Hallo, test!')\n}</code></pre>\n<p><em>Note: the demo code is using <a href=\"https://vuejs.org\">Vue</a>, which I leave out in this blog post to simplify things. But that\u2019s where <code>this</code> points to: a collection of variables on the Vue instance.</em></p>\n<h3>Subscribing for the PushAPI</h3>\n<p>Once the user clicks the button \u2018Subscribe\u2019, the following function gets triggered. In here, we again get the ServiceWorker registration, and then access the PushManager on it, which we tell to subscribe.</p>\n<pre><code>async function subscribe() {\n const reg = await navigator.serviceWorker.getRegistration()\n const sub = await reg.pushManager.subscribe({\n userVisibleOnly: true, // required for Chrome\n applicationServerKey: urlB64ToUint8Array(this.publicVapidKey)\n })\n\n this.notifications = true\n const key = sub.getKey('p256dh')\n const token = sub.getKey('auth')\n\n await this.$http.post('/subscriptions', {\n endpoint: sub.endpoint,\n key: key ? btoa(String.fromCharCode.apply(null, new Uint8Array(key))) : null,\n token: token ? btoa(String.fromCharCode.apply(null, new Uint8Array(token))) : null\n })\n\n this.subscribed = sub !== null\n},</code></pre>\n<p>Some browsers have their own way of doing authentication, but the most universal is with a <a href=\"https://blog.mozilla.org/services/2016/08/23/sending-vapid-identified-webpush-notifications-via-mozillas-push-service/\">Vapid</a> key pair. The package I use for the backend came with a way of creating them. We give the public key to the PushManager, which will give us a <code>Subscription</code> object.</p>\n<p>In the end, we send the <code>Subscription</code>\u2019s key, token and endpoint to the server via a POST request.</p>\n<p><em>Note: my HTTP library of choice is <a href=\"https://github.com/axios/axios\">axios</a> and the <code>urlB64ToUint8Array()</code> function can be found <a href=\"https://github.com/gbhasha/base64-to-uint8array/blob/master/index.js\">here</a></em></p>\n<h3>Storing the Subscription</h3>\n<p>For the backend, I\u2019m using a <a href=\"http://laravel-notification-channels.com/webpush/\">Laravel package for WebPush</a>, which allows me to save the endpoint with very minimal code:</p>\n<pre><code>public function update(Request $request)\n{\n $this->validate($request, ['endpoint' => 'required']);\n $request->user()->updatePushSubscription(\n $request->endpoint,\n $request->key,\n $request->token\n );\n return response()->json(null, 201);\n}</code></pre>\n<p>As you can see, it is using the user to associate the data with. (I fake the auth in the demo, which I do not recommend.) It ends up in a database, with four main columns: <code>user_id</code>, <code>endpoint</code>, <code>public_key</code>, <code>auth_token</code>.</p>\n<p>In theory, you can go without users, but you will need to store the other parts. The token and key look like random strings, but the endpoint is an actual URL, on a subdomain of either Mozilla or Google, depending on the browser. (No support on Safari yet, mind you.)</p>\n<p>These endpoints and tokens can expire, so you will need to keep an eye on the table.</p>\n<h3>Sending the notification</h3>\n<p>I can be short about this part: I have no idea. The following code is all it takes to trigger it:</p>\n<pre><code>Notification::send(\n User::all(), \n new NewBlogPostCreated($content, $notify)\n);</code></pre>\n<p>... where <code>$content</code> is the content of the post, and <code>$notify</code> a boolean, telling my ServiceWorker whether or not to show a notification (we\u2019ll get to that).</p>\n<p>The <code>NewBlogPostCreated</code> class extends Laravel\u2019s build-in <code>Notification</code> class and has these two methods:</p>\n<pre><code>public function via($notifiable)\n{\n return [WebPushChannel::class];\n}\n\npublic function toWebPush($notifiable, $notification)\n{\n return (new WebPushMessage)\n ->title($this->notify ? 'notify' : 'update-cache')\n ->body($this->content);\n}</code></pre>\n<p>There is a lot of magic behind the scenes here. I have no idea. In the end, they send a POST request to the endpoints of those users, after signing the right things with the right keys.</p>\n<h3>Receiving the notification and then don\u2019t</h3>\n<p>Next, we\u2019re back in Javascript-land, however, this is the ServiceWorker-province. The ServiceWorker, once installed, is a script, written in Javascript, but completely decoupled from any window. It lives in your browser and represents not one page, but your whole website. </p>\n<p>It\u2019s quite hard to wrap your head around at first, but, I think the PushAPI makes it easier: there is no window involved with a push message, and there is no page involved with a push message. There is only your ServiceWorker, which acts for your whole website.</p>\n<p>The ServiceWorker script itself consists of a series of callbacks, that are executed whenever things happen. In the case of a push message, the <code>'push'</code> event is triggered:</p>\n<pre><code>(function() {\n 'use strict';\n\n self.addEventListener('push', function (e) {\n const data = e.data.json()\n\n self.caches.open('manual')\n .then(cache => cache.put('hello', new Response(data.body)))\n\n if (data.title == 'notify') {\n e.waitUntil(\n self.registration.showNotification(\n 'New content!', \n {body: data.body}\n )\n );\n }\n });\n\n})();</code></pre>\n<p>That\u2019s all I need for receiving push notifications. I first retrieve the data from the message. Then I open the cache named \u2018manual\u2019 and I put the body of the message in that cache as the content of a URL (in this case \u2018offline.test/hello\u2019). It is made for pages, but I use it as a key-value store here.</p>\n<p>Then I check the title field, which I have abused for this purpose. If it is set to the magic string \u2018notify\u2019, I will trigger the notification. If it\u2019s something else I will do nothing.</p>\n<p>This shows that I don\u2019t have to: I can leave the notification out, but I still get a ServiceWorker activation and I can do whatever I want with it.</p>\n<h2>Use cases</h2>\n<p>I think this can be used for creepy things (can I occasionally ping my ServiceWorkers and ask for data like \u2018how many windows are open?\u2019 and phone that home?), but I also think there are nice uses for this as well.</p>\n<p>As Jeremy wrote: this can be used for magazines, podcasts and blogs to push new content to my phone, to read on a plane or in the subway when I\u2019m offline. I see a nice feature for a web-based IndieWeb <a href=\"https://indieweb.org/reader\">Reader</a> too: it can push me copies of posts it collected.</p>\n<p>I think the Reader is a nice place to use this. With great power comes great responsibility. Do I want to grand that great power to that weird magazine, that dubious podcast, that blog I visit once or twice a month? I might know you well, I might not. Do I trust you, pushing megabytes on my phone without me noticing?</p>\n<p>Web apps like a Reader are easier to bond with. Plus: once I know my Reader supports reading offline, I might visit it in the subway. Will I remember the magazine? </p>\n<p>The last bonus of the IndieWeb Reader specifically: it can send me posts from any magazine or podcast or blog, whether they support offline reading or not. But that\u2019s more specific to the Reader than it is to Push.</p>\n<p>I\u2019m also very curious to know how things will evolve if ServiceWorkers get even more superpowers. How well will those pair with a free ServiceWorker activation? Lot\u2019s of exploring to do!</p>" }, "author": { "type": "card", "name": "Sebastiaan Andeweg", "url": "https://seblog.nl/", "photo": "https://aperture-proxy.p3k.io/10e8aeca31d1cd146999fcacc07a8eb9ad47c813/68747470733a2f2f7365626c6f672e6e6c2f70686f746f2e6a7067" }, "post-type": "article", "_id": "1411685", "_source": "1366", "_is_read": true }
{ "type": "entry", "published": "2018-11-13T07:17:11-05:00", "url": "https://david.shanske.com/2018/11/13/an-indieweb-podcast-episode-11-four-iwcs-later/", "name": "Episode 11 - Four IWCs Later", "content": { "text": "https://david.shanske.com/wp-content/uploads/2018/11/Indieweb11.mp3In the latest episode of An Indieweb Podcast, Chris Aldrich and I get together to talk about what we\u2019ve been up to since the last episode in September.\n\u00a0", "html": "<a href=\"https://david.shanske.com/wp-content/uploads/2018/11/Indieweb11.mp3\">https://david.shanske.com/wp-content/uploads/2018/11/Indieweb11.mp3</a><p>In the latest episode of An Indieweb Podcast, Chris Aldrich and I get together to talk about what we\u2019ve been up to since the last episode in September.</p>\n<p>\u00a0</p>" }, "author": { "type": "card", "name": "David Shanske", "url": "https://david.shanske.com/", "photo": "https://david.shanske.com/wp-content/uploads/avatar-privacy/cache/gravatar/2/c/2cb1f8afd9c8d3b646b4071c5ed887c970d81d625eeed87e447706940e2c403d-125.png" }, "post-type": "article", "_id": "1408734", "_source": "5", "_is_read": true }