OmniAICreator/Qiita-1.07M huggingface dataset:
LaravelでPOSTデータ(JSON)とGETデータを同時にFormRequestでバリデーションする方法

# 結論
LaravelでPOSTデータ(JSON)とGETデータを同時にFormRequestでバリデーションする方法は、validationDataをオーバーライドして受け取ったデータを再生成することで解決できます。

## 実際のデータ
```
http://example.com/api/v1/chairs?t=2022-12&w=1
```
```json
[
    {
        "day": "2022-12-19",
        "hoge": 5,
        "fuga": 1,
        "hogehoge": [
            1,
            2
        ]
    },
    {
        "day": "2022-12-05",
        "hoge": 2,
        "fuga": 1,
        "hogehoge": [
            1,
            2
        ]
    }
]
```

### コード
```php
    public function rules()
    {
        $rules = [
            'query.t' => 'required|date_format:Y-m',
            'query.w' => 'required|integer|between:0,6',
        ];

        // メソッドがPOSTの場合のルール
        if ($this->method() == 'POST') {
            $rules = [
                'json.*' => 'required|array',
                'json.*.day' => 'required|date',
                'json.*.hoge' => 'required|integer',
                'json.*.fuga' => 'required|integer',
                'json.*.hogehoge' => 'required|array',
                'json.*.hogehoge.*' => 'required|int',
                'query.t' => 'required|date_format:Y-m',
                'query.w' => 'required|integer|between:0,6',
            ];
        }

        return $rules;
    }

    public function validationData()
    {
        return [
            'json' => $this->except('t', 'w'),
            'query' => $this->only('t', 'w')
        ];
    }
```

# 解説
## データの再形成
以下のコードがポイントで、バリデーション対象のデータを受け取り、jsonに対してGETパラメーターのtとwを除いたものを収納しています。
queryに対してGETパラメーターのtとwのデータを収納しています。
```php
    public function validationData()
    {
        return [
            'json' => $this->except('t', 'w'),
            'query' => $this->only('t', 'w')
        ];
    }
```

## バリデーション部分
今回の場合、少し特殊で、GETとPOSTでのルールを分けています。
__jsonの配列は繰り返すので"*"で処理__
__再形成せず直接t,wだけ入れるとt.*.dayなどと無いはずのものも検証対象とされてしまう…__

```php
    public function rules()
    {
        // 基本は、このルールで。(GET)
        $rules = [
            'query.t' => 'required|date_format:Y-m',
            'query.w' => 'required|integer|between:0,6',
        ];

        // メソッドがPOSTの場合のルール上書き
        if ($this->method() == 'POST') {
            $rules = [
                'json.*' => 'required|array',
                'json.*.day' => 'required|date',
                'json.*.hoge' => 'required|integer',
                'json.*.fuga' => 'required|integer',
                'json.*.hogehoge' => 'required|array',
                'json.*.hogehoge.*' => 'required|int',
                'query.t' => 'required|date_format:Y-m',
                'query.w' => 'required|integer|between:0,6',
            ];
        }

        return $rules;
    }
```
__更新系(PUT, PATCH)時にのみバリデーション制御するということも可能です。__
```php
        // メソッドがPUT, PATCHの場合のルール
        if (in_array($this->method(), ['PUT', 'PATCH'])) {
            $rules = [
                'hoge' => ['required', 'string', 'max:255', Rule::unique('hoges')->ignore($this->hoge)],
            ];
        }
```
rails_helper.rb に require 'capybara/rails' と require 'capybara/rspec' は書かなくていい

[capybara](https://github.com/teamcapybara/capybara) gem の README の [Setup](https://github.com/teamcapybara/capybara/blob/5c8674713fa964211de43138180edfab1cc041ce/README.md#setup) と [Using Capybara with RSpec](https://github.com/teamcapybara/capybara/blob/5c8674713fa964211de43138180edfab1cc041ce/README.md#using-capybara-with-rspec) の段落には次のように、`require 'capybara/rails'` と `require 'capybara/rspec'` を追記してねと書かれています。

> If the application that you are testing is a Rails app, add this line to your test helper file:
>
> ```ruby
> require 'capybara/rails'
> ```

> Load RSpec 3.5+ support by adding the following line (typically to your `spec_helper.rb` file):
>
> ```ruby
> require 'capybara/rspec'
> ```

なので、いつも rails_helper.rb に `require 'capybara/rails'` と `require 'capybara/rspec'` を追記していました。
しかし、[rspec-rails](https://github.com/rspec/rspec-rails) gem のコードを読んだところ、rails_helper.rb もしくは spec_helper.rb に `require 'capybara/rails'` と `require 'capybara/rspec'` を書く必要はないということがわかりました。

なぜかというと、rails_helper.rb に書かれている `require 'rspec/rails'` の中の `require 'rspec/rails/vendor/capybara'` で `require 'capybara/rails'` と `require 'capybara/rspec'` が書かれているからです。

## コードへのリンク

rails_helper.rb の7行目に `require 'rspec/rails'`

https://github.com/rspec/rspec-rails/blob/c60ff7907559653cd9d1ec1a6113bf86c9359fab/lib/generators/rspec/install/templates/spec/rails_helper.rb#L7

rspec-rails/lib/rspec/rails.rb の15行目に `require 'rspec/rails/vendor/capybara'`

https://github.com/rspec/rspec-rails/blob/c60ff7907559653cd9d1ec1a6113bf86c9359fab/lib/rspec/rails.rb#L15

rspec-rails/lib/rspec/rails/vendor/capybara.rb の2行目に `require 'capybara/rspec'` 、7行目に `require 'capybara/rails'`

https://github.com/rspec/rspec-rails/blob/c60ff7907559653cd9d1ec1a6113bf86c9359fab/lib/rspec/rails/vendor/capybara.rb#L2

https://github.com/rspec/rspec-rails/blob/c60ff7907559653cd9d1ec1a6113bf86c9359fab/lib/rspec/rails/vendor/capybara.rb#L7
【laravel】日付間の差分をDBへ登録したい

## 日付間の差分をDBへ登録したい
サイト作成をしていて、入力したDateカラムの情報を用いて
日付間の差分を登録したいと考えました。

DBへはユーザーが日付をそれぞれ入力(`start_day`と`last_day`)し、
それらの差分(何日間か)を計算してDBへ登録したい。

```
$start_day = '2022-12-12';
$last_day = '2022-12-31';
$interval = ($last_day)-($start_day);
echo $interval // 19
```
のようなイメージ。
型などが影響してか、Date型同士の引き算がlaravelではエラーになってしまったので
そのやり方を考えた。

## strtotime関数でフォーマットする
ユーザーが入力した日付データを使って、実際にその差分(日数)を出してみる。
```
public function store(IdealWeightRequest $request) {

        $idealWeight = new IdealWeight();

        $idealWeight->start_day = $request->start_day;
        $idealWeight->last_day = $request->last_day;

        $startDay = strtotime($idealWeight->start_day);
        $lastDay = strtotime($idealWeight->last_day);
        $idealWeight->period = ($lastDay - $startDay) / (60 * 60 * 24);

}
```
strtotime関数は2038年問題の際に動作に影響が出てしまう恐れがあるそうなので
Datetime関数を使うのが良いとか。
ですが今回は一旦strtotime関数でやってみました。
また余裕があったらDatetimeやCarbonなどでチャレンジしてみます。

### 追記

@sgrs38 さんより教えていただきました!
いつもありがとうございます!

Cabonの場合
```
$sabun = Carbon::create('2022-12-12')->diffInDays(Carbon::create('2022-12-31'));
```

```
public function store(IdealWeightRequest $request) {

        $idealWeight = new IdealWeight();

        $idealWeight->start_day = $request->start_day;
        $idealWeight->last_day = $request->last_day;

        $idealWeight->period = Carbon::create($idealWeight->last_day)->diffInDays(Carbon::create($idealWeight->start_day));

}
```
Vonageを使いたかったのですが... 




# まずはアカウントを取得します。

電話に来た確認コードを入力したら... ああ　即撃沈です。
何が悪かったのか、さっぱり理解できない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9f516910-99c3-dddd-e6bc-8fe301f5dd81.png)

そういえば、パスワードを英数だけで登録したら

The password can not be used because the password has been found in data breaches and must no longer be used.

というエラーになった。


お恥ずかしい。最近はSalesforceばかりで遊んでいるので、どうも他のクラウドサービスがよく分かりません。うまく接続できたのはfreeeくらいですね。

Salesforceではありがちなブラウザの問題かもしれないと気を取り直してシークレットモードで挑戦。
やっぱりダメですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/b6613b9f-cf70-2752-2ddb-882c157f6800.png)



難しい。

SalesforceからSMSを投げてみようかと思っていたのですが... 
まぁ、諦めも肝心でしょう。今回は仕事の案件ではなかったから特によしとします。
せめて、何の問題なのかを教えてくれたらなぁって思う。能力低いと言われてしまえば、確かにサインインでもできんので否定はできませんね。


# Vonageへようこそ！初めてご利用いただくお客様へ　というメールが来たけど...

アカウントに問題があると言われているのに連動してないみたいですね。　

どこか質問できるようなサイトはあるのかなぁ。　

[login ページ](https://www.vonagebusiness.jp/log-in/)

# Vonage APIの使用を開始する方法 というメールも来てしまった...

サインインできないのに、何故メールがくるのだろうか？　

もしかしたら、これからログインできるのか？

やっぱり、ダメですね

アカウントの問題
アカウントに問題があるためサインインできません。

やっと、ナレッジベースへのURLを見つけたけど、私の能力では難しすぎて解決策を探せませんでしたね。全部文字で書かれている、それも大嫌いな英語だった。日本語を選択しても英語だったな。

やはりSalesforceの方がかなり簡単です。ちょっと難しすぎますね。

# パスワードの変更から...

ダメですね。変更メールは来ましたが... ログインできないですね。　かなり難しい
【初心者向け】TypeScriptの実装プロセス/tsconfig.jsonの設定例

TypeScriptの使い方をまとめました。
インストール～コンパイル実行、設定ファイルのメモです。

## TypeScriptのメリット
- 型の指定が可能
- 古いブラウザでも動作できるようにコンパイル
- JavaScriptには無い機能（インターフェース/ジェネリクスなど）
- コンパイラの設定が可能

## 開発環境サンプル
- エディター......Visual Studio Code
- 拡張機能（必須ではない）
  - ESLint
  - Prettier

## TypeScriptのインストール
``` node.js
npm install -g typescript
```

## コンパイルの実行
### ウォッチモード（プロジェクト全体）
プロジェクト全体を監視して、ファイルが変更されたら自動的にコンパイルを行います。
```
tsc --init
tsc --watch
または
tsc --init
tsc -w
```
--init
での初期化とは
「配下のファイルをすべてTypeScriptによって管理する」
ということを意味します。
tscconfig.jsonが作成されるので、コンパイルの厳密さや対象のファイルなど細かな設定が可能です。
### ウォッチモード（特定のファイル）
指定したファイルが変更されたら自動的にコンパイルを行います。
```
tsc script-name.ts --watch
または
tsc script-name.ts -w
```

### 適宜コンパイルを行う
毎回コマンドを入力するのは面倒なので、別のやり方が良いと思います。
```
tsc script-name.ts
```

## tsconfig.jsonの設定例
### exclude：指定したファイルをコンパイル対象から除外する
```tsconfig.json
{
  "compilerOptions": {
    ～中略～
  },
  "exclude": ["node_modules", "exclude-file.ts", ...]
}
```
ファイル名にはワイルドカードを指定できます。
またexcludeを設定する場合は、"node_modules"の指定を含ませることが必要です（defaultでの指定は不要）。
→node_modules内のファイルがコンパイルされるのを防ぐため

### include：指定したファイルのみコンパイル対象とする
```tsconfig.json
{
  "compilerOptions": {
    ～中略～
  },
  "include": ["include-file.ts", ...]
}
```
ファイル名にはワイルドカードを指定できます。
またexcludeを設定する場合は、"node_modules"の指定を含ませることが必要です（defaultでの指定は不要）。
→node_modules内のファイルがコンパイルされるのを防ぐため
### rootDir：TypeScriptファイルの場所を指定する
```tsconfig.json
"rootDir": "./src",
```
上記includeでも似たようなことは可能。
しかしrootDirによりルートフォルダを明示すると、root外にTypeScriptファイルがある場合にエラーが出る（意図しないフォルダ構成になることを回避できる）。
### outDir：JavaScriptファイルの出力先を指定する
```tsconfig.json
"outDir": "./dist",
```
### removeComments：コメントを削除してコンパイル
```tsconfig.json
"removeComments": trur,
```
Google共有ドライブで社外データ共有をする際に気を付けたこと

この記事は[アイスタイルAdvent Calendar 2022](https://qiita.com/advent-calendar/2022/istyle) 23日目の記事です。

初めまして、株式会社アイスタイルのkikuchiyurです。
ここに記事を書いている方々はだいたいみなさんエンジニアの方だと思います。（かっこいい！！！本当に憧れます！！！:heart_eyes:）
今僭越ながら記事を書かせてもらっている私ですが、「コーポレートIT室」という部署に所属しています。
プログラムをゴリゴリ書くといったTHEエンジニアではなく、社内のITシステムに関わるところの業務フロー整備、システム管理、セキュリティ管理、システム導入といったことを幅広くおこなっています。

## 目次
1. 今日話すこと
2. Google共有ドライブで社外共有しようとした背景
3. これまでの社外共有における課題
4. Google共有ドライブで社外共有しようとして出てきた新たな課題
5. セキュリティを守るために打った対策
6. まとめ

## １．今日話すこと
前置きの通り、THEエンジニアではないので、少し（いや、だいぶ？）他の皆様と毛色の違う内容になりますが、ご了承ください:pray:
今日は、今まさに社内で推し進めている**Google共有ドライブ活用**のうち、<font color="Magenta">**社外データ共有**</font>について少し書かせていただきます。

## ２．Google共有ドライブで社外共有しようとした背景
以前は社外の方とデータを共有する際、メール添付やオンラインストレージを使用していました。用途やファイルサイズ、機密性の有無などで適宜使い分けていました。
メール添付やオンラインストレージにももちろんメリットはありますが、それ以上に業務上様々な課題が挙がり、社内のあらゆるところから「もう少し楽にデータ共有できたらいいなぁ～」というお声が聞こえてきたんです。
また、その頃アイスタイルでは全社的にGoogleの活用促進を進めようとしている時期でした。

## ３．これまでの社外共有における課題
メールやオンラインストレージでのデータ共有は、主に以下のような課題がありました。
1. 最新版の管理が難しい（メール、オンラインストレージ共通）
2. ファイルが更新された際に、再送したりファイル更新するのが手間（メール、オンラインストレージ共通）
3. ファイルサイズに制限あり（メール、オンラインストレージ共通）
4. 別途アカウント発行が必要（オンラインストレージ）

これらを解決するために、アイスタイルでは社外とのデータ共有に[**Google共有ドライブ**](https://support.google.com/a/users/answer/7212025?hl=ja)を使用することにしました。

## ４．Google共有ドライブで社外共有しようとして出てきた新たな課題
Google共有ドライブを使うことで前述したような課題は解決したものの、利用者側の自由度が上がった分、設定次第では<font color="red">**セキュリティ事故のリスクも上がりました。**</font>
オンラインストレージはデータを置くときに必ずパスワードをかけていたり、一定期間経過すると自動的にデータが削除される仕様なので、手間がかかる分、セキュリティリスクからはある程度守られていました。
一方Google共有ドライブは、アクセス権限の制御やデータの公開範囲等しっかりと設計しないと、**誰でもアクセス可能なデータがオンライン上にずっと置いてある**、という状態になりかねません:scream:

Google共有ドライブの便利な部分を享受しつつ、セキュリティ事故を起こさず安全に利用できるように設計する必要があります:fist:

## ５．セキュリティを守るために打った対策 
Google共有ドライブで社外共有する際に、セキュリティ事故に繋がらないよう対策を打ちました。いくつかご紹介させてください。

1. マイドライブでは個人で社外共有できないような設定にした
前述の通り、個人でガンガン社外共有できる状態はかなり危険です:warning:
やっちゃいけないことだって知らずにやっちゃった！！！みたいな事件が起きた場合にみんなが悲しいことになるので、制限をかけました。

2. 社外の方の権限追加は上長の承認必須
共有先の相手が適切か、申請者の上長の承認をワークフロー上で得てから権限を付与しています。

3. ドライブの命名規則を統一し、一目で社外共有していることがわかるようにした
ドライブの名前に「社外」と付けてます。簡単なことですが大事！

4. ログ蓄積（Google標準機能）
1～3のような対策は行っていますが、とはいえ、何かあったときのためにログを追えるよう、常日頃ログの蓄積を行っています。これはGoogleの標準機能で備わっているので、安心です！

## ６．まとめ
Google共有ドライブは大変便利な反面、設定を誤ると機密情報の漏洩が容易に起きてしまう危険性があります。
私が所属している部署ではセキュリティ管理も仕事の一つなので、
Google共有ドライブの利用促進を行うと共に、運用していく中で日々改善していき、安全に利用できる設計を目指しています！
（お恥ずかしながら今までセキュリティに関して意識が低かったので、今の部署で日々勉強中の身です）

とても簡単な説明ではありましたが、Google共有ドライブで社外データ共有をする際に気を付けたことについてお話させていただきました。
読んでくださりありがとうございました:santa_tone2::evergreen_tree:

## 参考文献
- [共有ドライブとは](https://support.google.com/a/users/answer/7212025?hl=ja)
- [Workspace の DLP を使用してデータの損失を防止する](https://support.google.com/a/answer/9646351?hl=ja)
とりあえずやってみて正規表現

![スクリーンショット 2022-12-19 14.09.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2656687/4e1ba645-0438-efc9-4f17-fc65cc66d26a.png)
みなさま、こんにちは！こんばんわ！
E-kan株式会社の村岡です。

正規表現を使うことで、爆速とまでは言いませんが、効率化できることが増えるので、私がよく使っているメモ帳から**ちょっと役立つ正規表現**をご紹介します。

## 基本編

| パターン式 |　意味（内容）　|
|:-----------|:------------|
|[]|[]内に指定した文字のどれかと一致|
|^|行頭と一致|
|$|行末と一致|
|.|任意の１文字と一致|
|()|正規表現をグループにまとめる|
|｜|前後にある正規表現のいずれかと一致|
|+|直前の正規表現の1回以上の繰り返しに一致|
|?|直前の正規表現に0回or１回一致|
|{m,n}|直前の正規表現のm～n回の繰り返しに一致|
|[^]|[]内に指定した文字でない場合に一致する|
|+?|直前の正規表現の1回以上の繰り返しに一致|
|*?|直前の正規表現の0回以上の繰り返しに一致|
|??|直前の正規表現に0回もしくは１回一致|
|*|直前の正規表現の0回以上の繰り返しに一致|
|{m,n}?|直前の正規表現のm～n回の繰り返しに一致|
|\A|文字列の先頭と一致|
|\b|単語境界と一致(\wと\Wの間の空文字列と一致)|
|\B|\B以外と一致|
|\d|数字と一致([0-9]と同じ)|
|\D|\d以外と一致|
|\s|空白文字と一致|
|\S|\s以外と一致|
|\w|英数字とアンダースコア_に一致|
|\W|\w以外と一致|
|\Z|文字列の末尾と一致|

正規表現は、組み合わせによって、色々なデータを変更・修正・チェックすることができます。
基本的な使い方を確認して、応用すれば多種多様なものに対応できます。

例えばこのような形ですね。

## 応用編

| パターン式 |　意味（内容）　|
|:-----------|:------------|
|^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$　|Emailアドレス|
|^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$　|ドメイン名|
|^(http|https)://([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$　|インターネットURL|
|^[a-zA-Z0-9_\-.]{3,15}$　|ユーザー名 (Twitter username)|
|^0\d-\d{4}-\d{4}$　|固定電話|
|^(070|080|090)-\d{4}-\d{4}$　|携帯電話|
|^050-\d{4}-\d{4}$　|IP電話|
|^0120-\d{3}-\d{3}$　|フリーダイヤル|
|^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,10}$　|パスワード(大文字小文字英数字組み合わせ、特殊文字禁止、長さは8-10|
|^\d{4}-\d{1,2}-\d{1,2}$　|日付 (YYYY-MM-DD)|
|^\d{3}-\d{4}$　|郵便番号|
|^([a-zA-Z]+-?)+[a-zA-Z0-9]+\\.[x|X][m|M][l|L]$　XML|
|\n\s*\r　|空白行|
|^\s*|\s*$　|先頭後尾空白文字|
|\d+\.\d+\.\d+\.\d+　|IPアドレス※ものすごく単純にしています。|
|^[0-9]*$ |数字|
|^\d{n}$ |N桁数字|
|^\d{n,}$ |N桁以下数字|
|^\d{m,n}$ |M-N桁数字|
|^(0[0-9]*)$ |ゼロから始まる数字|
|^([1-9][0-9]*)$ |ゼロ以外から始まる数字|
|^(\-)?\d+(\.\d{1,2})?$ |小数点以下1-2位数字|
|^[1-9]\d*$ |正整数|
|^\-[1-9]\d*$ |負整数|
|^[A-Za-z0-9]+$ |英数字|
|^.{3,20}$ |長さが3-20の全ての文字|
|^[A-Za-z]+$ |大文字小文字26英字|
|^[A-Z]+$ |大文字26英字|
|^[a-z]+$ |小文字26英字|
|<[^>]+> |タグから文字列抜き出し|

## 正規表現をチェックできるサイトのご紹介
[正規表現じぇねれーた](http://rtilabs.rti-giken.jp/files/2011_11_02/)
[正規表現チェッカー](http://okumocchi.jp/php/re.php)

## まとめ
データを扱う上で、覚えておくと便利ですね。
IT分野の方は馴染みが多いと思いますが、備忘録として見ていただければ幸いです。
事務作業しかやってないよ！という方でも覚えておくと便利だと思いますので、お試しいただければと思います。

## ちょい足し

Markdown記法がめんどいなと思っている方へ。
https://stackedit.io/
こちらで書くと大変便利ですΣ('◉⌓◉’)

私のメモ帳からのご紹介でした。
少しでも皆様の役に立っていただければ幸いです。
AWS WAF ClassicからAWS WAFv2に移行した話

# はじめに
## AWS WAFについて
以下の資料が詳細まで説明がされていて分かりやすかったので、こちらを御覧ください
https://d1.awsstatic.com/webinars/jp/pdf/services/20200324_AWS_BlackBelt_AWS_WAF_Update.pdf

## 移行するモチベーション

以下、AWSが公開しているガイドラインから抜粋した内容になります。
AWS WAF Classicでは新しい機能を受け取ることができなくなるため、AWS WAFv2の利用を推奨していることが分かります。

> AWS WAF provides two versions of the service: WAFv2 and WAF
Classic. AWS recommends using AWS WAFv2 to stay up to date with the
latest features. AWS WAF Classic no longer receives new features. AWS
WAFv2 includes features that are not available in WAF classic, including a
separate API and Console. This paper focuses on implementation with
AWS WAFv2.

https://d1.awsstatic.com/whitepapers/guidelines-implementing-aws-waf.pdf

### 主な変更点
公式ドキュメントでもAWS WAF ClassicとAWS WAFv2を比較して、強化された機能や変更点の解説がされています。

https://docs.aws.amazon.com/waf/latest/developerguide/waf-migrating-why-migrate.html

> 変更点の抜粋
> - AWS Managed Rules for AWS WAF
> - New AWS WAF API
> - Simplified service quotas (limits)
> - Web ACL limits are now based on computing needs
> - Document-based rule writing
> - Rule nesting and full logical operation support
> - Variable CIDR range support for IP set
> - Chainable text transformations
> - Improved console experience
> - Expanded options for Firewall Manager AWS WAF policies
> - AWS CloudFormation support for all rule statement types

全体的に各種機能が向上しており、クォータの制限なども緩和されていることが分かります。

# 移行手順
公式が提供している仕組みがあるため、今回はその仕組みを使った移行方法をまとめています。

https://docs.aws.amazon.com/waf/latest/developerguide/waf-migrating-procedure-automatic.html

No|作業内容|画面キャプチャ|備考
:--:|:--|:--:|:--
1|AWS WAFの画面からmigration wizardを押下|![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107176/1c3dc5fe-e68b-c968-fd34-379bc9dcd7e7.png)|AWS WAF Classicのコンソール上で表示されます
2|予めS3にバケットを作成する必要があるため、①にある「Create new」を押下|![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107176/3a635804-ed40-dfdf-af86-c0b307450949.png)|ここで、指定するバケット名は　`aws-waf-migration-{xxxxx}` とする必要があります
3|バケットのポリシーを設定| ```{"Version": "2012-10-17", "Statement": [{"Effect": "Allow","Principal": {"Service": "apiv2migration.waf.amazonaws.com"},"Action": "s3:PutObject","Resource": "arn:aws:s3:::<BUCKET_NAME>/AWSWAF/<CUSTOMER_ACCOUNT_ID>/*"}]}```| 以下はは適宜書き換え<br>`BUCKET_NAME`<br>`CUSTOMER_ACCOUNT_ID`<br>
4|No2の画面で、②〜④を入力して「Next」を押下||②では移行したいWeb ACLを選択する
5|「Start creating CloudFormation template」を押下|![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107176/1ebf3042-bd09-06da-363b-388922627418.png)|設定に不備がある場合はエラーになるので、適宜対応
6|CFnスタックの作成| ![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107176/a3168a60-4dee-aaac-6dc4-1378c095b770.png)|バケット以下に作成されたCfnのテンプレートファイルを元にスタックの作成が開始

# さいごに
移行作業の過程でCFnテンプレートが作成されるので、IaC化がまだの場合は合わせて検討してみても良いかも知れません。
graphql-rubyを利用する際のtips

# イントロスペクションのブロック

通常時は、下記のようなイントロスペクションを実行するとGraphQLのスキーマ情報が一覧できてしまう

```graphql
{
  __schema {
   	queryType {
   	  name
   	  description
   	}
  }
}
```

スキーマ構造をされにくくするために、本番環境では実行できない方が好ましい
(queryやmutationから推測はできてしまうが...)

graphql-rubyをrailsで使うときは以下の記述でブロックできる

```ruby
class GraphqlTestSchema < GraphQL::Schema
  disable_introspection_entry_points if Rails.env.production?
	...
end
```

# directiveの書き方

主に注釈など、SDL(スキーマ定義言語)で仕様を表現したいときに使う

[https://graphql-ruby.org/type_definitions/directives.html#schema-directives](https://graphql-ruby.org/type_definitions/directives.html#schema-directives)

```ruby

# directiveの型を作成する
class Directives::Permission < GraphQL::Schema::Directive
  argument :level, String
  # どのtypeで使うのか定義
  locations FIELD, OBJECT
end

class Types::TestType < Types::BaseObject
  field :test_field, String, null: false

  # TestというObjectタイプに付与する例
  directive Directives::Permission, level: "manager"
end
```

SDLで確認する

```ruby
irb(main):003:0> printer = GraphQL::Schema::Printer.new(GraphqlTestSchema)
irb(main):003:0> puts printer.print_schema

directive @permission(level: String!) on FIELD | OBJECT                                                                     
                                                                         
(中略)

type Test @permission(level: "manager") {
  testField: String!
}
```
WSLと格闘した話

# はじめに

ちょうど一週間前、WSLが動かなくなって試行錯誤したときの話です。
やったこと、直した方法などを書いていきます。

# 経緯
- Flutterに挑戦しようと思い、環境構築をする
- この際に、コントロールパネル→Windowsの機能→Virtual Machine Platformなどの設定をいじる 
- Flutterの環境は上手く入れることができたものの、VS CodeのWSLターミナルが動かないことに気づく...
って感じでした
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627437/fd466e16-121f-605d-40b5-3050544c0122.png)
上がエラー画面

# 決定打
Virtual Machine PlatformとHyper-VとWSLを無効化して再起動してから再度チェックを入れる（後輩に助けてもらいました、ありがたすぎる!!!）

# 決定打にたどり着くまでにやったこと
- 設定を元に戻し、再起動する
    - 治らない。BIOSで確認しても正しく設定されているのに...


- Windows Subsystem for Linuxのチェックを外し、再起動
    - 治らない


- 何もわからないので、WSL, Ubuntu共に消す
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627437/ba7dcfb9-85d2-a6a4-b574-2219e780a99f.png)
    - 上記のように、謎にUbuntuが2つはいっていたので両方消した


- 再度入れ直すが、エラーが出る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627437/55b22aab-f7f6-b82d-0320-4abc184f4a64.png)


- Ubuntuが悪いのでは？とおもい、Debianを入れるが、同様のエラー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627437/f06cbf17-627b-c88f-1711-10024dc202f8.png)

- 「決定打」に書いてある、「Virtual Machine PlatformとHyper-VとWSLを無効化して再起動してから再度チェック」をする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627437/1f10b716-3ec5-dfb0-33c0-7497de0bb44b.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627437/ba8cd331-a024-50d6-3995-56d985deebfb.png)
    - 無事インストールが上手くできた！

## 道中のツイート
https://twitter.com/itsuki_jpnlonvn/status/1599663103708647424

https://twitter.com/itsuki_jpnlonvn/status/1599699505884327936

# やるべきだったこと
- 関係しそうな機能のチェックを全部外し、再起動→再度チェックを入れる
    - 一つ一つ外して、入れて...を繰り返していたため時間かかった

# 入れ直した後にやったこと
- Githubの再設定
    - その際に、lock failed: Operation not permitted とエラーが出た
    - https://alessandrococco.com/2021/01/wsl-how-to-resolve-operation-not-permitted-error-on-cloning-a-git-repository
        - これで解決できた（らしい、記憶にない）

# さいごに?
先日サポーターズさんのハッカソンに参加した際、cmdだと正常に動くのに、WSLだと永遠に動かない自体に遭遇した。なので、最近はWSLをほぼ使っていないです...(費やした時間がもったいない...)
asdfが便利すぎる

# はじめに
これは [KWC Advent Calendar 2022](https://qiita.com/advent-calendar/2022/kwc) の記事です。

KWCでバックエンドエンジニア ~~兼 クイズ作家~~ をしている広島在住の@nishihama-kwcです！
今回は、一緒に働いているメンバーが使ってたasdfというツールが便利すぎて泣いたので、その感動を共有したいと思います。

# asdfとは
プログラミング言語やgitなどのツールを一括でバージョン管理できるコマンドラインツールです。
pyenvなどを使うと言語のバージョンを管理できますが、asdfは複数の言語やツールをまとめて管理できるのでとても便利で使いやすいと思います。
個人的には、ローカルでちょっとしたコードを最新の言語バージョンで実行したい時などに、専用のディレクトリを作って試すという使い方をしています。

https://asdf-vm.com

# 使ってみる
インストール手順は[公式ドキュメント](https://asdf-vm.com/guide/getting-started.html)にわかりやすく書いてありますが、ここではasdfを使ってMacに最新版のGoをインストールする手順を簡単に示します。

MacにHomebrewを入れている方は以下のコマンドでインストールできます。
```
% brew install asdf
```
インストールが終わったらバージョンを確認します。
```
% asdf --version
v0.10.2
```

## Goのインストール
ここからはasdfにプラグインを追加という形でGoをインストールします。
まず、インストール可能なプラグインを以下で確認してみます。
```
% asdf plugin list all
...
golang                        https://github.com/kennyp/asdf-golang.git
...
```
Goのプラグインをインストール。
```
% asdf plugin add golang https://github.com/kennyp/asdf-golang.git
```
インストール可能なGOのバージョンを確認します。
```
% asdf list all golang
...
1.19.3
```
バージョンを指定してインストールします。
```
% asdf install golang 1.19.3

※インストール可能な最新バージョンを入れたい場合は以下でOK。
% asdf install golang latest
```
インストールされたバージョンを確認。
```
% asdf list golang
1.19.3
```
特定のディレクトリ(ここでは~/sandbox/golang)のみにGoのバージョンを適用したい場合は以下を実行。
```
% cd ~/sandbox/golang 
% asdf local golang 1.19.3
```
グローバルに適用する場合は以下を実行。
```
% asdf global golang 1.19.3
```
Goがインストールされているか確認。
```
% go version  
go version go1.19.3 darwin/amd64
```

## Goのバージョンを切り替えたい
現在のバージョン1.19.3から1.19.2へ変更したい場合。
```
% asdf list all golang | grep 1.19.2
1.19.2
% asdf install golang 1.19.2
% asdf list golang
1.19.2
1.19.3
```
バージョン1.19.2を適用。
```
% cd ~/sandbox/golang 
% asdf local golang 1.19.2

or

% asdf global golang 1.19.2
```

## バージョンもしくはプラグインを削除したい
インストールしたGoのバージョンを削除。(Goの1.19.2を削除)
```
% asdf uninstall golang 1.19.2
```

追加したプラグインを削除。
```
% asdf plugin remove golang
```

# コマンドチートシート
list や allなどややこしいなと感じるところがあるので、表にまとめました。

|     やりたいこと      | コマンド |
| ----------- | ------- |
| インストール可能なプラグインの一覧表示 | asdf plugin list all |
| プラグインを追加 | asdf plugin add <プラグイン名> <URL> |
| 指定したプラグインのインストール可能なバージョンを一覧表示 | asdf list all <プラグイン名> |
| プラグインのバージョンを指定してインストール | asdf install <プラグイン名> <バージョン名>（or latest） |
| プラグインを指定してインストールされているバージョンを一覧表示 | asdf list <プラグイン名> |
| カレントディレクトリにプラグインのバージョンを適用 | asdf local <プラグイン名> <バージョン名>（or latest） |
| グローバルにプラグインのバージョンを適用 | asdf global <プラグイン名> <バージョン名>（or latest） |
| 指定されたプラグインのバージョンを削除 | asdf uninstall <プラグイン名> <バージョン名>（or latest） |
| 指定されたプラグインを削除 | asdf plugin remove <プラグイン名> |

# おわりに
本稿では、プログラミング言語やgitなどのツールを一括でバージョン管理できるasdfコマンドについて書きました。使い始めると、asdfで管理できるツールは全て一括管理したくなりますし、同じ操作感でバージョン管理や変更できることに感動できると思います！
[KWC Advent Calendar 2022](https://qiita.com/advent-calendar/2022/kwc) も終盤に差し掛かりました。怒涛のラストスパートもお楽しみに！
Box×Salesforce活用のススメ3(Boxを使ってオンボーディング！)

# はじめに
このネタばかりですがBoxとSalesforceの連携ネタを書きます。
今回はBox内のコンテンツをSalesforce内でうまく表示してオンボーディングに役立てよう！というテーマで書いてみます。
ネタの1つとしてSalesforceの「アプリケーション内ガイダンス」という機能も利用してみますので、ご存じない方は下記を確認してみてください！

この記事で書く世界観は **Boxにオンボーディングに必要なコンテンツをすべて集約しておく。そしてそれらをSalesforceを使ってタイムリーに必要な人に提示する。** です、ぜひ読んでみてください。

https://help.salesforce.com/s/articleView?id=sf.customhelp_lexguid.htm&type=5

※過去の記事はこちら
* [Boxとの連携でSalesforceをより便利に活用しよう(Box for Salesforce)](https://qiita.com/kamadhi/items/006626ddb0b66a70e902)
* [Box×Salesforce活用のススメ](https://qiita.com/kamadhi/items/bcada53ca82d9aa7403a)
* [Box×Salesforce×Slack活用のススメ](https://qiita.com/kamadhi/items/e4d395e2b9c16cbd8810)
* [Box×Salesforce活用のススメ2(Box Lightning Component Pack for Community Cloud)](https://qiita.com/kamadhi/items/730b5d98d6b48f9ca013)

# 目次
1. Boxコンテンツを必要な人に・必要な箇所に表示しよう(「Box」×「アプリケーション内ガイダンス ドッキングプロンプト」)
2. Boxコンテンツを必要な人に・必要な箇所に表示しよう(「Box」×「アプリケーション内ガイダンス ウォークスルー」)
3. 商談内容に合わせた有益情報をBoxから取り出そう

# 1. Boxコンテンツを必要な人に・必要な箇所に表示しよう(「Box」×「アプリケーション内ガイダンス ドッキングプロンプト」)
Salesforceって毎日アクセスするシステムですよね(Boxもですが！)
ならば全社員にアナウンスしたい内容をSalesforceを使って必要な人に表示させて効果的なオンボーディングを実現しましょう！というネタになります。

Salesforceのアプリケーション内ガイダンスを活用すれば、任意の場所に任意のタイミングで任意の方にポップアップの形で情報を表示することができます。ここに、Boxの共有リンクを貼り付けたり、みて欲しい動画を貼り付けておくことで、簡単に情報周知を行いオンボーディングに繋げることができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986270/4b08472b-09c6-d9af-c567-6da7b24528c2.png)


# 2. Boxコンテンツを必要な人に・必要な箇所に表示しよう(「Box」×「アプリケーション内ガイダンス ウォークスルー」)

このアプリケーション内ガイダンスを利用して、Salesforce自体の使い方のオンボーディングにも役立てていただくことができます。
Salesforceを活用する際の最大の壁は利用者への定着です。定着させるために、膨大な量のマニュアルを作成し、何度も何度も社員への勉強会をされている会社様も多いと思います。しかし、いざSalesforceを使うときになるとマニュアルどこだっけ・・マニュアル分厚すぎてどこをみればいいかわからない・・・・ということを経験されたことのある方も多いのではないかと思います。Boxとアプリケーション内ガイダンスでその課題を解決してしまいましょう！

アプリケーション内ガイダンスのウォークスルーは一連のステップを通じてオンボーディングを支援する機能で、Salesforceコンポーネントの任意の位置に説明文を記載することができます。
ここにBox内のコンテンツの共有リンクを貼り付けておけば、必要な箇所のマニュアルを効果的に周知していくことが可能です。
ユーザーにとってはマニュアルを探す必要がなくなり、タイムリーに必要な情報にアクセスできるようになります！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986270/c763db61-512d-3ed8-3dd9-c172ac158776.png)

# 3. 商談内容に合わせた有益情報をBoxから取り出そう
Boxの中って過去の誰かが作成してくれた優良コンテンツや、優良動画がものすごくたくさん眠っていますよね。
それらの情報をたとえば商談に効果的に活用できたら便利だと思いませんか？
実はSalesforceってレコードの内容に合わせて表示させるコンポーネントの出しわけが可能なんです。これを用いれば、レコード内容に合わせてたとえば「製品A」を提案する商談の時は製品Aに関する提案書やマニュアル・動画が格納されている共有リンクが表示される。
「ソリューションA」を提案する商談の時はソリューションAに関する提案書やマニュアル・動画が格納されている共有リンクが表示される。
そんなことを実現することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2986270/68377b51-40ea-d2dc-181f-535442595745.png)

また、これらはSalesforceのプロファイル等で入社1年未満の人だけに表示させるといったこともできるので新入社員や中途社員のオンボーディングに利用できそうですね！

# さいごに
人材の流動化が当たり前になってきた現在、オンボーディングは多くの会社様でホットなテーマになってきていると思います。
Boxにオンボーディングに必要なコンテンツをすべて集約しておく。そしてそれらをSalesforceを使ってタイムリーに必要な人に提示する。それぞれの強みを活かして効果的なオンボーディングが実現できそうです！
【初級】AndroidStudio　エラー時の原因確認について（コンパイルエラー）

# 記事の内容
AndroidStudioに限った事ではないのですが、学習する際エラーや上手く動作しない場合でつかえてしまう事も多いと思います。（自身の事です笑）
今回エラーが出たので解消までの手順と考え方を書きました。

* 動作環境

| OS | AndroidStudio | 
|:--:|:--:|
| Windows 10 | Android Studio Flamingo 2022.2.1 |


# 結果：今回のエラーの原因
なぜだかGradleのバージョンが合っていませんでした。

### エラー内容に書いてありました
エラー内容は流れて行ってしまうようなので1つ前のエラー内容に書いてありました💦


`e: This version (1.3.2) of the Compose Compiler requires Kotlin version 1.7.20 but you appear to be using Kotlin version 1.8.0-RC which is not known to be compatible. `

（Googleさんの翻訳）
Compose コンパイラのこのバージョン (1.3.2) には Kotlin バージョン 1.7.20 が必要ですが、互換性が不明な Kotlin バージョン 1.8.0-RC を使用しているようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/b90ad24f-36bd-733e-7bef-dec80d9573bf.png)


ただ最初にこれを見ても意味が分からなかったので今回の確認方法は自身にとって少しは役に立つものとなりました。見返すと何やっていたのかなぁ💦とは思いますが日々このような事の積み重ねです笑


# エラー前後に行った事を確認

#### 「何もしていないのに」エラーになりました！
今まで動いていたし「何もしていないのに…」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/922f083e-d382-ab93-c7ba-619c56f5322f.png)
あるあるですよね笑

### エラーになる前に行っていたことを確認
容量削減のためGradleのフォルダを削除していました。
※作り直しされるのでこの事が今回の原因ではないとは思います。

### エラー文字列でWeb検索
（AndroidStudio下部、ビルドタブ）
`Compilation error. See log for more details`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/0de1e775-b842-eca0-3a2d-b63d19ec4d0a.png)
「ビルドのクリーン」や「リビルド」などが出て来ましたがこの方法では解消出来ませんでした。

### →切り分け
ネットの情報も全て正解ではないのと環境の違いもあるので一旦他の方法で進めます。


### 簡単なプログラムに修正
少し内容を修正して簡単なプログラムにしてみましたがコンパイルエラーは出たままでした。

### →切り分け
プログラムが悪そうではない？

### 同様のプロジェクトを作成
試しに新規作成したプロジェクトで動作確認を行いつつ同じ内容にしたところ…普通に動きました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/deb79491-df47-4292-35c6-b1c4a3538869.png)

### →切り分け
どこかに差異が？


### 設定ファイルを確認
改めて両方のビルド（Gradle）設定を見比べてみました。

（エラー有り側の設定）
id 'org.jetbrains.kotlin.android' version ***'1.8.0-RC'*** apply false
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/99011c2d-c70b-77da-4eca-537a29ceedd4.png)


（エラー無し側の設定）
id 'org.jetbrains.kotlin.android' version ***'1.7.20'*** apply false
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/ae08aa2a-f5d8-6756-2754-d9736191752a.png)


### →切り分け
バージョンが違っていました。
プロジェクトを作る際に特に何も設定していないはずですが…。


### エラーメッセージを再確認
　当記事内：[エラー内容に書いてありました](###-エラー内容に書いてありました)

「互換性が不明な Kotlin バージョン 」の意味がやっと分かりました💦
要は「使えないバージョンを使っていた」と言う感じですね。

### 対応とエラー解消
・該当部分をコメント　※何かあった時に戻したいのでコメントにしています。
・解消するバージョンを追加　※エラーメッセージで教えてくれているバージョン
・ビルド（「トンカチマーク」をクリック）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3004096/28cc4853-b4fa-1e52-71f3-e4b72067547a.png)

エラーが解消されました！！！




いつもこのように失敗したり確認したり遠回りもたくさんしています。
解消しなかった場合は別の事を進めるようにしています笑
【前編：概要編】空メールを送ったら登録用メールが返ってくるアレをSESで実装する

ごきげんよう、@An_nAです！
この記事はハンズラボ [Advent Calendar 2022](https://qiita.com/advent-calendar/2022/handslab) 21日目の記事です。

今年わたしが初めて体験したことの一つに、Amazon Simple Email Service（以降、SESと表記します）でのメール受信があります。ただ受信すれば良いわけではなく、SESでメールを受信したらメールのデータを保存しつつメール送信元にSESでメールを送る、という構成でした。

これ、思っていたよりややこしかったんですよね。
備忘録がてら実施したことをまとめますので、どなたかの参考になれば幸いです。

前編となる本記事では、まずは概要とおさえておきたいポイントをご紹介します。
短い記事ですが、後編の前提知識となりますので、ぜひご一読いただければと思います。
コードだけ見たい！という方は[後編の記事](https://qiita.com/An_nA/items/d689c6e265907f261e8f)をご参照ください。

## 実現したいこと
今回は、以下を実現したいと思います。

- ユーザーがシステム宛に空メールを送ると、システムから登録用URLが記載されたメールが届く。

受信したメールの送信元アドレスをどこかに保存しておきたいですね。
もうちょっと流れを噛み砕いてみましょう。
1. ユーザーがシステム宛にメールを送信
1. 受信したメールの情報をDynamoDBに登録
1. 登録用URLを生成
1. システムから、ユーザー（メール送信元）に登録用のURLを記載したメールを送信

という感じでいけそうです。

## おさえておきたいポイント
SESでは「受信ルール」というものを使うことで、受信したメールをS3バケットに保存したり、Lambda関数を呼び出したりすることが可能です。今回もこの受信ルールから呼び出したLambdaでDynamoDBへのデータ保存処理やメール送信処理を行います。

参考：
・[Amazon SES を使用した E メールの受信](https://docs.aws.amazon.com/ja_jp/ses/latest/dg/receiving-email.html)
・[受信ルールを使用した受信者ベースの制御](https://docs.aws.amazon.com/ja_jp/ses/latest/dg/receiving-email-concepts.html#receiving-email-concepts-rules)

概要を構成図で表現すると、こんな感じです。
メール受信用SESとLambdaがバージニア北部(us-east-1)に配置されている点が特徴的ですね。
理由はのちほど説明します。

メールデータの保存用DynamoDBやメール送信用SESは他の機能(本記事のスコープ外なのであえて描いていません)でも使用したいので、バージニア北部ではなく東京に置くこととします。

![Advent2022.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/624944/18d1e98b-3fab-626c-709a-e35dfa294e55.png)

さて、SESでのメールの受信と受信ルールの使用にあたり、おさえておきたいポイントを２つご紹介します。

### SESでメールを受信できるリージョンは限定されている
構成図をもう一度見てみましょう。
前述の通り、SESがバージニア北部(us-east-1)と東京(ap-northeast-1)にそれぞれ存在していますね。これは、メールの受信が以下のリージョンでのみ可能(2022年12月現在)なためです。
* US East (N. Virginia)
* US West (Oregon)
* Europe (Ireland)

残念ながら東京リージョンのSESにはメールを受信する機能がないので、今回の構成ではメール受信にバージニア北部のSESを利用します。

参考：
・[Amazon Simple Email Service endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/ses.html)

### 受信ルールで呼び出すLambdaは、受信用SESと同じリージョンに配置する
受信ルールで呼び出すLambdaは、メール受信に利用するSESと同じリージョンに配置する必要があります。今回の例だとバージニア北部ですね。

参考：
・[Lambda 関数のアクションを呼び出す](https://docs.aws.amazon.com/ja_jp/ses/latest/dg/receiving-email-action-lambda.html)

バージニア北部のLambdaから東京のDynamoDBやSESを利用するとなると、少し工夫が要りそうな予感がします。

---

SESでメールを受信するにあたり、気をつけないければならないポイントをご紹介しました。
短いですが、前編はここまでです。
[後編](https://qiita.com/An_nA/items/d689c6e265907f261e8f)では、ご紹介したポイントを踏まえつつ、実装していきますよ。
どうぞお楽しみに！
【d.py】ココフォリア形式のログをどどんとふ形式のログに変換する

# 概要
discord.py用のcogコードです。
`main.py`から`load_extension`する事を想定しています。
`main.py`の作例は[こちら](https://qiita.com/HikaruR/items/e518441cbe5a9a6acd77)

## バージョン情報
Python 3.8.12
discord.py 2.1.0

# 実装される機能
TRPGセッションツール[ココフォリア](https://ccfolia.com)で出力されるログを、hybridコマンドを通して古き良きどどんとふ形式のログに変換します。
[どどんとふ全タブ用コンバータ](http://dummy.flop.jp/trpg/conv/)を通した後に文字化けしている状態を修復するhybridコマンドも同梱しています。

```python:html_conv.py
import discord
from discord.ext import commands
import re #正規表現を扱うモジュール
import typing #typing.Optional解禁

class HTML_conv(commands.Cog, name = 'ログ変換'):
  """ココフォリア形式のログをどどんとふ形式に変換します"""
  
  def __init__(self, bot: commands.Bot):
    super().__init__()
    self.bot: commands.Bot = bot

  async def cog_check(self, ctx: commands.Context):
    if ctx.author.bot:
      return False
    else:
      return True

  @commands.hybrid_command(name = "ココフォログ変換", aliases = ["ココフォ"])
  @discord.app_commands.rename(log = "ログ")
  async def log_conv(self, ctx: commands.Context, log: typing.Optional[discord.Attachment]):
    """
    ココフォリア形式のログをどどんとふ形式のログに変換します
    
    Parameters
    -----------
    log
      htmlログを添付してください
    """
    if log is None:
      await ctx.send("ログが無いです", ephemeral = True)
      return
    if not log.content_type in 'text/html; charset=utf-8':
      await ctx.send(f"これ{log.content_type}です\n文字コードUTF-8のHTMLログください", ephemeral = True)
      return
    data = await log.read()
    data = data.decode("utf-8")
    data = re.sub(r'\s+<p style="color:(?P<color>.*);">\s+<span> (?P<tab>\[.*\])</span>\s+<span>(?P<text>.*)</span> :\s+<span>\s*', r"\n\g<tab><font color='\g<color>'><b>\g<text></b>：", data)
    data = re.sub(r'\s*</span>\s+</p>', r"</font><br>", data)
    data = re.sub(r'(#\d+)\n', r"<br>\1", data)
    data = re.sub(r'\s+<meta name="viewport" content="width=device-width, initial-scale=1.0" />', r"", data)
    with open(log.filename, "w") as f:
      f.write(data)
    comp = discord.File(log.filename)
    await ctx.send("お次はこちら\nhttp://dummy.flop.jp/trpg/conv/", file = comp, ephemeral = True)

  @commands.hybrid_command(name = "ログ修復", aliases = ["整形ログ修復", "修復"])
  @discord.app_commands.rename(log = "ログ")
  async def log_repair(self, ctx: commands.Context, log: typing.Optional[discord.Attachment]):
    """
    webで加工後のログの文字化けを修復します
    
    Parameters
    -----------
    log
      htmlログを添付してください
    """
    if log is None:
      await ctx.send("ログが無いです", ephemeral = True)
      return
    if not log.content_type in 'text/html; charset=utf-8':
      await ctx.send(f"これ{log.content_type}です\n文字コードUTF-8のHTMLログください", ephemeral = True)
      return
    data = await log.read()
    data = data.decode("utf-8")
    data = '<!DOCTYPE html>\n<html lang="ja">\n  <head>\n    <meta charset="UTF-8" />' + data
    fname = log.filename.replace(".html", "_rep.html")
    with open(fname, "w") as f:
      f.write(data)
    comp = discord.File(fname)
    await ctx.send("完成しました！", file = comp)

async def setup(bot: commands.Bot):
  await bot.add_cog(HTML_conv(bot))
```
Looker導入の経緯とその普及活動について

## はじめに  
この記事は [フリュー Advent Calendar 2022](https://qiita.com/advent-calendar/2022/furyu "フリュー Advent Calendar 2022") の19日目の記事となります。  
  
## 概要  
Looker導入の経緯とその普及活動について、実体験をもとにつらつらと。
  
## 前提知識  
BigQuery  
Looker  
業界の専門知識
  
## データ分析環境の古さ  
弊社におけるプリントシール機情報の分析は極めて後進的でした。  
例えば1ヶ月前にどういった人がプレイしてその人が次プレイしたのはいつか、その人はプリのリピーターか、などを取得するためには毎回データエンジニアがガリガリSQLを書いて抽出する作業をしていました。  
当然時間もかかりますし人によって抽出方法（条件）が微妙に違っていたりしたので数字にズレも発生していました。  
そこで気付きました。  
  
　　<font color="Red">あまりに非効率だ！</font>  
  
と。  
データエンジニアにとってもデータ利用者にとっても、より良い環境を用意していかなければいけません。

## Looker導入  
そこでついにLookerの正式導入ということに至りました。Lookerについて、私が特に良いと感じた点は「簡単なデータであれば利用者が抽出可能」ということ。依頼があるたびにSQLを叩いてレビューしてグラフに成形して提出する、という手間とコストの掛かる作業から解放されるときがきたのです。
データ自体はすでにBigQueryに入っているため、今回データエンジニアがやるべきはLooker環境の構築のみです。  
LookMLでサクッと書いちゃいましょう。

![LookerDev.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975196/d24ababd-d822-b981-2cb8-3866fbb2c035.png)

はい、書きました。（全然お見せできず申し訳ありません。。）  
実際にはLookML初見から1人で3ヶ月ほどかけて使える状態まで持っていき、今現在も少しずつ改善を繰り返している感じです。  
元々SQLでガリガリ抽出する作業を行っていたため、どういったデータ構造か、どうすれば効率よく抽出できるかがわかっていたので、Looker環境の構築自体は非常に簡単でした。新規部署で一から環境構築となるともう少し手こずる気がします。  
  
## チームでの稼働に向けて  
多くのチームや企業であると思うのですが、BIツールを用意したから使ってもらうというフェーズに入ったときに、いまいちみんな使ってくれないということがあるかと思います。  
ここで大事なのはテクニカルスキルではなくヒューマンスキルです。（カッツ理論）  
  
数字を扱うものは基本的にエンジニアのほうが食いつきが良いため、そのあたりの人から丁寧に説明して利用頻度を上げていきます。エンジニア以外の人に対してはエンジニアが率先してLookerを使用してデータを用意してあげましょう。SSOT（Single Source Of Truth）が担保されているため安心してデータ提供ができ、SQLを書く手間がないため非常に時短で提供ができます。なによりもLookerでデータを見ることができるという事実を広めていくことが重要なのです。  

![ダッシュボード.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975196/2ce06dc4-fe89-4076-ee86-ed617aaa515f.png)
（こんな感じの見るだけで一通りのことがわかるダッシュボードを用意してあげることも有効ですね。）
  
ある程度広めたら関係者以外にも情報発信をしましょう。外堀を埋めていく感じです。  
ここまでしてようやくデータエンジニアの役割を達成できた状態です。  
  
## 今後の目標  
現状、プリントシール機の情報をリアルタイムで分析することができていません。  
解決策としてデータ通信の抜本的な改善が必要で、例えばPub/Subでデータを送受信しFunctionsで加工しBigQueryに投入する、といったフローを構築していこうかと検討中。。
  
## まとめ  
全然技術的なことが書けていませんね。。
ただ今回書きたかったことは書けました。  
  
データエンジニアの業務は多岐にわたります。  
個人的な感覚ですが、データエンジニアに必要なスキルは技術力だけではなく、問題を認識・理解し、解決に導く最適な手段を用意できる力も必要だと考えています。最適な手段がExcelでの提示なのであればそれでも良く、あくまでも利用者の視点に立って検討することが重要です。
SVGでスターレーティングを実装する

## はじめに
webサイトやアプリの口コミやレビュー等で見かける星のスターレーティングですが、
svgとhtmlとcssで実装できます。
javaScriptを使用すれば入力、選択された値を取得し、スターレーティングに設定することも可能です。

### htmlでsvgを定義する
幅と高さが0のSVGを作成します。
今回は部分的に色の付いた星を実装したいので、maskを使用し、一部だけ星の中の色をつけてid="mask"をセットします。
下記のコードのrect x="50%"の場合は半分だけ色を塗った星ができます。
再利用するためにsymbolにid="sample"をセットします。

```HTML
<svg style="width: 0; height: 0;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
    <defs>
      <mask id="mask">
        <rect x="0" y="0" width="32" height="32" fill="white" />
        <rect x="50%" y="0" width="32" height="32" />
      </mask>
      <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32" id="sample">
        <path d="M31.547 12a.848.848 0 00-.677-.577l-9.427-1.376-4.224-8.532a.847.847 0 00-1.516 0l-4.218 8.534-9.427 1.355a.847.847 0 00-.467 1.467l6.823 6.664-1.612 9.375a.847.847 0 001.23.893l8.428-4.434 8.432 4.432a.847.847 0 001.229-.894l-1.615-9.373 6.822-6.665a.845.845 0 00.214-.869z" />
      </symbol>
    </defs>
  </svg>
```

### 定義したsvgを再利用する
星は５個必要なので、上記で定義したsvgを５個使用します。
下記の`<use>`要素を使えば再利用が可能です。上記で指定したid="sample"を記述し紐付けます。
fillに塗りつぶしたい色とstrokeに線の色を指定します。
５個目の星はmaskで塗りの色のグラデーションをかけたいので、mask=url("#mask")を指定します。

```HTML
<svg class="star" viewBox="0 0 32 32">
    <use xlink:href="#sample"></use>
    <use xlink:href="#sample" fill="blue" stroke="blue"></use>
  </svg>
  <svg class="star" viewBox="0 0 32 32">
    <use xlink:href="#sample"></use>
    <use xlink:href="#sample" fill="#blue" stroke="blue"></use>
  </svg>
  <svg class="star" viewBox="0 0 32 32">
    <use xlink:href="#sample"></use>
    <use xlink:href="#sample" fill="#blue" stroke="blue"></use>
  </svg>
  <svg class="star" viewBox="0 0 32 32">
    <use xlink:href="#sample"></use>
    <use xlink:href="#sample" fill="blue" stroke="blue"></use>
  </svg>
  <svg class="star" viewBox="0 0 32 32">
    <use xlink:href="#sample" mask=url("#mask")></use>
    <use xlink:href="#sample" fill="none" stroke="blue"></use>
  </svg>
```

### CSSでスタイリング
星を横並びにして、余白をあけるのと星のサイズを指定します。
```CSS
.star-rating {
  display: flex;
  justify-content: center;
  gap: 5px;
}

.star {
  width: 36px;
  height: 35px;
  fill: blue;
}
```

下記のイメージのスターレーティングが実装できました。
![スクリーンショット 2022-12-19 12.38.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/936514/a918df17-ed18-ac26-6053-4bd764c2670e.png)
[web制作][初心者向け] flexboxを使って、並び替えができる画像とテキストの組み合わせを作る

flexboxについて学んでいる際に便利なテクニックを知ったので、備忘録として残したいと思います。

# こういうのが作りたい

以下の図のような、画像と対になるテキストを１組として配置したい。
![１の見本.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664550/ae4a759f-2827-ec66-81bc-9872ec0b156f.png)

# まずはHTML

まずはHTMLからです。
今回はこの画像とテキストの１つの組み合わせをclass="card"とします。
遊○王カードや、ポケ○ンカードを想像すると、上半分が画像で下半分に説明書あるという感じで、今回作りたいものに似ていますよね。
よって"card"はピッタリなクラス名ですね！

具体的なコードはこちら。

```index.html
<!-- 1つの画像と１つのテキストを持つclass="card"を親要素にする -->
<div class="card">
  <img class="card-image" src="" alt="" />
  <p class="card-text">Text1</p>
</div>
<!-- ２つ目のcard -->
<div class="card">
  <img class="card-image" src="" alt="" />
  <p class="card-text">Text２</p>
</div>
<!-- 以下のcardも同様に-->
.
.
.
```
class="card"が親要素になり、
その中に対になるclass="card-image"とclass="card-text"が子要素として入っていますね。

# 次はCSS

次はCSSです。
早速flexboxを使用します。
親要素であるclass="card"をdisplay:flexでflexコンテナにします。
すると子要素はデフォルトで横並びで表示されるので、画像の右隣にテキストという組み合わせがもう完成します！

```style.css
.card {
  display: flex;
}
```

# 形を整える

この時点で画像の隣に対になるテキストという組み合わせができていますが、画像やテキストのサイズによって大きさや配置がバラバラになってしまうので、CSSを使って理想の形に近づけていきます。

具体的には、この辺が必要になるかと。
```ctyle.css
.card {
  display: flex;
/* 画像とテキストをそれぞれ垂直方向の（縦軸の）中央に配置する */
  align-items: center;
/* 画像とテキストの間に隙間を作る（値は適当・隙間がいらない場合は不要） */
  gap: 2rem;
}

.card-image {
/* 画面全体の半分に画像が配置されるようにする */
  width: 50%;
}

.card-text {
/* 画面全体の半分にテキスト配置されるようにする */
  width: 50%;
/* テキストを水平方向の（横軸の）中央に配置する */
  text-align: center;
}
```

すると、こんな感じになるはず。

![画像とテキスト横並び　同じ向き (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664550/98ce92ce-a58f-4924-d80d-13ac007d547d.png)

# カードの左右を入れ替える

最後に、見本と同じよう画像とテキストを交互に表示させたいので、HTMLとCSSに以下の内容を追加します。

```index.html
<div class="card">
  <img class="card-image" src="img/antique.jpg" alt="" />
  <p class="card-text">Text1</p>
</div>
<!-- classに"card-reverse"を追加 -->
<div class="card card-reverse">
  <img class="card-image" src="img/catalog.jpg" alt="" />
  <p class="card-text">Text２</p>
</div>
<!-- 以下も１つおきにclass="card-reverse"を追加 -->
.
.
.

```

```style.css
.card-reverse {
/* 子要素の並ぶ向きを右から左に指定する */
  flex-direction: row-reverse;
}

```

完成です。
![画像とテキストが横並び.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664550/ff0d32f0-b9e2-d263-5a2c-0eef0c32c70f.png)

# おまけ　レスポンシブ対応

おまけですが、画面が狭い時に、以下のようなコードを加えると１組の画像とテキストを上下に配置することができます。

```style.css
@media (max-width: 767px) {
  .card {
    flex-direction: column;
  }
}
```

するとこんな感じになります。
![モバイル表示.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2664550/edc667fc-6312-1e12-35b4-a3d671103125.png)

最終的なコードはこちらになります。
```index.html
<div class="card">
  <img class="card-image" src="img/antique.jpg" alt="" />
  <p class="card-text">Text1</p>
</div>
<div class="card card-reverse">
  <img class="card-image" src="img/catalog.jpg" alt="" />
  <p class="card-text">Text2</p>
</div>
```
```style.css
.card {
  display: flex;
  align-items: center;
  gap: 2rem;
}

.card-image {
  width: 50%;
}

.card-text {
  width: 50%;
  text-align: center;
}

.card-reverse {
  flex-direction: row-reverse;
}

@media (max-width: 767px) {
  .card {
    flex-direction: column;
  }
}
```
VMware NSX サービス インターフェイス（旧称 CSP）の使い方


 <font color="blue">**VMware NSX**</font> における <font color="blue">**サービス インターフェイス**</font> の使用法について、確認した内容をまとめます。
(対象バージョン：VMware NSX 3.x - 4.x)

# VMware NSX サービス インターフェイス （旧称 CSP）とは

- VMware NSX 2.3 以降で提供される機能 （NSX 2.x における旧称は、CSP：セントラル サービスポート）
-  <font color="blue">**Tier-0 及び Tier-1**</font> に実装可能な、<font color="blue">**VLANインターフェイス**</font>
- 上記のVLANインターフェイス において、<font color="red">**NAT、Edge Firewall**</font>、旧NSX-T Native LB 及び <font color="red">**該当VLANセグメントへの分散Firewall**</font>  機能等が提供される
- 下記の理由で、 <font color="blue">**Tier-0 ではなく、主に Tier-1 において使用される機能**</font>である


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/251519/8ca798fd-3840-67dc-d854-8dc576e99f37.png)
出典：https://nsx.techzone.vmware.com/resource/nsx-reference-design-guide




# サービス インターフェイス と類似機能との比較
- Tier-0 サービス インターフェイス における <font color="blue">**類似機能**</font>： Tier-0 VLAN アップリンク
-  <font color="blue">**Tier-0 VLAN アップリンク**</font> ： VLANインターフェイス、NAT、Edge Firewall、<INS>BGP、OSP</INS>F、Static route、<INS>マルチキャスト</INS>、該当VLANへの分散Firewall 機能等を提供
- <font color="blue">**Tier-0 サービス インターフェイス**</font>： VLANインターフェイス、NAT、Edge Firewall 、Static route 、該当VLANへの分散Firewall 機能等を提供<font color="red">（ルーティング プロトコル等 に未対応）</font>


※参考資料：[NSX-T Service Interfaces：VMware Doc](https://communities.vmware.com/t5/VMware-NSX-Documents/NSX-T-Service-Interfaces/ta-p/2878675)

結論) <font color="red">**Tier-0 においては通常、機能制約の少ない Tier-0 VLAN アップリンク を使用**</font> する
<font color="green">(Tier-0 サービス インターフェイスは、Tier-1 サービス インターフェイス に合わせて開発された機能となる)</font>

# Tier-1 サービス インターフェイス の機能と ユースケース
- 機能の特徴：　従来のTier-1 オーバーレイ ダウンリンク(Geneve) では提供されなかった、VLANによるダウンリンク 及び NAT、Edge Firewall 及び 該当VLANへの分散Firewall 機能を提供

- <font color="blue">**ユースケース①**</font>： <font color="purple"><INS>物理PC環境 及びVLANセグメントの仮想環境</INS></font>に接続し、<font color="purple"><INS>NAT やEdge Firewall 及び 該当VLANへの分散Firewall 機能を提供</INS></font>する
- <font color="blue">**ユースケース②**</font>： <font color="purple"><INS>VLANセグメント に存在する、ロードバランサー製品への接続性を提供</INS></font> する

 # 参考URL
https://communities.vmware.com/t5/VMware-NSX-Documents/NSX-T-Service-Interfaces/ta-p/2878675
if文とswitch文以外の条件が多いコードの書き方

# この記事のまとめ
この記事は2分で読めます。

多くの条件分岐が必要なビジネスロジックがあるときに、if文やswitch文で書くとコードが長くなってしまって見づらいときあると思います。
言語によるのですがkey-value構造と無名関数を使ったテーブルプログラミングで書くと、きれいに書けるときがあるというお話です。
サンプルはgolangとtypescriptで記載しています。
省略記法ができるtypescriptはいい感じになったのですがgolangでは微妙だったので、アロー記法ができる言語限定かもしれないです。
完全に同じ処理であればkey-valueを使った配列のみで書けてしまうため、分岐内でちょっと違うことをしているケースを例にしました。

# golangの場合
## 環境 
go version go1.18.3 windows/amd64

## if文で書いた場合

```golang:ifhello.go
package main

import "fmt"

func main() {
	inputstr := 1
	outstr := ""

	// if
	if inputstr == 1 {
		fmt.Println("hello")
		outstr = "hoge"
	} else if inputstr == 2 {
		outstr = "fuga"
	} else if inputstr == 3 {
		outstr = "piyo"
	}

	fmt.Println(outstr)
}
```


## switch文で書いた場合
```golang:switchhello.go
package main

import "fmt"

func main() {
	inputstr := 1
	outstr := ""

	// switch
	switch inputstr {
	case 1:
		fmt.Println("hello")
		outstr = "hoge"
	case 2:
		outstr = "fuga"
	case 3:
		outstr = "piyo"
	}

	fmt.Println(outstr)
}
```

## テーブルプログラミングで書いた場合
```golang:tablehello.go
package main

import "fmt"

func main() {
	inputstr := 1

	// func
	table := map[int]func() string{
		1: func() string {
			fmt.Println("hello")
			return "hoge"
		}, 2: func() string {
			return "fuga"
		}, 3: func() string {
			return "piyo"
		}}
	fmt.Println(table[inputstr]())
}

```

# typescriptの場合
## 環境 
node -v
v16.5.0
tsc -t es6 hello.ts

## if文で書いた場合
```typescript:ifhello.ts
var inputstr = 1
var outstr = ""

// if
if(inputstr==1){
    console.log("hello")
    outstr = "hoge"
}else if(inputstr==2){
    outstr = "fuga"
}else if(inputstr==3){
    outstr = "piyo"
}

console.log(outstr)

```


## switch文で書いた場合

```typescript:switchhello.ts
var inputstr = 1
var outstr = ""

// switch
switch (inputstr){
    case 1:
        console.log("hello")
        outstr = "hoge"
        break;
    case 2:
        outstr = "fuga"
        break;
    case 3:
        outstr = "piyo"
        break;
}

console.log(outstr)

```

## テーブルプログラミングで書いた場合
```typescript:tablehello.ts
var inputstr = 1

// table
const table = new Map<number, ()=>string>([
    [1,()=>{console.log("hello"); return "hoge"}],
    [2,()=>"fuga"],
    [3,()=>"piyo"],
]);

var func = table.get(inputstr);
if(func != undefined)
{
    console.log(func());
}

```


使えそうな場面があったら使ってみてください。
typescriptの最後の呼び出し部分はきれいに書ける書き方があれば教えてください。
Workato：Cookie認証を使用する

# はじめに

REST APIの認証には、一般的にOAuth2、Basic認証、ヘッダ認証（トークン認証）等が用いられますが、一部のシステムではCookieへトークンをセットする方法が用いられる場合があります。

しかし、仕様の公開されていない内部API（そのシステム自身が使用するAPI）やWebブラウザからの利用を前提としているAPIを利用するには、Webブラウザからのアクセスと同様にログインページで認証を行い、認証後にレスポンスとして返されたCookieが必要となります。

Workatoでは、リクエスト時のパラメータを工夫することでCookie認証に対応することが可能です。

# 手順
## 1. Cookieの値を何らかの方法で取得します。
例えば、ログインフォーム等で認証が行える場合、認証完了後にレスポンスヘッダとして `Set-Cookie` が返されます。また、Cookie認証用のAPIエンドポイントが存在する場合、Cookieへセットする値がレスポンスで返されます。

なお、Cookieの値を取得する際には、必要に応じてAWS LambdaとSelenium/Puppeteerを組み合わせる、Web RPAサービスを利用する等、外部のツールやサービスを組み合わせて対応しなければならない（Workatoだけで処理が完結できない）場合があります。例えば、アプリケーションによってはCSRFチェック等のセキュリティ対策により、単純にユーザー名とパスワードをログインフォームのPOST先URLのパラメータとしてセットしてリクエストを行うだけではログインが成功しない（不正なリクエストとして、エラーとなる）場合があります。

## 2.Variablesコネクターを追加し、変数(Variables)を追加します。
追加した変数上で手順１で取得した戻り値を加工し、配列に変換します。

```
[Set-Cookie ※手順1の戻り値のデータピルを指定]
.gsub('[','').gsub(']','').gsub('"','').gsub(' ','').split(';')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/795b10d1-49c9-72ec-e98c-9d90303b5546.png)

## 3.HTTPコネクターを追加し、APIリクエストに係るパラメータを設定します。
Cookieとしてサーバへ渡したい値をセットします。例えば、0番目の配列の値をCookieへセットしたい場合は、次の通りとします。

```
[Cookie ※手順2の戻り値のデータピルを指定][0]
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/5ea8b90d-1697-e898-1c96-d6c874c9f421.png)

以上の設定を行い、レシピを実行することで、Cookie認証を確認することができます。Cookie認証を必要とされている場合は、是非お試しください。