
March 8, 2026
For many developers who experienced the early days of the hacker culture and the free software movement, programming once had a different rhythm.
It was exploratory. Curious. Creative.
Developers wrote small tools, scripts, and experiments simply because they could. Those scripts often solved small problems, automated repetitive work, or produced something interesting just for the joy of seeing it work.
In many modern software teams, however, development often revolves around a different metric: story points, sprint velocity, and continuous hotfixes. The focus shifts toward delivery pressure rather than creative problem-solving.
Small scripts are often overlooked.
But small scripts are where creativity thrives.
This project started as a way to rediscover that joy: a small Ruby script that generates an image of upcoming Ruby community events and publishes it automatically.
A simple idea. A simple tool. But a perfect playground for the hacker spirit.
Source Code
The bot used in this article is fully open source. You can explore the scripts that generate the image, post to Mastodon, and automate the workflow.
View the Source Code on GitHub
Includes the image generator script, Mastodon posting script, YAML event data, and the GitHub Actions workflow that runs the automation.
The Idea
The goal of the project is straightforward:
- Maintain a list of Ruby conferences and community events.
- Generate a visual summary as an image.
- Automatically publish it to social networks.
The result is a bot that periodically publishes a visual calendar of upcoming Ruby events.
The system is intentionally simple:
events.yml ↓image generator (Ruby + ruby-libgd) ↓image file ↓post_to_mastodon.rb ↓GitHub Actions automation
Each component is small and understandable.
And that is precisely the point.
The Data Source: events.yml
Everything begins with a simple YAML file.
Instead of a database or API, events are stored in a lightweight configuration file.
events: - name: RubyKaigi 2026 location: Hakodate, Japan date: 2026-04-16 - name: RailsConf 2026 location: Austin, TX date: 2026-07-08 - name: EuRuKo 2026 location: Brno, Czechia date: 2026-09-18
This approach keeps the system extremely flexible:
- anyone can contribute
- editing is trivial
- version control tracks changes
Sometimes the simplest data model is the best one.
Generating the Image with Ruby

The most interesting part of the project is the script that generates the image.
It uses ruby-libgd, a Ruby binding for the GD graphics library, which allows programs to create images programmatically.
The script reads the YAML file, sorts events by date, and prints them into a generated image.
Simplified example:
require "yaml"require "date"require "gd"events = YAML.load_file("events.yml")img = GD::Image.new(1200, 630)background = img.color_allocate(245, 242, 238)black = img.color_allocate(30, 30, 30)img.filled_rectangle(0, 0, 1200, 630, background)font = "fonts/DejaVuSans.ttf"y = 140events["events"].each do |event| text = "#{event['name']} — #{event['location']}" img.string_ft( black, font, 22, 0, 60, y, text ) y += 30endimg.png("ruby_events.png")
The script produces an image like this:
- a title header
- a list of events
- days remaining until each conference
- RubyStackNews branding
What makes this satisfying is that the output is visual.
The script does not just process data — it creates something tangible.
You run the program and an image appears.
Posting Automatically to Mastodon
Once the image is generated, another script takes care of publishing it.
Using the Mastodon API, the process is:
- Upload the generated image
- Create a status post
- Attach the image media
Example workflow in Ruby:
require "net/http"require "json"token = ENV["MASTODON_TOKEN"]media_upload = Net::HTTP.post( URI("https://ruby.social/api/v2/media"), { file: File.open("ruby_events.png") }, { "Authorization" => "Bearer #{token}" })media = JSON.parse(media_upload.body)Net::HTTP.post( URI("https://ruby.social/api/v1/statuses"), { status: "Upcoming Ruby events in the community", media_ids: [media["id"]] }, { "Authorization" => "Bearer #{token}" })
The result is a Mastodon post containing the generated image.
The entire process is still driven by small scripts.
No heavy frameworks.
Just Ruby.
The Automation Layer
Finally, the entire workflow runs automatically using GitHub Actions.
A workflow file schedules the job periodically.
.github/workflows/bot.yml
Example configuration:
name: Ruby Events Boton: schedule: - cron: "0 9 * * 1"jobs: generate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install dependencies run: bundle install - name: Generate image run: ruby demo/rsn_events_bot/social_event_image.rb - name: Post to Mastodon run: ruby demo/rsn_events_bot/post_to_mastodon.rb
Every week GitHub runs the scripts automatically.
No servers. No maintenance.
Just a scheduled workflow executing two Ruby scripts.
That is where the magic happens.
Small Scripts, Real Value
What makes projects like this meaningful is not their complexity.
It is their clarity.
A YAML file. A script that generates an image. A script that posts it. A workflow that runs everything automatically.
Each part is small. Understandable. Hackable.
This kind of project reminds us that programming can still be playful.
Sometimes the most satisfying tools are not large systems or complex architectures.
Sometimes they are just small scripts that do something useful — and a little beautiful — automatically.
And perhaps that is one way to keep the hacker spirit alive.
