Class: GoodbyeChatwork::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/goodbye_chatwork.rb

Constant Summary collapse

REQUEST_INTERVAL =
1
CHAT_SIZE =
40

Instance Method Summary collapse

Constructor Details

#initialize(id, pw, opt = {}) ⇒ Client

Returns a new instance of Client.



14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/goodbye_chatwork.rb', line 14

def initialize(id, pw, opt = {})
  @verbose = opt[:verbose]
  @id = id
  @pw = pw
  @opt = opt
  @interval = opt[:inverval] || REQUEST_INTERVAL
  @base_url = opt[:base_url] || 'https://www.chatwork.com'
  @token = nil
  @client = Faraday.new @base_url do |builder|
    builder.request :url_encoded
    builder.use :cookie_jar
    builder.adapter Faraday.default_adapter
  end
end

Instance Method Details

#account(aid) ⇒ Object



81
82
83
# File 'lib/goodbye_chatwork.rb', line 81

def (aid)
  @contacts[aid.to_s]
end

#export_csv(room_id, out, opt = {}) ⇒ Object



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/goodbye_chatwork.rb', line 114

def export_csv(room_id, out, opt = {})
  self.info "export logs #{room_id} ..."
  CSV.open(out, "wb") do |csv|
    fid = 0
    loop do
      r = self.old_chat(room_id, fid)
      r.each do |i|
        if opt[:include_file]
          fid = i['msg'].match(/\[download\:([^\]]+)\]/).to_a[1]
          if fid
            begin
              file_download fid, dir: opt[:dir]
            rescue Exception => e
              self.info "download error #{fid} #{e.to_s}"
            end
          end
        end
        ac = self.(i['aid'])
        csv << [Time.at(i['tm']).iso8601,
          (ac ? ac['name'] : i['aid']), i['msg']]
      end
      break if r.size < CHAT_SIZE
      fid = r.last['id']
    end
  end
  self.info "create #{out}"
end

#file_download(file_id, opt = {}) ⇒ Object



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/goodbye_chatwork.rb', line 85

def file_download(file_id, opt = {})
  info = self.file_info file_id
  if !info[:url] || !info[:filename]
    self.info "download error #{file_id}"
    return
  end

  d = open(info[:url]).read
  self.info "download #{info[:filename]} ..."
  fn = "#{file_id}_#{info[:filename]}".force_encoding('utf-8')
  out = fn
  if opt[:dir]
    unless File.exists?(opt[:dir])
      self.info "mkdir #{opt[:dir]}"
      FileUtils.mkdir_p opt[:dir]
    end
    out = File.join(opt[:dir], fn)
  end
  open(out, 'w') { |f| f.write d }
end

#file_info(file_id) ⇒ Object



106
107
108
109
110
111
112
# File 'lib/goodbye_chatwork.rb', line 106

def file_info(file_id)
  self.info "get file info #{file_id} ..."
  r = @client.get "https://www.chatwork.com/gateway.php?cmd=download_file&bin=1&file_id=#{file_id}"
  self.wait
  b = r.headers['Content-disposition'].match(/filename="=\?UTF-8\?B\?(.+)\?="/).to_a[1]
  { url: r.headers['Location'], filename: b.unpack('m')[0] }
end

#get_account_infoObject



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/goodbye_chatwork.rb', line 56

def 
  aids = @contacts.values.map { |i| i['aid'] }
  mids = @rooms.values.map { |i| i['m'].keys }.flatten.uniq.map(&:to_i)
  diff_ids = (mids - aids).sort
  pdata = 'pdata=' + JSON.generate({ aid: diff_ids, get_private_data: 0 })
  self.info 'load account info'
  r = @client.post "/gateway.php?cmd=get_account_info&myid=#{@myid}&_v=1.80a&_av=4&_t=#{@token}&ln=ja", pdata
  self.wait
  begin
    d = JSON.parse(r.body)['result']['account_dat']
    @contacts.merge!(d)
  rescue Exception => e
    self.info e.to_s
  end
  self.wait
end

#info(d) ⇒ Object



160
161
162
# File 'lib/goodbye_chatwork.rb', line 160

def info(d)
  STDERR.puts([Time.now.iso8601, d].flatten.join(' ')) if @verbose
end

#init_loadObject



47
48
49
50
51
52
53
54
# File 'lib/goodbye_chatwork.rb', line 47

def init_load
  self.info "load initial data..."
  r = @client.get "/gateway.php?cmd=init_load&myid=#{@myid}&_v=1.80a&_av=4&_t=#{@token}&ln=ja&rid=0&type=&new=1"
  self.wait
  d = JSON.parse(r.body)['result']
  @contacts = d['contact_dat']
  @rooms = d['room_dat']
end

#loginObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/goodbye_chatwork.rb', line 29

def 
   = @client.post '/login.php', email: @id, password: @pw, autologin: 'on'
  if .env.status == 302
	@client.url_prefix = URI.parse(.env.response_headers[:location].match(/^https?(:\/\/[-_.!~*\'()a-zA-Z0-9;\:\@&=+\$,%#]+)/).to_s)
    @client.get .env.response_headers[:location]
  end

  r = @client.get "/"
  self.wait
  self.info "login as #{@id} ..."
  @token = r.body.match(/var ACCESS_TOKEN = '(.+)'/).to_a[1]
  @myid = r.body.match(/var myid = '(.+)'/).to_a[1]
  raise 'no token' unless @token
  self.init_load
  self.
  self
end

#old_chat(room_id, first_chat_id = 0) ⇒ Object



73
74
75
76
77
78
79
# File 'lib/goodbye_chatwork.rb', line 73

def old_chat room_id, first_chat_id = 0
  self.info "get old chat #{first_chat_id}- ..."
  res = @client.get "https://www.chatwork.com/gateway.php?cmd=load_old_chat&myid=#{@myid}&_v=1.80a&_av=4&_t=#{@token}&ln=ja&room_id=#{room_id}&last_chat_id=0&first_chat_id=#{first_chat_id}&jump_to_chat_id=0&unread_num=0&file=1&desc=1"
  self.wait
  r = JSON.parse(res.body)
  r['result']['chat_list'].sort_by { |i| - i['id'] }
end

#room_listObject



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# File 'lib/goodbye_chatwork.rb', line 142

def room_list
  @rooms.to_a.sort_by { |i| i[0].to_i }.map do |i|
    name = i[1]['n']
    member_ids = i[1]['m'].keys
    c = i[1]['c']
    if !name && member_ids.size == 1 && member_ids.first == @myid
      [i[0], 'mychat', c]
    elsif name
      [i[0], name, c]
    elsif member_ids.size == 2 && member_ids.include?(@myid)
      ac = self.(member_ids.find { |i| i != @myid }) || {}
      [i[0], ac['name'], c]
    else
      [i[0], '...', c]
    end
  end
end

#waitObject



164
165
166
# File 'lib/goodbye_chatwork.rb', line 164

def wait
  sleep(@interval + rand)
end