kylemclaren
kylemclaren

Reputation: 768

Iterate through a JSON array - Sinatra

I have a basic Sinatra app that receives a webhook from PagerDuty, grabs some of the fields and inserts a new document into MongoDB.

post '/webhooks/pagerduty/' do

  request.body.rewind
  json = JSON.parse(request.body.read)

  @pd_id = json["messages"][0]["data"]["incident"]["id"]
  @ts = json["messages"][0]["data"]["incident"]["created_on"]
  @status = json["messages"][0]["data"]["incident"]["status"]
  @host = json["messages"][0]["data"]["incident"]["trigger_summary_data"]["HOSTNAME"]
  @description = json["messages"][0]["data"]["incident"]["trigger_summary_data"]["SERVICEDESC"]
  @state = json["messages"][0]["data"]["incident"]["trigger_summary_data"]["SERVICESTATE"]

  # MongoDB connection code omitted

  coll = db.collection('incidents')

  _id = SecureRandom.hex

  if @status != "resolved"

    coll.insert({ :_id => _id, :pd_id => @pd_id, :ts => @ts, :status => @status, :host => @host, :description => @description, :state => @state, :db_type => @db_type })

  else

    coll.update({ :pd_id => @pd_id }, { "$set" => { :status => @status }})

  end

  status 200

end

This works fine but the problem is that PagerDuty sometimes sends multiple JSON objects in the array and I'm not sure how to adjust the code and iterate through the array instead of grabbing the first object in the array in a DRY manner.

Upvotes: 0

Views: 825

Answers (1)

Jin
Jin

Reputation: 13533

Since JSON.parse(request.body.read)["messages"] is an Array object, you can do a Array#each call on it.

JSON.parse(request.body.read)["messages"].each do |element|
  processed = process(element)
  processed["status"] == "resolved" ? update(processed) : insert(processed)
end

def process(element)
  # extract the required data from the json object
  # return a Hash with the data
end

def insert(hash)
  # insert
end

def update(hash)
  # update
end

Upvotes: 1

Related Questions