What I’m Working On: WP2AT – A Ruby Gem
Tags: ruby, cli, wip
Published: 2021-03-24 01:38:46


## The Scenario: I work for a marketing company and our niche – the thing we’re really, really good at – is telling stories. One of the primary ways we tell our clients’ stories each month are blog posts. 

For new clients, it’s easy to remember all of the topics we’ve written about. But some of our clients have been with us for more than 8 years, and others have changed hands from client manager to client manager as the company evolves.

To help keep track of what topics we’ve written about, we started tracking blogs in AirTable. We keep track of the blog title, date posted, category, URL and Yoast SEO data as well. This makes it really easy for our writers to ensure we haven’t written about a topic, and see what SEO keywords we’ve focused on in the past. 

## The Problem: 
My coworkers and our interns have been inputting this data by hand. By hand. This is an issue for me because:

1. The potential for human error during the data entry process
2. The tables are never up to date because we always forget to update them
3. **BY HAND?!** This simple task takes up too much time, which is to say, it takes more than a minute. We’ve all got better things to do!

## The Hard Way:
My initial solution was to export all the WordPress data monthly from phpMyAdmin and then paste it all into AirTable. This took less time, but it still require that I access one client’s DB at a time, export the data and then find the correct table in AirTable and import it. This was still taking too much time, and the blogs were never posted at the same time, so I ended up doing this task the hard way several times a month.

## The Better Way:
I decided that I would build a program that uses the AirTable and WordPress APIs to gather the blog data and import it into AirTable, with a simple command in the terminal. 

## Done is Better than Perfect
Because I am on a React kick, initially I thought I would build this project as a Rails API backend with a React frontend. After some more planning, I realized that I didn’t need a GUI, I didn’t want to deal with creating users and storing passwords, and I wouldn’t want to worry about the security implications of storing AirTable API keys (which are required to make this work) or sending them in HTTP requests.  

I decided that the program should store data on the user’s computer in a YAML file. 

My next thought was to build a full-fledged CLI application. I very quickly got bogged down in all the puts statements and walking the user through the program loops. 

I decided that I didn’t need a full app that continued to run until the user exited the program. This project needs to go from WIP to portfolio project, so I shifted gears.

I want the user (i.e. me) to be able to run specific commands in the terminal that accomplished different tasks. Think using Git in the command line. `$ git config --global user.name "John Doe"`

I want to run a command like `wp2at sync` and have all the AirTable tables be updated with the latest WordPress blog info. I want to run `wp2at blogs` and get a list of all the blogs I’ve configured. Ruby gem with executables it is!

I started with a simple command:
```
$ bundle gem wp2at
```
In my bin directory, that was created for me with the previous command, I created a file wp2at. In this file, I use the shebang line to tell the computer that this code is in Ruby, require a Ruby file that will serve as the entry point to all the other code in the gem, and include an executable.

```
#!/usr/bin/env ruby

require_relative '../lib/wp2at'
Wp2at::Option.new.execute(ARGV)

```
Now, when I run `./bin/wp2at` in the terminal, `Wp2at::Option.new.exevute(ARGV)` is called. 

In my Option class, I have an instance method *execute* that takes the command line arguments. In *execute*, I use a (case statement)[ https://www.rubyguides.com/2015/10/ruby-case/] to run different methods based on the arguments.

```Ruby
    def execute(args)
        command = args[0]
        options = args[1]
        @current_settings = Settings.exists? ? Settings.load : Settings.new
        case command
        when "userconfig"
            puts options ? add_username(options) : @current_settings.username
        when "blog" 
            options ? @current_settings.add_blog(options) : @current_settings.list_blogs 
        when "sync"
            api = API.new(@current_settings)
            if options
                api.ping(options)
            else
                api.list_blogs
            end
        else
            puts "That's not an option"
        end
    
    end

```
## Status
Right now, the program loads or creates a Settings instance, based on the presence or absence of a YAML file. It can save a username and blogs to said YAML file. I’ve started to incorporate the WordPress API. The program can now GET blog data based on the blog info added to the Settings instance.

## Next Steps
Next, I’ll concentrate on formatting the returned blog data so that it can be easily sent to AirTable. 
I hope you’ll stick around and check back to see how this one progresses!