OmniAICreator/Qiita-1.07M huggingface dataset:
Minecraft:Bedrock Edition用の公式バニラサーバーを開いてみた

こんにちは、はにおかさいです。
悲願！？の公式のMCBEサーバーがリリース（本公開ではない）されたので触ってみます。
添付されている説明書にはdedicated server、即ち専用サーバーと表現されています、
リリースノートには「Bedrock Dedicated Server（BDS)」とタイトルがつけられています。

#長所
- モブが湧く
- レッドストーン系は完璧に動く
- 安定した動作
- メモリ消費量の圧倒的少なさ（アイドルでLinuxで60MBぐらい)
- ipv6に対応

#短所
- コマンド関連の実装はまだまだ甘そう
- プラグインが使えない
- ファイル数をやたらと消費する

#ダウンロード
https://minecraft.net/en-us/download/server/bedrock/
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/faf365f9-f037-a5d9-2232-09b047f658c3.png)

WindowsとLinux (x86及びx86_64対応バイナリ）が選べます


#設定
server.propertiesを起動前に編集してください。
allow-cheats=falseを
allow-cheats=true
にしないと鯖内でコマンドが使えません。

#起動
##Windows
###一度だけ
必要ファイルは自動で作られません、次の名前で空のファイルを作っといてください。
- ops.json
- whitelist.json
###起動
ダブルクリックで起動します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/245977/3008d38f-c372-08db-5c64-3c3b428dcdc7.png)



##Linux 

###注意
対応アーキテクチャは、、、

```
objdump -x ./bedrock_server |more

./bedrock_server:     file format elf64-x86-64
./bedrock_server
architecture: i386:x86-64, flags 0x00000112:
EXEC_P, HAS_SYMS, D_PAGED
start address 0x00000000017ac700

```

i386:x86-64......

通常のパソコンのCPUアーキテクチャでしか使えず、ラズパイ等のarmhfでは使えません。


ダウンロード後、フォルダを作ってその中で展開してください。

###一度だけ
必要ファイルは自動で作られません、空のものを作っといてください。

```
touch ops.json
touch whitelist.json
```

###起動

```
LD_LIBRARY_PATH=. ./bedrock_server


######
NO LOG FILE! - setting up server logging...
NO LOG FILE! - [2018-09-12 00:08:41 INFO] Starting Server
NO LOG FILE! - [2018-09-12 00:08:41 INFO] Version 1.6.1.0
NO LOG FILE! - [2018-09-12 00:08:41 INFO] Level Name: Bedrock level
NO LOG FILE! - [2018-09-12 00:08:42 INFO] Game mode: 0 Survival
NO LOG FILE! - [2018-09-12 00:08:42 INFO] Difficulty: 1 EASY
NO LOG FILE! - [2018-09-12 00:08:42 INFO] IPv4 supported, port: 19132
NO LOG FILE! - [2018-09-12 00:08:42 INFO] IPv6 supported, port: 19133
NO LOG FILE! - [2018-09-12 00:08:42 INFO] Listening on IPv6 port: 19133
NO LOG FILE! - [2018-09-12 00:08:42 INFO] Listening on IPv4 port: 19132
```

これではいれます。

#まとめ
簡単に公式でサーバーを立てられるのは便利です。粗削りなのと、ログ出力がコンソール含めてなされないのは気になりますが、いろいろ遊びかたはありそうですね。
KanonConductorのTrac1.2.3化とsetupのDockerfile化

# はじめに

 前の記事でできるだけ昔のKanonをコンテナ化しましたが、今回はできるだけ最新のKanonをコンテナ化してみました。コンテナ内に限定しOSはCentOS7にしました。コンテナなのでlinuxコンテナが動けばどこでも使えるようになり、動かす環境の他のソフトの影響を受けないので、今後数年間長く使えると思います。まだまだやれることはあるのだけれど、ここで一旦公開しておきます。使い方はまた別記事で書きます。

# 変更点

 * コンテナ化
   * OSはCentOS7に固定
   * OSやPython,Apacheのバージョンが固定され
 * Jenkinsは別コンテナに
 * MariaDB(MySQL互換)対応
 * Trac1.2.3に変更
   * 各種プラグインのエラー対応
   * カスタムフィールドの日付対応, GanttCalendarも修正

# リポジトリ等

ソースは hg clone https://bitbucket.org/okazakiyuji/kanoncontainer から取得してください
イメージは okazakiyuji/kanonconductor:v0.2b2 で取得できます

※ 使い方は…　もうすこし
Embedded FrameworkでCarthageライブラリを利用する際の注意点（CFBundleIdentifier Collision）

# 概要
Embedded Frameworkを組み込んだアプリをAppStoreの審査に提出しようとしたところ、アーカイブの検証の際に下記のエラーが表示され、つまづいたので記事にまとめます。

# エラー内容
> CFBundleIdentifier Collision. There is more than one bundle with the CFBundleIdentifier value <Carthageライブラリ名> under the iOS application <アプリ名>.

エラー文言によると、導入したCarthageライブラリのバンドルIDが複数同じものが存在し、衝突したようです。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/113553/92f5a00d-e07f-3c41-dddc-51c090677870.png)

# アプリ構成
アプリの構成は下記のように、OSSライブラリに依存するEmbedded Frameworkを作成し、さらにそのFrameworkをアプリから利用していました。依存関係はCarthageによって解消しています。

```
Application
↓
Embedded Framework（Carthageで導入）
↓
OSS Libraries（Carthageで導入）
```

# 原因と対処方法
iOSアプリではFrameworkのネストが許されておらず、Frameworkがネストしている場合はAppStoreの審査に提出することができないようです。
今回のケースでは、Embedded FrameworkおよびApplicationの両方でBuild Phasesにてframeworkのcopyを行ってしまっていました。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/113553/094a7863-4fa8-d85a-f4e5-2ac5833b7d3d.png)

copyをEmbedded Frameworkでは行わず、全てアプリケーション側でcopyすることで解決します。

# まとめ
 - iOSアプリではFrameworkのネストが許可されていない
 - Embedded FrameworkではCarthageライブラリのcopyは行わないようにする
指点字キーボードを試作

指点字キーボードを試作しています。
![IMG_5848.jpg](https://qiita-image-store.s3.amazonaws.com/0/59911/16fe2b83-1c07-84c8-ff62-8717d9a5e51d.jpeg)
[試作機](https://www.youtube.com/watch?v=xI7hSq7ywQU)

必要な材料は市販されている（秋葉原などで手に入る）ものを使用しており、原価は三千円程度です。

- [ブレッドボード　６穴版　ＥＩＣ－３９０１](http://akizukidenshi.com/catalog/g/gP-12366/) x2
- [リニア振動アクチュエータ　ＬＤ１４－００２](http://akizukidenshi.com/catalog/g/gP-06838/) x6
- [トランジスタ　２ＳＣ３３５５Ｌ－Ｔ９２－Ｋ](http://akizukidenshi.com/catalog/g/gI-09742/) x6
- [緑色ＬＥＤ](http://akizukidenshi.com/catalog/g/gI-06405/) x6　（確認用）
- [マイクロスイッチ　Ｄ３Ｍ－０１Ｌ１](http://akizukidenshi.com/catalog/g/gP-09187/) x6
- [コネクタコード](http://akizukidenshi.com/catalog/g/gC-09402/) x6
- [ジャンパーケーブル（オス－メス）](http://www.aitendo.com/product/16084)
- [絶縁ゴムシート](http://akizukidenshi.com/catalog/g/gP-10424/)(共振防止用)
- [USBコネクタ](http://www.aitendo.com/product/11687)
- [赤外線リモコン受信モジュール　ＳＰＳ－４４５－１](http://akizukidenshi.com/catalog/g/gI-00585/)
- [ＡＥ－ＡＴＭＥＧＡ３２８－ＭＩＮＩ　（Ａｒｄｕｉｎｏ　Ｐｒｏ　Ｍｉｎｉ互換）](http://akizukidenshi.com/catalog/g/gK-10347/)
- [１００均ショップのケース](https://www.cando-web.co.jp/)
- [ソフトウェア（開発中）](https://github.com/misawa2048/ec_git/tree/master/src/finger6keys)
GAE/GoでSendGrid APIv3でメールを送信する

## はじめに

AppEngineのMailAPIでもメールを送ることができますが、SendGridも利用できます。
GAEからの利用であれば、月12,000件まで無料で使えます。（2018年9月8日時点）
詳しくは[ドキュメント](https://cloud.google.com/appengine/docs/standard/go/mail/sendgrid)を参照してください。

以下は `go1.9` で試しました。

## SendGrid APIv3を使う

GAE/Goの[ドキュメント](https://cloud.google.com/appengine/docs/standard/go/mail/sendgrid)ではv2を使うやり方が紹介されていますが、より新しいAPIであるv3を使う方法を以下で紹介します。

コードはこんな感じです。Email helperを使うと jsonベタ書きしなくてもOKです。

```go

import (
	"context"
	"fmt"
	"os"

	"github.com/sendgrid/rest"
	sendgrid "github.com/sendgrid/sendgrid-go"
	"github.com/sendgrid/sendgrid-go/helpers/mail"
	"google.golang.org/appengine/urlfetch"
)

func sendMail(ctx context.Cotext, to, subject, plainTxt, htmlTxt string) error {
	sendgrid.DefaultClient = &rest.Client{HTTPClient: urlfetch.Client(ctx)}
	cli := sendgrid.NewSendClient("YOUR_API_KEY")

	fromM := mail.NewEmail("YOUR_NAME", "YOUR_EMAIL")
	toM := mail.NewEmail(to, to)
	msg := mail.NewSingleEmail(fromM, subject, toM, plainTxt, htmlTxt)

	res, err := cli.Send(msg)
	if err != nil {
		return err
	}

	if res.StatusCode >= 400 {
		return fmt.Errorf("send mail failed: %v", res.Body)
	}
    return nil
}
```

### ポイント

1. AppEngineなので以下のようにHTTPClientにurlfetchを使う必要があります。
`sendgrid.DefaultClient = &rest.Client{HTTPClient: urlfetch.Client(ctx)}
`

2. errorだけじゃなくstatuscodeをチェックする必要があります。メールの内容が正しくないと400などのステータスが返ってきます。

3. plainTextとhtmlTextの両方がないとエラーになります。APIの仕様と違う。。

## 感想

`NewEmail()`はMailを作るのではなくFromやToのアドレスを作る関数で、実際のMailを作るのは `NewSingleEmail()` です。わかりにくくないかな

[sendgrid/sendgrid\-go: The Official SendGrid Led, Community Driven Golang API Library](https://github.com/sendgrid/sendgrid-go)
ROS講座57 カメラ画像を圧縮して送信

# 環境
この記事は以下の環境で動いています。

| 項目 | 値 |
|:-:|:-:|
| CPU | Core i5-8250U |
| Ubuntu | 16.04 |
| ROS | Kinetic |

インストールについては[ROS講座02 インストール](https://qiita.com/srs/items/e0e0a9dc3f94c2d3348e)を参照してください。
またこの記事のプログラムはgithubにアップロードされています。[ROS講座11 gitリポジトリ](https://qiita.com/srs/items/25a56a6abda41dcf396e)を参照してください。

# 概要
ロボットでの画像の使い方として、遠隔操作のためにロボットについているwebカメラの画像を転送してリモートで見るという方法があります。しかしWebカメラの画像を非圧縮（以下の図の上）で送るとwifiの帯域が足らずに送信周期が下がりいわゆる「カクカク」した画像になります。
そのために画像を圧縮して送信する必要があります（以下の画像の下）。このためにimage_transportというパッケージを使いsensor_msgs/CompressedImage
型に変換します。また画像処理用のROSノードは圧縮した画像をそのままで処理することはできません。そのために受信した側では圧縮した画像の展開をする必要があります。

![cam_trasport.png](https://qiita-image-store.s3.amazonaws.com/0/254442/d58c5d81-8162-e199-1620-4e08b35a6362.png)


# image_transportのインストール
以下の2つのパッケージをインストールします。このパッケージをインストールすると特に何もしなくても`image_raw/compressed`というROSトピックが自動的に生成されます。

```shell:インストール
sudo apt-get install -y ros-kinetic-image-transport
sudo apt-get install -y ros-kinetic-image-transport-plugins
```

# image_view起動用のlaunch
```xml:cam_lecture/launch/republish.launch
<?xml version="1.0"?>
<launch>
  <arg name="use_compressed" default="false" />

  <group if="$(arg use_compressed)">
    <node name="image_republish" pkg="image_transport" type="republish" args="compressed raw">
      <remap from="in" to="/image_raw" />
      <remap from="out" to="/image_exp" />
    </node>
    <node name="image_view" pkg="image_view" type="image_view" >
      <remap from="image" to="/image_exp"/>
    </node>
  </group>
  <group unless="$(arg use_compressed)">
    <node name="image_view" pkg="image_view" type="image_view" >
      <remap from="image" to="/image_raw"/>
    </node>
  </group>
</launch>
```

ポイントは以下のrepublishノードの起動です。`args="compress raw"`は圧縮した画像を非圧縮の画像に変換するという指示です。入れ替えると非圧縮を圧縮に変換します。`in`と`out`を正しいROSトピック名にremapします。

```xml:republishノードの起動
<node name="image_republish" pkg="image_transport" type="republish" args="compressed raw">
 <remap from="in" to="/image_raw" />
 <remap from="out" to="/image_exp" />
</node>
```

# 実行
通信をするのでロボットPC側と手元PC側の2つのマシンで作業をします。

```shell:ロボットPC側のshellにて
export ROS_IP='192.168.2.20' #ロボットPCのIP
rosrun uvc_camera uvc_camera_node
```

```shell:手元PC側のshellにて（非圧縮で転送）
export ROS_IP='192.168.2.10' #手元PCのIP
export ROS_MASTER_URI='http://192.168.2.20:11311' #ロボットPCのIP 
roslaunch cam_lecture republish.launch
```

```shell:手元PC側のshellにて（圧縮で転送）
export ROS_IP='192.168.2.10' #手元PCのIP
export ROS_MASTER_URI='http://192.168.2.20:11311' #ロボットPCのIP 
roslaunch cam_lecture republish.launch use_compressed:=true
```

非圧縮の場合は転送容量は3.1MB/sですが1.6Hz程度しか出ていません。

![cam_repub1.png](https://qiita-image-store.s3.amazonaws.com/0/254442/408bc5cb-5544-bf3a-71a0-189f3a887b8b.png)


圧縮の場合は1.4MB/sと減っている上に30Hzが出ています。
![cam_repub2.png](https://qiita-image-store.s3.amazonaws.com/0/254442/74b2f438-a8ad-c3c1-6931-1512cedf4750.png)


# 参考
[画像圧縮によってフレームレートを向上させるパッケージの紹介](http://mprg-robot.isc.chubu.ac.jp/image_transport/)

# 目次ページへのリンク
[ROS講座の目次へのリンク](https://qiita.com/srs/items/5f44440afea0eb616b4a)
ブログを始めるのでQiita、note、Mediumなどのブログサービスを調べてみた。

@tacashionです。インターネット企業でデザイナーをしています。

#ブログを始めようと思う

会社のセミナーで、クリエイターとしてアウトプットをしていくことはとても大事、というお話を聞いて、確かにデザイナーとして日々案件としてアウトプットを出したり、色々と考えたりすることはありつつも、オープンな場所で自己表現というか、情報発信をする機会がなかなかないのもあり、ブログを始めようと思い至りました。

##どのブログサービスで始めるか

そんなきっかけでブログを始めようと思ったものの、どこで始めるか迷いました。
自分が思いついた候補は以下の通り。

* [Tumblr](https://www.tumblr.com)
* [はてなブログ](http://hatenablog.com)
* [note](https://note.mu)
* [Medium](https://medium.com)

加えて、会社の同僚から提案してもらったのが以下の2サービス。

* [WordPress](https://ja.wordpress.com)
* Qiita

##それぞれの特徴と偏見をまとめてみる

一行目が自分のイメージ、二行目以下が調べてみた所感です。

* [Tumblr](https://www.tumblr.com)
非常にライト。Twitter感覚。最近影がうすい気がする。

* [はてなブログ](http://hatenablog.com)
シンプルそう。
テキストが書きやすい。
記事次第でははてなブックマークで話題になりやすそう。

* [note](https://note.mu)
クリエイターっぽい人が使っているイメージ。
サービス紹介を見ると様々なメディアを気軽に投稿できるTumblrを思わせる特徴。
有料記事にして売れる。

* [Medium](https://medium.com)
英語の記事が多い。なんとなくおしゃれ。

* [WordPress](https://ja.wordpress.com)
自由度が高そう。
あとで聞くとプラットホームとしてのWordPressはいわゆるブログサービスで自分でカスタマイズ的な自由度はないらしい。

* Qiita
シンプルで技術的な記事に強そう。
というかQiitaは、プログラミングに関する知識を記録・共有するためのサービスです。と書いてある。

##自分がやりたいことを考えてみる

それぞれのサービスのイメージがつかめてきたところで、自分がブログを書くことでどうなりたいかを整理してみました

* 文章を書く、考える技術の向上
日々の業務の中でデザインいついて言語化して伝えることの重要性と、自分はまだ不十分と感じることがあり、思考を文章化するトレーニングをしたいと考えていました。

* クリエイターとつながりたい
文頭でも書きましたが、インハウスデザイナーとして働いているので、社外のデザイナーの方とお会いする機会も少ないので、少しでも交流のきっかけとなればと思っています。

なので、やや長めの文章で、職業・技術的な投稿が多そうな場が良いと思いました。

##そして選んだブログサービス

自分の求めているものと突き合わせた結果、中〜長文でクリエイターによる投稿が多そうなnote、Medium、Qiitaが候補として残りました。

プログラマー向けということで若干場違いではないかという不安感はありつつも、HTML5などのタグやUX関連の記事もあるのでまあ大丈夫かなということで、今、書いているQiitaをメインに始めて見ることにしました。

note、Mediumについても興味があるので試しに使ってみようかなと思いますので、ある程度利用したらまた記事にしたいと思います。
Laravelのヘルパ関数env()でnullが返却されていた話

「サーバーにあげたら挙動がおかしくなった:angel_tone2:」
という事があったのでメモです。

#原因

以下のコマンドでキャッシュを作った事により、env()はnullしか返してくれなくなった！

```
php artisan config:cache
```

ということでした。
ソースを見ると、そんな仕様みたいです・・・:sweat_smile:

日本語訳のマニュアルには以下のように記載されています:writing_hand_tone1:
https://readouble.com/laravel/5.5/ja/helpers.html#method-env
>Note: 開発期間中にconfig:cacheコマンドを実行する場合は、設定ファイルの中で必ずenv関数だけを使用してください。設定ファイルがキャッシュされると、.envファイルはロードされなくなり、env関数の呼び出しは全てnullを返します。

（ちょっと表現がおかしい・・・？）

#対策

env()関数はconfigファイル内だけで使うようにする！
config以外で使いたい場合は、一度configに定義した上で、config()関数で取得する！
です。

知っていればそれだけなんですが、知らないとハマる可能性高いので、あらかじめチームでは共有しておいた方がよいですね・・・:sweat_smile:
ずっとUbuntu+zshでnvmを使いたかったんだよ!!

## はじめに
`nvm`をgitからcloneしたのはいいけど、shutdownするたびに`nvm`が使えなくなる。
パスが消えるってことね。cloneしたファイルはあるみたいだけど。
毎回設定する必要があるとか、たまげたなぁ。

じゃけん、そんな面倒なことをしなくてもできるようにしましょうね〜

## nvmって?
Node.jsのバージョン管理が簡単にできるようにするもの。
`Node Version Maneger`なんだから、そらそうよ。

## インストール
nvmをインストールする方法も書いておきましょうか。

```
 $ git clone git://github.com/creationix/nvm.git ~/.nvm
```
Githubは[こ↑こ↓](https://github.com/creationix/nvm)

## 使い方
- インストール可能な`Node.js`を確認

```
$ nvm ls-remote
```

- `nvm`のインストール

```
$ nvm install バージョン指定
例) nvm install v10.8.0
$ node -v
v10.8.0
```

- インストールしたバージョンを確認

```
$ nvm ls
```

- インストールしたバージョンから使うバージョンを指定

```
$ nvm use バージョン指定
```

## .zshrcへの記入
これが本題よね
といっても、そんな難しいことはない。
起動のたびに読み込んでもらえば良いのだから、

``` .zshrc
# Setting nvm
source ~/.nvm/nvm.sh
nvm use "v10.8.0"
```
とでも書いておけばOK。

記入後は、

```
source ~/.zshrc
```

も忘れずに

## 参考記事
- [nvmの導入と使い方](https://qiita.com/tanishi/items/f741e4bebfb6b6d470dc)
fishでdirenvを設定する

2019/10/23更新

[公式のドキュメント](https://direnv.net/docs/hook.html)でフックするスクリプトが多少変わっていたので変更:santa:
更新前を設定していても動作に影響はありません🙋

# TL;DR
fishのconfigファイルにdirenvファイルを設定します:fish:
localでAPIトークンとか当て込むのに使用すると思います🙋


# 対象読者

- 環境ファイルdirenvとfishshellを使用する人

```bash
fish -v

# => fish, version 3.1.2
```

# 1.direnvをインストール

すでにdirenvインストール済みであればパスしてください🙋

```bash
brew install direnv
```

# 2. fishのconfigファイルにdirenvが発動するように記述

echoコマンドでconfig.fishファイルに'eval (direnv hook fish)'の文字列を挿入します🙋

```bash
echo 'eval (direnv hook fish)' >> ~/.config/fish/config.fish 
```

configを適応しましょう:santa:

```bash
source ~/.config/fish/config.fish
```

# 3.完了 :fishing_pole_and_fish::santa:

これでダメだったら、ターミナルを再起動してみてください:santa:


# 4. 確認

```.envrc``` の置いてある対象フォルダを通過すると、```.envrc``` が読み込まれるはずです:santa:

```
cd sample-dir/
direnv: loading .envrc
direnv: export +SAMPLE
```

# 参考

https://direnv.net/docs/hook.html

.gitignoreに「.envrc」を設定するのも忘れずにやっておきましょう🙋

だんだんfish好きになってきました:swimmer:
Elixirで 123456789 を 1億2345万6789 に変換する

大きい数字を読みやすいように漢字混じりの数字に変換するような
コードをElixirで書いてみました

```elixir
defmodule Kansuuji do
  @moduledoc """
  Documentation for Kansuuji.
  """

  @units ~w/万 億 兆 京/

  @doc """
  ## Examples

      iex> Kansuuji.parse 100
      "100"
      iex> Kansuuji.parse 10000
      "1万"
      iex> Kansuuji.parse 10001
      "1万1"
      iex> Kansuuji.parse 123456789
      "1億2345万6789"
      iex> Kansuuji.parse 100006789
      "1億6789"
      iex> Kansuuji.parse 98765100006789
      "98兆7651億6789"
      iex> Kansuuji.parse 98700100006789
      "98兆7001億6789"
  """
  def parse(num) do
    num
    |> Integer.to_string
    |> String.graphemes
    |> Enum.reverse
    |> Enum.chunk_every(4)
    |> Enum.map(fn x -> x |> Enum.reverse |> Enum.join end)
    |> process(-1, "")
  end

  def process([], _, output) do
    output
  end

  def process([h|t], -1, output) do
    process(t, 0, zero_suppress(h))
  end

  def process([h | t], unit_index ,output) do
    o = case zero_suppress(h) do
      "" -> output
      s -> "#{s}#{@units |> Enum.at(unit_index)}#{output}"
    end
    process(t, unit_index + 1, o)
  end

  def zero_suppress(s) do
    h = s
    |> String.replace(~r/^0+/, "")
  end
end

```

最初の以下の操作を行い、 4桁くぎりの配列を作っています

1. 与えられた数字を文字列に変換
2. 文字列を文字ごとの配列に変換
3. 配列の要素を逆転
4. 配列を４桁ごとにチャンク
5. チャンクされた配列の各要素をもとの文字列に戻す

そのあとはゼロサプレスしながら、空文字じゃなければ各単位を文字列にくっつけていって
あげている感じです。



こういったお遊びのときにもDoctestはすごい便利ですね :sparkles:
シンプルなNodeサーバ

POSTでjsonオブジェクトでパラメータなり何かを投げるとなにかJSONで投げ返してくるサーバを超簡単に作る

前回書いた https://qiita.com/makainuma/items/26e104138d864b2d8034 が更に簡略化できたので書いておく。

モジュールとしてこんなのを考える

```js
exports.body = function(req, act) {
    console.log(req.body);
    let json_data = {"Name":"dummy1"};
    act(json_data);
}
```

req.bodyが送ってもらったPOSTで投げ込んだjsonオブジェクトのはずで、それをもとに何か処理を行って結果のオブジェクトをjson化したものがjson_dataであるとする。これを送り返させる。

これが```modules/mod1.js```だとして、それを呼び出す側は

```js
const express = require('express')
const app = express();

app.use(express.urlencoded( {extended:true} ));
app.use(express.json());

app.use((req, res, next) => {
  res.header("content-type", "application/json;charset=utf-8");
  next();
});

const modules = [
  ['/mod1', require('./modules/mod1.js')],
  ['/mod2', require('./modules/mod2.js')],
  ['/mod3', require('./modules/mod3.js')],
];

modules.map((mod) => {
  app.post(mod[0], function(req, res) {
    mod[1].body(req, (ans) => {
      res.json(ans)
    });
  });
})

app.listen(3000, () => console.log('listening on port 3000!'))
```

のように記述する（mod1, mod2, mod3 と同じようにして複数機能を持たせたものとする）。
これをapp.jsだとして、```npm install express```しておいて```node app.js```して起動。

投げる側は

```sh
curl -X POST http://localhost:3000/mod1 -H "Accept: application/json" -H "Content-type: application/json" -d '{ "param": "p0001" }
```

で投げる
PowerShellで日付を変数に直接展開する

システム日付のファイルなどを作成する時に、

```test.ps1
$today = Get-Date -Format yyyyMMdd
"$today.txt"
```

だと一度変数に展開しないといけないので

```test.ps1
"$(Get-Date -Format yyyyMMdd).txt"
```

これだとわざわざ変数に展開せずに済む。
情報処理安全確保支援士を取得するための学習ログ　その4

# 初めに
この度、自分のスキルアップのために情報処理安全確保支援士の資格を取ることになりました。セキュリティに関する知識が乏しいため、勉強をしていくなかで普段の業務のセキュリティに関する知識を吸収することも目的としています。

# 本ブログの目的
このブログは、僕が情報処理安全確保支援士の勉強に使っている参考書[「うかる！情報処理安全確保支援士2018年版」](https://www.amazon.co.jp/情報処理教科書-情報処理安全確保支援士-2018年版-上原-孝之/dp/4798154180)の内容を自分で振り返るためのアウトプットの場にしようと思います。

# 1.4TCP/IPの主なプロトコルとネットワーク技術の基礎
TCP/IPは、インターネットをはじめ、組織内のネットワーク等で標準的に使用されている通信プロトコルである。TCP/IP階層は、アプリケーション層、トランスポート層、インターネット層、ネットワークインターフェース層に分かれている。

# 用語解説
「用語解説」で出てきた用語をまとめます。

## OSI参照モデル
国際標準化機構により制定された「開放型システム間相互接続」に基づき、相互通信を行うコンピューター等に必要な機能を7つの階層構造に分割したモデル。

## ペイロード
パケットのデータ部分のこと。

## ホップリミット
パケットの転送回数の上限を示す値。

## DHCP
ネットワークに接続されたコンピュータに対して、IPアドレス、サブネットマスク、DNSサーバーアドレス、ゲートウェイアドレス等の必要な情報を動的に割り当てるプロトコル。

## CIDR
IPv4において、IPアドレスの枯渇を防ぐために、既存のクラスによるIPアドレスのネットワーク部とホスト部の区切りを無視して柔軟にIPアドレスを割り当て、経路を選択する仕組み。

## SMTP
TCP/IPにおいて、電子メールの送信に用いられる標準的なプロトコル。

## POP3
TCP/IPにおいて、利用者端末がサーバから電子メールを受信するために用いられるプロトコル。受信したメールの全データが利用者端末にダウンロードされる。

## IMAP4
POP3と同様に、利用者端末がサーバから電子メールを受信するために用いられるプロトコル。POP3とは異なり、選択した電子メールだけを利用者端末に転送する機能、サーバ上の電子メールを検索する機能、電子メールのヘッダだけを取り出す機能などがある。

## HTTP
TCP/IPにおいて、Webサーバと利用者端末との間でデータの送受信を行うために用いられるプロトコル。

# 理解度チェックテスト
Q1.IPv4の問題点を挙げよ。
Q2.GETメソッドとPOSTメソッドの特徴を挙げよ。
Q3.VLANの構築によるメリットは何か。

# 前記事の理解度チェックテストの答え
前記事は[こちら](https://qiita.com/kabachanta/items/33341f4841041493c251)

A1.114個
A2.ISMS認証取得に向けた準備をし、適用範囲及び境界の定義をし、情報セキュリティ方針の確立をし、リスクアセスメントに対する取り組み方の決定をし、リスクの識別をし、リスクの分析及び評価をし、リスク対応のための選択肢の特定及び評価をし、リスク対応のための管理策を決定し、残留リスクの受容についてリスク所有者の承認を得て、適用宣言書の作成をする。
A3.ISMSの教育を実施したり、ハンドブックを配布したり、壁や扉にポスターやキャッチコピーを掲示する。
Ethereumのrlpxについて

[このドキュメント](https://github.com/ethereum/devp2p/blob/master/rlpx.md)の翻訳(途中)です。
## イントロ

RLPxは、アプリケーションがP2Pネットワークを介して通信するための汎用トランスポートおよびインターフェイスを提供する暗号ピアツーピアネットワークおよびプロトコルスイートである。RLPxは、分散アプリケーションの要件を満たすように設計されており、Ethereumで使用されている。

## 特徴

* ノード発見とネットワーク形成
* 暗号化されたハンドシェイク
* 暗号化された転送
* プロトコルマルチプレクサ（フレーミング）
* フロー制御
* Peer Preference Strategies
* Peer Reputation
* セキュリティ
  * 認証された接続性（ECDH + ECDHE、AES128）
  * 認証されたディスカバリープロトコル（ECDSA）
  * 暗号化された転送 (AES256)
  * 接続を共有するプロトコルが均一な帯域幅を持てる （フレーミング）
  * ノードは均一なネットワークトポロジーにアクセスでる
  * ピアはネットワークに一様に接続できる
  * nodeごとのreputationモデル
laravelのEloquentを使ってMySQLのデータを検索してみた

[前回](https://qiita.com/keb/items/9a2ca8564e641efe95e2)の続き

- modelの作成

```php
$ php artisan make:model City --migration
Model created successfully.
Created Migration: 2018_08_18_045057_create_cities_table
```

[プロジェクトルート]/app/City.phpが作成される

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class City extends Model
{
    //
}
```

- City.phpの修正

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class City extends Model
{
    // テーブル名
    protected $table = 'city';
    // タイムスタンプ
    public $timestamps = false;
}
```

- Controllerの修正
 - use Appの追加
 - MySQLからデータを取得し、Viewに渡す

```php
use App;

    public function index()
    {
        $city = App\City::all();
        return view('world', ['city' => $city]);
    }
```

- Viewの修正（一部抜粋）

```php
    <?php foreach($city as $row) {
      echo '<tr>';
      echo '<td>'.htmlspecialchars($row['ID']).'</td>';
      echo '<td>'.htmlspecialchars($row['Name']).'</td>';
      echo '<td>'.htmlspecialchars($row['CountryCode']).'</td>';
      echo '<td>'.htmlspecialchars($row['District']).'</td>';
      echo '<td>'.htmlspecialchars($row['Population']).'</td>';
      echo '</tr>';
    }?>
```

### 参考
https://qiita.com/shosho/items/5ca6bdb880b130260586
https://readouble.com/laravel/
nodejsのcommon jsモジュールに状態を持たせてはいけない。

CommonJSでたまにある以下の書き方。

```

const lib = require("./lib");
lib.data = "module-1";
function libの値をmodule1から取得() {
  return lib.data;
}
exports.libの値をmodule1から取得 = libの値をmodule1から取得;
```

モジュールのプロパティを使う側で簡単に設定出来るから使ってしまう事があるかもしれない。例えば[npmの日付フォーマッタであるdateformat](https://www.npmjs.com/package/dateformat)は曜日を国際化する時に以下のような書き方を指示している。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/007aa28a-b0a7-5219-6a93-c4d678767a6c.png)

しかし、この書き方はするべきではない。何故なら、プロパティが他のモジュールで上書きされてしまう。

以下のサンプルでindex.jsを実行した時にコンソールに表示される値に注目。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/5825/5ca35136-cd4b-eaa8-1f14-bbcf150ec052.png)

lib.jsの中のLib.dataというプロパティは、module-1.jsでもmodule-2.jsでも同じインスタンスが使われる。module-1.jsの中ではLib.dataのプロパティはmodule-1だが、module-2.jsで値が上書きされてしまう。せっかくモジュールを使っているのに、これじゃあ意味がない。

今回のようにどこでrequireしているか明らかな場合はいいが、npmからモジュールをインストールしたり、そのモジュールが依存した先が依存したりと全てをチェックする事は不可能。

自分で作ったモジュールであればこのような書き方はするべきではないし、既存のモジュールであれば、使う直前に値を再度上書きする必要がある。
go-ethereumのethashについて

[このwiki](https://github.com/ethereum/wiki/wiki/Ethash)を前半を翻訳してまとめたものになります

EthashはEthereum 1.0の為に作られたPoWのアルゴリズム.

Dagger-Hashimotoの最新バージョンではあるが、両方のアルゴリズムが大幅に進歩しているので、そのように呼ぶのは適切ではない。

大雑把なアルゴリムズは下記のようなものである

1. その時点までブロックヘッダを走査することにより、各ブロックについて計算可能なシードが存在する。
1. シードから16MBの疑似ランダムキャッシュを計算する。ライトクライアントはキャッシュを保存する。
1. キャッシュからは、データセット内の各アイテムがキャッシュからの少数のアイテムのみに依存するという特性を持つ、1 GBのデータセットを生成することができる。フルクライアントとマイナーがデータセットを格納する。データセットは時間とともに線形増加する。
1. マイニングでは、データセットのランダムなスライスとそれをハッシュ化したものを含める。キャッシュを使用して必要なデータセットの特定の部分を再生成することで、メモリを少なくして検証を行うことができるため、キャッシュだけが必要となる。

大規模なデータセットは30000ブロックごとに更新されるため、大多数のマイナーのやることはデータセットを読むことであり、変更することではない。

Ethashは以下の目標を達成することを意図している：
* ASIC対策
* GPUには優しい
* 軽量クライアントでも検証可能
* 軽量クライアントでも遅くアルゴリズムが動作する
* 軽量クライアントでも検証が早く

## FNV
FNVというハッシュ関数を使用。ばらつきやすいというメリットがある

```go
// 0x01000193 = 16777619 32bit用の定数
// 
func fnv(a, b uint32) uint32 {
	return a*0x01000193 ^ b
}
```

各数字の根拠

* 16MBキャッシュ: ASIC対策で軽量クライアントで検証可能なのがこのくらい
* DAGが256先まで: 時間とメモリのトレードオフが最悪1:1になる位にするため
* Datasizeが1GB: ASIC対策
* ~0.73x/年の成長レベル: ムーアの法則
* 64回アクセス: 軽量クライアントとASIC対策
* エポックの長さ: データの再読込をへらしつつASIC対策　この値は変更する可能性がある

block numberごとの cacheサイズとdatasetサイズ

```
block:         10 cache: 16.0MB dataset: 1024.0MB
block:        100 cache: 16.0MB dataset: 1024.0MB
block:      1,000 cache: 16.0MB dataset: 1024.0MB
block:     10,000 cache: 16.0MB dataset: 1024.0MB
block:    100,000 cache: 16.4MB dataset:    1.0GB
block:  1,000,000 cache: 20.1MB dataset:    1.3GB
block: 10,000,000 cache: 57.6MB dataset:    3.6GB
```

周期性を作らないようにblockがすすむごとにcacheサイズとdatasetのサイズを線形増加させるようにしている
go-ethereumのコンセンサスエンジン

go-ethereumではアルゴリズムに依存しないコンセンサスエンジンとして下記のinterfaceが定義されています。
ethashやcliqueはそれぞれ下記を実装しています。

```go
type Engine interface {
	//　Authorは、指定されたブロックを作成したアカウントのEthereumアドレスを読み出す
	//　但し、コンセンサスエンジンが署名に基づいている場合、ヘッダーのコインベースのアドレスと異なる場合がある
	Author(header *types.Header) (common.Address, error)

	// VerifyHeaderは、ヘッダーが指定されたエンジンのコンセンサスルールに準拠しているかどうかをチェックする
	// ここでオプションでシールを検証することも、VerifySealメソッドを使って明示的にシールを検証することもできる
	VerifyHeader(chain ChainReader, header *types.Header, seal bool) error

	// VerifyHeadersはVerifyHeaderに似ているが、同時に複数のヘッダーを検証する
	// このメソッドは、操作を中止するための終了チャネルと非同期に検証結果を取得する結果チャネルを返す（処理は入力スライスの順番）
	VerifyHeaders(chain ChainReader, headers []*types.Header, seals []bool) (chan<- struct{}, <-chan error)

	// VerifyUnclesは指定されたブロックのUncleが指定されたエンジンのコンセンサスルールに準拠しているかを検証する
	VerifyUncles(chain ChainReader, block *types.Block) error

	// VerifySealは、ヘッダーの暗号シールが、指定されたエンジンのコンセンサス規則に従って有効かどうかをチェックする
	VerifySeal(chain ChainReader, header *types.Header) error

	// Prepareは、特定のエンジンのルールに従って、ブロックヘッダーのコンセンサスフィールドを初期化する。変更は関数内で実行される
	Prepare(chain ChainReader, header *types.Header) error

	// Finalizeは、トランザクション後の状態（ブロック報酬など）に変更し、最終ブロックをまとめる
	// 注：ブロックヘッダーと状態データベースは、ファイナライズ時に発生するコンセンサスルール（ブロック報酬など）を反映するように更新される場合がある
	Finalize(chain ChainReader, header *types.Header, state *state.StateDB, txs []*types.Transaction,
		uncles []*types.Header, receipts []*types.Receipt) (*types.Block, error)

	// Sealは、ローカルマイナーのシールを指定された入力ブロックの一番上として新しいブロックを生成する
	Seal(chain ChainReader, block *types.Block, stop <-chan struct{}) (*types.Block, error)

	// CalcDifficultyは難易度調整アルゴリズム。新しいブロックが持つべきdifficultyを返す
	CalcDifficulty(chain ChainReader, time uint64, parent *types.Header) *big.Int

	// APIsは、このコンセンサスエンジンが提供するRPC APIを返す
	APIs(chain ChainReader) []rpc.API
}
```

# 処理される順番
実際にブロック生成は下記の順番でメソッドが呼ばれます。
* Prepare
* Finalize
* Seal
* Seal成功時(マイニング成功時)
  * 終わり
* Seal失敗時(マイニングに失敗し他のノードからブロックを受け取った時)
  * VerifyHeaders
    * Fetcher insert
    * fetcher validator call VerifyHeader
  * VerifyHeader
  * VerifySeal
    * fetcher inserter
    * BlockChain InsertChain
    * peerSet PeersWithoutBlock
  * VerifyHeaders
  * VerifySeal
  * VerifyUncles
データベース初心者メモ

データベースを使えるようになるため、学んだことを記録していきます。
現在はMySQL勉強中……

## 1. MySQLについて
インストール方法は[こちら](https://qiita.com/egplnt/items/99fdf456b67e9726ee0d)を参考にしました。

1. [MySQLのコマンドメモ](https://qiita.com/KamaToo/items/20262e57e02ec7641843)
2. [MySQLのデータベースを作成する](https://qiita.com/KamaToo/items/785fb19349d4e3a3e3ca)
3. [合計値を計算する]
(https://qiita.com/KamaToo/items/6b10c3e3aef9f841df55)
awsのEC2でpostfixとdovecotの構築

時間がかかった作業なので備忘する

基本は下記のサイトを参考して構築した

https://genchan.net/it/server/1566/

いくか留意点を記録する

１、centos7なのでソフトの起動及び自動起動につき、下記のコマンドで行う
systemctl restart postfixとか

２、SMTP-Authの設定について、saslauthd実装されていない場合があり、ネットで調べinstallする

３、awsにおいてまず、E メール制限緩和および逆引き申請が必要、ネットで調べ行う

４、下記のようにRoute 53で設定すること
![q29.png](https://qiita-image-store.s3.amazonaws.com/0/286146/fb397ed8-4b91-3978-278a-0cac9f5c5569.png)

５、下記をインストールすること
sudo yum install cyrus-sasl-plain
そうしないとログには下記のエラーが出る
SASL authentication failure: Internal Error -4 in server.c near line 1757


dovecotについては、上記の参考サイトプラス下記の設定が必要

まずは「10-auth.conf」というファイルを編集する。

auth_mechanisms = plain login

次に「10-ssl.conf」というファイルを編集。

ssl=no
nuxtでナビゲーションガード時、リダイレクトしてもlayoutが変わらない問題

# TL;DR

`context` の `nuxtState` に `layout` プロパティがあるので、そこにlayout値をぶっこむ！

# 前提

nuxt.jsでユーザー認証ガードをしなくちゃいけないけれども、LocalStorageに情報保持しなくちゃいけないときとかに、
非SSR な plugin をつくって [ナビゲーションガード](https://router.vuejs.org/ja/guide/advanced/navigation-guards.html#%E3%83%8A%E3%83%93%E3%82%B2%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%AC%E3%83%BC%E3%83%89) 設定することあると思います。
さらには非同期な処理も叩かなくてはいけないから、async/await にしちゃう！

そこで以下のように実装しました

``` javascript:~plugin/nav-guard.js（実際のコードではありません）
export default ({app,redirect}) => {
    app.router.beforeEach(async (to,from,next)=>{
      if( /* 非認証ページ */ ) { 
        next();
      } else if( /* 別途ストアの中に認証用データがないとき */ ){
        redirect('/login');
      } else {
        const auth = await なんらかの非同期メソッド();
        if( /* なんらかの非同期メソッドがオッケーだった時 */ ){
          next();
        } else {
          redirect('/login');
        }
      }
    })
}
```

リダイレクト後のページのlayoutが遷移前のPageComponentのlayoutのママだったんですね。
Vue-devtoolで見てもlayoutそのまま。

これも、universalモードで、直接アクセスしたときにのみ発生してまして、その後CSRで遷移するときは問題ないのです。

# 対処法

* `redirect` ではなく、routerの `next` でリダイレクトさせても発生
* `redirect` ではなく、`location.replace` を使うと問題なし
* `redirect` の時期を `setTimeout` すると時間によっては問題なし

2つ目は、layout/error を表示させてからリダイレクトする処理をしてた時に発見したんですが、早すぎてもだめでした。
ここも時間上の制約で深く探ってないです。
で、やっぱりredirectで処理させたかったので、\$nextTick ならどうだと思って、
[API: コンテキスト - Nuxt.js](https://ja.nuxtjs.org/api/context)
でどこからアクセスしようか探してた時に、`nuxtState` を発見しました。

こんな感じにすると無事正しいlayoutで表示されるようになりました。

``` javascript:~plugin/nav-guard.js（実際のコードではありません）
export default ({app,redirect,nuxtState}) => {
    app.router.beforeEach(async (to,from,next)=>{
      if( /* 非認証ページ */ ) { 
        next();
      } else if( /* 別途ストアの中に認証用データがないとき */ ){
        nuxtState.layout = 'login';
        redirect('/login');
      } else {
        const auth = await なんらかの非同期メソッド();
        if( /* なんらかの非同期メソッドがオッケーだった時 */ ){
          next();
        } else {
          nuxtState.layout = 'login';
          redirect('/login');
        }
      }
    })
}
```

（ただ、いまだに\$nextTickの実行方法がわかりません。app.\$nextTickは無いと怒られる...）

# 発生条件（がわかればいいなぁ）

これ、発生条件が自分には把握できず NuxtのGithubにもissue立ててないんですが、

* nuxt バージョンは 1.4.2
* universalモード
* ナビゲーションガードはクライアントサイドのみ
* コンポーネントが増えてくる前は大丈夫だった（ような気がする）
* `location.replace` だと大丈夫

ぐらいしかわかってません。

---

ぶっちゃけ、全部middleware内で、SSRでもアクセス可能な形の認証にしたかった。
あと、`next` でやってないのOKなのかなって疑問。
時間ができたら再度nuxt側含めて探ってみる予定です。
Ethereumのトランザクションの流れ(1) フロント編

web3.jsからトランザクションを実行する流れを追っていきます。
web3.jsのversionはv1.0.0-beta.36です。

# call web3編

## transfer(address) を実行するコード

```javascript
const Web3 = require('web3');
const web3 = new Web3();
web3.setProvider(new web3.providers.HttpProvider('http://localhost:8545'));
web3.eth.defaultAccount=web3.eth.accounts[0];
const ABI = require("./abi.js").abi;

const ADDRESS = "0x09ce7c529fd05ca8e5599f0ed424f48cd2a5424e";
const OWNER = "0x0be26a388d0524eeb0afbc08ee015e08e83e802c";
const contract = new web3.eth.Contract(ABI, ADDRESS);

const transfer = async (address) => {
    return await contract.methods.transfer(address, 100).send({
        from: OWNER,
    });
};

(async () => {
    console.log(await transfer("0xfc49f3aedc6d2f0cab4e0a1ff66913ccf2fe3661"));
})();
```

## json-rpcとして下記のリクエストを実行する

```javascript
{ jsonrpc: '2.0',
  id: 3,
  method: 'eth_sendTransaction',
  params:
   [ { from: '0xd986f2cb72530f45bfd575196fbad7064c454ecc',
       data:
        '0xa9059cbb000000000000000000000000d986f2cb72530f45bfd575196fbad7064c454ecc0000000000000000000000000000000000000000000000000000000000000064',
       gasPrice: '0x1',
       gas: undefined,
       to: '0xf30a6701ff5e70aabf27f474b3b4ae72563c3217' } ] }
```

## dataの仕組み

### signatureの作成

```javascript
    {
      "constant": false,
      "inputs": [
        {
          "name": "_to",
          "type": "address"
        },
        {
          "name": "_value",
          "type": "uint256"
        }
      ],
      "name": "transfer",
      "outputs": [
        {
          "name": "",
          "type": "bool"
        }
      ],
      "payable": false,
      "stateMutability": "nonpayable",
      "type": "function"
    }
```

上のようなabiのObjectから

```javascript
// web3.js/packages/web3-eth-abi/src/index.js
var utils = require('web3-utils');
// 省略
ABICoder.prototype.encodeFunctionSignature = function (functionName) {
    if (_.isObject(functionName)) {
        functionName = utils._jsonInterfaceMethodToString(functionName);
    }

    return utils.sha3(functionName).slice(0, 10);
};
```

`transfer(address,uint256)` が 0xa9059cbbになる

### 引数の部分

```javascript
// web3.js/packages/web3-eth-abi/src/index.js
ABICoder.prototype.encodeParameters = function (types, params) {
    return ethersAbiCoder.encode(this.mapTypes(types), params);
};

var ret = coder.encodeParameters(['address'], ['0xd986f2cb72530f45bfd575196fbad7064c454ecc']);
```

で、 `000000000000000000000000d986f2cb72530f45bfd575196fbad7064c454ecc0000000000000000000000000000000000000000000000000000000000000064` となる
DISCORDで千枝ちゃんを召喚してみた

# はじめに
実は私シンデレラなソシャゲをやってるんですよ。
そのゲームでミニチーム結成や傭兵募集で成績チェックってするじゃないですか？
デレマスボーダーbotさん（https://imcg.pink-check.school/）
よく見るのはデレマスボーダーbotさんだと思うんですが、やっぱり検索するのなんだかんだでめんどくさいわけですよ。
そこで、DISCORDのBOTでURLはってくれたら便利じゃないかなって。
あとさ、千枝ちゃんとしゃべりたくない？しゃべりたくない？（大事なことなのでry）

# DISCORDのBOTの作り方
DEVELOPER PORTAL(https://discordapp.com/developers/applications/)
上記サイトにDISCORDアカウントでログインします。

General Informationでbotの名前とアイコンを設定します。
![disbot1.jpg](https://qiita-image-store.s3.amazonaws.com/0/148269/e6c9452c-1291-b63f-2e6d-5f392d798868.jpeg)

Botからトークンをコピーします。
言うまでもないですが**間違ってもトークンは流出させないようにしましょう**。
![disbot2.jpg](https://qiita-image-store.s3.amazonaws.com/0/148269/8f4c4edb-d44a-9aaa-0d41-e17db49e6c74.jpeg)

OAuth2からbotとAdministratorを選択して、ＵＲＬをコピーします。
![tiebot4.jpg](https://qiita-image-store.s3.amazonaws.com/0/148269/e4e4eb02-4cdb-ac70-dfb0-bc57b95879e7.jpeg)

ＵＲＬにアクセスするとサーバーを選べるのでBOTを設置したいサーバーを決定します。
![disbot3.jpg](https://qiita-image-store.s3.amazonaws.com/0/148269/c2161b9b-6529-27b4-f1a0-83740ba25711.jpeg)

これでBOT作成は終わりです。簡単ですね。

# BOTのプログラム準備
今回はpython3で実装します。
pipから、discord.pyをインストールします。
https://github.com/Rapptz/discord.py

```python:discord.pyの取得
pip install discord.py
```

勿論pythonの他のライブラリを使いたい場合はそれぞれpipでインストールしてください。

また、BOTの親アカウントの設定から、テーマ→開発者モードをONにしてください。
これがないと一部機能が動かないっぽいです。
![tiebot5.jpg](https://qiita-image-store.s3.amazonaws.com/0/148269/f9011e0f-bc5d-60a2-7576-a7063a681e9b.jpeg)


# 実装
```python:tiebot.py
import discord

client = discord.Client()

@client.event
async def on_message(message):
    # 挨拶する千枝ちゃん
    if message.content.startswith('おはよう') and client.user != message.author and message.channel == client.get_channel('チェンネルID'):
        reply = f'おはようございます、{message.author.mention} さん'
        await client.send_message(message.channel, reply)
    # IDから成績を教えてくれる千枝ちゃん
    if message.content.startswith('おしえて,') and client.user != message.author and message.channel == client.get_channel('チャンネルID'):
        s_message = message.content.split(",")
        reply = f'https://imcg.pink-check.school/producer/detail/{s_message[1]}  です'
        await client.send_message(message.channel, reply)

# ここにはあらかじめ取得したトークンを貼り付けてください
client.run('トークンＩＤ')
```

チャンネルIDはDISCORDのチャンネル名を右クリックでIDをコピーしてください。
実際に動かしてみた結果がこちら
![tiebot6.jpg](https://qiita-image-store.s3.amazonaws.com/0/148269/691df5e2-5411-595f-a9cb-daf88a628162.jpeg)
うん、いい感じ。
あとはpythonで実装すれば夢が色々広がるんじゃないかな？

# おわりに
私の担当アイドルは橘ありすです（きりっ）
go-ethereumを読む(6) 補足 Service

gethではPluggableな実装になっており、serviceという単位でプログラム内では扱われています。
`EthService`がEthereumのコア機能をになっています。
v1.8.15ベースに解説します

具体例 サービスを登録しているプログラム

```go
// cmd/utils/flags.go
// RegisterEthService adds an Ethereum client to the stack.
func RegisterEthService(stack *node.Node, cfg *eth.Config) {
	var err error
	if cfg.SyncMode == downloader.LightSync {
		err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
			return les.New(ctx, cfg)
		})
	} else {
		err = stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
			fullNode, err := eth.New(ctx, cfg)
			if fullNode != nil && cfg.LightServ > 0 {
				ls, _ := les.NewLesServer(fullNode, cfg)
				fullNode.AddLesServer(ls)
			}
			return fullNode, err
		})
	}
	if err != nil {
		Fatalf("Failed to register the Ethereum service: %v", err)
	}
}

// RegisterDashboardService adds a dashboard to the stack.
func RegisterDashboardService(stack *node.Node, cfg *dashboard.Config, commit string) {
	stack.Register(func(ctx *node.ServiceContext) (node.Service, error) {
		return dashboard.New(cfg, commit, ctx.ResolvePath("logs")), nil
	})
}

// RegisterShhService configures Whisper and adds it to the given node.
func RegisterShhService(stack *node.Node, cfg *whisper.Config) {
	if err := stack.Register(func(n *node.ServiceContext) (node.Service, error) {
		return whisper.New(cfg), nil
	}); err != nil {
		Fatalf("Failed to register the Whisper service: %v", err)
	}
}
```

## ServiceContext

ServiceContextがservicesをmapで保持している

```go
type ServiceContext struct {
	config         *Config
	services       map[reflect.Type]Service // Index of the already constructed services
	EventMux       *event.TypeMux           // Event multiplexer used for decoupled notifications
	AccountManager *accounts.Manager        // Account manager created by the node.
}

func (ctx *ServiceContext) Service(service interface{}) error {
	element := reflect.ValueOf(service).Elem()
	if running, ok := ctx.services[element.Type()]; ok {
		element.Set(reflect.ValueOf(running))
		return nil
	}
	return ErrServiceUnknown
}

type ServiceConstructor func(ctx *ServiceContext) (Service, error)

// Serviceに必要なinterface
type Service interface {
	// Protocols retrieves the P2P protocols the service wishes to start.
	Protocols() []p2p.Protocol

	// APIs retrieves the list of RPC descriptors the service provides
	APIs() []rpc.API

	// Start is called after all services have been constructed and the networking
	// layer was also initialized to spawn any goroutines required by the service.
	Start(server *p2p.Server) error

	// Stop terminates all goroutines belonging to the service, blocking until they
	// are all terminated.
	Stop() error
}
```
go-ethereumを読む(1) 準備編

ブロックチェーンの勉強のためにEthereumのデファクトとなっている[go-ethereum](https://github.com/ethereum/go-ethereum)のソースコードを読んだのでそれを記録としてまとめます。
v1.8.15ベースに解説します。


## debug

pritty printがあると便利

go-ethereumは[govendor](https://github.com/kardianos/govendor)を使っているので下記のコマンドでインストールしておくのをおすすめ

```sh
$ govendor fetch github.com/k0kubun/pp@=v2.3.0
```
[使い方](https://qiita.com/k0kubun/items/5150fcb5d0740309d1eb)

## geth

### urfave/cli

gethでつかっているcliライブラリ

* https://github.com/urfave/cli
* http://tweeeety.hateblo.jp/entry/2017/06/07/130831

## 主要なディレクトリ構成

|名前|説明|
|:--|:--|
| accounts | Ethereumはアカウントベースなので、アドレスや鍵のプログラムがここにある　|
| cmd | gethコマンド,puppethコマンドなどコマンドのmain.goなどがある |
| common | Addressなどの汎用的に使う型やそれ用の関数がある |
| consensus | ethash(PoW), clique(PoA)などのロジックがある |
| core | Ethereumのコア機能の実装がある |
| eth | EthServiceの機能がある |
| ethclient | rpcリクエスト用のクライアントがある |
| ethdb | LevelDBのwrapper |
| event | FeedやSubscriptionといったものがある |
| miner | マイニング用の汎用的なロジックがある(ethash, cliqueなどの特化したロジック以外) |
| node | nodeをセットアップ、起動するためのロジックがある |
| p2p | p2pのロジックがある |
| rlp | Recursive Length PrefixというEthereumで独自定義されているバイナリフォーマット用のロジックがある |
| rpc | http,ws,ipcなど具体的なrpcサーバのロジックがある |
| trie | データ保存形式の作成ロジックがある |
社外コミュニティでプロダクトチームを結成し開発環境を整えたときのメモ

## はじめに
Windowsでソフトウェア開発をしてると笑われることが多いですが、
僕は、大学の頃から仕事でもプライベートでもWindowsPCでソフト開発しています。
そんな僕がとあるチームの開発環境をそろえることになったので、そのためのメモです。

## 目的
Pythonを利用した、Webアプリケーション開発のための開発環境を一通り揃えること。

## GitLabへの登録
チームのソースコード管理・タスク管理を無料で複数人で行えるサービスです。
[ここから登録！](https://gitlab.com/users/sign_in)

![１.png](https://qiita-image-store.s3.amazonaws.com/0/258294/0aad6f74-995a-02ac-66cc-0d37158dff90.png)
![2.png](https://qiita-image-store.s3.amazonaws.com/0/258294/d175ce29-e714-3541-d32c-c1e444c99b44.png)
![3.png](https://qiita-image-store.s3.amazonaws.com/0/258294/cd775ae2-4fb8-6677-ee90-63c1650f5b27.png)



### メモ：GitLabにした理由
GitHubだとprivateなリポジトリを作るのに有料だし、
BitbucketだとAtlassianToolと連携しないならタスク管理のメリットが薄いと考え、
GitLabにしました。

## gitアプリの導入
Gitコマンドでガンガン構成管理していこうぜ！派ですが、
初めはGUIでしょ！と思うので、GUIの_おすすめ_を提案！

### Windowsの場合
https://gitforwindows.org/
がぜん、`Git for Windows`です！
名前の通り、Windows上ではこれ以上のツールはないと思います。

※個人的には、Windows向けのGit CUIアプリの最高傑作と思っていて、
Windows上でGit CUIを使うなら`Git Bash`以外ありえないと思ってます。笑

### Macの場合
https://www.sourcetreeapp.com/
がぜん、`Source Tree`です！
個人的にGit GUIアプリの傑作と思っていますが、Windows上での動作が不安定なので、
Macの方にのみ、_おススメ_です。(※Windowsでは、GitBashがCUIの最高傑作なので！)

### メモ：Gitの使い方は以下のサイトが参考になります。
[サルでもわかるGit入門 〜バージョン管理を使いこなそう〜](https://backlog.com/ja/git-tutorial/)

## Eclipseの導入
http://mergedoc.osdn.jp/
から、4.2以降のEclipseをダウンロードする。
日本語の言語プラグイン込みでダウンロード可能なサイトです。

特段理由がなければ、Ultimateをダウンロードするのをおすすめしますが、
実装予定なのは、Python/html/css/javascriptで利用目的がエディタになるのでPythonパッケージでもOK！

![４.png](https://qiita-image-store.s3.amazonaws.com/0/258294/b063b4a8-5e34-925d-6cc4-842982db02f0.png)
![５.png](https://qiita-image-store.s3.amazonaws.com/0/258294/4340188b-e227-6940-64f9-b85bf67faf48.png)

## Pythonを導入する。
ここに限っては、多くの方がまとめているので、あえて新たにメモは起こしません。 笑

以下が参考になります。
### Windowsの場合
[Pythonのインストール方法（Windows）](https://gammasoft.jp/python/python-install-on-windows/)
を実施後、
[PyCharmのインストール方法（Windows）](https://gammasoft.jp/python/pycharm-install-on-windows/)
を実施することで、Windows上で、PythonのIDEも、エディタもそろいます！
_※Eclipseに慣れてからPyCharm使うと操作感の違いに最初戸惑うので注意が必要です_

### Macの場合
[Macにpython3系をインストール](https://qiita.com/hujuu/items/e29e8a77c55b93377184)
圧倒的、簡単！！

## あとがき
html/javascriptをメンテするのに、Eclipseを採用したのは、フォーマッタが良いからです。
他にも良いフォーマッタがあるエディタは多数存在しますが、使ってるとやっぱりEclipseのフォーマッタは優秀だなぁと思う次第です。カスタマイズもできますしね！
vscodeの「検索とExcel Viewer」の連続技をしてみた

#vscodeの検索を使ってみた。
vscodeの検索に,2通り(ctrl+F,ctrl+shift+F)ありました。
grepとの違いを調査中です。
(参考)Visual Studio Codeのファイルの中の検索
http://webdesign.vdlz.xyz/Editor/VSCode/Function/Edit/VSC_Edit001_SearchAcrossFiles.html

#Excel Viewerを使ってみた。
検索行数表示のカンマの整形をしてみた。
(参考)Excel Viewer
https://marketplace.visualstudio.com/items?itemName=GrapeCity.gc-excelviewer 
(参考)CSVデータがあればExcel形式で一覧表示したくなる気持ち＞ コマンド入力エリアにCSV: Open Previewと入力
https://devlog.grapecity.co.jp/entry/2017/02/10/vscode_xuni_csv_excel_viewer

#気にしない
「
Windows セキュリティの重要な警告
このプログラムの機能のいくつかが Windows ファイアウォールでブロックされています
すべてのパブリック、プライベート、ドメイン ネットワークで、Windows ファイアウォールにより Visual Studio Code の機能のいくつかがブロックされています。
名前(N):Visual Studio Code
」


　
#理解しないで置換を使うとちょっと危険
フォルダ内を置換します。
(参考)VS Code の便利なショートカットキー
https://qiita.com/12345/items/64f4372fbca041e949d0
#改行を含む検索をやってみた

(参考)Visual Studio Code: \n in regex file search not supported?
https://stackoverflow.com/questions/49942726/visual-studio-code-n-in-regex-file-search-not-supported
(参考)vscode Regular expression?
https://stackoverflow.com/questions/52304605/vscode-regular-expression
WordPressダッシュボードにアクセスできません

前提・実現したいこと
WordPressダッシュボードにアクセスできません 
 発生している問題・エラーメッセージ

このページを表示できません
対処方法
Web アドレスが正しいことを確認してください: http://---自分のURL---.com
Bing で "http://---自分のURL---.com" を検索してください
ページを最新の情報に更新
Details 
The DNS name does not exist.
Error Code: INET_E_RESOURCE_NOT_FOUND



URLにはhttp://---自分のURL---.com/wp-admin/が入力されています。

 該当のソースコード

特になし
 試したこと
define('WP_DEBUG', true);　　　
falseをtrueにした 
Exploreのキャッシュの削除
Exploreのパスワードのリセット 
インストールしたWordPressの初期化、アンインストール、再設置 


初めてWordPressを始めようとしている初心者です。
使っているのドメインはXdomainの有料一年契約のドメインで、Xdomainの無料サーバーを利用しています。
Xdomainさんの管理パネル->インストール済みWordPress一覧->ダッシュボードへ
というところからダッシュボードにアクセスしようとしているのですが上述のようにエラーが起きて入れない状況です。 
自分のパソコンの個人的にダウンロードしたFFFTPというソフトからはアクセスでき、何のファイルがあるのかなどは確認できます。いろいろダウンロードされていて正しくインストールされているっポイです。
Virtual Boxでローカル環境を作る初心者メモ

##ローカル開発環境を作る
引き続きの環境づくり。
Virtual Boxの上にCentOS乗せるんだけどVagrantというのをつなぎにして扱いやすくする方法。

手順はドットインストール。
[ローカル開発環境の構築 macOS編 (全14回) - プログラミングならドットインストール](https://dotinstall.com/lessons/basic_localdev_mac_v2)

###Virtual Box
virtualbox.orgからダウンロードしてインストール

###Vagrant
vagrantup.com からダウンロードしてインストール

###フォルダ構成つくりと設定
ホームフォルダ＞MyVagrant＞MyCentOS_201809 の下に仮想環境作って、IPアドレスを192.168.33.10にする。

```
#ホームフォルダの下にMyVagrantとかでVagrant用のフォルダを作る
$ mkdir MyVagrant

#作ったフォルダに移動
$ cd MyVagrant/

#サーバーが入るフォルダ作る（お試しで作るので目印に月いれてみる）
$ mkdir MyCentOS_201809

# 作ったとこに移動
cd MyCentOS_201809/

# CentOS6.8で初期化。設定ファイルの'Vagrantfile'ができつつ仮想環境ができる。
vagrant init bento/centos-6.8

# 'Vagrantfile'に192.168.33.10と記述する（エディタで書く代わりのコマンド）
sed -i '' -e 's/# config.vm.network "private_network", ip: "192.168.33.10"/config.vm.network "private_network", ip: "192.168.33.10"/' Vagrantfile
```

`vagrant init`すると以下のメッセージ出してくれました。

>Vagrantfileがこのフォルダにできたよ。
>`vagrant up`で起動できるよ。
>Vagrantfileにあるコメント読んで。
>ドキュメントは　vagrantup.com　にあるよ。



IPアドレス書き込むコマンド打ったあとVagrantfile開いてみたら15行目と35行目に初期化したOSと設定したIPアドレスが書かれてました。

```
# 15行目
config.vm.box = "bento/centos-6.8"

# 35行目
config.vm.network "private_network", ip: "192.168.33.10"
```


##仮想マシンを起動して終了
```
# 仮想マシンを起動する(起動したい仮想マシンのVagrantfileのあるフォルダで)
$ vagrant up

# 仮想マシンの状態を確認する
$ vagrant status

# 仮想マシンの停止
$  vagrant suspend 

# 強制終了したいときは
$ vagrant halt

```


Cloud9でもいいのか、、、
~~いやでもキッチンのWiFi弱いし、、、~~
あとでCloud9もやってみよう。

##今日のコマンド
lessでもファイルの中身は見れる
`less Vagrantfile `
RSpec3.8でセッション、クッキーを参照したい時のメモ

## 環境  
- Rails5.2
- RSpec3.8
  
## やり方
```ruby
# セッションを参照したいとき
session['user_id']
# クッキーを参照したいとき
@response.cookies['remember_token']
@request.cookies['user_id']
```

## 最後に
Rails tutorialの2週目を進めていてRSpecでやってみようと思ったときに、9章あたりで``undefined method `signed'``とエラーがでた。　　
ログアウトのテストとして、セッションとクッキーが削除されていることを確認した時に調べたメモ
Item 63: Beware the performance of string concatenation

# 63.文字結合のパフォーマンスに気を付けよ
文字結合を数多く行う場合には、+演算子による結合ではなく、StringBuilderを使うべし。
Stringはimmutableなので、文字結合するごとに新しいオブジェクトが作成されてしまう。

Stringを使った文字結合の例が以下。

```java
// Inappropriate use of string concatenation - Performs poorly!
public String statement() {
    String result = "";
    for (int i = 0; i < numItems(); i++)
        result += lineForItem(i);  // String concatenation
    return result;
}
```

StringBuilderを使った場合が以下。

```java
public String statement() {
    StringBuilder b = new StringBuilder(numItems() * LINE_WIDTH);
    for (int i = 0; i < numItems(); i++)
        b.append(lineForItem(i));
    return b.toString();
}
```
Seleniumのことをメモっておこうぜ☆（＾～＾）

# だらだら書く。

要は　ブラウザの検索フォームに　"天気予報"　とかキーワードを入れて　[Enter]キーまで押してくれるやつだぜ。
作ったWebサイトのテストを自動化するのに使ったり、
Excelのマクロを記録する感じで使える。

- Firefox
- Google Chrome

の２つだけに対応しているらしいが、Chrome でしか使ったことない。

「Selenium IDE」
https://chrome.google.com/webstore/detail/selenium-ide/mooikfkahbdckldjjndioackbalphokd

上のリンクからすぐ使える。
グーグルの拡張機能として入れると、Excelのマクロを記録する感じで使えるだけだぜ。

これが役に立ったと感じるのは、Windowsのタスクスケジューラーに登録して 毎日11時に Webサイトにログインする、
とか　そういう処理を自動化することだぜ。

また、ブラウザを立ち上げなくても　フォームにテキストを入力して　ボタンを押したのと同じことを
通信データのやりとりだけでやってしまうことを　「ヘッドレス」　という。

「ヘッドレス」は　ひとまず置いておく。

自動で入力していく方法は

- Selenium Side Runner (Excelのマクロ記録みたいに、プログラミングしなくてよくて再生できるやつ。2018-09-11時点で、Linux版とMac版しかないらしい。Windows版は作ってる途中らしい)

が使えるとベストだと思うんだが、Windows版はまだ無かった。
まだ、プログラミングするやつがある。

- WebDriver IO (いわゆるプログラミングするやつ)
- Selenium-WebDriver (Selenium用のWebDriver IO)


WebDriver IO は Webブラウザーの操作を自動化するやつで、 Python でも Ruby でも JavaScript でも C# でも Java でも有るのだろう、多分。

Selenium-WebDriver は、Selenium 用に WebDriver IO を　そのまま使うよりシンプルにしたやつだ。
わたしは Selenium-WebDriver　と、 JavaScript の Node js でやることにした。



／／書きかけ。
cloudbuildで、一つの環境変数で、引数に2つの値を渡せるようにする

タイトルだけだと何を言っているんだこいつは……と思われても仕方ないんですが、上手く説明ができない！

# 困ったこと！

```yaml
- name: 'gcr.io/cloud-builders/gcloud'
  args: [
    'app',
    'deploy',
    '${_DEPLOY_YAML}',
  ]
```

みたいな感じで、${_DEPLOY_YAML}のところに、app.yamlとcron.yamlを入れたいんですよ。
本番ではapp.yamlとcron.yamlだけど、stagingではapp.yamlしかdeployしたくないみたいなニッチな需要があってですね。

ただ環境変数に"app.yaml cron.yaml"と入れてしまうと、今度は「app.yaml cron.yaml」っていう間にスペースの入ったファイルを探して、そんなものはない！と怒られてしまうんですね。

# dockerでも同じようなことが

独自のDockerfileを作って起動させる時に、例えば……nginxとphpを動かしたいと思うわけじゃないですか。
ただ、DockerのCMDからは複数のコマンドは基本的に渡せないわけで。

```bash
# これは動かない！　というか実行できない！
docker run --rm -it hogehoge service nginx start && service php-fpm start && tail -f /dev/null
```

ならどうするかというと、2つのコマンドを実行するshellでも作って実行させるか、そういうshellをentrypointとして起動させるかとかになると思うんですね。
あれ、じゃあcloudbuildでも同じようなことをすれば行けるのでは……？

# cloudbuildでentrypointを使ってみる

```yaml
- name: 'gcr.io/cloud-builders/gcloud'
  entrypoint: '/bin/bash'
  args: [
    '-c',
    'gcloud app deploy ${_DEPLOY_YAML}',
  ]
```

という訳で設定してみたのがこれです。
gcloudコンテナの場合、特に何もしないとgcloudコマンドがentrypointとして起動されるんですが、/bin/bashに変更してます。
その上で、実行したいコマンド一式を文字列としてbashに送り込んで実行させて、当初に発生していた問題もクリア！　しています！
Raspberry PiでAlexa

RaspberryPi3modelBを購入したので前々から興味のあったAlexaを実装しよう
Aleｘaといえば去年あたりに声優スキルが実装されていたはずです。
早くレオナルド・ダ・ヴィンチ（cv:津田健次郎氏）の声に溺れたい:laughing:
ということで早速準備にとりかかりましょう！！！
#用意するもの
　-　Raspberry Pi　３　modelB
　-　SDカード（OSインストール済み）
　-　キーボード
　-　モニター
　-　マウス
　-　スピーカー　
　-　マイク
　-　コード類
#Alexa実装の手順
>
1. 音声デバイス（マイク、スピーカー）のセットアップ
2. Amazon開発者アカウントに登録
3. Alexa Voice Service をダウンロード
4. Alexaを起動

###1.音声デバイス（マイク、スピーカー）のセットアップ
今回利用したものは、
#####スピーカー：エレコム スピーカー USB給電 4W コンパクト ブラック MS-P08UBK
https://www.amazon.co.jp/%E3%82%A8%E3%83%AC%E3%82%B3%E3%83%A0-%E3%82%B9%E3%83%94%E3%83%BC%E3%82%AB%E3%83%BC-USB%E7%B5%A6%E9%9B%BB-%E3%82%B3%E3%83%B3%E3%83%91%E3%82%AF%E3%83%88-MS-P08UBK/dp/B071699KYN
#####マイク　：BU-Bauty いつでもどこへも携帯可能！世界最小USBマイク　PC Mac用USBマイク　超小型　超ミニ 22mmx18mmx5mm
https://www.amazon.co.jp/Buauty-BU-11-%E3%81%84%E3%81%A4%E3%81%A7%E3%82%82%E3%81%A9%E3%81%93%E3%81%B8%E3%82%82%E6%90%BA%E5%B8%AF%E5%8F%AF%E8%83%BD%EF%BC%81%E4%B8%96%E7%95%8C%E6%9C%80%E5%B0%8FUSB%E3%83%9E%E3%82%A4%E3%82%AF-PC-Mac%E7%94%A8USB%E3%83%9E%E3%82%A4%E3%82%AF-%E8%B6%85%E5%B0%8F%E5%9E%8B-%E8%B6%85%E3%83%9F%E3%83%8B-22mmx18mmx5mm/dp/B01KZPF1U8)

これらをRaspberryPiに接続する。
接続できているか確認する
>
```
pi@raspberrypi:~ $ lsusb
```

接続ができているのにスピーカーが動かない場合は[こちら](https://qiita.com/Pentas/items/178cc0299f1141f52799)


###2.Amazon開発者アカウントに登録
[失敗しないAlexa開発者アカウントの作り方]
https://dev.classmethod.jp/voice-assistant/how-to-safety-create-alexa-developers-account/

を参考にさせてもらいました。

###3.Alexa Voice Service をダウンロード
Alexa Voice Service のサンプルプログラムをダウンロード

>
```
$ cd Desktop
$ git clone https://github.com/alexa/alexa-avs-sample-app.git
```

　ダウンロードした中にある automated_install.sh を エディタで開き、ProductID、ClientID、ClientSecret の項目にそれぞれ取得した値をセット。
>
```
$ cd Desktop/alexa-avs-sample
$ sudo vi automated_install.sh
```
>
```
# This is the name given to your device or mobile app in the Amazon developer portal. To look this up, navigate to https://developer.amazon.com/edw/home.html. It may be labeled Device Type ID.
ProductID=[取得したProductID]
# Retrieve your client ID from the web settings tab within the developer console: https://developer.amazon.com/edw/home.html
ClientID=[取得したClientID]
# Retrieve your client secret from the web settings tab within the developer console: https://developer.amazon.com/edw/home.html
ClientSecret=[取得したClientSecret]
```

インストールプログラムを実行させる
>
```
$ cd ~/Desktop/alexa-avs-sample-app
$ . automated_install.sh
```

###4.Alexaを起動
terminalを３つ用意する
次の順で起動させる
>Terminal1
>
```　
cd ~/Desktop/alexa-avs-sample-app/samples
cd companionService && npm start
```   
>Terminal2
>
```
cd ~/Desktop/alexa-avs-sample-app/samples
cd javaclient && mvn exec:exec
```
>Terminal3
>
```
cd ~/Desktop/alexa-avs-sample-app/samples
cd wakeWordAgent/src && ./wakeWordAgent -e sensory
```

これで動くはず！
「Alexa!」  --- PON!
「レオナルドの時間を聞いて」　　---「レオナルドの時間を開きます　　--- レオナルド登場！！！」

>
[参考]
https://github.com/alexa/alexa-avs-sample-app/wiki/