2024-11-13 08:00:00
Yesterday, Lettini took a chance and posted about Jelly on Hacker News, a discussion site notorious for it's mercurial population of tech-maybe-too-saavy experts. Jelly is a tough sell for some of them, those with the technical skill to pipe email at a low level through custom-built filters running on their own cloud servers.
I'm not going to lie to you. I was pretty nervous.
And yet...
We got a really lovely response! It was also a great opportunity for us to practice talking about Jelly, about why we built it, what it stands for, and why people should consider it over other tools or workflows.
It gave us an opportunity to talk about our philosophy on pricing:
For us, affordability is part of the product itself.
We’re specifically building this not to hoover up every dollar on the table, but to serve smaller groups that have been left out in the cold by "bigger" tools, and who get screwed by per-seat pricing. We believe there are enough teams who fit this profile to be profitable.
There’s a difference between making profit and maximizing profit. the capitalists will call us crazy, but we're not here to maximize profit.
This really resonated:
I love this. Seriously.
This is such a refreshing perspective! I've always wondered if there's room for craftsmen to build quality products for smaller groups. Your focus on simple, well-designed software really resonates with me. Thanks for showing us a viable path.
A lot of people really got the product and the design choices we've been making:
I'm really liking the UX there! In sports-speak there's the "Whose got the ball" method to identify who is managing a topic...and the way this is executed - from what i saw in the video - seems really straight-forward to help answer that.
I really like the way this landing page is designed. And I think it really highlights one of the sales points, which is that you are decent and reasonable. Good stuff. I'm going to send this around to some people.
Of course, there were plenty of people offering their home-brewed alternatives that cover some of what Jelly does, setting up filters and forwarding and even using labels to "claim" messages.
It's fascinating to see how other people have approached this, and the existence of so many different "solutions" demonstrates, to me, that this is a problem that really exists in the world, and that really needs a Good Enough solution that works for people whether they are tech-saavy or not.
Anyway. Go try Jelly. It's approved by the smart folks at Hacker News. What are you waiting for?
2024-11-12 08:00:00
I have an admission to make. Social share images for Pika were broken on Twitter/X, LinkedIn, and Apple Messages for months. And it made me sad.
But in the past few months we got it fixed. And that made me very happy!
We really love our Pika social share images. They are pretty. They are readable. They reflect the theme chosen by the blogger. They're great! When they work.
One day we went to share one of our blog posts and noticed that Twitter/X wasn’t playing nicely with Pika. At the time that service had been repeatedly mucking with how it displayed links. Seemingly every week there was a new change. So we sat on it for a bit, but eventually we decided it was probably us, not them. Especially since a couple other services were also having issues.
We tried many and various things to fix it. I’ll share those below so we can get to the point…
The fix in our case was to make sure our server was returning the correct headers:
Content-Type: text/html; charset=utf-8
We arrived at this fix when a customer pointed out that our Content-Type
differed from other working services.
Using the service HTTP Header Check,
they shared output from our server that showed:
Content-Type: */*; charset=utf-8
Most services were fine figuring this out. Twitter/X, LinkedIn, and Apple Messages were not fine figuring this out. Naturally I introduced this bug when fixing another bug. 🤦
Our twenty-nine-comment thread on Basecamp proves we tried just about everything.
META
tags between Pika and various other blogs (including this one right here)META
tags about fifteen different ways for each little discrepancy that we detectedcharset=uft-8
vs charset=us-ascii
2024-09-09 08:00:00
FriendlyId is a helpful Ruby gem that streamlines creating permalinks and slugs for Rails applications. In Pika we're using it to help with generating permalinks for blog posts and pages as well as slugs for tags. When a customer wrote in with a request to modify the behavior of these permalinks, I wasn’t sure how easy it would be to override the default behavior. Turns out it wasn’t too bad!
In our case we wanted to change the permalink generated for things titled or named with apostrophes. For example, if your blog post title was "What’s the frequency, Kenneth?", when FriendlyId created the permalink it would replace the apostrophe with a dash:
what-s-the-frequency-kenneth
We wanted to change that so the permalink simply removed the apostrophe:
whats-the-frequency-kenneth
In fact, we wanted to do the same for all sorts of apostrophe, quote, and double-quote characters.
To make it happen we added this to our config/initializers/friendly_id.rb
file:
module FriendlyId
module Slugged
alias_method :original_normalize_friendly_id, :normalize_friendly_id
def normalize_friendly_id(string)
original_normalize_friendly_id(string.gsub(/'|"|‘|’|“|”/, ""))
end
end
end
We added some tests to assure that the behavior continues to work as expected and called it a day. 👏
2024-07-11 08:00:00
Dear readers, we need to apologize. We know some of you have noticed that Good Enough has gotten much quieter this year than last, across this blog, our newsletter, and socials. We’ve been heads down for the last few months on something new, but we’re now ready to come back up for air and hang with you again! We know you miss hearing from us.
So allow me to formally introduce Good Enough’s next product: Jelly! It’s a new shared inbox for teams. It’s a game-changer, and it’ll be out soon.
We last talked about this idea and the impetus for it back in March. As a small team of 6, we were just sharing a login to a single Fastmail inbox for all of our shared emails (i.e. [email protected], [email protected], [email protected], etc).
With every new product we built, our volume of emails from customers and friends grew, and by the end of last year we hit a tipping point. When we’d get an email, who on the team was going to answer it? How did anyone know they would answer it? Did they even see it? Where do we ask questions? Who on our team wrote this reply? We found ourselves constantly "Mark as unread"-ing email for others to hopefully find. It was a mess.
We knew we needed a better option, so we went searching for one. There’s plenty of help-desk adjacent inbox tools on the market, we thought. But oh boy, are they expensive! 🙈 We don’t need all the bells and whistles they charge to justify the high price, we just need a single inbox where we could properly collaborate. And we heard this same need from many other teams just like ours.
So we built one.
Jelly is our take on this common problem. It’s the simplest way for teams to jam on shared email, together. In Jelly, everyone on your team can easily see who-has-what, discuss messages privately in threaded comments, and gain a shared understanding of a conversation’s latest status.
We’ve actually been using Jelly for the last few months while we’ve been actively developing it. If you interacted with us over email recently, our team was using Jelly! And it’s been awesomely useful for us.
Let me give you a real example: Our resident Pika Expert Barry typically handles most email that’s sent to [email protected]. With Jelly’s ability to claim conversations, we can all now easily see at-a-glance which of those emails Barry said he’s going to handle, and which he hasn’t even seen yet. An immediate improvement.
Also, if I’m going to answer a Pika email but have a question for Barry first, I can ping him internally right within the conversation. This happens more often than you think!
And when Barry’s super efficient and knocks out a bunch of Pika emails before I start my day, I can catch up via the Recent Activity log.
The screenshots above are all from a quick funny demo account, but you get the point. There’s a bunch more features of the app, but at its core, it’s just like any other email inbox you’ve used before, but built for teams. We’ll be talking about it and showing off more over the next few weeks as we get back into the socials groove. We hope you follow along.
If you’re on a small team with shared addresses like hello@ or support@, we think Jelly could be really useful for you. Or if you’ve got a friend in this situation, please share!
We’ve got a few more i’s to dot and t’s to cross before it’s ready for a wider launch — we don’t even have a cute mascot yet! — but we’re going to open a beta pretty soon. If you’re interested in the beta or the wider launch, you can find a link to the waitlist here: https://letsjelly.com
2024-05-16 08:00:00
For a while now we've seen that images in our Pika atom feeds were not displaying in some feed readers. In fact, they weren't displaying in my own feed reader, which routes through Feedly. I was sad.
I spent a lot of time troubleshooting this. Compared our feed with a lot of atom and RSS feeds that worked. Eventually I came to a hair-brained idea: what if Rails's Action Text image display markup was confusing these feed readers?
Here was the content
portion of our non-working atom feed for an entry
with an image:
<content type="html"><div class="trix-content">
<div>An image is a beautiful thing.<action-text-attachment sgid="eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaEpJamRuYVdRNkx5OW1abVptYjNKMWJTOUJZM1JwZG1WVGRHOXlZV2RsT2pwQ2JHOWlMekV3TkRZL1pYaHdhWEpsYzE5cGJnWTZCa1ZVIiwiZXhwIjpudWxsLCJwdXIiOiJhdHRhY2hhYmxlIn19--a454c3d90c064b8d45d7ed11524dfbdd856d125a" content-type="image/png" url="https://pika.pika.page/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBaFlFIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3583419d5d88973090c20d101d0e61b2231f0740/image.png" filename="Screenshot 2024-01-04 at 11.31.26.png" filesize="65537" width="1884" height="272" previewable="true" caption="An image caption"><figure class="attachment attachment--preview attachment--png">
<img src="https://pika.pika.page/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBaFlFIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3583419d5d88973090c20d101d0e61b2231f0740/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJY0c1bkJqb0dSVlE2RkhKbGMybDZaVjkwYjE5c2FXMXBkRnNIYVFJQUJHa0NBQU09IiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--d0f1a0938c0356b14f70446487c075f2965131bb/image.png">
<figcaption class="attachment__caption">
An image caption
</figcaption>
</figure></action-text-attachment>
</div>
</div>
</content>
That's a little hard to follow, but taking out the escaped HTML, take note of this one spot:
<action-text-attachment sgid="eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaEpJamRuYVdRNkx5OW1abVptYjNKMWJTOUJZM1JwZG1WVGRHOXlZV2RsT2pwQ2JHOWlMekV3TkRZL1pYaHdhWEpsYzE5cGJnWTZCa1ZVIiwiZXhwIjpudWxsLCJwdXIiOiJhdHRhY2hhYmxlIn19--a454c3d90c064b8d45d7ed11524dfbdd856d125a" content-type="image/png" url="https://pika.pika.page/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBaFlFIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3583419d5d88973090c20d101d0e61b2231f0740/image.png" filename="Screenshot 2024-01-04 at 11.31.26.png" filesize="65537" width="1884" height="272" previewable="true" caption="An image caption">
<figure class="attachment attachment--preview attachment--png">
<img src="https://pika.pika.page/rails/active_storage/representations/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBaFlFIiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--3583419d5d88973090c20d101d0e61b2231f0740/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaDdCem9MWm05eWJXRjBTU0lJY0c1bkJqb0dSVlE2RkhKbGMybDZaVjkwYjE5c2FXMXBkRnNIYVFJQUJHa0NBQU09IiwiZXhwIjpudWxsLCJwdXIiOiJ2YXJpYXRpb24ifX0=--d0f1a0938c0356b14f70446487c075f2965131bb/image.png">
<figcaption class="attachment__caption">
An image caption
</figcaption>
</figure>
</action-text-attachment>
That special <action-text-attachment>
markup is certainly non-traditional HTML.
I got to wondering if maybe some feed readers were choking on it.
So I set to removing it.
# app/helpers/posts_helper.rb
def excise_action_text_attachment_from(html)
doc = Nokogiri::HTML.fragment(html)
doc.search('action-text-attachment').each do |attachment|
attachment.replace(attachment.inner_html)
end
doc.to_html
end
# app/views/posts/index.atom.builder
entry.content(excise_action_text_attachment_from(post.body.to_s), type: :html) if post.body.present?
It worked! Images were finally appearing in Feedly and all of the other feed readers we've tested. These hunches don't work out that often for me, but when they do. 👨🍳😘