2018年9月の記事一覧

社内ハッカソンイベント Raksul Hack Week #1 を開催中です

RakSul Hack Week Logo

エンジニアの二串です。

最近少しづつ朝晩が冷えるようになってきて秋の到来を感じますね。さて、秋といえばハッカソンですよね(!!?)

というわけで今週、ラクスルでは社内ハッカソンイベント「Raksul Hack Week #1」 を開催しています。

RakSul Hack Weekとは?

もともと月に1日、エンジニアは直接的な業務を離れ自由に開発をしていい Hack It Day という制度がありました。今回はそれを拡張し、1週間に渡って、全社的に(エンジニア、プロマネ、デザイナー混ぜて)やろうよ!というイベントです。さらりと書きましたが、1週間普段の開発を止めて、自由な発想でおもいっきりやってみる企画になります。今回が記念すべき(?)第1回目となります!!!

今回はやりたいことを事前にメンバーから集めて、出てきたアイデアをベースに数名1チームでチームを組んで、チーム=プロジェクトを作って取り組む方式を採用しました。

今週はシルバーウィークで月曜がお休みなので火曜から金曜まで計4日間の開催し、最終日にはチームごとの成果発表を開催します。成果発表会では、参加者の他、非参加者(ビジネスやカスタマーサポート)も交えての会となります。

楽しく作戦会議中の様子

各チームで作業が進んでます

今回は1週間ということで普段なかなか試せない技術スタックを試してるチームも多く、参加者達はそれぞれ盛り上がって来ているようです。

どんなことをやってるの?

例えば、

  • AWS lambda を使ってのFAXとウェブをつなげるサービスの開発
  • Nuxt.js + TypeScript で作るSlackと連携したウェブサービス
  • AIによる注文審査の自動化システム

などなど…. 技術領域も解決する課題も様々。今回は12チーム、総勢41名が参加しています。

もくもく作業中!?

さて、どんな成果物ができるでしょうか!!? 今から楽しみです。

また詳細はレポートします。

wifi打刻システムをつくった話

出社時/退社時の打刻ってとても面倒くさくないですか?

わかっていてもついつい打刻するのを忘れてしまいます。そして月末の勤怠締めで打刻忘れの箇所を手動で1つずついれていく。。とても非生産的ですね。

そこでシステム的にこの問題を解決するべく、メルカリの記事を参考にwifi打刻システムをつくりました。

wifi打刻システムとは社員さんが持っている端末(携帯やPC)がwifiに繋がった時に出社打刻をし、最後にwifiに繋がっていた時間を退社時刻として退社打刻を行うシステムです。

それではwifi打刻システムを作る方法について説明していきます。大きくわけて3つのステップに分けることができます。

  • 社員が持っている端末がwifiに繋がっていることを検知する
  • wifiに繋がった端末から社員を特定する
  • wifiに繋がった時に出社or退社の打刻をする

社員が持っている端末がwifiに繋がっていることを検知する

携帯やPCなどの端末にはMac Addressという端末毎に固有な物理アドレスが割り振られています。

wifiルーターに繋がっている端末のMac Addressを取得することでwifiに繋がっていることを検知しました。

Mac Address取得する方法はいくつかありますが、今回はsnmpwalkというコマンドを使いました。

ルーターと同じネットワーク内にあるサーバー上でsnmpwalkコマンドを打つと接続している端末の情報が得られます。

あとはその出力をparseすることでwifiに接続している機器のMac addressの一覧を取得しました。

wifiに繋がっている端末から社員を特定する

wifiに繋がっている端末のMac Addressの一覧が取得できたので、どのMac Addressがどの社員のものなのか特定する必要があります。

今回は単純にMac Addressと社員番号を紐づけるデータベースを用意しました。

どのMac Addressがどの社員のものなのかはwifi打刻の利用申請を出す際にMac Addressも教えてもらうようにしました。

iPhone/AndroidのMac Addressの調べ方は以下のサイトが参考になると思います。

これでMac Addressの一覧を社員番号の一覧に変換することができました。

wifiに繋がった時に出社or退社の打刻をする

社員番号の一覧が取得できるようになったので、後は出社or退社の判定をして打刻をすればよさそうです。

判定を行うために社員番号を取得するスクリプトをバッチで数分間隔で実行し、wifiに繋がっている社員番号一覧を取得した際に、その時の時刻をwifiに接続していた時刻として社員番号と共に各社員番号について記録しておきます。

{
  1: { # 社員番号:1の人がいつwifiに接続していたかを記録
    connected_at: "2018-09-05 14:31:52 +0900"
  },
  2: { # 社員番号:2の人がいつwifiに接続していたかを記録
    connected_at: "2018-09-05 14:31:52 +0900"
  },
}

出社についてはその日初めてwifiに繋がった場合に、その時刻を出社として打刻すればよさそうです。

退社については最後に接続した時刻と次にwifiに接続した時刻が一定時間以上離れていた場合に退社時刻として打刻するようにしました。こうすることでランチなどで外出してwifiが切れた時でも退社打刻されないようにしました。

ラクスルの勤怠システムにはAPIで打刻する機能があったので出社or退社と判断された時にAPIを使って打刻を行いました。また打刻されたかどうかわかるようにAPIで打刻した際にslackでDMを送って通知するようにしました。

これでwifiに繋がった時に出社/退社打刻してくれるwifi打刻システムが出来上がりました。

まとめ

打刻忘れや打刻修正などの無駄な作業をなくすべくwifi打刻システムをつくった話を紹介しました。

実際にwifi打刻を使っている社員さん達から「すごい便利」「快適になった」と言った声も頂いています。wifi打刻の仕組み自体はとても簡単なので、やろうと思えばすぐに導入できると思います。

打刻が面倒だと感じたら導入を検討してみてはいかがでしょうか。

ラクスルではエンジニアを積極採用しています

ラクスルに興味を持たれた方は是非一度オフィスに遊びにきてください!

宛名印刷ができる年賀状・喪中はがきをリリースしました

はじめに

ラクスルでエンジニアをしている藤田です。
先月、「年賀状・喪中はがき」という商品をリリースしました。
ラクスルで扱っている印刷サービスは基本的に、PDF等でアップロードされた印刷データを対象の商品(チラシや名刺など)に印刷してお客様へお届けするというものです。
今回リリースした商品は宛名印刷という機能があり、印刷データと一緒に宛名リストをアップロードしてもらい、印刷データと共にそれぞれの宛名をはがきに印刷します。他の商品では全く同じ印刷物が注文された部数だけ出来上がるのに対して、宛名印刷では一つ一つの印刷物が宛名の箇所だけ異なる内容になる点が特徴です。
一見するとシンプルに思われるこの機能ですが、実際に開発してみると意外と奥が深く面白かったので紹介したいと思います。

宛名印刷の難しさ

宛名印刷の難しさは「どうやって宛名を違和感なく宛名面にマッピングするか」にあります。組版処理とも呼ばれます。
下の画像を見ていただくと伝わるかと思うのですが、役職・部署の有無や文字数などで宛名面のどこに印刷するかが大きく変わります。
そのため、様々なパターンを考慮する必要があり必然的に開発も難しくなります。

今回はこのよう組版処理を実装するにあたって、開発スピード等を考慮して既成の組版ソフトを利用する方針としました。このソフトはWindows上でしか動作しないため、別途windowsサーバーをたてる必要がありました。

システム概要

少し簡略化していますが、組版処理に関連するシステムの概要図は上記のようになっており、次の通り処理されていきます。上述の組版ソフトは⑥で使用しており、SQSからキューを取得したりS3にアップロードしたりといった周辺の処理はWindowsとも相性が良いGolangで開発しました。

1. ユーザーが印刷データと宛名リスト(CSV)をアップロード
2. 印刷データと宛名リストをS3に保存
3. SQSに組版処理をエンキュー
4. SQSからキューを取得
5. S3から印刷データと宛名リストを取得
6. 組版処理を実施
7. 処理結果ファイルをS3に保存

Webアプリケーションと組版ソフトが動作するWindows Serverを繋げる方法として、Amazon SQSを利用しました。Windows Server上にAPIサーバーをたてる方法もありますが、やや開発コストが増える点と、宛名リストの件数によっては組版ソフトの処理に時間がかかるためキューイングが必要だったこともあり、SQSを採用しました。

マニアックな機能: CIDチェック

今回、開発した機能の中で面白かったものがCIDチェックです。CIDとはアドビ社が定めている文字ごとに一意に振られる番号のことで、フォントの文字を識別するために用いられます。例えば、フォントでは異体字の字形を区別する必要がありますが、Unicode等の一般的な文字コードでは同じコードが割り当てられていることがあるため、CIDが利用されます。
宛名印刷では、宛名に用いられるフォントとして正楷書CB1、リュウミンなど4種類から選択することができます。これらのフォントはカバーしているCIDの範囲以外の文字には使用することができないため、宛名リストで入力された文字が範囲内に含まれているかどうかをチェックすることが必要です。
CIDチェックの実装方法ですが、

1. 入力された文字に紐づくCIDを取得する
2. 取得したCIDが範囲内に含まれるかチェック

という順序でチェックをしていきます。
私が探した範囲ではRubyのライブラリ(CIDチェックはRailsアプリ内で行います)で文字列からCIDを取得するようなものはなかったため、UTF-8のコードとCIDをマッピングしたファイルを作成してUTF-8からCIDを引けるようにしました。
幸い、アドビ社が提供しているcid2code.txtというファイルにCIDと主な文字コードとの対応表がありましたので、このファイルを利用することでマッピングファイルを作成することができました。
細かい話になりますが、最終的に実装は下記のようになりました。

# app/validators/adobe_japan13_validator.rb

class AdobeJapan13Validator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    return if value.nil?
    chars = invalid_chars(value)
    record.errors.add(attribute, :invalid_character, invalid_chars: chars.uniq.join) if chars.present?
  end

  class << self
    def valid_strings_map
      return @valid_strings_map if @valid_strings_map
      @valid_strings_map = {}
      File.open(Rails.root.join('config', 'adobe_japan13.dat'), 'rb') do |f|
        f.each_line do |line|
          line.chomp!
          _cid, utf8 = line.split("\t")
          @valid_strings_map[utf8] = true
        end
      end
      @valid_strings_map
    end
  end

  private

  def invalid_chars(target_string)
    target_string.each_char.reject do |c|
      utf8 = c.unpack1('H*')
      self.class.valid_strings_map.key?(utf8)
    end
  end
end

バリデーターの中で読み込んでいる adobe_japan13.dat がマッピングファイルになっており、次のような内容になっています。左側の数字がCID、右側がUTF-8に対応しています。

# config/adobe_japan13.dat
1	20
2	21
3	22
4	23
5	24
6	25
7	26
8	27
9	28
10	29
11	2a
12	2b
13	2c
14	e28091
# 以下略

おわりに

この記事では宛名印刷という開発案件について紹介しました。
組版処理やCIDチェックといったものは印刷サービスならではで、他の会社ではあまり経験できないラクスルらしいテーマを紹介できたかなと思っています。