今日のつちや

田舎から元気に技術ネタと雑記を投稿します

技術書典4に向けて個人名刺兼ステッカーを作った

技術書典で個人名刺を用意しておきたくて作りました。

シールも作りたいなぁと思っていたよくばり者なので、シールベースで名刺サイズ(91x55)にしてみました。 Design&Adobeスキルゼロの私でもなんとか作れたので紹介。

きっかけ

f:id:corocn:20180325202719p:plain:w500

おすすめされたので!

印刷所

印刷所によってテンプレートが異なるので、先に印刷所を決めてます。 今回は教えてもらったアドプリントさんのマルチタイプシールを使ってます。

http://www.adprint.jp/Product/Intro/ss.aspx?Code=SS

コート 77kg ラミネート有(55 X 91mm) で注文しました。

切り抜き1箇所で100枚での注文で、3860円+送料500円 = 4360円です。 2箇所だと4300円+送料になりますね。 全印刷所比較してないんですけど、他のところはもっと高かったですね。

注文から到着までですが、1週間もかからず届きました。

使ったツール

Adobe Illustrator CC

印刷所のテンプレートはAI形式が多いんですよね。 技術書典の表紙作成とクソコラ作るためにフォトショを買ったんですが、 常用しないし、そこそこのお値段なので、1週間トライアルで全てすませちゃいました。

後述の理由により追加発注したんですが、トライアル期間で完結してます。なんかごめん。 次作成が必要なったら課金します。

Vectorizer

Online Image Vectorizer

普段使ってるアイコンがラスター画像しかなくて粗さが心配だったので、 上記ツールでラスター→ベクター変換しました。(よくよく考えたらイラレでできたのでは・・・?)

f:id:corocn:20180325203341p:plain

そこそこ綺麗になったから細かいことはいいや。

気をつけること

入稿前にチェックを読んでおくといいです。

スペルミス等もチェックしておきましょう。

http://www.adprint.jp/dataintro/basic.aspx

やっちまったこと

f:id:corocn:20180325203721p:plain

Engineerだったわ・・・。 醜態を晒す前に見つかってよかった(もう晒したけど)

これが理由で再入稿しました。 ついでに名前の部分も切り取れるようにした。

f:id:corocn:20180325222426p:plain:w200

こんな感じになっとります。

まとめ

普通の名刺より値段がはりますが、個別に作らなくていいのは楽でした。

f:id:corocn:20180325222128p:plain:w300

岐阜市近郊のうまい飯 (2018/03/23 更新)

食べたいもの別、再訪したいうまい飯情報(自分用メモ)です。 お高い店はピックアップしてませんし、車の移動が前提です。インスタ映えよりうまさ重視。

美味しいお店があったら、@corocn までこっそり教えてください。

麻婆豆腐

中華楼 - 岐阜市その他/中華料理 [食べログ]

  • マジ絶品。辛めなので注意。
  • そのへんの台湾料理やの麻婆豆腐とは違って本格的。
  • 担々麺も美味かった。

台湾まぜそば

台湾ラーメン大吉 - 西岐阜/ラーメン [食べログ]

  • 有名店。並ぶ。
  • 台湾ラーメンのほうが有名だけど、台湾まぜそばのほうが美味いと思う。
  • こちらも辛めなので注意。

味噌ラーメン

壱正 岐阜店 (イチマサ) - 岐阜/ラーメン [食べログ]

  • 普通のラーメン屋だけど、みその種類が選べて楽しい。
  • 味もいい。たまに無性に食いたくなる。
  • 店内で待てるし、スペース広くて良い。

もつ鍋

やっぱりラーメン黒野 - 名鉄岐阜/ラーメン [食べログ]

  • ラーメン屋みたいな名前だけど、もつ鍋が有名。
  • 安くて美味い。ドテ煮もおすすめ。
  • 夜しかやってない。

大衆中華

サンコック - 東大垣/中華料理 [食べログ]

  • ファミリー向け中華料理。安定している。
  • セットメニューの組み合わせが豊富。

カレー

カレーの文化屋食堂 - 名鉄岐阜/インドカレー [食べログ]

  • 日本風カレーともインドカレーとも言えない分類のカレー。
  • ガラムガラムガラム(キーマ風)が美味い。ファイナルカレーに近い。
  • 覚醒カシミールは人を選びそう。

ちゃんぽん

大光楼 墨俣店 - 東大垣/ちゃんぽん [食べログ]

  • にんにくたっぷりのベストちゃんぽん(旧:ベトコンちゃんぽん)がオススメ。
  • うまい。量も多い。

カジュアルフレンチ

Restaurant Venus & Mars (レストラン ビーナス&マーズ) - 西岐阜/フレンチ [食べログ]

  • 昼にランチで行くのがオススメ。かしこまらなくていいから楽。
  • キッシュがめちゃめちゃ美味い。追加で課金しても食べるべき。持ち帰りもできる。
  • シェフのおっちゃんが楽しい。

回転寿司

あみもとの里 かがしま - 西岐阜/回転寿司 [食べログ]

  • 穴子が絶品。ネタがでかく、450円で2本ついてくる。神か。
  • 下手に100円寿司いくならこっちのほうが良い。
  • コスパ最強。

とんかつ、味噌カツ

嬉しや - 西岐阜/とんかつ [食べログ]

  • 肉厚のみそかつが美味かった。
  • 豚の角煮もGOOD

洋食全般

キッチン 光陽亭 (KITCHEN Kouyoutei) - 岐阜市その他/洋食 [食べログ]

  • カジュアルイタリアン
  • ハンバーグドリアが美味かった

創作居酒屋

ビストロマルコ - 田神/居酒屋 [食べログ]

  • こじんまりとしたおしゃれな居酒屋。
  • こだわりの日本酒が置いてある。
  • 2人?でやってるので、最初にすべての料理から注文を組み立てなきゃいけないのが難しい。
  • しかしうまい。

ピザ

ダ ジェンナーロ (DA GENNARO) - 田神/ピザ [食べログ]

  • ピザ専門店だけあってピザは激ウマ。
  • オシャレな店なので気軽に行けない。入り口がどこか分からなくて毎回戸惑う。

パスタ

教えて!

そば

更科が有名だけど、そうじゃない、そうじゃないんだ。という気持ち。 美味いんだけどね。

教えて!

焼肉

美味いところはあるけどお高いし、 車走らせて養老まで行ったほうが楽しい。

教えて!

餃子

教えて!

ステーキ

今度21号沿いにいきなりステーキができる。

教えて!

Webpack 4.0.0 の Zero Configuration を試す

Webpack4.0.0が出てました。

github.com

さっそくZero Configurationを試してみます。 ウェブパック詳しくないマンなので、これでいいのか良く分からんですが・・・。

install

webpackとwebpack-cliを入れる

yarn add webpack webpack-cli

mode

modeオプションでdevelopmentとproductionを切り替えることができる

それぞれいい感じに設定してくれるみたい

package.jsonにscriptsを足す

  "scripts": {
    "dev": "webpack --mode development",
    "build": "webpack --mode production"
  },

srcとdist

デフォルトでは src/index.js に置くと、dist/main.jsに吐き出されるようになってる

src/index.jsに以下のように書いて

const test = () => console.log("Hello");
test();

ビルドする

yarn dev

dist/main.js見るとアローがそのまんまだった。 この時点ではbabel-loaderは適用されていないらしい。

バベる

.babelrc が 必要らしい

babelを入れる

yarn add babel-core babel-loader babel-preset-env

.babelrcを作る

{
    "presets": ["env"]
}

--module-bindオプションによって、*.jsはbabel-loaderを使用するよう指定できる

  "scripts": {
    "dev": "webpack --mode development --module-bind js=babel-loader",
    "build": "webpack --mode production --module-bind js=babel-loader"
  },

もっかいビルドする

yarn dev

無事バベれたことを確認。

感想

  • デフォルトでバベって欲しい!
  • 速さは良く分からない!

参考

https://www.valentinog.com/blog/webpack-4-tutorial/

技術書典4で認証付SPAの薄い本を書きます

技術書典4当選しました!! やったー!!

f:id:corocn:20180204205732p:plain

何書くか

個人開発でAuth0を使っていたら、組込が簡単で良かったんで、 Auth0でJWTを使ってSPAとバックエンドを繋ぐ薄い本を書こうと思います。

キーワード的には以下

  • Nuxt.js (Vue.js)
  • Rails API Mode + Knock
  • Auth0
  • Heroku

内容は、フロントエンドもくもく会 - 新年LT大会 で話した内容を細かく解説するような形です。

f:id:corocn:20180204205603p:plain

岐阜住みなので、名古屋でもくもく執筆会やります。 会場はMisocaのセミナールームを借りる予定です。

さあがんばるぞ!

技術書典4で同人誌を出すために「ワンストップ!技術同人誌を作ろう」を読んだ(良かった)

@corocn ですこんにちは。

技術書典4 の申込みが始まってますね。

今年は技術系同人誌を書いてアウトプットすることを目標に掲げたのですが、同人誌を書いたことのない私にとっては、何をやっていいか一切分からない状態です。(出版に関する知識がマジで無い)

そこで出会ったのがこの本

ワンストップ!技術同人誌を書こう - oyakata - BOOTH

コミックマーケット93で頒布されたやつですね。BOOTHで電子版を買いました。 結論から言うと最高だったので、初めて書くぞ!って人は読むと良いと思います。

200ページぐらいあるので、ざっと流し読みして、あーこんなことを気に留めておく必要があるんだーなるほどー!ぐらいのノリで読んで、詰まったときにじっくり中身を読むのが良さそうです。

以下ざっと読んだ感想。

感想

  • 当落関係なく書くつもりでやる。落ちたら委託すればいい。アウトプットに意味がある。
  • 印刷方法にはオフセットとオンデマンドがあるが、初めての人はオンデマンドで出すのが良さそう。
  • サイズはB5が主流。
  • Macヒラギノは商用利用可。
  • 原稿はGithubで管理すると良さそう。
  • 執筆ツールは色々あるが、Re:VIEW が良さげ。
  • 出力はPDF前提でやると、電子書籍で配布するのも捗りそう。
  • 表紙はオマージュ系、イラスト系、フリー素材系に別れそう。
    • たまたまお願いできる人がいたのでイラスト系にする。
    • 頼める人がいなかったらフリー素材にしたと思う。
  • 表紙はKeynoteで作るのが良さそう。
    • Keynoteは最高の作画ツール。
  • 画像は印刷用に300dpi以上で出すが、電子書籍はサイズが大きくなるので、解像度を少し下げる。
  • 確認用の連番としてノンブルというものがある。
  • ページ数は4の倍数にすべし。
  • プリンターはあったほうがいい。
    • 以前会社の人と話してて、「最近プリンターなんて必要なくない?」なんて言ってすいませんでした。要るわ。
  • PDFの入稿は同人誌業界ではマイナーだけど、技術系だと多いみたい。
  • トンボ・塗りたし。 指定の塗りたしを含めた「正しい」PDFの入稿が必要。
  • 横書きの技術書は左綴じ。
  • CMYK形式での変換を行って入稿するのが原則。
  • 直接搬入が一番楽。
  • ポスター作ったほうがいい。キンコーズなどで作れる。
  • 早割を締め切りにする。完成形の出力まで1回通しでやってみておくのが良い。
  • 当時は2万円分ぐらいを両替して持ち込む。必要なものの確認もスケジュールに含める。
  • 個人名刺を作らねばという気持ち。
  • 電子決済の話がないように思えたので、あとで調べておきたい。何が良いんだ?

上記トピックでも足りてないと思うので、スケジュールをはやめに決めたいですね。で、スケジュールを決めるためには印刷所の締め切りを考慮する必要があるので、まずは印刷所を決めようと思います。技術書典との連携が厚いところを選ぶつもりです。

これも大事だよってのがあれば、教えて欲しさ。 あとは会社の人の出版経験があるから、頼らせて貰うつもり。

以上、参考になれば!

追記

https://techbookfest.org/event/tbf04#guide によると

日光企画、ねこのしっぽ利用の場合、印刷所からの直接搬入が可能です。

とのことなので、2択な気がしてる。

2017の振り返り

新卒で就職したコッテコテの古き良き日本大企業から転職を決意して、今日で1000日経過した。

f:id:corocn:20171231152733p:plain http://counting.hatelabo.jp/count/rk959zjrfl(勝手に作られてた)

転職した

これが一番大きなイベントだった。

東京の会社も色々見に行ったけど、人混みが辛くなったのと、色々あって結局地元に落ち着いた。

昔大手の転職サイトに登録したら、やたらと電話がかかってきて死ぬほどダルい思いをしたので、 今回はWantedlyのみで転職活動していた。

たまたま貰ったスカウトメールの会社を見たら、 Twitterでフォローしてた雪うさぎのアイコンの人がいて、興味を持った(Twitter初期からフォローしていたけど、一切面識が無かった)

採用プロセスがかなりユニークで、トントン拍子で入社することになった。 そしてMisocaというクラウド請求書の会社にいる。かなり働きやすい会社だと思う。社員も人格者が多い。

勉強した

残業ゼロで時間が取れるようになったので、気になっていた技術で遊んだ

Ruby, Rails

  • 実は今の会社に入るまでは、PHPがメインの開発言語だったので、少し業務でRailsを書いた程度だった。 (なんで採用してもらえたか謎だけど、Computer Scienceのバックグラウンドがあるのは大きいのだろうか。)
  • がっつりRubyを書くようになって、虜になった。
  • RailsはWebpackerがカオスなので、最近はNuxt.js + Rails API Modeが良いんじゃないかと思ってる。

JavaScript, Vue.js, Nuxt.js

  • モダンジャッバスクリプトのナウい書き方が未だに分からなくて未だに困惑している。
  • JavaScriptをビルドするのが辛い。型の無い言語をビルドするのに抵抗がある。
  • React+Reduxを触ってきたけど、Vueのほうがしっくりきていて、Nuxt.jsがマジで良い。

AWS

  • 業務でも使うので色々触った。
  • サービス増えすぎて追いかけるが大変ではあるが、テクニカルサポートが手厚くて便利。
  • BlackBelt Dojoを会社で実施してもらうと凄く捗る。
  • 細かく設定できる分、個人ベースでさっと使うのには向いてない感じはある。

勉強会

  • フロントエンドもくもく会に参加してて、運営を手伝わせて貰っている。
  • 年明けにはLT大会もあるので楽しみ。

来年

  • 前のめりでやっていく
  • 新しい言語を学ぶ(Kotlinあたり)
  • 本を書きたい(技術書店に出したい)
  • 結婚したいです

今年もお世話になりました。 来年もよろしくお願いします。

Google HomeでTech系Podcastを聞く(Dialogflow + Cloud Functions編)

こんにちは、@corocnです。 今回は音声認識マンらしく話題のGoogle Homeを触ってみました。

Misoca Advent Calendar 2017 - Qiita の14日目の記事になります。

はじめに

最近は、Google HomeでTech系のPodcastを雑に聞きたいなぁという欲求があって、色々と試しています。

現状考えられるアプローチとして3つありまして

  1. Google Play Musicに音源を放り込む
  2. 専用のストリーミングサービスを作る
  3. Dialogflow + Cloud Functionsで音源を再生する (今回の記事)

1はコレじゃない感、2はそもそもが作り方が謎でして、「キーワードに反応して特定の音源が再生できれば何でもできるやろ」ということで、3番目を試した記事になっています。IFTTTは使いません。

rebuild.fmが聞きたいのが始まりだったのですが、Google Homeで再生可能な音源なら何でも適用できるはず。

既に色んな方がDialogflowの解説記事を出してくれていますが、それらを見た上でハマったポイントも掲載して、初心者向けチュートリアルしてまとめてみました。

Dialogflow

f:id:corocn:20171211215525p:plain

対話ボットを簡単に作成できるサービスになります。 自然言語対話プラットフォーム「API.AI」が、Googleに買収されたことで、名前を変えました。

https://dialogflow.com/

Dialogflowでは、プロジェクトを「Agent」という単位で管理します。以下の機能を使ってボットを作ります。

  • Entities: 会話に含まれるキーワードを定義
  • Intent: 会話の流れを定義
  • Fulfillment: SSML(後述)を生成するサーバーをWebhookで指定
  • Integrations: デプロイ

※ この先、Googleから許可を求められたら内容を確認の上、承諾して進めてください

Agent

左上のCreate new agentから作成できます。

f:id:corocn:20171211213728p:plain

作成画面が出るので、諸々の情報を入力してください。今回はpodcast-playerという名前にしてます。

V2 APIはbetaなので、今回はV1で試します。有効にしないでください。 (´-`).。oO(今度V2 APIの解説も書けたらいいな...)

f:id:corocn:20171211213744p:plain

Entities

Agentの作成ができたところで、Entitiesを定義していきます。

@podcast_name を @action して

という文章で実行する予定ですが、@podcast_name, @actionがEntityになります。それぞれキーワードと言い換え語を入力します。

f:id:corocn:20171211213801p:plain

f:id:corocn:20171211213813p:plain

f:id:corocn:20171211213825p:plain

登録できました。

Intent

Entitiesが定義できたので、Intentを作成します。 ちょっとクセのあるUIですが、

まず「podcast_nameをactionする」と入力して追加

f:id:corocn:20171211213837p:plain 追加された1文のEntityをマウスで範囲選択するとキーワードを適用できます。@podcast_nameでフィルタすると早いですね。@actionも同様です。

f:id:corocn:20171211213855p:plain 紐付けが終わるとUser saysとActionが自動で埋まります。

いくつかパターンを定義していきます。

f:id:corocn:20171211213910p:plain

保存の前にActionを必ず入力してください。 忘れがちですが、入れておかないと今後の処理で困ります。「play.podcast」にでもしておきます。

f:id:corocn:20171211213923p:plain

これで保存して完了です。

Fulfillment

最後にWebhookの設定をしたいのですが、この段階ではレスポンスを返す環境を用意してないので、適当なdummyにしておきましょう。

保存後、先ほど作成したIntentを見ると、ページの下部にFullfillmentの設定が追加されているはずなので、Webhookを有効にしておきましょう。

f:id:corocn:20171211213932p:plain

f:id:corocn:20171211213940p:plain 保存をお忘れなく。

SSML with Cloud Functions

Google HomeはSSML(Speech Synthesis Markup Language)という形式に対応しており、特定のキーワードに反応させて別途用意したサーバーからSSMLを返すことで、任意の発話やアクションを実行することができます。

今回はCloud Functionsを使って、簡易的なレスポンスサーバーを用意して試します。

SSML

詳しい文法は OfficialActions on Google(Google Home)で使用できるSSMLタグのまとめ | KOTODAMA TODAY を見ると良いと思います。

とりあえず凝ったことはせず、固定のURLの音源を再生する方針で進めます。

<speak>
 リビルドエフエムを再生します。
 <audio src="https://hoge/sample.mp3/"/>
</speak>

srcはHTTPSのみ対応しているので注意してください。

上記例では、sampleにしていますが、テスト時はS3とかCloud Storageに雑にファイルを置いて試していました。直リンでやると怒られると思いますので、自分で用意してみてください。

サンプルサーバー

以下をクローンして、functions/index.jsを書き換えます。 https://github.com/actions-on-google/dialogflow-webhook-template-nodejs

'use strict';

process.env.DEBUG = 'actions-on-google:*';
const { DialogflowApp } = require('actions-on-google');
const functions = require('firebase-functions');

exports.yourAction = functions.https.onRequest((request, response) => {
  const app = new DialogflowApp({request, response});
  console.log('Request headers: ' + JSON.stringify(request.headers));
  console.log('Request body: ' + JSON.stringify(request.body));

  // Fulfill action business logic
  function responseHandler (app) {
    // Complete your fulfillment logic and send a response
    app.tell({
      speech: '<speak>リビルドエフエムを再生します。<audio src="https://hoge/sample.mp3"/></speak>',
      displayText: 'さいせい'
    });
  }

  const actionMap = new Map();
  actionMap.set('play.podcast', responseHandler);

  app.handleRequest(actionMap);
});

app.tellのspeechのvalueにSSMLを直接記述できます。

actionMap.setのキーを、Intentで設定したaction名に変更することをお忘れなく。

また、サンプルのmp3は適宜書き換えてください。

Deploy Webhook

firebase へでデプロイします。

firebase-toolsが必要なので、この辺を参考に入れると良いです。 https://firebase.google.com/docs/hosting/deploying?hl=ja

以下のコマンドを順に実行して、deployします。

# functions以下でnpm install or yarn installが必要
$ cd functions
$ yarn install
$ cd ..

# firebaseへログイン
$ firebase login

# firebaseを初期化
$ firebase init

? Which Firebase CLI features do you want to setup for this folder? Press Space to select features, then Enter to confirm your choices.
> ◯ Functions: Configure and deploy Cloud Functions

? Select a default Firebase project for this directory:
> podcast-player

✔  Firebase initialization complete!

# deploy実行
$ firebase deploy --only functions

Function URL (yourAction): https://us-central1-xxxxxxxxxxxxxx.cloudfunctions.net/yourAction

✔  Deploy complete!

最後にfunction URLを教えてもらえるので、コピっておきます。 なお、そのまま叩くと「Action Error: no matching intent handler for: null」というエラーが出ますが、正常です。

Fulfillmentを修正する

ここでDialogflowのFullfillmentへ戻って、dummyのURLを、先ほど生成したFunction URLへ変更しておきましょう。

f:id:corocn:20171211214001p:plain

Integration

さてさて、準備が整ったので、DialogflowのIntegrationsから、Google Assistantを選択してテスト環境へ反映していきましよう!

といっても、Additional triggering intentsで、作成したintentsを選択し、UPDATE DRAFTを押すだけです。

f:id:corocn:20171211214010p:plain

「Actions on Google draft successfully updated」と表示されたら成功です。VISIT CONSOLEからアプリの管理ページへ飛べます。

テストしてみる

諸々準備が終わったので、実際に動かしてみます。

Assistant app

VISIT CONSOLEを押すとAssistant app draftに飛んでくるはずです。

② App InformationのEditを押して、Assistant app nameと、その発音を入力します。 ここで入力した情報を用いて、Google Homeからアプリを呼び出します。

f:id:corocn:20171211214020p:plain

すごく適当ですが、こんな感じです。Pronunciationが他のアプリと被ると怒られます。

保存したら、1個前のページに戻ってください。入力が足りない的なエラーが出ているかもしれませんが、本申請するわけではないので、気にしないでおきましょう。

ページ下部のTEST DRAFTボタンでシミュレーターを起動します。

シミュレーターテスト

少しハマったポイントです。 本来なら、以下のようなやりとりをすると音源が再生されるはずなのですが、現状シミュレーターだと上手く動かないようです。

f:id:corocn:20171211214030p:plain

VALIDATION ERRORSに、 「UnparseableJsonResponseAPI Version 2: Failed to parse JSON response string with 'INVALID_ARGUMENT' error: ": Cannot find field.".」と表示されていました。どうやらV2 APIの形式でリクエストを投げているようで、シミュレーター上でV1 APIで試す方法がわかりませんでした。設定があるのかもしれませんが、よく分からず。

実機テスト

シミュレーターで動かなかったので、実機で動かしてみます。 自身のGoogleアカウントと紐付いている状態ですので、Google Homeから先程作成したテスト用アプリを実際に立ち上げることができます。

注意: 動画を再生すると、あなたのGoogle Homeが反応するかもしれません

上記動画ではs3にテスト用として置いたrebuild.fmのmp3音源を再生しています。 途中に長い無音区間が入っているのは、音声をロードしているためです。サイズが80MBほどあって、完全に読み込むまで再生が始まらないのが微妙ですね。

また、Play Musicのような音楽再生ではないので、1回停止すると再開できません。不便だ。。

まとめ

汎用性のないままこの記事は終わりますが、Dialogflow + Cloud Functionsで特定のURLの音源を再生してみました。

もう少し応用すればいい感じにできるんじゃないかな〜?と思ってますが、シークや途中再生が困難なので、PlayMusicにぶっこんだほうが便利なんじゃないのこれと思っています。

Cloud Functionsでゴニョれるので、なんでもできそうですね。今後も色々試してみようと思います。