Half-Elf on Tech

Thoughts From a Professional Lesbian

Author: Ipstenu (Mika Epstein)

  • Interlude: Gutenberg Moves Fast

    Interlude: Gutenberg Moves Fast

    I’m taking a pause on my plugin posts to talk about Gutenberg.

    I really love Gutenberg. I’m not kidding! I find it far more enjoyable to write (stories) in plain apps (I used Apple Pages because it syncs between laptop and iPad, yes, I am often using my iPad to write my novel, yes, I will let the world know when it’s done). But when I write for the web, it’s a more visual medium, and Gutenberg is fantastic to represent what I’m writing as it will be properly seen by all!

    But.

    Gutenberg moves fast. Hella fast. So fast it can leave you in the dust, and it has a critical flaw that I feel has been stifling it’s growth and usage among developers.

    JS isn’t your Momma’s PHP

    This is obvious. Javascript ain’t PHP. PHP is a simple language that can be coerced into doing complex things if you understand basic algebra. Surprise! Everyone who considers themselves good at PHP? You’ve mastered the concepts of algebra! Alegrba is one of the easier ‘complex’ mathematic concepts to wrap your head areoud. You get “if a + b = c and a = 10 and c = 11 then b = 1” and you win!

    Javascript though, it’s a little more like calculus and trig, in that you have to understand the formulas a little deeper, and they have that thing where not just numbers and letters appear, but weird symbols.

    [nb: Like all analogies, this falls apart at scale, don’t read too much into it.]

    For the thousands of developers who whet their teeth on PHP, jumping into JS feels like you’re a first-year high schooler in senior maths! It’s scary, it’s complicated, and worst of all … it isn’t actually documented at the micro level, because it’s generally compiled.

    Micro vs Macro / Interpreted vs Compiled

    The macro scale is, more or less, the big picture of what your code is supposed to do. Micro would be each individual element. For PHP, you can clearly identify both the macro (the overall function) and the micro (each teeny process in that function). This is less so for JS because the languages are different.

    There are two primary types of code languages. PHP is what we call an interpreted language, because while the PHP binary is a compiled app, what you write is interpreted by the compiler. Basic JS (like jQuery) is also an interpreted language!

    Compiled languages need a “build” step – they need to be manually compiled first. And if that suddenly made you think “Wait, Gutenberg is JS but I have to build it!” then you have spotted the quirk! The JS we use in Gutenberg is actually JSX!

    JSX was designed for React (which is what we use to build in Gutenberg) and while it may contain some plain Javascript, it’s impossible to use the code without React. That’s why we have the build process, it takes the JSX, compiles it into JS, and saves it to a file.

    The Compilation Downfall

    This is where it gets messy … messier.

    When there’s an error in PHP, we get the error message either on the page or in our logs, depending on how we set up our environment. I personally pipe things to debug.log and just keep that file up as I bash on things. Those errors tend to be incredibly helpful!

    $mastodon not defined on /path/to/file.php:123

    In that example, I know “Ooops, I’m calling the variable $mastodon on line 123 of file.php and forgot to declare it!” Either I need an isset() check or (in this case) I brain farted and copied a line but forgot to rename the variable so I was setting $tumblr twice. Mea culpa, pop in, edit, save, done.

    On the other hand, I was testing out some blocks and modernizing them a little when suddenly … the block didn’t load. I got the WP notice of the block had an error. You’ve probably seen this if you’re a dev:

    Example of an error which says "This block has encountered an error and cannot be previewed"

    or this:

    An error: This block contains unexpected or invalid content.

    And if you’re like me, you used foul language and wondered ‘well… now what.’

    Enter the Console

    Unlike PHP, the errors don’t go to a nice debug.log file, it goes to your in-browser console. This is because, again, PHP is being directly interpreted on the server, and the server happily converts the PHP to HTML and Bob’s your uncle.

    JS (and JSX in this case) aren’t processed by the server. They’re processed on the fly in the browser. If you’ve ever wondered why too much JS, or bad JS, cause your browser to hang, that’s why. We moved the processing from the server (PHP) to the browser. On top of that, it’s also why JS content isn’t really cachable by traditional methods! But that’s another story.

    In this case, I got the first error (cannot be previewed) and being somewhat savvy with the world of Gutes, I popped open the console and saw this gem:

    wp.blockEditor.RichText value prop as children type is deprecated

    The rest of the message was warning me that the thingy would be removed in WP 6.3, and it had a link to ‘help’ resolve it. Spoilers? It didn’t. But take a deep breath. Let’s debug.

    Debugging Gutenberg

    The first issue was that the error came on a page with multiple blocks. I happened to be using a custom plugin I wrote that contains about 6 blocks, you see, so I opened a new page on localhost and added each block, one at a time, until I determined the issue was my incredibly simple spoiler block.

    How simple is this block? It’s basically a custom formatted paragraph, so everyone could use the same design without having to remember the exact colours. I could have made it a ‘reusable block’ on the site but, at the time, I wanted the practice.

    Next I went to that link, which was for “Introducing Attributes and Editable Fields“. I admit, I was a little confused, since I was already using attributes and editable fields! But I did the logical thing and searched that page for the word ‘children.’ My thought process was that if something was being deprecated, it would have a warning right?

    Gif from Blazing Saddles, where Dom DeLuise is a director and walks up to an actor who made a mistake. He uses his bullhorn to scream WRONG! at the man, and bops him in the head with the bullhorn.

    Okay, maybe I was looking in the wrong place. This error is specific to RichText so I clicked on the link to read the RichText Reference and again, looked for “children.” Nothing. Zip. Nada. I followed the link for the more in-depth details on GitHub and still nothing.

    At this point, I ranted on Mastodon because I was chapped off. I also popped open the Gutenberg Deprecations page, and looked for “children” but all I could find was a message to use children!

    RichText explicit element format removed. Please use the compatible children format instead.

    Logically there should be a note that “children is deprecated, please use…” but there is not.

    Now, here is where I accidentally stumbled on a fix, but after I made my fix is when I found the Github issue about this!

    If you are still using “children” or “node” sources in the block attribute definition, like so:

    content: {
     	type: 'array',
     	source: 'children',
     	selector: 'p',
     }
    

    Then change it to use the “html” source instead to get rid of the deprecation warning:

    content: {
     	type: 'string',
     	source: 'html',
     	selector: 'p',
     }
    

    And in fact, that was the correct fix.

    Here’s the Flaw

    None of that was properly documented.

    The link to ‘help’ fix the error didn’t mention the specific error, it talked about attributes at the MACRO level. I was (obviously) already using attributes, else I wouldn’t have had that error at all.

    There is no proper documentation that could help someone fix the issue on their own UNLESS they happened to be trawling through all the issues on GitHub.

    As I put it to my buddy, the reasons developers are salty about Gutenberg are:

    1. It changes pretty much every release
    2. There’s no real way to tell people if it impacts you so you have to check every release and read the console logs, which is not what devs are used to
    3. The JS console won’t tell you (I don’t know if it can) what file caused the warning, so finding it is a crap shoot
    4. The documentation is high level, which is not helpful when you get micro level errors

    Okay, can we fix it?

    At this point, if you’ve made a WordPress Block for Gutenberg, make sure you test every single release with the JS console open. If you don’t do this, you will have a rude awakening until things are made a little better.

    How can things be made better? It will have to begin with a culture shift. Traditionally WordPress has used a “release and iterate” model. With Gutenberg, we’ve become “move fast and break things,” but that is only sustainable if everything broken can be documented for a fix.

    That means I see only one way to correct this, and it’s to slow down Gutenberg enough that deprecations AND THEIR CORRECTIONS are properly documented, and the error messages link to a page about deprecations.

    We need to not link to the general “here’s how attributes work” page, but instead to a specific page that lists those deprecations along side the WordPress versions impacted.

    Another matter is we should be posting in the Field Guide about these things. Currently the 6.3 field guide links to all the various pages where you can find information, but that means you have to click and open each one and hopefully find your exact usage. In my case, those links to the ten Gutenberg versions being ported to core never mention the issue I had.

    If we don’t start slowing down and paving the road for developers, we will begin haemorrhaging the very people who make WordPress a success.

  • Plugins: I Hate Security Plugins (mostly)

    Plugins: I Hate Security Plugins (mostly)

    Do not get excited. This is not going to be a name and shame post. No plugin will be named directly, though I bet a number of people will wonder if I meant their plugin.

    So here is your one and only explanation. After reviewing plugins for something between 12 and 15 years, as a pretty much daily process, I have incredibly strong opinions about development, companies, and ideologies. If you, while reading this, think I might mean you … probably not. You folks have no clue how many of the same problems I’ve seen!

    Actually, if you’ve read stories like ArsTechnica on how a plugin was tracking users, you have an idea. But it gets worse.

    With that done, I hate …

    99% of ‘Security’ Plugins

    This includes Jetpack. I know I said I wasn’t going to name and shame, and I’m not. Jetpack is the perfect illustration of the first problem with security plugins, and that is their WAF (web application firewall) requires editing files, and multiple times it’s broken on upgrade.

    I repeat, this is not a shame! The problem isn’t Jetpack is bad or wrong, here. The problem is even within a webhost, you get a dozen different versions of server software! Trust me, your webhost would loooove if all our sites were on the same server, but that isn’t how it works. You acquire servers in batches, so you get batches of ‘like’ and then god knows.

    But. Because of the myriad versions of server setups, it is impossible for Jetpack (or any WAF type plugin) to work perfectly 100% of the time. And this is especially true of upgrades, where servers prioritize different processes.

    Basically, I hate them because they can’t do the one thing for everyone, and I accept that.

    The real thing I hate about security … The things I hate…

    • They aren’t secure
    • They’re the wrong tool for the job
    • They slow your site
    • They think they know everything for everyone

    Safety in Danger

    Not being secure is as galling as you think. I have seen the vast majority of security plugins have the most basic wrong code out there. We’re talking not sanitizing, wrong sanitizing, not using prepare with SQL calls, not escaping, using sanitize functions to escape (and vice versa), and no nonces.

    All that was seen in a plugin I reviewed back in late 2022, and I remember just putting my face in my hands and shouting ‘aaaaarrrrrrgggggghhh’ loud enough to wake my aged cat. And it was not the only one.

    There are very few security plugins that have ever passed an initial review without having to be held back for security. I can only think of one in 2022-23, and they had a unique WordPress.org-only error (stable tags).

    Because of that, I’m probably never going to use anyone’s security plugin. I just cannot trust plugins that, by their nature, are trying to protect, but are not safe. It’s like locking your front door and leaving your patio doors wide open.

    Hammering with a Spoon

    I also have long said that most security plugins are the wrong tool. This directly relates to making your site slow, because you are using WordPress to monitor and secure itself. That’s always gonna be slow, folks. And honestly having your app be the check for itself has the blindingly obvious flaw of … if the site gets hacked, that plugin is gonna be useless in 10 seconds.

    The correct place for a firewall is a separate app on your server (or via DNS). The wall comes outside the town, people! It draws the line between dangers and safe.

    PS I would rename any plugin that’s a WAF to a castle or something beside wall. You’ve built a tiny fortress castle and WordPress is the noble who lives inside. You’re the last line of defence.

    The Need for Speed

    How do security plugins make a site slow? This should be obvious. If a plugin has to run on every single load of your site and check it the person visiting is an evil doer… it slows things down. The more checks, the slower.

    That’s it. Pretty simple.

    This is another reason I think they’re the wrong tool. They’re on WordPress, and run using the same specs that WordPress can. PHP is usually more limited than other commands on a server.

    I Know You Know

    The whole “I know better” schtick was popularized by Steve Jobs. He claimed he knew what customers wanted before they did.

    There was a plugin developer who had a security plugin that thought that. He got into a pissing match with another plugin that is hard to explain without naming names. Now, in this case I don’t feel the need to protect. They took to the forums and outed themselves. Heck, you can see some of the details of this saga on WPTavern.

    Even though there is a little more to the story, it really doesn’t pertain to this. Suffice to say, some of my burnout is directly related to that event, which was years before I retired from plugin reviews. Oh and no, it’s not about a safe-space situation that people seem to think I run in when I tell them I’m not going to continue a conversation. I just don’t feel the need to waste time and energy on someone who refuses to compromise. I feel that if I’m at an impasse and won’t be able to change the other’s mind, I will agree to disagree and stop arguing.

    That event is far from the only time I’ve seen someone decide “I know what is best, and I will force it” in a security plugin. Instead of giving options, or recommended settings, they go out and block what they think is wrong, regardless of the nuances. Sometimes they do it without a way to override, and that just isn’t cool.

    While the goal of perfect security is laudable, the reality is it’s impossible. There will never be a perfect solution for everyone, and if your security plugin doesn’t allow for the nuance of the real world, then I got nothing for you.

    Basically, Don’t

    This probably reads like “don’t bother with a security plugin.”

    There are some reasons you would want to use them. I use a lot of security checks on my sites, within WordPress, but for a specific purpose. See, I use them as tools to interact with services.

    For example, Akismet and spam. I have written bespoke plugins to stop a serial idiot from submitting a form so I don’t have to fire up my terminal and block IPs. I hate IP blocks. They always hurt the innocent.

    And yes, I am using the WAF from Jetpack right now on a large site! Warts and all, it’s been helpful.

    But for me? Having seen what I have with security plugins? They will always be a hard sell.

  • Plugins: When It Changed

    Plugins: When It Changed

    Many people have told me that I should write a book about plugins and name and shame the shitty ones.

    I’m not down with that.

    For the past fifteen years or there abouts, I’ve been reviewing plugins at WordPress.org. In 2015 I took over as the rep. I stepped down entirely in July 2023 for personal reasons that have nothing to do with my passion for WordPress, but is in fact “because” of WordPress.

    In fact, it’s really “because” of plugins. But to be specific, it’s because of developers.

    Book Him, Danno

    I really mean this. It didn’t used to be this bad at all. Sure we had some rough devs, many of whom have left the ecosystem, but overall the level of ashattery was tolerable. You could have an argument and things were kind of okay.

    I distinctly remember when that changed. Like, I can tell you exactly where I was standing, talking to a coworker, when it dawned on me what was happening and that this was probably a turning point.

    It was 2010 and we got the weirdest email from a company (fake name Booker Inc.) who explained their former employee (fake name Liam) had stolen a plugin.

    Stealing a plugin is a weird concept to many when you think of OpenSource. You can’t steal something that is free, and anyway WordPress’ license lets you fork (copy and alter). A lot of people despise me for saying they stole, likely becuase of that. But the reality here is if you take something, created by someone else, put your name on it and proclaim it was 100% your original work … ya done stole.

    An employee stealing from a company though, that was fascinating. I replied asking for some more details and what really was going on. As it transpired, Booker Inc. made a booking plugin that was behind a paywall, primarily built by an employee, Liam, who then was terminated, took the code, and put a copy up on WordPress.org.

    The Investigation

    Naturally the first thing I did was check the logs. Since Booker Inc’s was a paywall’d plugin, I asked for a copy to compare to as well. The logs I wanted to compare to their timeline claim. Liam was fired on X date, and a week later the plugin was submitted.

    That told me that it was extremely likely Booker Inc.’s plugin came first. I downloaded both plugins and ran a diff on them using DeltaWalker. What I saw was a line by line copy, where all copyright and credit was removed.

    The copyright is the reason, by the way, that I use the terms “theft” and “stealing” when I talk about this kind of thing. Copyrights and trademarks are, as I often say, “things with which one does not fuck around.” Copyright and Trademark laws are serious shit, and the GPL even says you need to include copyright! In fact…

    If you have copied code from other programs covered by the same license, copy their copyright notices too. Put all the copyright notices for a file together, right near the top of the file.

    How to Use GNU Licenses for Your Own Software

    Translation? Don’t remove people’s copyright!

    That means in this case, we had copyright infringement (the second plugin had removed the copyright), and a copy of a plugin that was line-to-line identical except the name.

    Oh and it was copied from a plugin … that wasn’t GPL.

    Conclusion Clue(do): Close the plugin.

    The End is the Beginning

    After the second plugin was closed, Liam was emailed something to the gist of “Your plugin is a copy of your old employers, Booker Inc., and you broke copyright. On top of that, the code isn’t GPL, so we can’t host it.”

    That’s pretty reasonable, I thought. It wasn’t until about 10 years later that we sat and formalized all those emails as you see today (mad thanks to Josepha for being my copy editor back in those days!). Back then, 2010? Nah, we were winging it. But the email in this story was serviceable.

    At the same time we did that, I emailed Booker Inc. and said the plugin was closed and we wouldn’t host it because of the GPL thing. Done, dusted, situation over.

    Liam replied that the code was legally his and he had the right to do this and change copyright as the owner.

    And you know what? That might have been the case.

    Above and Beyond

    One thing about plugins that pisses off OpenSource purists is that the guidelines are above and beyond the GPL. Meaning, you have to meet all the requirements and restrictions of the GPL, but you also have follow the WordPress.org guidelines!

    So what guidelines kick in when Booking Inc. reports a plugin is not GPL and Liam says since the plugin was 100% his, and he can re-assign the licence? Is that still theft? Is it violating the GPL requirement (one of the few we cannot give a ‘pass’ on)?

    At the time, the guidelines had a lot more wiggle room. Today, WordPress.org is patently clear that even if the premium plugin is GPL, we will not host it because it hurts the ecosystem. I readily agree that all plugins behind paywalls hurts the ecosystem as well, but taking someone’s work and giving it away (usually claiming it’s yours), is a dick thing to do. You took money out of their pockets and could be wrecking a small business. It’s a balancing act.

    I immediately asked Booking Inc. if they had a contract for the work that clearly spelled out ownership. They did, and agreed to share it with Plugins. It stated the work would be the property of Bookings Inc.

    Next I asked Liam if he had a copy of his contract so we could validate ownership rights. He did, he shared it with us, and lo the contracts matched.

    Now, regardless of my personal feelings on this, it was pretty clear. The contracts spelled out the code would belong to the company. It also actually said that the code wasn’t GPLv2, which I’d never seen in a contract before. The contract also stipulated that Liam would work with a team. They did the UX, he did the PHP.

    So. I emailed Liam back and said I was sorry, but the contract made it clear that he did not have legal ownership, and thus couldn’t change the license. In addition, even if he was the owner, the contract indicated he was not the sole developer, and would have to get permission from everyone who wrote so much as a line of code to change the license.

    Booking dot Hell

    At first, Liam seemed to understand. He didn’t like it, but he understood he’d signed this contract. I told him something I have told many people before, and it’s always get a contract that protects you. If someone hires you for work, get that damn contract to protect you. There’s a story I will share later about a reverse of this situation, but basically that contract exists to clarify who owns the code, who has the rights, and it wasn’t Liam.

    About a week or so later, Liam submits a new plugin. Also booking related. I eyeball it because while that contract implied an NDA existed to restrict Liam on working on booking code, I knew that wouldn’t hold up in court in their country. However, there is a fun legal concept known as “fruit from the poison tree.”

    If a single line of code in that plugin was taken from Booking Inc.’s plugin, the entirety of the new plugin was not permitted. Generally we advise people to not try and submit a similar/related plugin, mostly for that concern, but also because of bad-blood. There was no way on earth that Booking Inc. would be chill.

    As it happened, the code was about 75% the same. It was summarily rejected and Liam was told why. I distinctly remember telling him not to submit another booking plugin, because the wall for him was so high, he’d have to start from zero and not use anything from the original.

    Liam said he was mad, but understood. He said he wouldn’t resubmit a booking plugin.

    Liam Lied

    For the next three weeks, Liam made a new account every other day or so, and resubmitted variations on the plugin. I rejected them all and would email his first address, explaining he needed to stop.

    He didn’t. We ended up banning first his email domains, then his IP, and there was a time he couldn’t even visit .org. I hate doing that kind of ban, because it impacted others, but again, hard choices.

    Then it got weird.

    Someone with another booking plugin emailed plugins freaking out because they got an email, impersonating me, telling them that their plugin was closed! It was a mostly copy pasta of my email. And Liam had spoofed the plugin email address.

    I had the new person check the email headers, and we confirmed it was not official. But then more people with booking plugins contacted us! Worse, those emails had “me” attacking those people! The closest I get in plugin emails to insulting people is when I tell them they made a stupid choice, or they acted like a jerk.

    We fixed the spoofing issue, and that stopped, but it was that second email, the second one impersonating me, that told me this was bad. Real bad. This was changing the game bad.

    Abuse is Now Common

    It’s been 13 years, give or take, and people like Liam went from being a once in a decade occurrence to yearly to weekly, and finally to pretty much daily.

    People hear “no” and decide the correct thing is to be a complete and utter abusive asshole. They believe they have the right to do what they want, and damn everyone else. These days people call it being a “Karen.” Oh and yes, they ask if they can speak to my manager.

    A creepy smiling woman, who is about to break down an annoying customer.
    I AM the Manager (unknown source)

    By May 2023, if a day went by without someone, somewhere, deciding that the plugins team could fuck themselves, I was surprised and relieved. You’d get three in one day, move their emails to the auto-block system, and it would be tense for a couple days because most people made fake accounts to try again.

    And again.

    And again.

    The Toll

    While Liam pissed me off, personally, in retrospect what he did was tell me we needed to clean up the guidelines, organize our rules, and make it more clear that being abusive needed to stop. Impersonation should be an instant permaban.

    WordPress.org didn’t get a community guideline until 2022, and yes, I was one of many people who regularly complained that we needed it a hell of a lot sooner. It became up to each team to sort out how to handle infractions, and what in fact was an infraction.

    Each team has suffered rage quitting and burn out, due in part to the loosey goosey guidelines like that. It feels like you don’t have real support. If we did, that saga I refer to as “my idiot harasser” would have been a lot shorter. Or over.

    I don’t blame WordPress directly for this. The community has done their level best to help and protect each other. So has leadership, as much as they could. But I really do feel the absolute lack of overall guidelines for “don’t be a dick” would have short circuited a lot of the pain people have had to deal with.

    No, this was clearly not a thing WordPress did. This was a shift in the world, and honestly? It’s only gotten worse.

    Why Not Name?

    I have a lot of stories like this, and I absolutely will be sharing more. But I will not tell you exactly who people are.

    Oh Liam probably sees himself in this, and that’s fine. What’s he going to do? Leave a comment to complain I’m not telling the whole story, and out himself as a human who felt impersonation was the right way to prove his point? He crossed a line and there probably is no way back at this point.

    But naming him removes the “probably” from that. Naming him means that he is forever branded as the asshole. And I actually still firmly believe that nearly everyone can come back from crossing that line.

    Otto has often called me an optimist for that. He’s right. I am optimistic that the human condition lends itself to empathy. We’re all on this rock together. We aren’t getting to Mars if we can’t figure out how to exist respectfully with people we disagree with.

    And I feel that most people want to be in a group. Humans don’t want to be alone. Getting excluded from the group hurts, and people will do anything to get back in if that’s the only group. That’s reasonable, right? And when people have a bad day, getting kicked out, they lash out.

    Likely Liam and most people like him never think about me again. I recently was reminded that for an adult, making a joke about a kid being chubby doesn’t stick in the adult’s memory, it’s just another day. But that kid will remember the time and place their parent called them fat.

    I’m not the parent.

    I remember the days, probably all of them given a prompt, I’ve had to tell someone no and close the door on them. Because it remains my secret hope that everyone like Liam feels a little bad, and sorry. Not sorry because he got kicked out, though. Sorry that he hurt someone.

    And if that happens? If a Liam developed the empathy to understand how his actions harmed others and sincerely apologized? I would be the happiest woman in the world.

    I want to leave that door open for the Liams in the world.

    I hope you will too.

  • Plugin Stories: What Do You Want to Hear?

    Plugin Stories: What Do You Want to Hear?

    By July 2023, I will be retired from reviews.

    There are a lot of reasons why, but none matter for the purpose of this post.

    I’ve already written up and scheduled some posts about my time there, and things I’ve seen. One about when I realized the atmosphere in developers had made a serious shift (it involves plugin theft, NDAs, GPL, and impersonation), as well as why I hate most security plugins.

    But my problem is that I have a lot of plugin stories to tell.

    What kind of stories do you want to hear? What things have you always wondered about?

    While I will not name names except in cases where the story happened in public. In my first post (July 5) I’ll explain why in a little more detail about why I don’t name, so don’t ask for that. Besides, if I name and shame, they’ll come after me and I’m too tired for that shit.

    I’m weeding through my notes (yes, I have them for self protection) of stories that can be sanitized and retold, but not all can.

    Do people want to hear about common mistakes? Do they just want to see someone losing their blob (that’s most of them)? The ones I think most people would want to hear is thinks like the guy who stole a plugin from the contractor he hired.

    So. Comments are open. Do the thing. But be nice.

  • Zaptodon

    Zaptodon

    On a site, I use Zapier to automate a specific set of tasks. Every day, the website sets up a show/character of the day (I think you know what site this is…) and it posts that show/character to Twitter, Tumblr, Facebook and …. Mastodon.

    Or at least it does now.

    Zapier

    Caveat! I pay for this service. The webhooks used are in the starter package at $19.99/month annually.

    There’s a service, Zapier, that allows you to make incredibly complex if/then/else checks and performs an action. It’s not cheap, but at $250 a year it’s not expensive for my needs. Way back when, I picked it because I needed something that would let me actually script, and I recognized that running pushes like that all from my own server was a lot more work than it should be, what with all the libraries and so on.

    Seeing as that wasn’t driven by a post or any action except time, it had its own quirks. But then one day in May we all woke up and saw how dumb Twitter was. They priced WordPress.com and Automattic out of their own API!

    But not Zapier.

    Note: Automattic made the right choice here. With the API cost starting at $42,000 a month (yes, a month, and I can remember when I made that a year and thought I was hot shit), knowing how inexpensive Jetpack Pro/Premium/Whatever is, there was no way they could justify it.

    Zapier’s business model has a large chunk invested in pushing things to social (among all sorts of cool things, like calendar integration). So when I had to revisit how I posted new articles to Twitter anyway, I figured I’d wrangle Mastodon as well.

    The Zap Flow

    Overall, my flow looks like this:

    Screenshot of the Zapier flow, which shows: 1 - new item in RSS, 2 Post in Webhooks, 3 Create Tweet

    But what goes in each?

    The first one is a built in and easy trigger. It follows the RSS for the site and, when there’s a new article, off it goes.

    The third one is the tweet, which is about as straightforward as you might expect.

    The second one is Mastodon. That’s where we’re going to concentrate today.

    Add an App

    To do this, you need to create an ‘app’ for your Mastodon account. Log in to your instance (mine here is mstdn.social) and edit your profile. On that page, on the menu to the left, is an item called Development.

    On that page you’ll see a list of Applications, if you have any, and a button to create a New Application. That’s what we want to do today. Click on that button and you’ll get the basic data:

    New Application setup on Mastodon, asking for name and website.

    I put in “Zapier” and “https://zapier.com” as my

    Scroll further down and there are a bunch of options. You only need to have these two checked:

    • read:accounts
    • write:statuses 

    The read will let us know things worked, and write … I really hope that one is obvious for you, but you have to be able to write to post.

    Click create and you will be redirected to the Application page where it will now list your app to Zapier. Click on that and you’ll be show a page with the set up info, but now it has a Client Key and a Client secret.

    Example of the client keys and tokens.

    I clicked regenerate right after I took this screenshot.

    You’ll be able to get at this whenever you want, so don’t panic.

    Back to Zapier

    Over on Zapier, pop open your Zap. In my case, I had a pre-built one for Twitter, so I added this in by telling it I wanted to add an Action. Since I pay for Zapier, I have access to their premium webhook to post:

    Pretty clear I think. I need “Webhooks by Zapier” and the Event is POST. That’s telling Zapier what to do with the hook.

    The next part of the step is the Action and that has a lot of stuff. The first two are the URL and the Payload:

    The URL is going to be https://yourinstance.com/api/v1/statuses?access_token=[YourToken] — What’s your token? Remember that as the third item shown on the edit page for your Application over on your instance? Yep! Paste that in.

    I picked JSON for my payload since I’d been using it elsewhere. For the next part, I have to dig out the data. For Mastodon, you want your data ‘type’ to be status since that is literally telling it “I wanna make a status post!” and the content I made the description and the link.

    Example of STATUS and content.

    If you click on that box where I have description etc, it’ll pop up with more options!

    Example of other data you could insert.

    Pretty nifty! I left the rest as default:

    • Wrap Request In Array – no
    • File – empty
    • Unflatten – yes
    • Basic Auth – empty
    • Headers – empty

    Click on continue and you can test.

    Done!

    That’s it! Now your RSS feeds will auto post to Mastodon.

    I’m sure someone’s wondering “Why aren’t you using ActivityPub, Mika!?!” And the answer is… It doesn’t actually work on all hosts. ActivityPub requires you to be able to write to your .well_known/ folder and, currently, you cannot do that on DreamHost because it’s managed at the server level.

    This is not a wrong choice by either party! DreamHost (especially on DreamPress, the managed WP solution) wants to prevent you from breaking your SSL. Now, thanks to @diziara, there is a workaround if you can edit the .htaccess file in your .well_known folder:

    # Permit access to the challenge files but nothing else
    Order allow,deny
    Allow from all
    
    RewriteCond %{REQUEST_URI} ^/[.]well-known/webfinger+$
    RewriteRule .* /wp-json/activitypub/1.0/webfinger [L]
    
    RewriteCond %{REQUEST_URI} ^/[.]well-known/acme-challenge/[a-zA-Z0-9_-]+$
    RewriteRule .* - [L]
    
    RewriteRule .* - [F]
    

    Assuming your install is in root (mine is) you put that into the .htaccess and it works! I was surprised that it also let me edit on DreamPress, but I’m not sure if that will last. I’ll keep my support-thread updated though.

    And the other thing… I don’t want people to ‘follow’ my blog like that. I mean, you could, but also people follow me as me, and if I auto-post to ‘me’ then it works. Telling people to follow my blog and me is tricky since people are lazy (seriously we all are). But if that’s your thing, then yes, you absolutely can follow @ipstenu@halfelf.org and get all my articles.

    I’m still going to use a combination, since while I do want people to follow my blog, I suspect more will follow me instead. Also it’s easier to follow up on engagements (questions etc) if I’m watching ‘me’ and not two places. The other problem is it’s letting you follow ME at my blog. My other site has many more authors, and this isn’t quite right for that.

    The nice thing, though, is that there isn’t a single perfect answer for everyone’s use case. For most people, ActivityPub will work and they can be made discoverable. For the others, though, hold on until end of June. My friends at Automattic are planning to have post-to-mastodon support in their next iteration.

    I’ll still need my zaps since I post things that aren’t blog posts, but I’m looking forward to one less.

  • It’s Not About the Money

    It’s Not About the Money

    I left Twitter last year for a very personal and specific reason. That reason? They refuse to protect anyone.

    There remains a number of humans on Twitter who delight in harassing, blasting, humiliating (trying …), and vilifying me. One of whom was actually (briefly) banned. And it was rough enough before the new regime, who has made things objectively worse. Not a little worse, a lot worse.

    I went over to Mastodon and I have no regrets. It’s much nicer, even though there are some flaws (spam at the moment, but also some gatekeeping and racism that needs to stop). For example, on Sunday recently, I posted how I don’t believe in AI. I am my father’s daughter, after all, and there is nothing intelligent about what we’ve created, save in our own. The machine does not think, it does not innovate, it keeps to what it knows.

    On Mastodon? That got a lot of nuanced conversations. On Twitter I had to be handy with the block button.

    Now no social media is “great” for the soul, but Twitter has been doing a dumb ass speed run and hurting as many people as possible.

    Dangerous Minds

    On April 8th, Twitter removed the language in its hateful conduct policy that explicitly protected transgender people from online harassment. 

    Prior to the rule change, Twitter’s Hateful Content Policy stated:

    We prohibit targeting others with repeated slurs, tropes or other content that intends to dehumanize, degrade or reinforce negative or harmful stereotypes about a protected category. This includes targeted misgendering or deadnaming of transgender individuals. In some cases, such as (but not limited to) severe, repetitive usage of slurs, or racist/sexist tropes where the context is to harass or intimidate others, we may require Tweet removal. In other cases, such as (but not limited to) moderate, isolated usage where the context is to harass or intimidate others, we may limit Tweet visibility as further described below.

    It now is:

    We prohibit targeting others with repeated slurs, tropes or other content that intends to degrade or reinforce negative or harmful stereotypes about a protected category. In some cases, such as (but not limited to) severe, repetitive usage of slurs, or racist/sexist tropes where the context is to harass or intimidate others, we may require Tweet removal. In other cases, such as (but not limited to) moderate, isolated usage where the context is to harass or intimidate others, we may limit Tweet visibility as further described below.

    They removed a key number of words.

    1. dehumanize
    2. misgendering
    3. deadnaming

    This removal of stated protections happens at the same time Florida is banning drag shows, health care for trans youths, and more.

    Be Judged By Your Actions

    This is a technical sort of blog, I know. But this overlaps into that, so hold on a second.

    People will judge you by your actions. If you treat people like dirt, you will be seen as an asshole. If you’re Jewish, you’re likely familiar with the saying similar to “If someone sits down at a table with 11 Nazis, and doesn’t leave, you now have 12 Nazis.”

    The point being, your action of giving money to someone’s company when you are aware of their transphobic, homophobic, antisemitic, hate-filled actions, we are all going to look at you like you’re an asshole too. And when you allow those people in your community, you’re saying “I’m okay with these people who dehumanize others.”

    Now, how does this relate to tech, besides Twitter being a tech company?

    Take a LONG hard look at Twitter right now. See how many people are being unmitigated assholes to the users, and see that nothing is being done to stop it. Got that image in your head?

    Awesome. Now. What are YOU doing to stop it in YOUR products?

    I talk about how tech is open to being abused so much because, thus far, we have done very little to actually protect anyone. I mean, you tell me how you can block someone who could spin up a hundred accounts in minutes, just to email you and be a jerk? There are, of course, somethings you cannot stop but think about it this way…

    If someone came to your home to harass you, there are resources (cops, for example). It someone’s harassing you on Twitter, you go to Twitter support, right? They do nothing, which means they have a product and they don’t care about you. Hell, Twitter will tell you that someone telling you to that you deserve to suffer is fine, but will ban you for telling them to jump in a volcano, because you made a death threat.

    Not a joke. Happened to a friend.

    There aren’t laws that properly cover online abuse. They’re aren’t. Don’t get me started. But that means the responsibility is on US, the creators of the tools. I’ve said it a million times, if you make a forms plugin and do not take time to figure out ways to allow people to protect themselves, you failed. Look at how much custom code I’ve had to make just to get people to leave me alone!

    If your code won’t protect me, I won’t use it because it’s not safe. And when you side with people who categorically make things unsafe, well, now I don’t trust you.

    Stand By What You Believe In

    Someone’s probably going to ask me how far I go with this. I’ll put it this way. If, tomorrow, Musk ‘bought out’ WordPress, I would quit my job and start over with anything else. And I’d have to think about what to do with my websites.

    At the same time, if you’re still using Twitter as a non-paying user? That’s your call and I won’t think ill of you for it. There absolutely are some communities that only exist on Twitter, and moving them is a pain in the ass. I feel this way about Facebook, I hate it and I hate how it treats people, but I understand it’s a necessary evil. I wish it was easier to move everyone elsewhere, but not all products are built like WordPress.

    That’s the nice thing, I think. If, tomorrow, I had to quit WP, I really do have options! I can export and migrate! Because WordPress lets you own your data. But that’s another post.

    And contrary to what some people may think, I am absolutely in support of paying for social media! I donated to my Mastodon host (I just switched so I have to set things back up again) because a couple bucks a month for enjoyment is something I can afford.

    I’m opposed to PAYING to be treated like a second or third class human, and I absolutely judge you when you do pay them.

    Listen and Protect

    Here’s my advice and it starts with a story.

    Back in 2010 or so, there was a courthouse in Franklin County Ohio that had a glass staircase.

    Why is that a problem?

    Go put on a skirt while I stand underneath and tell you what color your underpants are (if you wear them).

    That’s a damned obvious problem to anyone who regularly wears skirts and dresses. Why didn’t the courthouse think of that? Men probably designed it and didn’t ask or didn’t listen until the Judge saw it and got pissed off.

    In order to make things safe, you have to listen to people. If a skirt-wearing human comes up and says “Hey, this is bad, people can see my panties” you shouldn’t do what the Courthouse did. They had a guard there to warn women, which is not a solution, and said they’d hope people would be mature … That is not listening, and it sure isn’t protecting.

    What they could have done is change the underside of the glass to reflect, or put a film on, or cordon it off so people can’t stand underneath. But instead they went “meh.”

    If you go ‘meh’, you’re the problem folks. You didn’t listen, and when the opportunity arose, you didn’t help.

    So. Listen. Think about what it means to someone else. Have empathy. And then code with that empathy.

    And spend your bucks with that empathy too, by the way.