sim_repo.rb

 1# frozen_string_literal: true
 2
 3require "lazy_object"
 4require "value_semantics/monkey_patched"
 5
 6require_relative "sim"
 7
 8class SIMRepo
 9	value_semantics do
10		db Anything(), default: LazyObject.new { DB }
11	end
12
13	KEEPGO_HEADERS = {
14		"Accept" => "application/json",
15		"apiKey" => CONFIG[:keepgo][:api_key],
16		"accessToken" => CONFIG[:keepgo][:access_token]
17	}.freeze
18
19	def find(iccid)
20		EM::HttpRequest.new(
21			"https://myaccount.keepgo.com/api/v2/line/#{iccid}/get_details",
22			tls: { verify_peer: true }
23		).aget(head: KEEPGO_HEADERS).then { |req|
24			SIM.extract(JSON.parse(req.response)&.dig("sim_card"))
25		}
26	end
27
28	def refill(sim, **kwargs)
29		iccid = sim.is_a?(String) ? sim : sim.iccid
30
31		EM::HttpRequest.new(
32			"https://myaccount.keepgo.com/api/v2/line/#{iccid}/refill",
33			tls: { verify_peer: true }
34		).apost(
35			head: KEEPGO_HEADERS,
36			body: kwargs.to_json
37		).then { |req| JSON.parse(req.response) }
38	end
39
40	def owned_by(customer)
41		customer = customer.customer_id if customer.respond_to?(:customer_id)
42		promise = db.query_defer(<<~SQL, [customer])
43			SELECT iccid, nickname FROM sims WHERE customer_id=$1
44		SQL
45		promise.then { |result|
46			EMPromise.all(result.map { |row|
47				find(row["iccid"]).then { |sim| sim.with(nickname: row["nickname"]) }
48			})
49		}
50	end
51
52	def put_owner(sim, customer, nickname=nil)
53		db.query_defer(<<~SQL, [customer.customer_id, sim.iccid, nickname])
54			UPDATE sims SET customer_id=$1, nickname=COALESCE($3, nickname) WHERE iccid=$2 AND customer_id IS NULL
55		SQL
56	end
57
58	def available
59		db.query_defer(<<~SQL).then { |r| find(r.first["iccid"]) }
60			SELECT iccid FROM sims WHERE customer_id IS NULL LIMIT 1
61		SQL
62	end
63end