OmniAICreator/Qiita-1.07M huggingface dataset:
MTTRの改善をする中で分かった「この3ステップで業務フローを改善できる！」

この記事は[モチベーションクラウドシリーズアドベントカレンダー2021](https://qiita.com/advent-calendar/2021/mcs)の18日目の記事です。

はじめまして、リンクアンドモチベーションCREチームの粟田です。
本記事では、弊社で行なってきたMTTRの改善をどのようにしてきたか、を題材に、生産性向上を目的とした業務フロー改善のポイントを紹介します。

# 何について書いてるの？
エンジニア組織における、多種多様な業務を行う中で、改善をしようとするも、以下のような課題にぶつかったことはないでしょうか？

* 課題がなんとなくある気はするが、思い付かない...
* コスパよく改善したいが、時間だけかかっている...

弊社でもMTTRの短縮に目的としたインシデントフローのブラッシュアップを行う際、上記のような壁にぶつかりました。
しかし、以下のステップで課題を特定し、インシデントフローの改善をすることで、最終的にMTTR30分の短縮へとつなげることができ、また一般業務フロー改善にも利用できる内容であるため、紹介したいと思います。

# 業務フロー改善の3ステップ
1. 目標を定める（理想設定）
2. 時間を計測・記録する（現状把握）
3. 全体→詳細記録した時間から課題を特定し、改善策を打つ（課題設定・解決策立案）

それぞれの内容について、具体的に行った内容を交えつつ紹介したいと思います。

## 1. 目標を定める
課題は理想と現状のギャップであるため、まず理想を描く必要があります。
そのために、理想となる目標を定めます。

インシデントフローにおける目標は、「MTTR 1時間未満」と設定しました。
書籍[「LeanとDevOpsの科学」](https://www.amazon.co.jp/dp/4295004901)を参考に、ハイパフォーマーの基準を目指そう、ということで設定しました。

![スクリーンショット 2021-12-16 20.25.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331984/b5bc0f24-eefc-57a6-d060-76648f82914d.png)


## 2. かかった時間を記録する
続いて、課題特定の準備として、かかった時間を記録します。
多少面倒かもしれませんが、

- 蓄積すること
- 詳細に洗い出しておくこと

が、課題特定につながりました。

具体的には、二つの情報を記録しています。

**※以降転載する図表は実際に数値ではなくサンプルです。**

①各インシデントにおける復旧時間をその対応方法とともに、蓄積。
![スクリーンショット 2021-12-16 21.16.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331984/5b0f9a14-7aad-34a7-8d2d-2874bf21348f.png)

②一つのインシデントにおける各対応内容と、かかった時間などの情報を詳細に記録。
![スクリーンショット 2021-12-16 21.18.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331984/7b3ea51a-2184-e6d5-00b3-ce0815730cab.png)
①のそれぞれのインシデントに対して、発生〜暫定対応完了までのステップを、体制構築・原因調査・暫定対応時の詳細な内容に分けて、時間計測をしていました。



## 3. 全体→詳細と課題を特定し、改善策を打つ
これまでのステップで、理想と現状がわかったので、最後のステップは課題特定と改善策の決定です。
1で決めた目標を達成するために、2で貯めた記録を元にボトルネックとなる課題を特定し、その改善策を決めます。

進め方は、
1. 全体で蓄積したデータから、目標と照らして削減マストであり頻度の高い種別を抽出
2. 時間がかかっている特定の種別にて、詳細に貯めた時間を確認し、不要に時間をかけている作業を特定
3. 対象の作業から改善策を決定
と進めました。

具体的には、
①各インシデントにおける復旧時間の蓄積から、どの対応方法のインシデントが復旧に時間がかかっていたかを特定

![スクリーンショット 2021-12-16 21.40.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331984/24949c46-e176-5288-f178-dad3cd893417.png)

図のように、ロールバックを対応方法とする場合、時間がかかる傾向にあることが発見されました。

②ロールバックを行うインシデントの対応時の詳細な時間を確認し、不要に時間をかけている作業と原因を特定
![スクリーンショット 2021-12-16 21.45.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/331984/3e9624ad-5c5c-17b7-0412-8c5134dcdade.png)

課題抽出から改善策の策定までのアクションは以下のように整理されます。



- **時間がかかっている対象作業の特定**
    - 詳細に時間の記録より、ロールバックの判断・レビュー・実作業に時間がかかっていることを特定
- **各時間がかかっている作業の妥当性の検証**
    - 妥当性を検証することで、課題であるフローは、ロールバックの判断とレビューであることを特定
- **課題であるフローの解決できる粒度への整理**
    - 判断時には、判断基準が不明瞭であったために実行の判断に時間がかかってしまったことが課題であることと整理
    - レビュー時はレビュー依頼の際のコミュニケーションの取り方が悪く、レビュワーが気づけなかったことが課題であると整理
- **改善策の決定**
    - インシデント時のロールバックの際の判断基準の明確化
    - 緊急リリースの際のレビュー依頼


上記流れを踏むことにより、最終的には冒頭にも述べたような30分のMTTRの改善へとつながりました。

# まとめ
今回ご紹介した事例のように、時間の計測や記録には多少工数を要するものの、3ステップで課題特定→改善することによって、妥当性が高く、かつコミュニケーションフローの整備といったようなコスパの良い策で改善をすることができるようになります。
インシデントフローの改善はもちろん、リリース作業フローなどといった定常的な業務にも適用できると考えておりますので、業務改善にお役立ていただければ何よりです。
Next.jsのRouterとuseRouterは何が違うのか

# 結論
大体同じ。でも基本は`useRouter`を使う方がベター。

# useRouter vs Router
画面遷移する時や、URLパスを取得したい時など利用する`useRouter`。
以下のように使うことができます。

```react
import { useRouter } from 'next/router';

const router = useRouter();
router.push('/home'); // '/home'へ遷移
```

同じく`Router`というものもあり、オブジェクトも画面遷移やURLパスの取得にも使えます。

```react
import Router from 'next/router';

Router.push('/home');  // '/home'へ遷移
```

何が違うのか...。
[公式ドキュメント](https://nextjs.org/docs/api-reference/next/router)を見てもその違いが分からなかったのでちょっと調べてみました。

# 若干の違い一覧
[Nextのリポジトリで行われていたDiscussion](https://github.com/vercel/next.js/discussions/18522)を参考にしてみました。
そこで示されたいくつかの意見を一覧にします。

**同じだよという意見**
- 違いはなくアプローチの仕方が違うだけ。
- `useRouter`は`RouterContext`をクラス化しただけ。つまり同じ。

**ちょっと違うよという意見**
- `useRouter`はクラスコンポーネント内部で使用することはできないという違いがある。
- `Router`は常にその時点の最新のグローバル状態を指すのに対し、`useRouter`はレンダリング中のルートを参照するという違いがある

**おすすめの書き方に関する意見**
`react@>=18`の同時実行性などとの互換性を保つために、以下のようにすべき。
- 関数コンポーネントでは`useRouter`を一般的に使用する。（クラスコンポーネントなら`withRouter`）
- `Router`は、Reactのライフサイクルの外でのみ使用する（例：useEffectやイベントハンドラの中）。

## 「`react@>=18`の同時実行性などとの互換性を保つ」とは？
この点についてさらに説明があったので、自分の理解に噛み砕いてみました。
以下の例を考えてみるとよく分かると思います。

> 【例】
**ユーザーがリンクをクリックした時**、
そのページは多くのデータを取得する必要があるために**ユーザーが待機させられた**とします。
その間に**現在のパス名をalert()するボタンをクリック**したとしたらどうなるでしょうか。

> 遷移前のページがクリックと同時に再レンダリングされます。
`useRouter`を使用していると**現在のページのURLが`alert`で表示**されますが、
`Router`オブジェクトをしようしていると、**遷移後のページのURLが表示**されることになります。

このケースであれば『`alert()`ボタンを押した時点でのページのURL』が欲しいはずなので、
この場合には`useRouter`を使っておきたいです。
ただ`userRouter`は`useEffect`などの**コールバック関数内で呼び出すと以下のようなエラーが出る**ので、それを避けられないような時には必要に応じて`Router`オブジェクトを使えば良いということみたいですね。

```
React Hook "useRouter" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.
```

# 最後に

全然解釈違うよ・間違ってるよというのがあれば教えてもらえると幸いです。
認証や認可によってゼロトラストの基軸に！ID管理を行うIDaaSって何？

# はじめに
　今年の秋ごろくらいから業務でIDaaSについて調べることがあり、自分なりにまとめてみました。IDaasって名前は聞いたことあるけれど、どういうものなの？といった人にとってざっくり理解できるような内容を目指して書きました。
# IDaaSとは
　Identity as a Serviceの略称で、読み方としては「アイダース」「アイディアース」などと呼ばれるクラウドサービスです。
　主な機能としては各種クラウドサービス等への認証（多要素認証、シングルサインオン）・認可（アクセスコントロール）・ID 管理・ID 連携などがあります。
　複雑化・多様化するクラウドサービスなどのID認証やアクセス権限の管理などを一元化して行っているのがIDaaSです。現在利用しているADと連携ができる機能があるIDaaSもあり、これまでのID基盤と連携させて使用することも可能です。
　主なIDaaSとしてはAzure Active DirectoryやOkta、Oneloginなどが挙げられます。国産のIDaaSとしてはトラスト・ログインやIIJIDなどがあります。
# IDaaSが求められるようになった背景
　従来ID管理はオンプレミスのActiveDirectoryなどの機能でした。サービスやシステムなども社内から使用することが前提とされていたので、社内の内側を主に管理する方式でした。
　昨今はこれまでのクラウドサービスの普及やテレワークの推進などにより利用状況が大きく変わってきました。それに伴いさまざまな課題が新たに生じました。主な課題としては３つほど挙げられます。

### 　クラウドサービス使用数に伴う管理作業の増大
　一つ目の課題はクラウドサービスの使用数増加に伴う管理作業の増大です。現在組織で使っているクラウドサービス数は非常に多くなっています。利用するIDが増えるたびに管理するIDも増えていきます。さらには異動や入退社がある際にはクラウドサービスごとにIDの作成・変更・削除などをする必要があり、管理者の負担はクラウドサービスの利用数に比例して増大していきました。

###　社外からのクラウドサービス利用によるVPN回線のひっ迫
　二つ目はテレワークなどの社外からのクラウドサービス利用によるVPN回線のひっ迫です。コロナ禍以降多くの企業ではテレワークを推進し、それに伴い社外から業務を行うことも多くなりました。これまでの利用前提は社内からだったのでファイアウォールなどでアクセス制御を行えばよかったのですが、社外からこれまでと同じように利用するにはいったん社内環境にVPN接続したうえで利用するなどアクセス制御をしなければならず、VPN回線がひっ迫する原因になっていました。

###　サービスへの不正アクセスリスク
　3つ目はサービスへの不正アクセスのリスクです。パスワード認証のみしているクラウドサービスはIDとパスワードさえ分かれば誰でもどこからでもサインインが可能です。仮にアクセス制御を設定していないサービスであれば、パスワードなどが漏洩した場合は不正アクセスの危険性があります。


　こうした中で注目されるようになったのがIDaaSです。IDaaSの機能である多要素認証や認可機能を使うことでよりセキュリティを強化することもでき、安心してクラウドサービスを利用することができます。さらにはシングルサインオン機能を使うことで、管理する必要があるパスワードも減らすことができます。

# IDaaS主な機能
|機能名|内容|
|:--|:--|
|**シングルサインオン**|一度メインのIDaaSへサインインすれば、他のクラウドサービスへのサインインを自動で行ってくれる機能。|
|**多要素認証**|クラウドサービスへのサインイン時に、2つ以上の要素によって行う認証。|
|**認可**|クラウドサービスにアクセスが可能な利用者や端末、場所等に制限をかけて、管理者の許可を得た条件でサービスを利用できるようにする機能。|
|**ID管理**|IDaaSで管理しているIDの作成／変更／削除などを行う機能。|
|**プロビジョニング**|ID管理などで変更したユーザ情報を他のクラウドサービスにも同期させることができる機能。|
|**ログ管理**|ユーザがどのサービスをどれくらい利用しているのかといった利用履歴やアクセス状況などを確認する機能。|

※IDaaSによっては上記機能を有していないものもあります。

# IDaaSのメリット
###　不正アクセス防止
　従来のID・パスワード認証に加えてモバイルデバイスを利用したアプリでの認証や、顔認証・虹彩認証などの生体認証の多要素認証を導入することで、たとえパスワードが漏洩したとしても不正にアクセスされることを防ぐことができます。また、利用できる利用者や端末などを認可機能により制限をかけることで、必要な人だけに権限を割り当てることもできます。

###　パスワード管理の軽減
　これまでユーザは数多あるクラウドサービスのIDやパスワードの管理を行っていました。IDaaSのシングルサインオン機能を利用することによって、管理するパスワードの数は激減します。使用するパスワードも減るので、定期的なパスワード変更やそれに伴って新しくパスワードを覚える必要もなくなります。ユーザだけでなく管理する側もこれまで対応してきたパスワード関連の問い合わせや対応も減り負担が減ります。

###　ID管理の軽減
　これまでは入社・異動・退社などがあった場合はサービスごとにIDの追加・削除を行ってました。IDaaSのプロビジョニング機能を使えば、管理するサービスは一つだけで自動的に各サービスへ情報が同期されます。これにより管理者の管理作業の負担も減ります。また、退社したユーザのIDが残り続けるといったセキュリティリスクも減らすことができます。

###　VPN回線ひっ迫の解消
　従来のクラウドサービスの利用方法として、社内環境からのアクセスが前提となっている場合、社外からサービスにアクセスする場合は社内環境へのVPN接続が必要になり回線ひっ迫も課題の一つでした。IDaaSの場合はVPN接続をするかわりに多要素認証機能や認可機能で認証・認可を行うのでVPN接続を使うことはありません。

# IDaaSのデメリット
###　機能を実装できるサービスが限られている
　シングルサインオンやプロビジョニングなどの機能はすべてのサービスに対応できるわけではなく、一部サービスに限られているケースが多いです。とくに国産のクラウドサービスについてはまだ未対応のものも多いのですべてのサービスがIDaaS機能の恩恵を享受できるわけではありません。

###　主流なサービスが海外製品である
　現在IDaaSで主流となっているOktaやOneloginはいずれも海外製品です。もちろん日本語サポートなどもありますが元々が海外のため一部機能やサービスなどが日本語でなかったりサポートに頼らず使おうとしても説明が英語であるといったことはあります。

# さいごに
　以上がこれまで調べた情報をまとめたものになります。ちなみに私も少しだけAzureADの評価版を触ってみましたが、できることがたくさんあり、上手に使いこなせば効率的でより安全なID管理、サービス利用ができるのではないかと感じました。
　ただ、まだ未実装であったりな部分もある発展途上のサービスなので、今後さらに使いやすくなっていくのではないかなと思います。
Vue.js(Nuxt.js)にて親子間のコンポーネントでのデータの受け渡し（メモ）

## 親子間のコンポーネントでのデータの受け渡し方法
Vuejs(Nuxt.js)において親子のコンポーネント間でデータを受け渡す際は`props`を使用する。
### 使用例
1. まず親コンポーネントから受け渡すデータを定義する。

（親コンポーネント index.vue）

```vue
<template>
  <ChildComponent :name='name' />
</template>

<script>
export default {
  data() {
    return {
      name: ''
    }
  }
}
</script>
```

2.子コンポーネントにデータを受け取る`props`を用意する。

（子コンポーネント ChildComponent.vue）

```vue
<!-- templateは省略 -->
<script>
export default {
  props: [name] //本来はObject形式でtype等を記載した方が良いが、簡易的に左記のように記載
}
</script>
```

以上の手順を踏まえると子コンポーネントで親コンポーネントから受け取ったデータを扱うことができる。

##子コンポーネントからデータを更新するには
子コンポーネントで受け取ったデータを直接変更することができないので間接的に変更しなければならない。
したがって`$emit`を使用して親コンポーネントのイベントを発火して親に変更してもらう。

### 使用例

1. まず子コンポーネントでプロパティを作りsetterとgetterを定義し、`v-model`で設定する。

（子コンポーネント ChildComponent.vue）

```vue
<template>
  <input v-model='setName' />
</template>

<script>
export default {
  props: [name]
  computed: {
    setName: {
      get() { return.this.name  }
      set(newVal) { this.$emit('update:name', newVal } // 更新された値をセットして親のupdate:nameイベントを発火
    }
  }
}

</script>
```

2.親コンポーネントでイベントを発火させる。

```vue
<template>
  <ChildComponent :name.sync='name' />
</template>

<script>
export default {
  data() {
    return {
      name: ''
    }
  }
}
</script>
```

以上で子コンポーネントで入力された`input`タグが親コンポーネントの`name`に反映される。

`sync`の使い方については以前書いた記事があるので下記参照。
[Vue.js(Nuxt.js)におけるsync修飾子とは（備忘録）](https://qiita.com/soicchi/items/76650719bf6e9899ac4b)

## 参考文献
[Vue.js公式ドキュメント](https://v3.ja.vuejs.org/guide/component-custom-events.html#v-model-%E3%81%AE%E5%BC%95%E6%95%B0)
[Nuxt.js 親子コンポーネント間の双方向データバインディングを実装する(3/4)](https://blog.cloud-acct.com/posts/u-signup-page-3/)
ConoHaでVPNを構築したかった。→WindowsDesktop使ってみた

#書こうと思っていたテーマ
　
VPNサーバーを立てて美雲このは様にネットワークを守って貰おう

   →流行病（Covid-19）に感染。後遺症に苦しみながら記事の構想を練っていたら締め切りだった。
　　クリスマスまでには実用化したい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212894/7f04e25b-1de5-6d2a-4227-50ac7aa0661b.png)

　2番目に考えたテーマ
　「株主優待を使い、ConoHaを便利に使う」
　→技術系の記事にならない。やめた。何年も前に売っていた。
　
#実際のテーマ：WindowsDesktopを使ってみた
　テーマ理由：新規にPC買うよりもWindows環境を準備しやすい。タブレットPCでWindowsが使いたいことがあった。ついでにVPS上で2022年美雲このはオリジナル卓上カレンダーを購入したい。

###１．導入

WndowsServer2016 Remote Desktopを使います。
CPU 2Core、SSD100GB、メモリ1GBで月1100円は安い方だと思いつつ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212894/ea7ee418-45a4-daff-a1b3-778e43459cb5.png)


###２．起動

ごく普通のWindowsです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212894/e4b4a1da-f9b4-fe18-d0f2-77b558fbf09d.png)

スタートメニューに「美雲このは公式サイト」のショートカットがある。

このは可愛いからショートカット開いてみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212894/7a1899b7-1770-002d-dc75-adbc3b758f99.png)


###３．ここまでにかかった時間
10分かからず。こんなに早く構築するなんてすごいや

どうしてもパソコンを使いたい時に電車賃を払って、時間もかけてネットカフェに行くよりも、借りた方が早く済む。ネットカフェよりも安い。

###４．気を付けること
インターネット経由なので、ConoHaのネットワークが強くても手前のタブレットのインターネット速度が遅いとカクカク

###５．盲点
思っていた記事が書けなかったので
カレンダーを追加で購入しようとしました
ConoHaのサイトを開くとカレンダーの購入リンクが表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212894/7007bf68-2148-bd73-4497-f3cde45f8dc8.png)

しかし、VPSからショップにアクセスは不可
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212894/8af61528-1178-5fb4-727d-198840db3f6b.png)

*ConoHa Advent Calendar 2021でカレンダーを頂いていますが、
布教用で
　足らないので必要で毎年追加購入してます。

購入できなかったけどヨシ
そして
このは清楚このは可愛い。
APIとは

**はじめに**
今回は、APIとは何なのかについて、全く知識のない状態から調べてみてわかったこと、感じたことをまとめていきます。

**目次**
本記事の目次です。
1.APIとは
2.具体例
3.APIの仕組み
4.メリット
5.デメリット
6.まとめ

**1.APIとは**
Application Programming Interfaceの略


1.ソフトウェアの機能の一部を公開して他の人でも利用出来るようにした物
2.APIを利用するには、「API連携」が必要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359247/42f09442-76b7-a03d-9fcc-9213dc4e0628.png)

**2.具体例**
ぐるなびのサイトをもとに、どのようなAPIが使用されているのか

＜LINE API＞
＜Facebook API＞
＜GoogleMap API＞

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359247/521d4a53-a46a-7488-4e4a-66c0b8d65fb2.png)
外部サイト（ぐるなびサイト）上でのLINEやFacebookアカウントを使ったログイン機能。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359247/0330c816-5f86-bec7-4f4a-8912b6af8b5a.png)
Google Maps をウェブサイトに表示できる


**3.APIの仕組み**
API連携とは...
決められたルールに従ってリクエスト（要求）すると、APIを提供するサービスやソフトウェアが処理し、その結果をレスポンス（応答）します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359247/42f09442-76b7-a03d-9fcc-9213dc4e0628.png)

郵便番号検索API
https://basket.step.rakuten.co.jp/rms/mall/bs/morderfrom/?l2-id=step0_pc_purchase_top_1

http://zipcloud.ibsnet.co.jp/doc/api


**4.メリット**
https://locked.jp/blog/what-is-api/
 ＜ 開発費の削減 ＞
 APIを動かすための実装は必要になりますが、自前でDB内にデータを入れるテーブルを作ったり、データをメンテできる処理を作ったりするほどの工数はかかりません。

 ＜ 負荷の軽減 ＞
DBにアクセスする必要はないし、実データは持たないのでディスク容量を圧迫することはありません。結果が返るまでのレスポンスが遅ければ、それはAPIの所有者側の問題となるので対応する必要はありません。

 ＜運用の問題軽減＞
 郵便番号辞書はAPIの所有者側で管理するので、使う側は辞書の変更に対して何もする必要はありません。APIを使う側は、APIの背後にあるインフラを意識する必要はないのです。ただ使う、それだけです。

**5.デメリット**
＜API連携先に左右される＞
APIを提供する企業が何らかの理由でサービスの提供を停止すると関連した自社のサービスにも影響が生じるリスクがあります。自社のサービスがAPIの提供企業のサービスに依存しすぎるとユーザーに適切なサービスが提供出来なくなります。

＜不具合の対応が困難＞
APIを提供する企業のサーバーに何らかの障害が発生した場合、自社のサービスにも不具合が発生する可能性があります。この場合、自社では障害の対応ができないため、様々な状態の想定と対応策を検討しておく必要があります。


**6.まとめ**
APIは、身近に使用されているものだということが分かった。今後を見据えて、API連携の理解は必要不可欠だと感じたので、分からないことは今のうちに解消して開発に着手していくことが重要。

**参考サイト**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2359247/48f9366a-6e10-aa3c-64b7-7efeccb7ccde.png)
APIとは？初心者向けに分かりやすく解説します。 (sint.co.jp)

郵便番号検索API - zipcloud (ibsnet.co.jp)

APIについて徹底解説！気になるWeb APIとの違いから実際の使い方まで分かりやすく説明します。 | GeeklyMedia(ギークリーメディア)

今さら聞けないIT用語 やたらと耳にするけど「API」って何？ – データのじかん (wingarc.com)

APIとは何か？API連携ってどういうこと？図解で仕組みをやさしく解説 ｜ビジネス+IT (sbbit.jp)

APIとは？意味やメリット、使い方を世界一わかりやすく解説 | 侍エンジニアブログ (sejuku.net)

APIとは？APIとWeb APIの違いは？初心者向けに３分で解説 | ビズドットオンライン (it-biz.online)

API連携とは？API連携のメリット・デメリット・活用法｜データ連携ツール「ASTERIA Warp」｜EAI/ESB国内シェアNo.1｜アステリア
自作モーダルメモ

時々モーダルのライブラリで不具合出たりして使えないことがあるので、超簡単モーダル自作のやつを備忘録で置いておきます。
jqueryです。

とりあえずなので変な部分あります。

## js

```ruby:javascript
var current_scrollY;

function modalOpen() {
	current_scrollY = $(window).scrollTop();
	$('body').attr('data-modalActive', 'true');
	$('body').css({
		position: 'fixed',
		top: -1 * current_scrollY,
		'zIndex': 10
	});
	$('html').prop({ scrollTop: 0 });
}

function modalClose() {
	$('body').removeClass('menu-open')
	$('body').attr('data-modalActive', 'false');
	$('body').css({
		position: 'relative',
		top: 'auto'
	});
	$('html').prop({ scrollTop: current_scrollY });
	return;
}
function modalToggle() {
	if($('body').attr('data-modalActive')=='true'){
		modalClose();
	}else{
		modalOpen();
	}
}

$(function(){
  $('.modal-open').on('click', function (e) {
    e.preventDefault();
    $($(this).attr('href')).fadeIn();
	modalOpen();
  });
  $('.modal-close').on('click', function () {
	$('.modal').fadeOut();
	modalOpen();
  });
})
```

## scss
```ruby:scss
.modal{
  display: none;
  position: fixed;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0,0,0,0.2);
  z-index: 99999;
  &__wrap{
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 80px 20px;
    height: 100%;
  }
  &__inner{
    width: calc(100% - 40px);
    max-width: 800px;
    background-color: #fff;
    margin: 80px auto;
    overflow-y: scroll;
    @include mq(md, max){
      margin: 40px auto;
    }
  }
}
```
kotlinのSAM変換

# kotlinでSAMのCallbackを登録する方法

## JAVAの場合

```java
        btn.setPressReleaseCallback((state) -> {
            int discard = state ?
                Log.i(TAG, "aiueo")
                 : Log.i(TAG, "kakikukeko");
        });
```

## Kotlinの場合

```kotlin
        btn?.setPressReleaseCallback({ pressed: Boolean ->
            {
                if (pressed) Log.i(TAG, "aiueo")
                else Log.i(TAG, "kakikukeko")
            }
        } as PressReleaseCallback)
```

ラベルも使える

```kotlin
        for (manager in managers) {
            val btn = findViewById<ExButton>(manager.value.buttonId)
            btn.setPressReleaseCallback({ pressed: Boolean ->
                callback@{
                    if (bashing(pressed)) return@callback

                    Thread {
                        val player: IMusicPlayer = getPlayer(manager)

                        if (pressed) {
                            when (manager.key) {
                                PlayerKind.JetPlayer -> player.play("/data/local/tmp/sample.midi")
                                else -> player.play("/data/local/tmp/sample.wav")
                            }
                        } else {
                            player.stop()
                        }
                        player.playState = !player.playState
                    }.start()
                }
            } as ExButton.PressReleaseCallback)
        }
```
Reactテスト道場 〜Jest編〜

みなさん、テストコードはちゃんと書いてますでしょうか？
私は今回アサインされたプロダクトで初めて書きました :dizzy_face: :dizzy_face:

テストを書くことがなんか大切であることはわかるけど、
書く時間がない...なんか難しそう...って思う人もいるかもしれません。
自分は正直、思ってました。笑

でも実は、ただの「確かめ算」をしているだけでそこまで難しくない & それ以上に大きなメリットがある、と
テスト書き始めて2ヶ月程度で気づき始めました。

そんなテスト初心者の自分が、テストの素晴らしさを力説しようと思います:muscle_tone1:

## そもそもなんでテストを書くの？

### 自分たちが書いたコードがちゃんと正しく動き続けることを保証するため
プロダクト開発する上で、こんなことが起きちゃったりしていませんか？

:scream:  「このパターンの場合、このロジックでは正しく動きません！！！」 
　　→ このパターンのテストを書いてちゃんと検証しておけばなぁ。

:fearful:  「Cちゃんがコードを改修したら、このロジックが壊れました...」 
　　→ ちゃんとテスト書いておけば、テストが通らないから気づけたのになぁ。

基本、コードは正しく動き続けることは保証できません。人間の心と同じく脆いです(白目)

一方でテストを書くことで、不安なパターンを事前にチェックしておくことができたり、
壊れたタイミングで知ることができたりするので、「正しく動き続けることを保証」をすることができます。


### どんな処理であるか共同開発者に伝える、ドキュメント的な役割

例えば、下記のような「ぱっと見じゃようわからん処理」があったとします。

```js
export const filteredArray = <T>(a: T[], b: T[]): T[] => {
  return a.filter((a) => b.some((b) => b === a));
};

```

テストを書きましょう。

```ts
describe('filteredArray', () => {
  test('配列aと配列bが一致している要素を取り出す', () => {
    const dummyArrayA = ['a', 'b', 'c', 'd'];
    const dummyArrayB = ['c', 'd', 'e', 'f'];
    expect(filteredArray(dummyArrayA, dummyArrayB)).toEqual(['c', 'd']);
  });
});

```

ああ、この処理は「配列aと配列bが一致している要素を取り出す」ものなんだ。ってことが一目瞭然です。

今回の例はシンプルな処理ではありましたが、
もっと複雑な処理や複雑な、パターンの処理がある時に、
コードを読まなくとも、テストでどのような処理かを伝えることができます。


### コードの責務が正しいか確認するため
「なんかこのコードテストが書きづらいぞ...」ってなった時は、そもそもコードが正しい責務で書かれていない可能性があります。
そのため、テストは処理を見直す機会も与えてくれます。

## テストを書くフロー
### 0. テストファイルの作成

検証したいロジックのある同階層に、同じファイル名で`〇〇.spec.js`/`〇〇.test.js`というファイル (もちろん`.ts`でも可)を作成します。

### 1. コードをひとことで言語化 
`describe`という名前づけ関数を用いて、コードの責務を言語化していきます。

```js
describe("名前", () => { 処理 })
```

`describe`は入れ子にできるため、自分はテストを書く時は下記のように書きます。

```js
describe('関数名', () => {
  describe('その処理を一言で説明', () => {
    // 
  })
})
```

### 2. テストケースを網羅させる
`test`もしくは`it`というテストケースを書く関数を用いて、パターンの洗い出しを行います。

```js
test("テストケース", () => { 検証 }) // 日本語okなのでこっち使いがち。
it("テストケース", () => { 検証 }) // itは「振る舞い」という意味合い。そのため、基本英語で書いたりする。
```


基本的には、「**分岐が発生した場合全てのパターン**」に対して、書きます。

```js
describe('関数名', () => {
  describe('その処理を一言で説明', () => {
    test('〇〇の時、××', () => {
      // 検証
    })
    test('△△の時、◻︎◻︎', () => {
      // 検証
    })
  })
})
```

### 3. 正しい挙動をしているか確認
`expect`というテスト対象を指定関数を使って、正しい挙動をしているか確認します。
`expect`は、検証したい内容に合わせてテストマッチャーをチェーンさせていきます。

```js 
//値が一致してるか
expect(テスト対象).toEqual(値);　

//値が一致していないか
expect(テスト対象).not.toEqual(値);

```

1つの`test` / `it` には必ず 一つの`expect`が必要です。

```js
describe('関数名', () => {
  describe('その処理を一言で説明', () => {
    test('〇〇の時、××', () => {
      expect(テスト対象).toEqual(値);　
    })
    test('△△の時、◻︎◻︎', () => {
      expect(テスト対象).not.toEqual(値);
    })
  })
})
```

テストマッチャーの種類は非常に多く覚えるのが大変であるため、自分は下記の逆引き記事を見て
自分のテストしたいものに合うものを探して使っています！

https://qiita.com/chimame/items/e97883fd46b67529d59f#%E3%83%86%E3%82%B9%E3%83%88%E3%83%9E%E3%83%83%E3%83%81%E3%83%A3%E3%83%BC%E7%B7%A8

---

以上、テストの書き方でした！！
明日はhooksのテストの書き方に関してです！！
バージョン管理 - Gitのインストール

## はじめに
今回はGitを使い始める前にコンピュータ(利用OS)でそれを使えるようにします。
バイナリのインストーラーを用いてLinux上へGitと主な関連ツールをインストールしていきましょう。
なお、インストールはMacOS、LinuxOSによって方法がいくつかあります。
今回は、LinuxOSに対し簡易的に導入できる方法をご紹介します。


## Gitのインストール
yumを用いてインストールしていきます。

```
$ yum install git-all
```
※接続ユーザにてインストール権限がない場合、sudo にて権限を与えつつ実行する。


## 初期設定
Git をインストールしたら、名前とメールアドレスをグローバルの設定ファイルに設定します。

```
$ git config --global user.name "[任意の名前]"
$ git config --global user.email "[任意のメールアドレス]"
```
上記設定を行うことで、 ``~/.gitconfig`` ファイルが次のように設定されます。

``` 
[user]
    name = [任意の名前]
    email = [任意のメールアドレス]
```

あとで変更も可能です。
変更は ``git config`` コマンドを利用して設定してもよいですし、``~/.gitconfig`` を直接編集しても構いません。

プロジェクトごとにユーザを設定する場合は、作成したリポジトリフォルダごとに別途設定します。

1度設定している情報の確認は以下でできます。

```
$ git config --list
```


## リポジトリの作成
①任意の場所にGit用のフォルダを作成します。
　どこに作成してもよいのですが、今回は「/var/lib/git」に作成します。

```
$ cd /var/lib/git/
$ sudo mkdir [任意のフォルダ名]
$ cd [任意のフォルダ名]
```


②管理専用でリポジトリを作成します。

```
$ git init --bare
```

　実行すると、下記のようにメッセージが出力されリポジトリが作成されます。

```
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint:
hint:   git config --global init.defaultBranch <name>
hint:
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint:
hint:   git branch -m <name>
Initialized empty shared Git repository in /var/lib/git/[任意のフォルダ名]/
```


③フォルダを確認すると、Gitのプロジェクト用フォルダが作成されています。

```
$ ls -al
total 16
drwxrwsr-x 7 ec2-user ec2-user  119 Nov 30 15:01 .
drwxr-xr-x 3 root     root       22 Nov 30 15:00 ..
drwxrwsr-x 2 ec2-user ec2-user    6 Nov 30 15:01 branches
-rw-rw-r-- 1 ec2-user ec2-user  126 Nov 30 15:01 config
-rw-rw-r-- 1 ec2-user ec2-user   73 Nov 30 15:01 description
-rw-rw-r-- 1 ec2-user ec2-user   23 Nov 30 15:01 HEAD
drwxrwsr-x 2 ec2-user ec2-user 4096 Nov 30 15:01 hooks
drwxrwsr-x 2 ec2-user ec2-user   21 Nov 30 15:01 info
drwxrwsr-x 4 ec2-user ec2-user   30 Nov 30 15:01 objects
drwxrwsr-x 4 ec2-user ec2-user   31 Nov 30 15:01 refs
```


##　おわりに
本日はここまでとなります。
開発時にブランチを切って開発を進めていくことでブランチごとにバージョン管理が利用できると思います。
Power Platform、M365のおすすめブログ等

# はじめに
　Power Platformのうち3つ、Power BI、Power Apps、Power Automate、そして、Power Platformと関係するMicrosoft 365に関して、Microsoft MVPの方他のブログ等、個人的なチョイスで、お伝えします。

## Power BI

### かがたさんのQiita

https://qiita.com/PowerBIxyz

### ゆうごさんのQiita

https://qiita.com/yugoes1021

### テクテク日記

https://marshal115.hatenablog.com/

[マーシャルさん](https://twitter.com/marshal_dabao)のブログ

### spumoni ふくよりさんのQiita

https://qiita.com/spumoni

### Japan CSS Support Power BI Blog

https://jpbap-sqlbi.github.io/blog/

日本マイクロソフト Power BI サポート チームのブログ

### いしかわのQiita

https://qiita.com/ishiayaya

## Power Apps

### Power Appsの使い方

https://zezeze.hateblo.jp/

通称「zezezeのブログ」。前田さん提供。

### やまさんのQiita

https://qiita.com/yamad365

### りなたむさんのQiita

https://qiita.com/rnakamuramartiny

### JSON MIYAKEさんのQiita

https://qiita.com/MiyakeMito

### 業務ハックLab

https://yo-yon.hatenablog.com/

よ~よんさんのブログ

### When I was XXX in the toilet, I came up with an idea!　/s-tbl tech Blog 

https://hanakuso365.hatenablog.com/

あきらさんのブログ

## Power Automate

### nrjlog | 「のりじ」のブログ。

https://zuvuyalink.net/nrjlog/

### 前川さんのQiita

https://qiita.com/maekawawawa

### たなさんの覚え書き

https://tana-techlog.net/

## Power Platform 全般

### Microsoft Power Platform Weekly News Power BI レポート

https://bit.ly/PP-WeeklyNews

@yugoes1021 さんによる。Power Platform 4つ + Power Queryの公式ブログの集約

### Japan Dynamics CRM & Power Platform Support Blog 

https://jpdynamicscrm.github.io/blog/index.html

日本マイクロソフトの Dynamics CRM & Power Platform テクニカル サポート チームのブログです。

## Microsoft 365

### Art-Break Tech Blog

Art-Break Tech Blog : Taichi Nakamura – Microsoft 365 ( Office 365 ) や Power Platform についての情報発信ブログ

https://art-break.net/tech/

太一さんの通称「黒いブログ」!?　Teams等の最新のトライアル話が多く、貴重です。

### idea.toString();

idea.toString(); – Microsoft 365 や Office 365 に関する情報を投稿しています。興味の赴くままに。 https://idea.tostring.jp/

https://idea.tostring.jp/

太田さんのブログ、大事 & 興味深い話が多いです。

### SharePoint Technical Notes

https://shanqiai.weblogs.jp/

愛さんによるSharePoint等のブログ

### Microsoft TeamsのQiita

https://qiita.com/organizations/microsoftteams

日本マイクロソフトさんの方による、Microsoft TeamsとPower PlatformのQiita

# おわりに
　2021/12時点、わたしがよくアクセスする方のページを中心にチョイスしました！（今後、微修正更新をするかもです）
[py2rb] namedtuple

# はじめに
移植やってます。
# namedtuple (Python)
```python
Protein = namedtuple('Protein', ('description', 'sequence'))
```
https://www.shoeisha.co.jp/book/detail/9784798163642

**独習Python**では、辞書やクラスでも代替できると書いてあります。
# Struct (Ruby)
```ruby
Protein = Struct.new(:Protein, :description, :sequence)
p1 = Protein.new('abc', 'setumei', 'ATGC')
puts p1.description
```
https://qiita.com/jnchito/items/fb4ed2238ee3404b4403

**【初心者向け】順番に意味がある配列はハッシュに置き換えよう**に親切な解説があります。

ただし今回は、これだとp1.p2...p99とか大量発生しそうな気も
# Hash (Ruby)
```ruby
protein = {}
protein[:abc] = { description: 'setmei', sequence: 'ATGC'}
puts protein[:abc][:description]
```
今回は、これにしようかな
# メモ
+ Python の namedtuple を学習した
+ 道のりは遠そう
【Pinia】npm init vue@next でVueのセットアップをしてPiniaを使ってみる

# Piniaが公式の推奨状態管理ライブラリに

https://qiita.com/ms2geki/items/719f3033466c0da205b4

また、npm init vue@next が推奨のプロジェクトセットアップ方法となりました。

#npm init vue@nextでで作成されるフォイルを覗いてみましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659469/afa9a283-ea42-10b9-0b0c-b48be2324b14.png)
Piniaを使用するか聞かれるのでYesにします。
フォルダ構成（一部抜粋）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659469/d5f9cf30-fd3c-0ce2-54f0-561199e6463f.png)



## main.ts

```typescript:main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'

import App from './App.vue'
import router from './router'

const app = createApp(App)

app.use(createPinia())
app.use(router)

app.mount('#app')
```

既にPiniaを使用する為のセットアップが完了しています。

## counter.ts

```typescript:counter.ts
import { defineStore } from 'pinia'

export const useCounterStore = defineStore({
  id: 'counter',
  state: () => ({
    counter: 0
  }),
  getters: {
    doubleCount: (state) => state.counter * 2
  },
  actions: {
    increment() {
      this.counter++
    }
  }
})
```
ここでStoreの定義、状態を取得する為のgettersと状態を操作する為のactionsが定義がされています。Storeはいくつでも作成できますが、idは一意である必要があります。


## App.vue（一部抜粋）

```vuejs:App.vue
<script setup lang="ts">
import HelloWorld from '@/components/HelloWorld.vue'
</script>

<template>
  <header>
    <img alt="Vue logo" class="logo" src="@/assets/logo.svg" width="125" height="125" />

    <div class="wrapper">
      <HelloWorld msg="You did it!" />

      <nav>
        <router-link to="/">Home</router-link>
        <router-link to="/about">About</router-link>
      </nav>
    </div>
  </header>

  <router-view />
</template>
```

\<script\>タグのデフォルトが\<script setup>となっています。
基本的にはCompositionAPIと変わらないのですが、\<script setup>を使うと、コンポーネントをimportするだけで使用できるようになるのと、refやreactiveで宣言したリアクティブな値をreturnせずにテンプレート内で使用することができ、コードの見通しが良くなります。只、親コンポーネントから子コンポーネントのインスタンスを参照する時に、子コンポーネント側でdefineExposeをする必要があったり、propsやemitの定義にはdefinePropsやdefineEmitsを使用する必要があります。

https://v3.vuejs.org/api/sfc-script-setup.html

# 早速Piniaを使ってみる

HelloWorld.vue を書き換えます。

```vue:HelloWorld.vue
<script setup lang="ts">
import { useCounterStore } from "@/stores/counter";
const {counter,doubleCount,increment}=useCounterStore()
</script>

<template>
    <h1 class="green">-doubleCount-{{counterStore.doubleCount}}</h1>
    <button @click="counterStore.increment">カウント増加</button>
</template>

```

##結果
期待通り動いています！
![pinia.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659469/08186229-df2e-30c2-be15-3610af2bf789.gif)

# まとめ
見ての通り、Piniaでの状態管理はとても簡単でなのですが、デフォルトのstoreの定義の仕方だと、TypeScriptの恩恵を受けるためにasを使って型アサーションしなければならなかったりするのですが、CompositiionAPIを使うことで、よりシンプルにstoreを定義でき、TypeScriptの恩恵も受けやすくなります。そちらに関してこちらでまとめています。

https://qiita.com/ms2geki/items/7a450936754b793e0873
【祝公式化！🌸】PiniaがVue.js公式のレポジトリ化&公式の推奨ライブラリとなりました！

#Piniaが公式の仲間入りへ!

<blockquote class="twitter-tweet"><p lang="lt" dir="ltr">Pinia is now at vuejs/pinia 🍍<a href="https://t.co/dDcfSIaZO9">https://t.co/dDcfSIaZO9</a></p>&mdash; Eduardo.𝚟𝚞𝚎 (@posva) <a href="https://twitter.com/posva/status/1471381656351223811?ref_src=twsrc%5Etfw">December 16, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#Vuejsの推奨状態管理ライブラリがPiniaに！
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">🔥 Beware!<br><br>The new <a href="https://twitter.com/vuejs?ref_src=twsrc%5Etfw">@vuejs</a> default recommendations!<br><br>Vue CLI ➡️ create-vue (npm init vue@next)<br>Vetur ➡️ Volar<br>Vuex ➡️ Pinia <a href="https://t.co/dYcQpMvZ0R">pic.twitter.com/dYcQpMvZ0R</a></p>&mdash; VueDose (@VueDose) <a href="https://twitter.com/VueDose/status/1463169464451706897?ref_src=twsrc%5Etfw">November 23, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


## npm init vue@next
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659469/886ab6c6-e394-ec74-052f-356b2ca96fe1.png)


#早速Piniaを試してみました

![pinia.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/659469/08186229-df2e-30c2-be15-3610af2bf789.gif)

https://qiita.com/ms2geki/items/3e258cccda1b74f379ac
作品：レスポンシブページ（Responsive Page）

#概要
Odin Projectレッスンによって作ったレスポンシブサイト。

レッスンURL: https://www.theodinproject.com/paths/full-stack-ruby-on-rails/courses/html-and-css/lessons/building-with-responsive-design

Github: https://github.com/RistoLibera/Responsive_Page

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/2dc0b385-4347-20a5-7d23-db23d5879786.png)

作品URL: https://ristolibera.github.io/Responsive_Page/

#使用技術

・HTML+CSS
・Git
・GitHub
・Oracle VM VirtualBox

#内容一覧

このワンページサイトは、ズームの値に従って三つのレイアウトに変更することができます。

まず、

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/46b4563d-ca53-3af1-7969-4b59a0848236.png)

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/a4943881-b378-a06c-5e4d-1679b00c05f9.png)

デスクトップビュー。

次は、

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/cc8aee20-d92d-08fe-8fd4-96a97bda8d65.png)

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/f2c28c58-4d18-d5bf-a605-ba4b0628e760.png)

ノートパソコンビュー。

最後は、

![6.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/fbd8be66-7d2b-46c1-5e7d-18d993f441cb.jpeg)

![7.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613718/fec0850d-0eee-07e8-0bc0-3589b9204377.jpeg)

スマートフォンビュー。

#まとめ

二つ目の作品です、この作品でHTML、CSSの基礎知識を固めてレスポンシブデザインのコツも把握しております。
Vue.jsの"Hello Vue!"をwebpack+typescript環境でやってみる

# 概要
Vue.jsをwebpack+typescriptな環境で動かしたかったのですが情報が少なかったので記事にしてみました。
Vue.jsの初心者向けガイドにある最初の一歩「[宣言的レンダリング](https://jp.vuejs.org/v2/guide/index.html#%E5%AE%A3%E8%A8%80%E7%9A%84%E3%83%AC%E3%83%B3%E3%83%80%E3%83%AA%E3%83%B3%E3%82%B0)」を確認するところまでをまとめています。
フロントエンド周りは初心者なのでいくつか余分なものが含まれるかもしれませんがご了承ください。

# やったこと
## 1.nodeプロジェクトの作成と必要なパッケージの取得

```sh
npm init -y
# webpack
npm install -D webpack webpack-cli
# typescript
npm install -D typescript ts-loader
# vue
npm install vue
npm install -D vue-loader vue-template-compiler
```

## 2. tsconfig.jsonの作成

```sh
npm exec -- tsc --init
```

## 3. webpack.config.jsの作成
プロジェクトのルートディレクトリに下記内容で`webpack.config.js`という名前のファイルを作成

```js
// Vue-Loaderを使うために必要
const { VueLoaderPlugin } = require("vue-loader")

module.exports = {
	entry: "./src/index.ts", // エントリポイント
	output: { // 出力先の設定
		path: `${__dirname}/dist`,
		filename: "main.js"
	},
	module: {
		rules: [ //　各種入門ドキュメントに書いてあったのをとりあえず羅列してます
			{
				test: /\.ts$/,
				use: "ts-loader",
			},
			{
				test: /\.vue$/,
				loader: "vue-loader",
			},
			{
				test: /\.css$/,
				use: [
					"vue-stype-loader",
					"css-loader",
				],
			},
		],
	},
	resolve: {
		extensions: [".ts"],
		alias: {
			"vue$": "vue/dist/vue.esm.js",
		},
	},
	target: ["web", "es2016"],
	plugins: [
		new VueLoaderPlugin(), // VueLoaderPluginを設定
	]
}
```

これでようやく設定周りが完了です。

## 4. typescriptのコードを作成
続いてコードの作成です。
エントリポイントに`src/index.ts`を指定しているので`src`ディレクトリの中に`index.ts`を下記内容で作成します。

```ts
import Vue from "vue"

let app = new Vue({
	el: '#app',
	data: {
		message: 'Hello Vue!'
	}
});
```

## 5. ビルド
下記コマンドでビルドします。

```sh
npm exec -- webpack --mode=development
```

## 6. 表示用HTMLを作成
`webpack.config.js`の`output`に指定したところにjavascriptファイルができていると思うのでこれを読み込んで表示するためのHTMLを作成します。
ここでは`dist`ディレクトリの中に`index.html`というファイルを作成しています。

```html
<!doctype html>
<html>
	<head>
		<title>test page</title>
	</head>
	<body>
		<div id="app">
			{{ message }}
		</div>
		<script src="./main.js"></script>
	</body>
</html>
```

## 7. 動作確認
`dist/index.html`をブラウザで開いて確認します。
![スクリーンショット 2021-12-17 9.02.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2399365/abda2de6-644a-296d-5fb7-ada8295e544f.png)
無事表示されました！

# あとがき
プログラミング歴はそこそこになってきましたが、フロントエンドは初心者なので結構ここまで苦労してしまいました...
内容全てを理解するには時間がかかりそうですが、これでVue.jsのガイドを読み進める準備はできたので色々試してみたいと思います。
Windows10でAndroid端末を複数台繋げた状態で、Appiumで特定の端末を指定できるか試してみた。

久しぶりに、Appium使うことになったので、試しに複数台端末の接続に挑戦してみました。

以前書いた記事はこちら、、Appiumを使って、Android端末を操作することを実践してみたわけです。

https://qiita.com/jun_higuche/items/7c6a23ed4f9cda53b8a0



今回は、Windows10でAndroid端末を複数台繋げた状態で、Appiumで特定の端末を指定できるか試してみました。

:::note info
いきなり結論ですが、
端末指定で「udid」を指定すれば可能です。
:::

まずは、物理的にPCに２台のAndroid端末を接続します。
![imgpsh_fullsize_anim.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448092/2416add2-4ad6-ae03-8f49-739b6934adfb.jpeg)

「adb devices」コマンドで接続確認。２行表示されることを確認
※ここで、２行表示されないとか、「attached」が「device」以外の場合には接続がおかしいです。

```
>adb devices
List of devices attached
****** device
****** device
```

Android端末を指定できるかの確認のために、Appiumの接続クライアントを利用。「JSON Representation」で「udid」を指定。このとき、値は、↑の「adb devices」コマンドで取得した「******」の箇所を「uuid」として指定するのです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448092/f22488f5-5e62-030e-44fe-933578defaee.png)

↓こんな感じで指定したAndroid端末が見えるようになるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/448092/deb8e4b5-3a27-4edc-ac18-8cef2c857d52.png)

PythonやJavaのプログラムからの指定も同様に「udid」を指定することで、複数端末のうちから選択することが可能となります。
AWS側のメンテンナンス影響かAWS Personal Health Dashboardで確認してみた

# はじめに
AWSからメンテンナンスの為、対象EC2を停止させる旨の連絡が届いておりました。
実際、予定時刻になった際にEC2が停止されました。

https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instance-retirement.html

こうした際にAWS側の作業影響か、AWS Personal Health Dashboardで判断する事が出来ます。

# AWS Personal Health Dashboardとは？
自分のAWS環境に影響を及ぼすメンテナンス(EC2の停止等)または障害情報を確認できます。

似たAWSサービスに**Service Health Dashboard**がありますが、下記の違いがあります。
・Service Health Dashboard → AWS全体の情報を表示
・Personal Health Dashboard → 自分のAWS環境に影響を及ぼす情報のみを表示

https://aws.amazon.com/jp/premiumsupport/technology/personal-health-dashboard/

# まとめ
AWSサービスのイベント履歴を調べるサービスにCloudTrailがあります。
今回はAWS側のメンテナンスだった為CloudTrailに記録されておらず、
Personal Health Dashboardに記録されていました。

今後自分のAWS環境で変更があった際はCloudTrailだけではなく、
Personal Health Dashboardも念のため確認した方が良いなと感じました。
AtCoder004をやった(Java)

AtCoder004をやった。
~~C問題のちに追記予定。。。間に合わない、いろいろと。~~
C問題追記(12/17)

##[A](https://atcoder.jp/contests/abc004/tasks/abc004_1)
借金の算出方法を参考に実装

```java
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        Scanner scan = new Scanner(System.in);
        ArrayList<String> list = new ArrayList<String>();
        
        System.out.println(scan.nextInt() * 2);
    }
}
```

##[B](https://atcoder.jp/contests/abc004/tasks/abc004_2)
180度回転させたときの状態をイメージまたは、書き出してみると簡単かもしれない
競プロで初めてStringBuilder使った。

```java
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        Scanner scan = new Scanner(System.in);
        ArrayList<String> list = new ArrayList<String>();
        
        for(int i = 0; i < 4; i++){
            StringBuilder sb = new StringBuilder();
            sb.append(scan.nextLine());
            sb.reverse();
            list.add(i, sb.toString());
        }
    
        System.out.println(list.get(3));
        System.out.println(list.get(2));
        System.out.println(list.get(1));
        System.out.println(list.get(0));
    }
}
```

##[C](https://atcoder.jp/contests/abc004/tasks/abc004_3)
123456って文字列を入力値に基づいて差し替える。
例えば、15って入力値が与えられたら、456123これが正当
入力値は10^9が最大値というところで、普通にループさせたらパンクしてしまう。
なので、何かしらの工夫が必要。
※クソコードです。最後の入れ替えのところもっときれいに書ける気がします。

```java
import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        Scanner scan = new Scanner(System.in);
        ArrayList<String> list = new ArrayList<String>();
        
        int num = scan.nextInt() % 30;
        String str = "";
        if(num >= 0 && num < 5){
            str = "123456";     
        }else if(num >= 5 && num < 10){
            str = "234561";
        }else if(num >= 10 && num < 15){
            str = "345612";
        }else if(num >= 15 && num < 20){
            str = "456123";
        }else if(num >= 20 && num < 25){
            str = "561234";
        }else if(num >= 25 && num < 30){
            str = "612345";
        }

        char[] ch = new char[6];
        if(num % 5 == 0){
            System.out.println(str);
        } else {
            for(int i = 0; i < str.length(); i++){
                ch[i] = str.charAt(i);
            }
            // 初期化
            str = "";
            // 出力用(組み替えるところまで)
            for(int i = 0; i < num % 5; i++){
                str = str.concat(String.valueOf(ch[i + 1]));    
            }
            // 出力用(残った文字)
            for(int i = num % 5; i < ch.length - 1; i++){
                if(num % 5 == i){
                    str = str.concat(String.valueOf(ch[0]));    
                }
                str = str.concat(String.valueOf(ch[i + 1]));    
            }
            System.out.println(str);
        }
    }
}


```

いつかC問題もJavaで解きたいな(n回目)。
Rails 7.0 のリリースノートまとめ

## はじめに
2021年9月15日、Rails 7 のアルファ版がリリースされました。
通常、Rails のアルファ版リリースは行わないのですが、フロントエンドに大きな変更が加わることによって、慎重に検証する必要があると判断したみたいです。

ちょうど社内で Rails 7 についてアウトプットする場があり、良い機会なので情報をまとめてみたいと思います。

## 1. フロント面のリニューアル
まず Webpacker が廃止され、フロント面がリニューアルされます。
ES6 / ESM のブラウザサポートの進歩、HTTP/2 の普及、importmap の新標準に対応するためです。
具体的には、Turbllinks と Rails UJS が Stimulus と Turbo の Hotwire コンビに置き換わります。
node_modules、bundler の設定に依存せず、フロントの開発にありがちな問題も発生しません。

また、Rails と JavaScript + CSS bundler の統合も劇的に改善されたそうです。
Rails の新しい JavaScript と CSS で起動できる2つの Gem を通じてアプリケーションを起動できたり、importmap で始まるアプリケーションを esbuild、rollup.js、Webpack、Tailwind CSS、 PostCSS、 Dart Sass、 Bootstrap で変更することが簡単にできるようになっています。

## 2. Active Record の実行時暗号化機能
Active Record に実行時暗号化機能が追加されます。
HEY （Basecamp のサービス） で用いられている暗号化属性を抽出し、 Active Record に追加することによって、実行時の暗号化も可能になりました。
これはハッカーが DB やそのスナップショット、アプリケーションの log にアクセスした場合、暗号化により情報を保護することができます。

しかしより重要な点は、Active Record Encryption を使用することで、コードレベルでアプリケーションの機密情報を定義できることです。
例えば、暗号化されたデータを保存する監査可能なアプリケーションを構築することができます。

詳細を知りたい方は、こちらを確認してください。
[https://edgeguides.rubyonrails.org/active_record_encryption.html](https://edgeguides.rubyonrails.org/active_record_encryption.html)

## 3. ActiveRecord で生成されたクエリにコメントが追加
Marginalia により、ActiveRecord で生成されたクエリにコメントが追加されるようになりました。
デフォルトでは各クエリの最後に、アプリケーション、controller、および action の名前がコメントとして追加されます。

## 4. 非同期クエリの読み込み速度向上
Controller で関連性のない2つのクエリを読み込む必要がある場合、Relation#load_async によって同時にロードができるようになりました。
それぞれ0.1秒かかる複雑な3つのクエリがある場合、以前は1つを実行するのに0.3秒、計0.9秒必要でした。
ただこの方法だと並列で実行することができるので、計0.3秒で処理が完了します。

## 5. Zeitwerk の一元化
かつての const_missing では、さまざまな癖や欠陥した機能を伴っていましたが、Zeitwerk コードローダーに一元化されました。

## 6. その他ハイライト
- コンピューターの性能向上により、大規模なアプリケーション以外では、Spring はあまり意味をなさなくなったため、デフォルトでオフになりました。
- ActionController:Live#send_stream は、Controller の Action でオンザフライ生成されるファイルを簡単にストリーミングできるようになりました。
- 並列化されたテストは、CPU コア数とテスト数を比較し、それにおおじて並列化の規模を調整できるようになりました。
- Active Storage はより高速で安全な libvips をデフォルトの Variant プロセッサとして使用するようになりました。

## さいごに
いかがでしたでしょうか。
フロント面が大幅なリニューアルとなり、Rails 7 に期待を膨らませている方も多いと思います。
Rails 7 は年内のリリースを目指しているみたいなので、アルファ版を用いて新機能のテストにドンドン協力していきましょう！

## 引用
- https://weblog.rubyonrails.org/2021/9/15/Rails-7-0-alpha-1-released/
アプリケーションログ設計方針

実務で活用しているアプリケーションログの設計方針
参考: [体系的に学ぶ 安全なWebアプリケーションの作り方](http://amazon.jp/dp/B07HHT54YR)5.4ログ出力

## ログに記録すべきイベント  
ログに記録すべきイベントは多すぎても少なすぎても駄目
一般的には以下に示す認証・アカウント管理や重要な情報や操作に関するイベントを記録する

* ログイン・ログアウト（失敗も含む）
* アカウントロック
* ユーザ登録・削除
* パスワード変更
* 重要情報の参照
* 重要な操作（物品の購入、送金、メール送信など）

## ログフォーマット 
ログの出力項目は、4W1H ( いつ | 誰が | どこで | 何を | どのように ) に従った以下の項目を取得する

* アクセス日時
* ログレベル ( debug | info | warn | error | fatal )
* リモートIPアドレス
* ユーザID
* アクセス対象（URL、ページ番号、スクリプトIDなど）
* 操作内容（閲覧、変更、削除など）
* 操作対象（リソースIDなど）
* メッセージ、トレース
【Chrome Extension】chrome.storageから取得した値を変数として利用する

使い方合ってるかは保証しません。
自己責任でご利用ください。

---

## 準備

```javascript
async function getValuesFromChromeStorage (key) {
  let results = null;
  
  await new Promise(function (resolve) {
    chrome.storage.sync.get([key], function (values) {
      results = values[key];
      resolve();
    });
  });
  return results;
}
```

## 使う

```javascript
async function example () {
  // getValuesFromChromeStorageの処理を待つ。
  // hogeというキーのStorageデータを取得する。
  const values = await getValuesFromChromeStorage('hoge');
  // getValuesFromChromeStorageの処理が終わったら結果が表示される。
  console.log(values);
}

// 実行
example();
```

▼即時関数の場合▼

```javascript
(async() => {
  const values = await getValuesFromChromeStorage('hoge');
  console.log(values);
})();
```
ラピッドチャレンジ　応用数学

# 線形代数


## 行列式
特徴として以下の3つが挙げられている。

- 行列式性質1

```math
\begin{vmatrix}
\vec{v_1}  \\
\vdots \\
\vec{w} \\
\vdots \\
\vec{w} \\
\vdots \\
\vec{v_n}
\end{vmatrix}
= 0
```

- 行列式性質2

```math
\begin{vmatrix}
\vec{v_1}  \\
\vdots \\
\lambda \vec{v_i} \\
\vdots \\
\vec{v_n}
\end{vmatrix}
= \lambda
\begin{vmatrix}
\vec{v_1}  \\
\vdots \\
\vec{v_i} \\
\vdots \\
\vec{v_n}
\end{vmatrix}
```

- 行列式性質3

```math
\begin{vmatrix}
\vec{v_1}  \\
\vdots \\
\vec{v_i} + \vec{w} \\
\vdots \\
\vec{v_n}
\end{vmatrix}
= 
\begin{vmatrix}
\vec{v_1}  \\
\vdots \\
\vec{v_i} \\
\vdots \\
\vec{v_n}
\end{vmatrix}
+
\begin{vmatrix}
\vec{v_1}  \\
\vdots \\
\vec{w} \\
\vdots \\
\vec{v_n}
\end{vmatrix}
```

講義では平行四辺形(符号付)と行列式の対応で説明されていたが、行列式性質3については
ベクトルvi と ベクトルw が平行ではないケースで、直感で理解できなかった。
式を覚えるという意味ではわかりやすいが、理解できないのが気持ち悪いため、行列式の別の定義も載せる。

### 行列式の定義


```math
\begin{vmatrix}
A
\end{vmatrix}
= \sum_{\sigma \in S_n} \rm{sgn( \sigma )} a_{1\sigma(1)}a_{2\sigma(2)} \cdots a_{n\sigma(n)}
```

```math
S_n は n文字の置換の集合。\rm{sgn}(\sigma) は置換の符号を表す。
```
この定義を用いると、行列式1,2,3の性質がすぐ導ける。
また、講義で触れられていた、
行を入れ替えると符号が変わる性質、
余因子展開についても同様に導ける。

## 固有値固有ベクトル

正方行列Aに対して

```math
A \vec{x}=\lambda \vec{x}
```

を満たす

```math
\vec{x} \neq \vec{0}, \lambda
```

をそれぞれ固有ベクトル、固有値という。
まず

```math
\begin{vmatrix}
A- \lambda I
\end{vmatrix}
= 0
```

から

```math
\lambda
```

を計算し、それより連立方程式(解が一意に決まるとは限らない)を解き、固有ベクトルを求める。

### 固有値分解

固有値がどの二つをとっても異なっている場合についてのみ述べる。
固有値、固有ベクトルをそれぞれ

```math
\lambda_i ,\vec{v_i}
```

で表す。

対角成分に固有値を並べた対角行列を[^1]

```math
\Lambda =
\begin{pmatrix}
\lambda_{1} & & \\
  & \lambda_2 &\\
  &  & \cdots \\
\end{pmatrix}
```

固有ベクトルを並べた行列を

```math
V =
\begin{pmatrix}
\vec{v_1} & \vec{v_2} & \cdots
\end{pmatrix}
```

とする。このとき、

```math
AV = V\Lambda \\
\therefore A = V\Lambda V^{-1}
\therefore A^n = V \Lambda^{n} V^{-1}
```

とかける。
対角行列はべき乗が容易なため、上記式によりAのべき乗も容易に計算できる。

特異値分解は固有値分解の一般形である。

# 確率・統計

### 条件付確率の定義

```math
P(Y=y|X=x) = \frac{P(Y=y \cap X=x)}{P(X=x)}
```

X=x が成り立っているとき Y=yとなる確率のこと。

### ベイズの定理

```math
P(Y=y|X=x)P(X=x) = P(X=x|Y=y)P(Y=y)
```

条件付確率の定義より明らか。
モンティ・ホール問題や陽性検査のパラドックスなど、面白い応用例も多い。

### 期待値・分散・共分散

確率論だとあまり見ない気がするが、統計だと

```math
X^2, X^3, X^4
```

の期待値なども計算することがある。(歪度、尖度など)

分散は平均からのずれの2乗の平均である。
2乗しているのは平均から+のずれと-のずれを同一視したいため。
データのばらつきをみるのに、平均からの距離(平均-データの絶対値)の平均を使うこともある。

共分散は-1から1の間の値をとり、
正の値: 同じ方向へ変化(1に近いほど強い相関
負の値: 反対方向へ変化(-1 に近いほど強い相関
0: 独立
となる。

### 統計的に重要な分布

離散分布

- ベルヌーイ分布
- 二項分布
- 幾何分布
- 負の二項分布
- ポアソン分布
- 超幾何分布
- 離散一様分布

など

連続分布

- 正規分布
- 指数分布
- ガンマ分布
- ベータ分布
- t分布
- F分布
- カイ2乗分布
- 一様分布
など

推定や検定の手法でよく使う。

# 情報理論

### 自己情報量

```math
I(x) = -\log(P(x)) = \log(W(x))
```

発生確率が低いものを大きくなるように定義されている。
また、独立な事象A,Bに対し、A,Bの両方が起こるという事象の情報量はAの情報量とBの情報量の和になる。

### シャノンエントロピー

```math
H(x) = E(I(x)) = - \sum P(x) \log P(x) 
```

自己情報量の期待値。


###　カルバック・ライブラー　ダイバージェンス

```math
D_{KL}(P||Q) = E_{X \sim P}[log \frac{P(x)}{Q(x)}]
```

自己情報量の差の期待値とみてよい。同じ事象・確率変数における異なる確率分布の違いを表す。

### 交差エントロピー

```math
H(P,Q) = H(P) + D_{KL}(P||Q) = -E_{X \sim P} \log Q(x)
```

カルバック・ライブラー　ダイバージェンス　の一部分をとりだしたもの。-log Q を P で期待値取っただけ。

[^1]: 対角行列とは、対角成分以外の成分がすべて0になる行列のこと。
Nuxt(Vue)を使用していたらsass-loaderが原因でエラーになったのでまとめてみた

#前提
エンジニア目指して勉強中の身です。Nuxt.jsを用いたポートフォリオ作成中、突然エラーになり苦戦したので、同じ境遇の方へ向けて記事としてまとめます。マサカリを投げていただきましたら、フォローいたします。

#開発環境
node: 16.13.1
npm: 8.1.2

#エラー
```
Module build failed (from ./node_modules/sass-loader/dist/cjs.js):
TypeError: this.getOptions is not a function
    at Object.loader (/Users/user_neme/Template/nuxtjs-boilerplate/node_modules/sass-loader/dist/index.js:25:24)
```

#原因
■1
まず、NuxtでSassを使うには

・node-sass
・sass-loader

2種類のパッケージが必要とのこと。

■2
sass-loaderの11.0.1を使うなら
node-sassの5.0.0以上を使わなければならない。
https://www.npmjs.com/package/node-sass

■3
サポートされているwebpackの最小バージョンが"5"であることが必須。
（詳細は参考より）

#解決
バージョンを合わせる。

```
npm install node-sass@5.0.0
npm install sass-loader@11.0.1
```


node-sassのみ変更の場合(5.0.0以上)

```
npm install node-sass@5.0.0
```

sass-loaderのみ変更の場合(10.1.1へダウングレード)

```
npm install sass-loader@10.1.1
```

###参考
https://note.com/aliz/n/n70a7a5f802df
https://mykii.blog/nuxt-update-sass-loader/
https://ma-vericks.com/nuxt-scss/

#まとめ
パッケージなど、とりあえず最新版にしてみたり、推奨なので問題ないでしょ、という考えは変えなくてはいけないと思いました。バージョンによる互換性など、調べてからアップグレードしていきたいと思います。

###余談
まとめてみるとシンプルだとわかるのですが、記事通りに実行しても(していない)エラーになったり、前提がわからなかったりと時間だけが過ぎていくことも少なくないです。改めて、闇雲に探すのだけは避けたい所存です。

先輩方が仰るよう、公式リファレンスから一次情報を得られることがベストだと思います。
https://nuxtjs.org/ja/releases/
Discordの通知をすべてDiscordで通知するBOT

[クソアプリ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/kuso-app) 17日目の記事です。

# 初めに
どうも、最近Javascriptばっか使ってて、Pythonを忘れかけてる人です。

この記事では、pycordというPythonのライブラリを使ってDiscord botを使ったので、その紹介をしていきます。

# 作ったBOT紹介

Discordの通知をDiscordでします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974385/a3635ba8-88b1-4c08-c6cd-25ce4b1f1237.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/974385/c65b917a-110c-1d8a-38e9-09ae3ba97582.png)
送信されたもの、すべてが通知されます。

## コマンド

### n.join
通知をonにします。

このコマンドを実行すると、コマンドを実行したサーバーのメッセージのうち、botが閲覧できるメッセージの送信通知が全部DMで送られてきます。

### n.leave
通知をoffにします。

これで、あのうるさいﾋﾟｺﾋﾟｺ音にうんざりしなくて済みます。

# 招待URL

https://discord.com/api/oauth2/authorize?client_id=915404382189785109&permissions=68608&scope=bot

# Pycord
この記事で紹介したbotは、このライブラリを使って開発しました。

pythonでdiscord botといえばdiscord.pyが主流でした。しかし、とある理由で開発が中止となってしまいました。
そんなdiscord.pyの後継者として、いま注目を浴びてるのが、このライブラリ

https://github.com/Pycord-Development/pycord

docsもどこか懐かしい感じがします。

https://docs.pycord.dev/en/master/

## インストール

```bash
pip install -U py-cord
```
 

## 基本機構

```py
import discord

class MyClient(discord.Client):
    async def on_ready(self):
        print(f'Logged on as {self.user}!')

    async def on_message(self, message):
        print(f'Message from {message.author}: {message.content}')

client = MyClient()
client.run('my token goes here')
```

https://docs.pycord.dev/en/master/intro.html#basic-concepts

この記事で紹介したbotのコードは、このコードをベースに作りました。

## 簡易コマンド
コマンドの実装方法には複数あります。

- Slash Command
- ext.commands
- message.content

こんな感じかな？

このbotで使った方法は、message.contentを使った方式です。

上で書いた基本機構の`on_message`で受け取った引数`message`を使ってコマンドを実装します。

```py
if message.content.startswith('n.join'):
  # 処理
```

こんな感じ

イコールを使ってもよかったけど、~~のちに他の人を強制的に通知onにするいたずら機構も作ろうと思い、~~`.startswith()`を使いました。

## DMへメッセージ送信
DMへのメッセージ送信は、[discord.Member](https://docs.pycord.dev/en/master/api.html#member)に[send()](https://docs.pycord.dev/en/master/api.html#discord.Member.send)することでできます。

## Intents問題
通知対象のdiscord idをdictで保管してます。
メッセージを受け取ったら、通知をするためにそのidからメンバーを取得します。

しかし、最初は、このintentsを設定していなかったため、メンバーを取得できませんでした。

二時間くらいかけて、解決

```py
intents = discord.Intents.all()
client = MyClient(intents=intents)
```
こいつをclient.run()の前に追加してあげると、解決

## Herokuにデプロイしよう！

https://qiita.com/1ntegrale9/items/aa4b373e8895273875a8

こんな記事があります。

requirements.txtに、discord.pyと書いてあるので、py-cordに書き換えましょう

```diff:requirements.txt
- discord.py[voice]>=1.7.3
+ py-cord>=1.7.3
```

バージョンはお好みで

デフォルトのPythonのバージョンは3.8.5なので、気に入らない人は、
`runtime.txt`
を書き換えましょう。

# 各種URL

- [招待URL](https://discord.com/api/oauth2/authorize?client_id=915404382189785109&permissions=68608&scope=bot)
- [Github リポジトリ](https://github.com/sas08/notificator)
- [py-cord Github リポジトリ](https://github.com/Pycord-Development/pycord)
- [Discord BotをHerokuに上げるQiita記事](https://qiita.com/1ntegrale9/items/aa4b373e8895273875a8)

# 最後に

楽しかった。

少し改良して、特定の人が送信したメッセージだけ送信したり、通知メッセージにチャンネルへのリンクを埋め込んだり、他人の通知を強制的にonにするいたずらをしたり、、、
夢がありますね！

また、次の記事で会いましょう ﾉｼ
Winter '21リリースのロールアウトによる単一のプロセスとして、パスワードをリセットしてユーザーの電子メールアドレスを更新することはできません。


別々に変更しなさいということかな？

https://help.salesforce.com/s/articleView?id=000354956&type=1


この設定変更の影響でこれもできた？
[新しいパスワードを生成し、すぐにユーザーに通知する」を使用しながらセルフサービスユーザーを有効にする](https://help.salesforce.com/s/articleView?id=000327818&type=1)

[Securely Update Email Addresses and Reset Passwords](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000E9UhASAV)