Skip to content

Instantly share code, notes, and snippets.

@dwilkie
Last active December 9, 2021 08:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dwilkie/d6bff7ce48d0980f5b3a8d70c4b9f4f6 to your computer and use it in GitHub Desktop.
Save dwilkie/d6bff7ce48d0980f5b3a8d70c4b9f4f6 to your computer and use it in GitHub Desktop.
Import contacts into SCFM
## import_contacts.rb
# Imports contacts into SCFM from CSV file.
### CSV file format
# CSV File must have a `phone_number` or `telephone_number` column
# which contains the phone number of the contact. The phone number
# must be in international E.164 format. All other additional columns
# are added to the contact's metadata with the key being the column header
### Usage
# API_KEY="replace-me-with-api-key" CONTACT_DATA_FILE=tmp/contact_data.csv ruby import_contacts.rb
#### Docker
# docker run --rm -it -v `pwd`:`pwd` -w `pwd` -e CONTACT_DATA_FILE=path-to-csv-file.csv -e API_KEY="replace-me-with-api-key" ruby:alpine ruby path-to-import-contacts.rb
#### Windows
# @echo off
# set CONTACT_DATA_FILE=trials.csv
# set API_KEY=z7FD0IcQ3FqNfutbZJQdXwKcDsKXaI1SVV5Wrh9G-g8
# ruby import_contacts.csv
require "net/http"
require "uri"
require "csv"
require "json"
require "pathname"
DATA_FILE = ENV.fetch("CONTACT_DATA_FILE")
API_KEY = ENV.fetch("API_KEY")
API_ENDPOINT = URI.parse("https://scfm.somleng.org/api/contact_data")
def build_contact_data(row)
data = row.to_h.transform_keys do |key|
key.to_s.strip.downcase.gsub(/\s+/, "_")
end
phone_number = data.delete("phone_number") || data.delete("telephone_number")
raise("Invalid file. Missing column header: 'phone_number'") if phone_number.nil?
{
msisdn: phone_number,
metadata: data.compact
}
end
def do_request(options = {})
uri = options.fetch(:uri)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri)
request["Content-Type"] = "application/json"
request["Authorization"] = "Bearer #{options.fetch(:api_key)}"
request.body = options.fetch(:body).to_json
http.request(request)
end
def parse_csv
csv_text = Pathname.new(DATA_FILE).read
csv = CSV.parse(csv_text, headers: true)
csv.map do |row|
build_contact_data(row)
end
end
def import_contacts(contact_data)
contact_data.each_with_index do |data, i|
puts "Importing contact #{i + 1} of #{contact_data.size}" if i % 100 == 0
response = do_request(
uri: API_ENDPOINT,
body: data,
api_key: API_KEY
)
unless response.kind_of?(Net::HTTPSuccess)
error = {
"message" => response.body,
"code" => response.code
}.reject { |_k, v| v.empty? }
puts "Failed to create contact: #{data}. Error: #{error}"
end
end
puts "Done importing contacts!"
end
contact_data = parse_csv
import_contacts(contact_data)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment