タダケンのEnjoy Tech

楽しみながらラクに成果を上げる仕組みを考える

【Python】チャットワークに通知を送るスクリプトをより実用的に改良する

f:id:tadaken3:20170917160104p:plain

こんにちは!
タダケン(@tadaken3)です。

先日、「いつも隣にITのお仕事」に、Pythonを使ってチャットワークに通知を送る方法について解説した記事を寄稿しました。

tonari-it.com

Requestsモジュールを使いチャットワークAPIにアクセスして、メッセージを送る方法を解説しました。「いつも隣にITのお仕事」では、プログラム初心者向けの内容にフォーカスしているため、Requestsモジュールの使い方を中心にご紹介しています。

ですが、このままだと、

  • ルームIDやメッセージ内容を変更する度に、コードを変更する必要がある
  • スケジュールで定期的に実行する際に実行ログが出力されない

などの課題があります。

そこで本ブログでは、チャットワークに通知を送るPythonスクリプトをより実用的なコードに改良する方法をご紹介します。1

argparseを使ってパラメータを管理する

argparseモジュールはコマンドラインのインタフェースを簡単に作成できる標準モジュールです。

Pythonプログラムを実行した際にコマンドライン引数を設定できます。メッセージ内容やルームIDをコマンドラインから指定できるようになります。

#!/usr/bin/env python

import argparse

def main():
    # パーサの作成
    psr = argparse.ArgumentParser()
    # -m / --message というオプションを追加.デフォルトは 'hello! '
    psr.add_argument('-m', '--message', default='hello! ')
    # コマンドラインの引数をパースしてargsに入れる.エラーがあったらexitする
    args = psr.parse_args()
    # argsからmessageに格納された引数を取り出す
    print(args.message)

if __name__ == '__main__':
    main()


実行時にコマンドラインで引数を指定しないとデフォルトの内容、引数を指定した場合は引数の内容が表示されます。

$ python sample_argparse.py
hello! 
$ python sample_argparse.py -m 'Good Bye!'
Good Bye!

loggingを使ってログを出力する

Pythonでログ出力を実装するためには標準モジュールのloggingを使います。

loggingを使うと、ログをレベル分けしたり、ログ出力のフォーマットを設定できます。loggingの詳しい使い方は以下の記事が参考になります。

www.sejuku.net

ログの設定を以下のように記述します

logger = logging.getLogger(__name__)
# 出力するログレベルの設定。INFO以上のログが出力されるようになる
logger.setLevel('INFO')

# ログのファイル出力先を設定
fh = logging.FileHandler('chatwork.log')
logger.addHandler(fh)

# ログのコンソール出力の設定
sh = logging.StreamHandler()
logger.addHandler(sh)

# ログのフォーマット設定
formatter = logging.Formatter('%(asctime)s:%(lineno)d:%(levelname)s:%(message)s')
fh.setFormatter(formatter)
sh.setFormatter(formatter)


ログを出力をしたい場合、ログを出力したいタイミングの箇所で以下のように記述します。

logger.info('これは正常動作です')
logger.warning('実行可能だけども警告があります')

チャットワークに通知するスクリプトを改良する

では、これらを踏まえて、チャットワークへ通知するスクリプトを改良してみましょう。

main関数を作って、メインルーチンを記述しています。APIキーとルームIDのデフォルト値はご自身が使うものに変更してください。2

#!/usr/bin/env python
# -*- encoding: utf-8 -*-

import argparse
import requests
import logging

def main():
    # ロガーを呼び出し
    logger = get_logger()

    # 処理が開始されることをロギング
    logger.info('start')
    
    # コマンドライン引数からルームID、メッセージ内容を取得
    psr = argparse.ArgumentParser()
    psr.add_argument('-a', '--apikey', default='#Your Chatwork API KEY')
    psr.add_argument('-r', '--roomid', default='Your Room ID')
    psr.add_argument('-m', '--message', default='にゃんぱすー')
    psr.add_argument('--version', action='version', version='%(prog)s 1.0')
    args = psr.parse_args()
    
    # エンドポイントの生成
    ENDPOINT = 'https://api.chatwork.com/v2'
    post_message_url = '{}/rooms/{}/messages'.format(ENDPOINT, args.roomid)

    # チャットワークAPIにポストする場合のヘッダー、パラメータを設定
    headers = { 'X-ChatWorkToken': args.apikey}
    params = { 'body': args.message }
    
    # ポストリクエストを実行
    r = requests.post(post_message_url,
                        headers=headers,
                        params=params)
    # ステータスコードが200(成功)以外の場合、警告をする
    if r.status_code != 200:
        logger.warning(r.text)
    
    # 処理が終了したことをロギング
    logger.info('end')

# ロガーの設定
def get_logger():
    logger = logging.getLogger(__name__)
    logger.setLevel('INFO')
    
    fh = logging.FileHandler('chatwork.log')
    logger.addHandler(fh)
    
    sh = logging.StreamHandler()
    logger.addHandler(sh)
    
    formatter = logging.Formatter('%(asctime)s:%(lineno)d:%(levelname)s:%(message)s')
    fh.setFormatter(formatter)
    sh.setFormatter(formatter)
    return logger

if __name__ == '__main__':
    main()

では、「chtwk.py」というファイルに保存して実行してみましょう。

コマンドラインからの入力を受け付けて、ログもきちんと出力されていますね。chatwork.logファイルにも実行した結果が記録されているはずです。 f:id:tadaken3:20170917154920p:plain

チャットワークにもコマンドラインで設定したメッセージ内容で通知が送られています。 f:id:tadaken3:20170917154943p:plain

まとめ

ちょっとしたツールでもキチンと作っておくと、再利用できるようシーンが増えます。結果的には業務の時間短縮につながったり、メンテナンスしやすくなりますので、意識しておくと良いのではないでしょうか。

今回作成したコードはGithubにもおいてありますので、ご参考に!

読者登録をお願いします

本ブログではPythonGoogle Apps Scriptの役立つテクニックを公開しています。よろしければ読者登録もしくはTwitterアカウントのフォローをしていただけると更新の励みになります。ぜひ一緒にプログラミングを学びましょう。

みんなのPython 第4版

みんなのPython 第4版


  1. 元ネタはこちらの記事です。pythonで小さなツールを作る時のtips - Qiita

  2. APIキーについてもコマンドラインから取れるようにしていますが、変更して使うケースが少なければ、環境変数に入れて管理する方法もあります。こちらを参考に。【Python】トークンなどの認証情報は環境変数で管理しよう - 肩の力を抜いて

ゼルダ開発者に学ぶチーム全体の生産性を上げる方法

f:id:tadaken3:20180325125308p:plain こんにちは!
タダケン(@tadaken3)です。

日本最大のゲーム開発者向けカンファレンス「CEDEC 2017」が9月1日まで行われていました。ボクの好きなゲームの一つ「ゼルダの伝説 ブレス オブ ザ ワイルド」(以下、BotW)についても多くセッションが開かれてました。

今回はBotWのセッションを読んで学んだこと、感じたことをまとめてみました。

自作のバグ検知ツール「ZELDA_ERROR」で制作効率が上がった

たくさんのセッションが公開されたのですが、個人的に注目したのがこちらの記事です。

jp.ign.com

簡単にまとめると、

BotWは任天堂の歴史の中でも今までにない規模の制作規模だったそうです。制作規模が大きいため、バグも大量に発生し、面白さを検証するためのテストプレイもままならない状態でした。

QAエンジニアである大礒さんが、BotW専用のデバッグツール「ZELDA_ERROR」を作って、効率的にバグ報告をできるようにしました。

通常、ゲームのソフトの開発は制作の終盤にデバックを行なうのですが、「ZELDA_ERROR」のおかげ開発の初期からデバックを効率的に行なうことができ、その効果も制作サイクルを早く回せました。

という内容です。

道具を作ってチームの力を最大限に活かす

ボク自身もBotWは100時間以上遊びましたし、いち任天堂ファンとして、開発の裏側の話を知って単純にすごいなと思いました。

※我が家のニンテンドースイッチ

「ZELDA_ERROR」の記事を読んで一つ思い出したことがあります。

任天堂の元社長、故・岩田さんとほぼ日の糸井さんのとある対談記事です。

当時ふたりは「MOTHER2 ギーグの逆襲」というスーパーファミコンのソフトの開発を行っていました。

開発は難航し4年間たっても完成の目処が見えない状態でした。あまりにも開発が難航したため岩田さんが助っ人として、開発陣に加わったときのエピソードです。

当時の状況を二人はこのように振り返っています。

糸井
あー、もっともですね(笑)。
で、そのときに岩田さんが
なにからはじめたかというと、
まず、道具をつくりはじめたんですよね。
つまり、目の前に大きな問題がごろごろあって、
すごくたいへんだぞ、というときに、
直接は、それに取りかからなかった。
だから、離れたところから見ると、
ぜんぜん手をつけてないように見えたんです。
ところが、それは、問題を片づけていくための
道具をつくっていたんだよね

岩田
はい。

糸井
(まわりのスタッフに向かって)
おもしろいんだよ、これは。
問題を1個ずつ片づけていくかというと
そうじゃないんだ。
いったん、道具をつくっておいて、
「みんなが使える道具をつくりましたから、
これで、あなたはここをつくってください」
というふうに建て直していったんだ。
つまり、道具さえできたら、
あとはやるだけなんですっていう
やり方をしていましたよね。
HOBO NIKKAN ITOI SHINBUN - 1101.com

このとき、岩田さんが具体的に作った「道具」は、当日まだ珍しかった電子メールだそうです。システムを社員一人ひとりのPCに入れさせて、コミュニケーションを円滑化しました。

開発がうまくいってない原因として、コミュニケーションがうまくいっていないと分析したんでしょうね。今でこそメールなんか当たり前ですが、1990年代の話ですから驚きです。

他にも岩田さんは、ファイルの更新状況を管理するために、バージョン管理システムを構築して、MOTHER2の開発効率を劇的に改善しています。1

岩田さんは、いきなりソフトの開発に入らず、みんなが使えるツールを作って、チーム全体の生産性をアップしました。

結果4年間も開発が難航していたMOTHER2が、岩田さんが開発に入ってから1年で発売までこぎつけました。

任天堂の大磯さんがおこなった「ZELDA_ERROR」を作って、チームの開発力を底上げするというのも、岩田さんのやり方そのままです。

岩田さんのDNAはしっかりと任天堂の開発陣に受け継がれているんだなと感じました。

目の前の問題にすぐ取り掛かる前に

とくに忙しくて切羽詰まっているときほど、目の前の問題をすぐに解決しようと手を動かしがちです。

ボクなんかもタスクがたくさんあって消化できるかわからないときほど、不安になってすぐに目の前の課題から手を付けがちでした。

ですが、むかしに岩田さんのツールを作る方法を知ってから、

  • もしまた同じような問題が起きたらまた時間がかかってしまうのではないだろうか
  • そもそも何が本当に問題なのだろうか

ということを一度立ち止まって考えるようになりました。

そして、自分でも自動化したりツールを作ってみたいと思いプログラミングを学び始めました。

プログラミングを少しずつ学んで行く過程で、ちょっとずつ自分の業務を自動化していきました。

時にはそれをチームに公開して他の人も使えるようにしてきました。

もちろん岩田さんや大礒さんのようなすごいツールではありませんし、日々の問題を解決する本当にちょっとしたプログラムだったりします。

それでも、作ったツールが増えれば増えるほど、仕事はどんどん自動化され、楽になっていきました。

まとめ

みんなが使えるツールを作って、チーム全体の生産性をアップするメソッドは、チームで仕事をすすめていく上で非常に役に立つ考え方です。

プログラミングの強みは、ツールを自分で創ってしまえるところだと再認識しました。

プログラミングを学んで、個人の生産性だけでなく、チームの生産性をアップしていけるといいですね。

読者登録をお願いします

本ブログではプログラミングについての記事を公開しています。よろしければ読者登録もしくはTwitterアカウントのフォローをしていただけると更新の励みになります。ぜひ一緒にプログラミングを学びましょう。

岩田さん 岩田聡はこんなことを話していた。

岩田さん 岩田聡はこんなことを話していた。

新装版 ほぼ日の就職論。「はたらきたい。」 (ほぼ日ブックス)

新装版 ほぼ日の就職論。「はたらきたい。」 (ほぼ日ブックス)

ゼルダの伝説 ブレス オブ ザ ワイルド - Switch

ゼルダの伝説 ブレス オブ ザ ワイルド - Switch

【Python】トークンなどの認証情報は環境変数で管理しよう

f:id:tadaken3:20170909203312p:plain

こんにちは!
タダケン(@tadaken3)です。

今回はPythonのプログラムを書く際のちょっとした小ネタをご紹介します。 認証情報などうっかり外部に漏らしてしまうと大事になる情報を安全に取り扱う方法を解説します。

WEB APIを利用するときに認証情報をコードに記述していると、、、

WEB APIを利用をするプログラミングを作る場合、トークンなどの認証情報をコード内に記述する場合があるかと思います。

例えば、このようにGETリクエストをしてWEB APIを利用するケースです。

import requests

url = 'www.samlple.co.jp/api/v1'  #ダミーのURLです。
token = 'hogehogehogehoge'
headers = { 'SampleToken': token }

requests.get(url, headers=headers)

自分ひとりで使う場合はとくに問題なさそうです。

ですが、コード内に認証情報が埋め込まれているため、他人に共有する際に、そのまま認証情報を公開してしまうということが考えらます。(ボクも社内のWikiにコードを公開した際に、うっかり認証情報を載せてしまったことがありました、、、)

社内の場合は、それほど大きな問題にはならないですが、もしインターネット上に公開した場合、最悪アカウントが乗っ取られて悪用されるケースもあります。とくにGithubにコードをアップするときなどは要注意です。

Amazon Web Serviceのインスタンスが乗っ取られて190万円の請求がきたというような事例もあります。1

d.hatena.ne.jp

認証情報を環境変数で管理する

そのために認証情報はプログラム上に直接書かずに、読取専用のファイルなどでしっかり管理するのが安全です。

ただ、ちょっとしたコードを作るために、毎回認証情報用のファイルを作ったりするのもめんどうなので、認証情報をOSの環境変数に保存するという方法があります。

環境変数(かんきょうへんすう)はOSが提供するデータ共有機能の一つ。OS上で動作するタ>スク(プロセス)がデータを共有するための仕組みである。 環境変数 - Wikipedia

環境変数トークンなどを保存しておき、コードを実行する際に必要な場合は、それらを呼び出して使います。

Pythonの場合、標準のosモジュールで環境変数を設定できます。

“SAMPLE_API_TOKEN"という環境変数に"hogehogehogehoge"というトークンを保存する例です。

import os

# 環境変数を設定する
os.environ["SAMPLE_API_TOKEN"] = "hogehogehogehoge"



環境変数は一度設定すれば、それ以降は永続的に使えます。 環境変数を読みこむには以下のように記述します。

import os

# 環境変数を読み込む
token = os.environ["SAMPLE_API_TOKEN"]

#もしくは
token = os.environ.get("SAMPLE_API_TOKEN")



一番最初に載せたサンプルのコードを書き換えるとこのようになります。

import os 
import requests

url = 'www.samlple.co.jp/api/v1'  #ダミーのURLです。
token = os.environ["SAMPLE_API_TOKEN"]
headers = { 'SampleToken': token }

requests.get(url, headers=headers)

まとめ

これで他人にコードを共有する際も認証情報は公開せずに管理できます。ちょっとしたことなのですが、うっかりやってしまいがちなので、セキュリティ的に認証情報は環境変数で管理することをオススメします。

読者登録をお願いします

本ブログではプログラミングについての記事を公開しています。よろしければ読者登録していただけると更新の励みになります。ぜひ一緒にプログラミングを学びましょう。

みんなのPython 第4版

みんなのPython 第4版


  1. リンク先のケースでは、不正に利用されたため無事に請求が免除されたようです。

プログラミングを習得するには、とにかく写経することがオススメ

f:id:tadaken3:20180325120346p:plain

こんにちは。
タダケン(@tadaken3)です。

プログラミングを学習する方法は、たくさんあります。入門書、プログラミングのスクール、オンラインでの学習サイト、プログラミングの入門動画などなど。たくさんの方法があってどれが効果的なのか迷ってしまいますよね。

そんなあなたに取って置きの方法をお伝えします。それは写経です。ボクはプログラミングを習得するには「写経」が一番いいと考えています。

とにかく書き写す

プログラミングをはじめて学ぶ方は、まずはサンプルコードをひたすら書き写すのがオススメです。プログラミングは「言語」なので、習得するにはどうしても書いて覚える必要があります。言語なので書けば書くほどうまくなるというのが持論です。

書いているうちにその言語の特徴や文法が体に染み付いてきますし、「書いて動かす」を繰り返すことでプログラミングの勘所みたいなものが養われます。とくにプログラミング初心者にわからなくても書いて覚える写経が効果的です。

書くことでわからないところが明確になる

最初はサンプルプログラムの意味がわからないかもしれません。ですが、それは初めて学ぶことなので当たり前です。本をサラッと一回読んだだけで理解できるのであれば、誰も苦労はしないでしょう。

意味がわからないながらも、コードを自分で打ち込んでいきます。サンプルコードを打ち込んだ後、実際動くかどうか試してみます。するとたいていの場合、うまく動かなかったり、エラーコードが表示されます。

でも、決してめげないでください。

エラーメッセージが出ている場合は、エラーメッセージを読んでみましょう。もしわからなければ、Googleで検索してみます。どの辺に間違いがあるか当たりがつくかもしれません。

もしエラーメッセージを見てもわからなければ、打ち込んだコードとサンプルコードをもう一度チェックしてみましょう。以外なところでタイプミスをしていませんか。

また理解していないメソッドやキーワードがあれば、それを覚えておきましょう。今はわからなくてもあとで調べてみて理解できるかもしれません。

そうやって試行錯誤しているうちにプログラムがやっと動くようになりました!おめでとうございます。

きっと本をサラッと読んだだけでは、理解したかどうかもあやふやだったところまで、理解できたのではないでしょうか。

これが写経の効果です。実際に書いて動かすことで、プログラミングは上達します。

「ほんたった」があると写経が捗る

写経をするときは、本をたてておくブックスタンドがあるととても便利です。コレはあるのとないので大きく違うので、プログラミングを始めようと思ったら、まず買っておくべきです。

個人的には、EDISONの「ほんたった」がオススメです。「ほんたった」は折りたたみ式のブックスタンドでカバンに入れて持ち運びができるので、会社・自宅の両方で使えます。気分転換にスタバで写経したりもできます。

折りたたみができる分、通常のブックスタンドよりも若干高めですが、それでも2500円程度です。

「ほんたった」は通常のバインダーに加えて補助バインダーがついてるので、ページがめくりやすいところも気に入っています。

EDISON ほんたった黒(ハードケース入り)

EDISON ほんたった黒(ハードケース入り)

まとめ

写経は泥臭い方法かもしれませんが、プログラミングを習得するに、より確実な方法です。1日5分でいいので、プログラミングの写経を始めてみませんか。きっと効果が実感できるはずです。

読者登録をお願いします

本ブログではプログラミングについての記事を公開しています。よろしければ読者登録していただけると更新の励みになります。ぜひ一緒にプログラミングを学びましょう。

はてなブログにコマンド一発で投稿するPythonスクリプトを作ってみた

f:id:tadaken3:20170824220135p:plain こんにちは。
タダケン(@tadaken3)です。

はてなブログへの投稿を少しでも便利にしたいと思い、テキストファイルをはてなブログに投稿するPythonスクリプトを作成しました。使い方をご紹介します。

github.com

はてなブログは、はてなブログAtomPubというAPIを公開しています。認証形式はOauth2、WSSE、BASICに対応しています。今回のスクリプトではWSSE認証で、ブログの投稿を行っています。1

はてなブログ投稿スクリプトの使い方

事前準備

以下の環境で動作することを確認しています。Python3のスクリプトです。

  • python: 3++
  • system: mac OS X, windows 7

まずスクリプトをGitHubからDLします。

$git clone https://github.com/tadaken3/hatenablog_post.git


もしくはGithubのページにアクセスして、「Clone or download」ボタンを押してダウンロードします。

f:id:tadaken3:20170824152859p:plain

依存関係のあるPythonライブラリはrequestschardetです。requestsはHTTPライブラリ、chardetはファイルの文字コードを調べるのに利用しています。pipでインストールしましょう。

$pip install requests
$pip install chardet


次に認証情報をスクリプトに埋め込みます。hatenablog_post.pyファイルの以下の部分を変更します。

username = 'username'
api_key  = 'API key'
blogname = 'yourblogname.hatenablog.com'


usernameは、はてなのIDです。api_keyとblognameは、はてなブログの管理画面から「設定>>詳細設定」で確認することができます。AtomPubの欄に記載があります。例えば、このブログの場合は「tadaken3.hatenablog.jp」です。2

f:id:tadaken3:20170824145612p:plain

これで準備がオッケーです。

ブログを投稿してみる

hatenablog_post.pyと同じディレクトリにブログ原稿を保存します。ファイルの1行目がタイトル、2行目以降が本文になります。例えばblog.mdというファイルを作ってブログタイトルと原稿本文を書いて保存してみましょう。

作成したファイルを引数にとって、スクリプトを実行します。

$ python hatenablog_post.py blog.md


うまくいくとブログに下書きに記事が反映されます。ブラウザではてなブログにアクセスして確認してみてください。

f:id:tadaken3:20170824150058p:plain

まとめ

cotEditorという軽量のテキストエディタを使用して、ブログ原稿を書いてます。cotEditorはPythonスクリプトで機能を拡張できるようだったので、今回のスクリプトを作成しました。自分がラクをしたいので。3

今回はテキストのみですが、いずれは画像も含めて一発で投稿できるようにしたいと思っています。

参考サイト

みんなのPython 第4版

みんなのPython 第4版


  1. 本記事で紹介したスクリプトは参考サイトにあるkaraageさんの記事をベースにしています。Python3で動くようにしたのとファイルの取扱などを改良しています。

  2. api_keyなどは環境変数に入れて参照することをおすすめします。ネット上にうっかり公開しないよう気をつけましょう。

  3. ちなみにこのままだと諸事情によりcotEditorで動きません。微妙に改良したのはこちらです。

いまこそプログラミングを学んで自由を手に入れよう。

f:id:tadaken3:20170819203506p:plain こんにちは。
タダケン(@tadaken3)です。

ボクはもともと経理部出身だったのですが、独学でプログラミングを勉強して、現在はデータアナリストとして仕事をしています。

プログラミングを学んだことで、ボクは人生は大きく変わりました。プログラミングは自由を手に入れる切符です。プログラミングを学ぶ人が増えるといいなと思い、この記事を書きました。

プログラミングは時間を生み出すスキルである

プログラミングは、英語や簿記といったスキルとくらべて、特徴的なところがあります。それはプログラミング自体が時間を生み出すスキルであることです。

プログラミングを学ぶと、様々なタスクをPCにやってもらうことができます。しかも、人間が手作業で行うより、PCは高速かつ正確にタスクを処理します。手作業だと半日かかっていた集計作業が、プログラミングを学ぶことでたったの5秒で終わるといったことも珍しくありません。

もちろんプログラムを作成するのに時間がかかりますが、一度作ってしまえば、その後も集計作業は自動で処理できます。空いた時間にさらにプログラミングの技術を高めていけば、より高度なこともプログラミングできるようになります。こなせるタスクは増える一方で、それにかかる時間は減っていくという減少が発生します。

プログラミングを学ぶ→時間ができる→さらにプログラミングを学ぶ→さらに時間ができる

というサイクルが回り始めます。プログラミングを学ぶことで時間の複利効果の恩恵をうけることができるのです。

自分のやっている仕事をひとつ自動化してみる

プログラミングを学ぶ上でよくある悩みが、基本的な文法な内容を学んだあと何を作っていいのかわからないという悩みです。

まずは自分のやっている仕事をひとつ自動化するプログラムを作ってみることをおすすめします。いきなりすべてを自動化することは難し位と思いますので、ほんの少しのタスクを自動化することを考えてみるといい勉強になります。

また、プログラミング言語にはC、Java、Ruby、Python、Javascriptなどたくさんの言語があります。たくさんありすぎて迷ってしまいますね。ですが、仕事を自動化するためには何を勉強すればいいのかという観点であればおのずと学ぶべきことが見えてきます。

例えば、

などの方法があります。

勉強することはたくさんある。それを乗り越えるメリットもたくさんある

プログラミングを学ぶ始めると、学ぶべきことがたくさんがあるなと感じます。

基本的なインターネット通信の基本的な仕組み、OSの成り立ち、コードのバージョンを管理する方法といったことやきれいなコードを書く方法や実用に耐える設計手法、ソフトをテストする方法などあげればキリがありません。

ボク自身もまだまだ勉強中ですし、新たに学ぶ分野で「入門書を買ってきて、本に書かれているとおりにススメてみたけどうまく動かない」といったことはしょっちゅうあります。

ですが、わからないことをググったりしながら、エラーコードと悪闘しながら、少しずつできることを増やしています。スキルを身につけると達成感があり、もっとプログラミングについて勉強したいと思うようになりました。

学習することはたくさんありますが、それを乗り越えることでできることがどんどん増えていくというのは、ものすごい充実感があります。まるでモンハンでどんどんと強いモンスターを倒す感覚です。

あなたが今持っているスキルと組み合わせれば鬼に金棒

あなたはセールスマンでしょうか❔それともデザイナー?銀行員でしょうか?

であれば、プログラミングを学ぶことは大きなチャンスです。プログラミングを学ぶことでスキルの掛け算が発生します。 プログラミングだけが得意なエンジニアはたくさんいますが、スキルを組み合わせることで、あなたの市場価値を一気に高めることができます。

  • マーケティング☓プログラミング
  • デザインセンス☓プログラミング
  • 金融知識☓プログラミング

また、あなたが今持っている知識を活かして、WEBサービスやアプリを作ることができるかもしれません。自分でWEBサービスを作って生活していければ、会社をやめて独立することだって可能です。

クラウド会計ソフトのfreeeを立ち上げた佐々木さんはエンジニア経験のなマーケッターだったのは、ボクを勇気づけてくれました。

読者登録をお願いします

本ブログではプログラミングについての記事を公開しています。よろしければ読者登録していただけると更新の励みになります。ぜひ一緒にプログラミングを学んで自由を手に入れましょう。

みんなのPython 第4版

みんなのPython 第4版

Google Apps Scriptでfreeeの取引データを取得してスプレッドシートに保存する方法

f:id:tadaken3:20170815174404p:plain こんにちは。
タダケン(@tadaken3)です。

前回は、freeeのAPIを利用するためにOauth2認証にそって、アクセストークンを取得する方法を解説しました。

tadaken3.hatenablog.jp

今回は、取得したアクセストークンを利用して、freeeの取引データをAPI経由で取得して、スプレッドシートに書き出してみます。アクセストークンさえ取得できれば、あとは簡単です。1

前回のおさらい

前回はアクセストークンを取得して、取得したアクセストークンを使って事業所のデータを取得し、ログに出力するところまで解説しました。

簡単におさらいしておくと

  1. alertAuthメソッドでfreeeの認証をおこなう
  2. getCompanyIdで認証後に取得したアクセストークンを利用し、事業所のデータを取得

という流れです。前回のコードはこちら。

//先程取得したAppID・Sceretを入力
var appId = "あなたのApp id";
var secret = "あなたのシークレット";

// 認証のエンドポイントとなるダイアログを表示します。
function alertAuth() {
  var service = getService();
  var authorizationUrl = service.getAuthorizationUrl();
  var template = HtmlService.createTemplate(
    '<a href="<?= authorizationUrl ?>" target="_blank">認証</a>. ' +
    '認証が完了したら再度操作を行ってください。');
  template.authorizationUrl = authorizationUrl;
  var page = template.evaluate();
  SpreadsheetApp.getUi().showModalDialog(page, "認証が必要です");
  Logger.log("認証が切れています");
}

//freeeAPIのサービスを取得
function getService() {
  return OAuth2.createService('freee')
      .setAuthorizationBaseUrl('https://secure.freee.co.jp/oauth/authorize')
      .setTokenUrl('https://api.freee.co.jp/oauth/token')
      .setClientId(appId)
      .setClientSecret(secret)
      .setCallbackFunction('authCallback')
      .setPropertyStore(PropertiesService.getUserProperties())
}

//認証コールバック
function authCallback(request) {
  var service = getService();
  var isAuthorized = service.handleCallback(request);
  if (isAuthorized) {
    return HtmlService.createHtmlOutput('認証に成功しました。タブを閉じてください。');
  } else {
    return HtmlService.createHtmlOutput('認証に失敗しました。タブを閉じてください。');
  }
}

//認証後、取得したアクセストークンを元にfreeeAPIからカンパニーIDを取得する
function getCompanyId() {
  var freeeApp = getService();
  var token = freeeApp.getAccessToken();
  var options =
   {
     "method"  : "get",
     "headers" : {"Authorization" : "Bearer "+ token}

   };
  var res = UrlFetchApp.fetch("https://api.freee.co.jp/api/1/companies",options);
  Logger.log(res)
}

以下はレスポンスの例になります。ログにこのようなデータが出力されているはずです。

{
  "company" : {
    "id" : 1,
    "name" : "freee事務所",
    "name_kana" : "フリージムショ",
    "display_name" : "freee事務所",
    "role" : "admin",
    "account_items" : [ ... ],
    "taxes" : [ ... ],
    "items" : [ ... ],
    "partners" : [ ... ]
  }
}

事業所のデータからカンパニーIDを取得する

次に、この事業所のデータからカンパニーIDを取り出します。カンパニーIDはfreeeの事業所識別するIDです。取引データを取得・追加するときに必要になってきます。2

JSON形式で保存されているので、getCompanyIdメソッドを以下のように書き換えます。

APIの詳細は以下もご覧ください。

freee APIドキュメント

function fetchFreee(url) {
  var freeeApp = getService();
  var token = freeeApp.getAccessToken();
  var options =
   {
     "method"  : "get",
     "headers" : {"Authorization" : "Bearer "+ token}

   };
  var json = UrlFetchApp.fetch(url,options).getContentText();
  var jsonData = JSON.parse(json);
  return jsonData
}

function getCompanyId() {
  var jsonData = fetchFreee("https://api.freee.co.jp/api/1/companies")
  var companyId = jsonData['companies']['0']['id'];
  return companyId
}

データを取得するたびにfreeeのAPIにアクセスするため、処理を抽象化して、fetchFreeeメソッドを追加しています。fetchFreeeはエンドポイントとなるURLを渡すことでJSONを返します。

取引一覧のデータを取得する

freeeでは、取引という概念で収入と支出を管理しています。発生日、支払期日、金額、支払残額、収入か支出か、決済口座などの情報が取引データを見るとわかります。

取引の一覧を取得すること、スプレッドシート上で収支の分析ができるようなります。

取引のAPIに関する情報はこちらをご覧ください。

freee APIドキュメント

今回は試しに取引発生日、収支のタイプ、金額、備考欄を取得してみます。 JSONがネストしているので注意してください。また、今後スプレッドシートでやり取りしやすいように二次元配列で値を返すようにしています。

function getSalesData() {
  var companyId = getCompanyId();
  var dealsData = fetchFreee("https://api.freee.co.jp/api/1/deals?company_id=" + companyId);
  
  //deals
  var dataCnt = dealsData["deals"].length;
  var arr = [];
  
  for(var i=0; i<dataCnt; i++){
    var issue_data   = dealsData["deals"][i]["issue_date"]
    var type         = dealsData["deals"][i]["type"]
    var amount       = dealsData["deals"][i]["amount"]
    var description  = dealsData["deals"][i]["details"][0]["description"]
    arr.push([issue_data, type, amount, description])
  }
  return arr
}

取得したデータをスプレッドシートに書き出す

最後に取得したデータをスプレッドシートに書き出すメソッドを追加します。dataというシートを事前に作成しておいてください。実行すると取得したfreeeの取引のデータが出力されます。

//detaというシートに取得したデータを書き出す。
function setDataToSheet(){
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName('data'); 
  var arr = getSalesData()
  var lastRow = arr.length;
  var column = arr[0].length;
  Logger.log(arr)
  sheet.getRange(2,1,lastRow,column).setValues(arr);
}

ちょっと長くなってしまったので、すべてまとめたものはGistにおいておきます。

freee-get-deals.gs · GitHub

まとめ

今回はfreeeのAPIを使って

  1. カンパニーIDを取得
  2. 取引一覧のデータを取得
  3. 取得したデータをスプレッドシートに書き出す

上記の3つをおこなう方法を解説しました。freee自体で様々な指標を確認することはできるのですが、スプレッドシートに書き出すことで、自分自身で経営分析をいろいろな観点でできるようになります。

このブログについて

副業やプログラミングに関する記事を書いています。(ときどき、それ以外のことも) 読者登録してもらうと更新の励みになりますのでよろしくお願いいたします。


  1. freeeのAPIを利用するには、法人プランの場合、ライト、ビジネス、エンタープライズ。個人プランの場合はスターター、スタンダード、プレミアムのいずれかを利用している必要があります。

  2. アカウントに2つ以上事業所を登録している方は、操作したい事業所のカンパニーIDを取得しましょう。

Javascriptで作るMacアプリ!JXA入門編

f:id:tadaken3:20180325122642p:plain こんにちは!
タダケン(@tadaken3)です。

Macユーザーのあなたに業務効率化のテクニックをお伝えします。Mac OSはYosemite以降であれば、なんとjavascriptでMacの自動操作ができるんです。通称JXA(javascriprt for Automition)といいます。今回はJavascriptでMacを操作するJXAをご紹介します。JXAは簡単なMacアプリも作れてしまいます。

JXAで何ができるの?

具体的にJXAでどんなことができるのでしょうか。例えば以下の様なことができます。

  • MailやiTunesなどMac標準のアプリを操作
  • ファイルやFinderの操作やMac自体の設定変更
  • EvernoteやChrome、Adobe PhotoshopなどApple以外のアプリも操作可能

複数のアプリを組み合わせて、ちょっとした作業を自動化する自分だけのアプリが作れるのです。例えば、ある画像ファイルをMailとEvernote両方に保存するアプリやiTunesのタイマー起動するアプリなどが作れます。基本はjavascriptなので、学習コストが低いこともメリットです。デザイナーの方でもjavascriptなら普段のWEB制作でも触れることは多いと思いますので、応用できますね!

JXAでアプリを作ってみよう

ではさっそくJXAでアプリを作っていきましょう。JXAを使うには「スクリプトエディタ」を使います。「Lancepad」の中の「その他」を開いてください。

f:id:tadaken3:20170708133953j:plain

その他を開くと中に「スクリプトエディタ」があります。スクリプトエディタを立ち上げてみましょう。

f:id:tadaken3:20170708134004j:plain

スクリプトエディタが立ち上がりましたね。

早速JXAを書いていきましょう!と言いたいところなんですが、ひとつ注意があります

スクリプトエディタでは、JXAの他にAppleScriptを書くことができます。Macの自動操作はもともとAppleScriptが標準だったのですが、Yosemite以降Javascriptにも対応し、JXAが使えるようになりました。両方に対応しているため、どちらのスクリプトを書いているのか明示する必要があります。

といってもとても簡単です。メニューバーの左上の部分を「javascript」に変更するだけです。

f:id:tadaken3:20170708134032j:plain

これで準備はオッケーです。早速スクリプトを書いて、アプリを作っていきましょう。

Macに入っているアプリを呼び出すには以下のように書きます。

Point var app = Application("アプリ名");

Macのシステムイベントを呼び出して、ダイアログにメッセージを表示させてみましょう。

//Macのシステムイベントを呼び出す
var sys = Application("System Events");

//StandardAdditionsという命令の集合があります。
//displayDialogがStandardAdditionsに含まれているため、機能をオンにします。
//最初はおまじないみたいなものと思ってください
sys.includeStandardAdditions = true;

//ディスプレイにダイアログを表示させる命令です。
sys.displayDialog("君はすごいフレンズなんだね");

できましたでしょうか。アプリとして保存するには、保存時にファイルフォーマットを「アプリケーション」に変更します。デスクトップにHello.appと保存してみてください。

f:id:tadaken3:20170708204529j:plain

ダブルクリックするとアプリが起動して、ダイアログが表示されます。簡単です!

f:id:tadaken3:20170708203611p:plain

ファイルをドラッグ&ドロップすると定型メールを作成するアプリを作ろう

次は実践的なアプリのサンプルをご紹介します。フリーランスで仕事をしていると定期的に成果物をメールで送信する必要があります。たいした作業ではないのですが、毎日のことなので自動化できるとトータルで結構な作業時間の短縮になります。

ファイルをドラッグ&ドロップしたら、定型的なメールを作成するアプリを作りましょう。

以下のコードをスクリプトエディタに打ち込んでみてください。contentの部分とadressの部分を自分が送りたい相手先に変更してください。

openDocumentsの部分で、ドラッグ&ドロップされたファイルを受け取り、createEmailの部分でメール本文を作成しています。スクリプトの詳細は、次回ご説明しますね。

//openDocumentsでドラッグ&ドロップされたファイルを受け取る
function openDocuments(docs) {
    //件名を今日の日付に設定する
    var today = new Date();
    var month = today.getMonth() + 1;
    var date = today.getDate();
    var subject = month + "月" + date + "日の成果報告";
    
    var content = "tadaken3さん\n\n" + "本日の作業分です、ご確認ください。\n\n";
    var address = "tadaken3@hogehoge.com";//宛先のアドレス
    
    //件名、アドレス、本文、ファイルをもとにmailを作成する
    createEmail(subject,address,content,docs);
    }

function createEmail(subject,address,content,docs){
    var Mail = Application("Mail");//Mailアプリを呼び出す
    var msg = Mail.OutgoingMessage({
        subject: subject, //タイトル
        content: content, //本文
        visible: true
    });
    Mail.outgoingMessages.push(msg)
    var rec = Mail.ToRecipient({
            address : address   // 送信先を指定
    });
    msg.toRecipients.push(rec); 
    
    //ファイルを添付する
    for (d in docs) {
        var attachment = Mail.Attachment({fileName: docs[d]});
        msg.characters.push(attachment);
    }
        
    Mail.activate();  
}

先程と同様にアプリケーションとして保存しましょう。アプリ名はautoMailer.appとしました。 デスクトップにアプリができましたね。

f:id:tadaken3:20170708210314j:plain

作成したアプリに成果物のファイルをドラッグ&ドロップすると、、、

f:id:tadaken3:20170708210419j:plain

添付ファイル付きのメールが自動で作成されました。確認して送付すればオッケーですね!

まとめ

今回はJXAの最初の一歩として

  • スクリプトエディタの使い方
  • アプリの作成方法

をお伝えしました。Macユーザーには心強い味方ですね。Javascriptで書けるのもとても魅力的です。次回もJXAの実践的なテクニックについてお伝えしますね。

今回の記事はいかがでしたか?

副業やプログラミングに関する記事を書いています。(ときどき、それ以外のことも)
読者登録してもらうと更新の励みになりますのでよろしくお願いいたします。

月末日や最終金曜日にGoogle Apps Scriptを自動で実行するテクニック

f:id:tadaken3:20170703141142p:plain こんにちは!
タダケン(@tadaken3)です。

Google Apps Scriptでは、トリガー使ってスケジュールでスクリプトを実行することができます。処理を自動化するにあたってとても心強い味方なのですが、トリガーだけではスケジュールを組むのが難しいパターンもあります(例えば月末日など)。

今回は、Dateオブジェクトから取得できる値をうまく使って自在にスクリプトをスケジュール実行するテクニックをお伝えしていきます。

毎月1日にスクリプトを実行する

毎月1日にスクリプトを実行するには、トリガーだけで実行可能です。トリガーの設定方法を見ていきましょう。

トリガー設定するには、メニューバーにある時計マークをクリックします。

f:id:tadaken3:20170703133109p:plain

実行したい処理を選んでイベントを「時間主導型」「月タイマー」に変更しましょう。すると日にちと時間を設定できます。画面の例では、毎月1日処理が実行されます。

f:id:tadaken3:20170703133123p:plain

月の最終日にスクリプトを実行する

最終日は少し工夫が必要です。最終日は月によって30日や31日もしく28日だったりします。2月の場合はうるう年も考慮しないといけません。

スクリプト側で最終日かどうか判定するロジックを入れて対応しましょう。

今日の日付に1日分足したもの(つまり明日)が月初めの1日であれば、『今日は最終日』になります。最終日の次の日は絶対に1日だからです。この方法で条件を判定しましょう。

dateオブジェクトに対して、getDateメソッドを実行することで『日』を取り出すことができます。 2017年6月30日の場合は『30』の部分です。

Point dateオブジェクト.getDate();

dateオブジェクトに更新する場合は、setDateメソッドを利用します。日を整数で与えます。

Point dateオブジェクト.setDate('日');

実際のコードはこのようになります。

//トリガー設定用
function trigger(){
  date = new Date();
  date.setDate(date.getDate()+1);//今日の日付に一日足す
  if (date.getDate() === 1){//最終日の判定
    main();
  };
}

function main(){
  //実際に処理を実行する内容をここに記載する
  Loggor.log("今日は月末です")
}

トリガーは「日タイマー」を選んで毎日実行するように設定します。

f:id:tadaken3:20170703133600p:plain

最終金曜日にトリガーを実行する

最終金曜日に処理を実行する場合は、こののように考えます。今日の日付に7を足した日付(つまり翌週の同じ曜日の日)が、来月になっていれば『今日は最終金曜日』です。

『月』を取り出すには、getMonthメソッドを使います

Point dateオブジェクト.getMonth();

実際のコードを見てみましょう。

//トリガー設定用
function trigger(){
  date = new Date();
  var month = date.getMonth()//判定したい日の月を取得


  date.setDate(date.getDate()+7);//7日を足す
  var month_next_week = date.getMonth()//7日後の月を取得
  if (month != month_next_week){//月が一致しなければ最終週
    main();
  };
}

function main(){
  //実際に処理を実行する内容をここに記載する
  Logger.log("今日はプレミアムフライデーです")
}

毎週の金曜日にトリガー設定をしておけば、最終金曜日のみ処理が実行されます。

f:id:tadaken3:20170703192947p:plain

毎月25日にトリガーを実行。25日が土日の場合は前倒しにする

25日に実行したいけど、土日の場合は日にちを前倒しして処理を実行したい場合もあると思います。例えば、お給料日を判定するような場合です。通常は25日に処理が実行されますが、25日が土日の場合は23日もしくは24日実行したい場合です。

この場合は、日にちと曜日のデータを組み合わせて条件判定を行ないます。25日に実行する場合で、具体的なケースを見ていきましょう。

  • 25日が土曜日の場合、24日が金曜日
  • 25日が日曜日の場合、23日が金曜日

つまり、以下の3パターンで処理が実行されればいいことになります。

  • 23日が金曜日
  • 24日が金曜日
  • 25日が土日ではない

曜日を取得するには、getDayメソッドを使います。getDayメソッドが返す値は数字になります。日曜日が0となる点にご注意ください。

Point dateオブジェクト.getDay();

実際のコードを見ていきましょう。

//トリガー設定用
function trigger(){
  var today = new Date();
  //getDayメソッドが返す値は、日曜日から0で始まります。対応する配列を用意します。
  var week = new Array("日", "月", "火", "水", "木", "金", "土");
  var day =  today.getDay();//曜日を取得
  //ログに曜日を出力しています。
  Logger.log(week[day])

  var date =  today.getDate();//日付を取得

 //23日かつ金曜日なら実行
  if (date === 23 &&  week[day] === '金'){
    main();
 //24日かつ金曜なら実行
  } else if (date === 24 && week[day] === '金'){
    main();
 //25日でかつ土日ではない場合に実行
  } else if (date === 25 && week[day] != '土'  && week[day] != '日'){
   main();
  };
};

function main(){
  //実際に処理を実行する内容をここに記載する
  Logger.log("今日はお給料日です!")
}

あとは、23日、24日、25日に処理を実行するトリガーを設定すれば、オッケーです。

f:id:tadaken3:20170703134244p:plain

まとめ

トリガーと日付の判定を組み合わて、定期的にスクリプトを実行する方法をお伝えしました。

Dateオブジェクトから値を取得するメソッドをまとめるとこのようになります。他にもアイデア次第で、スクリプト実行するスケジュールを組むことができると思います。

メソッド 取得でくるもの 備考
getFullYear()
getMonth() 値は0~11(1月~12月)
getDate()
getDay() 曜日 値は0~6(日曜日~土曜日)

今回の記事はいかがでしたか?

副業やプログラミングに関する記事を書いています。(ときどき、それ以外のことも) 読者登録してもらうと更新の励みになりますのでよろしくお願いいたします。

Macユーザーにオススメ!複数のアプリ・フォルダをダブルクリック一発で立ち上げる方法

f:id:tadaken3:20170701182902p:plain こんにちは!
タダケン(@tadaken3)です。

あなたは、朝、会社についてまず何をしますか?

チャットアプリやメーラーを立ち上げてメッセージの確認、インターネットブラウザを開いてニュースサイトをチェックして、作業フォルダを開いて・・・というよう毎朝のルーティン作業がだれしもあると思います。

複数のアプリやフォルダを立ち上げるのは案外、面倒ですよね。Macユーザーであれば、複数アプリやフォルダ・ファイルを開く作業はシェルスクリプトで簡単に効率化できます。

今回はショルスクリプトで複数のファイルやフォルダ、アプリケーションをダブルクリック1発で起動する方法をご紹介します。

Mac専用のOpenコマンドでFinderやアプリを開く

MacではOS X専用のコマンドopenコマンドを使用すると、ターミナルからFinderを起動してファイルやフォルダ(ディレクトリ)を表示することができます。

ディレクトリ・ファイルを開く

Finderを開く場合は、開きたいディレクトリのパスを指定します。例えば以下のように実行すると、デスクトップがFinderで開かれます。

open ~/Desktop


デスクトップにあるPDFファイルを開く場合の以下のように実行します。ファイルに関連付けられているアプリが自動的に起動します。

open ~/Desktop/I-am-gundom.pdf


まとめ open "ディレクトリ・ファイルのパス"

アプリを起動する

アプリケーションを起動する場合は「-a」オプションに続けてアプリを指定します。/Applicationsや/Applications/Utilitesフォルダにあるアプリやツールはこの方法で開くことができます。

open -a ”Google Chrome”

ただし、アプリを指定する際は、Finderに表示されている日本語名の名前ではなく、アルファベットなど表示されている実際のアプリを指定する必要があります。拡張子の「.app」は指定しなくても、ほとんどのアプリは起動できます。アプリ名にスペースが含まれる場合はクォーテーションでくくって指定します。

指定のアプリでファイルを開くには次のように実行します。 cotEditerというエディタでテキストファイルが開かれます。

open -a cotEditer ~/Desktop/setsuna−f−seiei.txt


まとめ open -a "アプリ名"

複数アプリを実行するスクリプトを作成する

では実際に「Chrome」「Chatwork」を開いて、デスクトップを表示するシェルスクリプトを作ってみましょう。テキストエディタを開いて、以下のようにシェルスクリプトを書いてみましょう。

#!/bin/bash
open -a "Google Chrome"
open -a ChatWork
open /Desktop

たったの4行で終わります。簡単ですね。

作成できたらファイルを保存しましょう。ここで重要なポイントです。通常シェルスクリプトは拡張子を「.sh」にして保存します。Macの場合は拡張子を「.command」にすることで、ファイルをダブルクリックしてシェルスクリプトを実行できます。*1

Point ファイル名 .command

作成したファイルは「open_some_apps.command」と名前をつけて、デスクトップに保存しましょう。

ファイルに実行権限を与える

最後にファイルに実行権限を与えます。「ターミナル」からchmodコマンドで実行権限を付与します。*2

#!/bin/bash
chmod +x ~/Desktop/open_some_apps.command

作成したファイルをダブルクリックしてみてください。Chromeとチャットワークが立ちあがり、Finderにデスクトップが表示されていれば成功です。

まとめ

今回はMacユーザーのためのシェルスクリプトのテクニックを紹介しました。ちょっとしたテクニックですが、アイデア次第で日々のルーチンワークを効率化することができます。

  • Mac専用のopenコマンドでFinderやアプリを起動する
  • シェルスクリプトの拡張子を「.command」に変更してダブルクリックで起動

次回もシェルスクリプトのテクニックを紹介していきますね。お楽しみに!

今回の記事はいかがでしたか?

副業やプログラミングに関する記事を書いています。(ときどき、それ以外のことも) 読者登録してもらうと更新の励みになりますのでよろしくお願いいたします。

*1:ターミナルから、shコマンドでファイルを実行することもできます。Linuxとの互換性は失われてしまいます。

*2:chmodはファイルやディレクトリのファイルパーミッションを変更するコマンドです。詳しくはリンク先をご覧ください。https://ja.wikipedia.org/wiki/Chmod

Google Apps ScriptでHTML・XMLのスクレイピングをするライブラリを公開してみた

f:id:tadaken3:20170627092403p:plain こんにちは!
タダケン(@tadaken3)です。

HTMLやXMLを整形・解析して、必要なデータを取り出すことををスクレイピングといいます。副業のお仕事関係で、Google Apps Scriptを使い、HTMLをスクレイピングする作業が必要になったのでいろいろ調べていたのですが、せっかくなのでHTML・XMLをスクレイピングするためのGoogle Apps Scriptのライブラリを作成してみました。

コードはこちらの記事を参考にさせていただきました。ありがとうございます。

HTML/XML Parser for Google Apps Scriptのご紹介

ライブラリの基本的な情報は以下のとおりです。

ライブラリ名:
HTML/XML Parser for Google Apps Script

GitHub:
https://github.com/tadaken3/html-parser-gas

スクリプトID:
1Jrnqmfa6dNvBTzIgTeilzdo6zk0aUUhcXwLlQEbtkhaRR-fi5eAf4tBJ

まず、スクリプトIDを使って、ライブラリを追加します。 Google Apps Scritpのメニューバーの「リソース>ライブラリ」と辿っていきます。

f:id:tadaken3:20170626232437p:plain

すると以下の画面が出てくるのスクリプトIDを入力してください。

f:id:tadaken3:20170626232501p:plain

これでライブラリが追加されました。

parserライブラリの使い方

ライブラリの使い方は簡単です。以下の3つのメソッドで要素を取得します。

  1. IDを指定するgetElementByIdメソッド
  2. クラス名を指定するgetElementByClassNameメソッド
  3. タグを指定するgetElementByTagNameメソッド

IDを指定するgetElementByIdメソッド

getElementByIdメソッドでは、ID名を指定して要素を取得します。

書き方

parser.getElementById(対象の要素,ID名)

実際のコードはこのようになります。

var src = '<doc>'
        + '  <title id="doc-title">Anime Japan Expo</title>'
        + '  <chapter class="chapter">'
        + '    <paragraph class="paragraph">Do you like Anime?</paragraph>'
        + '  </chapter>'
        + '</doc>';

function parseXMLById() {
  var doc   = XmlService.parse(src),
      xml   = doc.getRootElement(),
      title = parser.getElementById(xml, 'doc-title');
  Logger.log(title.getValue());
}

するとidがdoc-titleの「Anime Japan Expo」がログに出力されます。

クラス名を指定するgetElementByClassNameメソッド

getElementByClassNameメソッドでは、クラス名を指定して要素を取得します。

書き方

parser.getElementByClassName(対象の要素,クラス名)

実際のコードはこちらです。

var src = '<doc>'
        + '  <title id="doc-title">Anime Japan Expo</title>'
        + '  <chapter class="chapter">'
        + '    <paragraph class="paragraph">Do you like Anime?</paragraph>'
        + '  </chapter>'
        + '</doc>';

function parseXMLByClassName() {
  var doc   = XmlService.parse(src),
      xml   = doc.getRootElement(),
      paragraph = parser.getElementsByClassName(xml, 'paragraph');//パラグラフを指定してます。
  Logger.log(paragraph[0].getValue());
}

クラス名がparagraphの「Do you like Anime?」がログに出力されます。

タグを指定するgetElementByTagNameメソッド

最後に、タグ名を指定するgetElementByTagNameメソッドです。

書き方

parser.getElementByTagName(対象の要素,タグ名)

サンプルコードはこのようになります。

var src = '<doc>'
        + '  <title id="doc-title">Anime Japan Expo</title>'
        + '  <chapter class="chapter">'
        + '    <paragraph class="paragraph">Do you like Anime?</paragraph>'
        + '  </chapter>'
        + '</doc>';

function parseXMLByTagName() {
  var doc   = XmlService.parse(src),
      xml   = doc.getRootElement(),
      title = parser.getElementsByTagName(xml, 'title');
  Logger.log(title[0].getValue());
}

こちらの場合は、titleタグの「Anime Japan Expo」がログに出力されます。

最後に

今回は、Google Apps ScriptでHTMLやXMLをパースするライブラリ「parser」についてお伝え致しました。HTMLやXMLをパースするイメージを掴んでいただけたでしょうか。Google Apps Scriptでスクレイピングをする際にきっと役立つと思います。:1

【追記 2017/01/23】ほかにも良さげなPaserライブラリを見つけました

「Parser」という同じ名前のライブラリを発見しました。Parsingの仕方が異なりますが、こちらも便利そうです。 ぜひ、参考にしてみてください。

www.kutil.org

読者登録をお願い致します!

本ブログではPython、Google Apps Scriptの役立つテクニックを公開しています。よろしければ、本ブログの読者もしくはTwitterアカウントのフォロワーになっていただけると更新の励みになります。ぜひ一緒にプログラミングを学びましょう。

tadaken3.hatenablog.jp

詳解! GoogleAppsScript完全入門 ~GoogleApps & G Suiteの最新プログラミングガイド~

詳解! GoogleAppsScript完全入門 ~GoogleApps & G Suiteの最新プログラミングガイド~


  1. 今回掲載したライブラリは自由に使ってもらって構いません(MIT ライセンス)。

コマンドラインからSlack、チャットワーク、LINEに簡単に通知が送れるNotifyというツールをリリースしました

f:id:tadaken3:20180325122838p:plain こんにちは! タダケン(@tadaken3)です。

以前お伝えしていたとおり、Go言語の勉強を進めています。

tadaken3.hatenablog.jp

今回はコマンドラインからSlack、チャットワーク、LINEに簡単に通知を送るツールを作成しましたので、ご紹介を致します。

Notifyの機能について

機能はとてもシンプルです。百聞は一見にしかず。こちらのデモをご覧ください。コマンド一発で、Slack、LINEやチャットワークに通知を送ることができます。デモではSlackしか載せていませんが、もちろんLINEやチャットワークにも通知が送れます。

f:id:tadaken3:20170619230038g:plain

Notifyを利用するには

せっかくなので、利用方法について簡単にご紹介させていただきます。 Notifyを利用いただくには、まず、こちらからご自身の環境にあったファイルをダウンロードしてください。

リリースページ

ダウンロードしたあとzipファイルを解答すると、notifyの実行ファイルが入っています。 こちらを実行ファイルをパスがとっているところにファイルを保存してください。

パス?って何って方は以下の記事を参考にしてみてください。

あとはホームディレクトリに、「.notify.yaml」という設定ファイルを作成します。 この設定ファイルに、各チャットツールのアクセストークンやルームID、チャンネルなどの情報を保存します。

line_access_token: XXXXXX
chatwork_access_token = XXXXXX
room_id = XXXXXX 
slack_token = XXXXXX 
channel = genneral

アクセストークンは設定ファイルに保存しなくても、コマンドラインのオプションで指定することもできます。 詳しい説明は以下のページにも記載していますので、こちらもご覧ください。

github.com

Notifyを作ろうと思った理由

「Notfiy」を作ろうと思ったきっかけは、現在、本業やブログ執筆でいろんなチャットサービスを利用しています。案件やプロジェクトによって、利用しているチャットツールが異なっているので、ひとまとめにして簡単にメッセージが送れるようにしました。

作ってみて勉強になったこと

今回は、コマンドラインツールを作成を目的にしたいたこともあり、vimというエディタで開発しました。vimを本格的に触ったので、最初は四苦八苦しながらでしたが、デスクにチートシートを貼り付けて少しずつコマンド覚えていきました。まだまだなれないことも多いですが、一回使い出すととても便利です。なにより、コマンドプロンプトやターミナルで使えるエディタというのは便利でした。

また、作成したコードをGithubにあげるだけでなく、Githubのリリースページに実際のリリースページを置くところまでやってみました。

今後やりたいこと

とりあえず、作ってリリースしたので、動くことは動くのですが、機能としてはまだまだブレッシュアップが必要だなと思っています。とりあえず、画像や添付ファイルの送信なんかにも対応していきたいと考えています。

また、コードはある程度書けるようになったのですが、設計・デザインパターンの勉強がきちんとできていないので、このあたりはもうちょっときれいに作り変えたいと思っています。

あと、テストコードもきちんと書けていないので、テストの技法なども勉強して、ちゃんとテスを書けるようにならないとなと感じました。

もし、要望や改善提案などあれば、Pull Requestいただけるとうれしいです。

「ExcelVBAを実務で使い倒す技術」、いよいよ発売です(書評)

f:id:tadaken3:20180325122314p:plain

みなさん、こんにちは! タダケン(@tadaken3)です。

今回「ExcelVBAを実務で使い倒す技術」タカハシさんに献本いただきましたので、早速紹介したいと思います。ありがとうございます。

f:id:tadaken3:20170424194727j:plain
献本いただいたVBA本

気になる目次も紹介します。

  • 第1章 脱初級への第一歩は「道具であるVBE」を使いこなすことから
  • 第2章 イミディエイトウィンドウの神髄
  • 第3章 バグを制するものはVBAを制する
  • 第4章 システムの成功と失敗の分かれ目は設計にあり
  • 第5章 できる担当者のコーディングは発想からして違う
  • 第6章 リーダブルコードでVBAを資産化する
  • 第7章 「変化」への耐久性を持たせるためのVBAの作法
  • 第8章 VBAは個人作業のみならず「チーム」にも革命をもたらす

ExcelVBAを実務で使い倒す技術は良き先輩となる本

この本の感想を一言で述べるとプログラミング初心者にとっての「良き先輩となる本」です。とくに、プログラミング経験がなく、周りに開発者の先輩・メンターがいない状態で、VBAでプログラミングを学ぼうと思う初心者の方にとっては、最良の先輩となるはずです。

例えば第3章では「エラーコードの読み方」がまとめられています。この手の内容は、開発者であれば、現場の先輩などから、おのずと習得して行くことだと思います。しかし、独学だとそうは行きません。そこで、本書が役に立つのです。

他にも、「検索の上手な使い方」や「読みやすいコードを書くためのコツ」といった、入門書には書いていないけど、開発をする上でとても役に立つ情報がこれでもかというくらい盛り込まれています。

初心者だけでなく、再入門にも!

また、初心者だけでなく、今まで何度かVBAやプログラミングに挑戦したけど、うまくいかなかったという方にも本書はとてもおすすめです。基本的なループや条件分岐といった文法を超えて、実際にプログラミングを仕事で役立てる方法を、学ぶことができます。

今までバラバラだった知識が、つながって一つの線になる感覚です。基本となる軸の通った知識があれば、どんな形でも応用ができるようになると思います。本書を読めば、コピペや写経から脱却して、オリジナルのコードを書けるようになるはずです。

まとめ

個人的には第7章『「変化」への耐久性を持たせるためのVBAの作法』がとても参考になりました。こういった作ったコードを、長期的に資産として活用していくための視点もふくまれているため、ほんとにためになる本だと思います。

ぜひ、書店やネット通販を通じてお手元にどうぞ。

ExcelVBAを実務で使い倒す技術

ExcelVBAを実務で使い倒す技術

GO言語、はじめました。

f:id:tadaken3:20180325123210p:plain

みなさん、こんにちは! タダケン(@tadaken3)です。 すっかり更新が滞ってしまいました。

突然ですが、GO言語に入門しようと思ったので、その経緯をブログに綴っておこうと思います。

なぜ、GO言語なのか

会社では基本、Python・Rなどでオレオレツールを作っていたのですが、他の人に使ってもらう際に、PythonやRをインストールしてもらわないといけないので、何かいい方法はないかなと思っていたら、GO言語にたどり着きました。

プログラミングは、基本、ネット記事や書籍をあさりながらやっていたので、独学だったということもあり、自分用のツールばかり作っていたのですが、そろそろ、一般に公開できるものが作りたいなと思ったのもきっかけです。

GitHubなんかに自分の作ったツールを公開できれば、かっこいいなあと。

f:id:tadaken3:20170424210747j:plain
Go言語を学ぶために購入した本

GO言語のメリット

node.jsなどとも迷ったのですが、以下の2点で、GOに決めました。 結構単純な理由です。

言語仕様のシンプルさ

GOは、機能の割にはシンプルな言語仕様で作られています。そのあたりがPythonに近いのかなと思って、勉強することにしました。

シングルバイナリの手軽さ

GOで書かれたプログラムは基本的に単体で実行可能なシングルバイナリとして提供できます。いったんコンパイルしてしまえば、MacやLinux、Windowsといった様々な環境で利用することができます。そのため、簡単なCLIツールなどを作るのに向いています。

まとめ

せっかくなので、このブログで定期的に学習の予定を公開できればいいなと思っています。 もしよかったら、アドバイスだったり、おすすめの書籍など教えてもらえるとうれしいです。

Golangを学んだことを活かしてCLIツールを作ってみた(追記)

GoでLINEやSlack、チャットワークにメッセージを送れるコマンドラインツールを作ってみました。

tadaken3.hatenablog.jp

実際作ってみて、言語仕様のシンプルさを実感しましたし、配布も簡単なのでとてもいいですね。

読者登録をお願いします

本ブログではプログラミングについての記事を公開しています。よろしければ読者登録していただけると更新の励みになります。ぜひ一緒にプログラミングを学びましょう。

本記事をレバテックさんが取り上げていただきました。

Go言語を勉強中という方に読んでほしい記事まとめ

他にもGo言語を学ぶ上で参考になりそうな情報がまとまっています。 こちらも参考に!