OmniAICreator/Qiita-1.07M huggingface dataset:
Dell 製品での PC の BIOS ( というか UEFI ) を Update したいが、バッテリーが消耗していてできない場合の対処法

# What is this

よく忘れるのでメモ
たまにしか使用しないくせに探し出すのがとても大変なので

出典は以下の URL

https://www.dell.com/support/kbdoc/en-us/000134938/forcing-a-bios-update-without-the-ac-adapter-attached-on-a-dell-laptop

# Summary

BIOS のアップデートプログラムを入手し、管理者権限で 　`<アップデータ.exe> /foceit` を実行

# 問題点

Dell の Laptop PC の BIOS を Update する際には、バッテリー残量が 10% 以上残っている必要があります。 
しかし、一応使える形で PC を廃棄したい ( ≒ 予備用 PC として保持したい ) 場合、バッテリーがヘタっているとバッテリー残量が 0% とか 255% とかで表示され、そのままでは BIOS の Updater が実行できません。

大抵の場合 BIOS を Update する意義はほとんどありませんでしたが、最近は脆弱性に対応する BIOS Updater がよく提供されています。ただ、バッテリがヘタっている PC でカテゴリが「重大」な BIOS Updater があると、Dell Support Assist や Dell Command Update でいつまでも消えない更新プログラムが残り続けます。それがなんとも嫌。

BIOS Updater は Windows Update でも提供されている場合があるのですが、なぜか Windows Update 経由で Update しても Dell Support Assist はうまく認識してくれない ( ≒ インストールを求める )  ようです。

# Details

今回の例として、(Dell) OptiPlex 3070 Small Form Factor を例とします。

1\. Dell のサポートサイト ( ドライバおよびダウンロード ) にアクセス

https://www.dell.com/support/home/ja-jp?app=drivers

2\. 「製品の自動検出」か、「製品の識別」で Service Tag 等を入力
　今回は OptiPlex 3070 Small Form Factor が検出された、とします。

3\. BIOS Updater の入手

　「<製品名> 用のドライバーおよびダウンロードの完全なリストにアクセスします」をクリック
  「<製品名> システム BIOS」という欄があるので、「ダウンロード」をクリックしてダウンロード
  今回の場合、OptiPlex 3070 Small Form Factor 用の BIOS Updater として「Dell OptiPlex 3070システムBIOS」が表示されます。
  ダウンロードされたファイル名は　OptiPlex_3070_1.24.0.exe でした。
  ※ Laptop じゃねえ、とは思いますが、今回はあくまでも一例として紹介。

4\. 管理者権限でコマンドプロンプトを起動

　Windows 10 / 11 ならば、「Windowsロゴキー」+「R」で「ファイル名を指定して実行」のダイアログが表示されます。
 「名前」の欄に "cmd" と入力後、「Ctrl」+「Shift」+「Enter」で UAC が表示されるので、「Windows コマンドプロンプト」であることを確認後、「OK」をクリック

 5\. BIOS Updater を起動
 
 　大抵の良い子の SE さんなら「ダウンロード」フォルダに落ちているはずです。
  Windows 11 であれば、右クリックして表示される Popup menu に「パスをコピー」というメニューがあるので、それをクリック
  コマンドプロンプトにパスを貼り付けた後 `  /forceit` を追記して実行します。
  なお、Deskop PC の BIOS Update でも `/forceit` オプションは実行できました。

 # 注意点
 
 BIOS Updater を実行する際には、電源がきちんと刺さっていることを確認しましょう。
 それをやらないと文鎮化します。
コードエディタCursorをコマンドに割り当てる

最近コードを書くのにCursorを使用している。
以前はVscodeを使っていたが便利すぎて戻れない。

ただ自分が使用している環境がKubuntu22.04であり、Cursor自体はAppImageで落ちてくるのでそのままではダブルクリックして実行しなければいけないというなんだか悲しいことになる。Vscodeみたいにコンソールから``code .``というような具合にしたい。

頻繁に再セットアップをするので忘れないように手順を書く。

## bashシェルでのエイリアスの作成方法
1. ホームディレクトリにてviで`.bashrc`を開く。
    ```bash
    vi ~/.bashrc
    ```
    <br>
2. ファイルの最後に以下の行を追加します。
    ここで、`your_command`は任意のコマンド名に、
    `/path/to/YourApp.AppImage`は    AppImageファイルへのパスに置き換えてください。
   
    ```bash
    alias your_command='/path/to/YourApp.AppImage'
    ```

   今回はCursorなので自分の場合はcursorにしました。
    <br>
3. 変更を保存してファイルを閉じます。
    <br>
4. 最後に、以下のコマンドを実行して`.bashrc`の変更を反映します。

    ```bash
    source ~/.bashrc
    ```
    
これで、任意のコマンド名をターミナルで入力すると、AppImageアプリケーションが起動します。
WinSCPを使用してrootファイルを安全に編集する方法




## 概要
この記事では、WinSCPを使用してAWSなどのサーバー上のrootファイルを編集する手順を説明します。
AWSのインフラエンジニアとして、この方法は特に有効です。

## 必要な前提知識
- 基本的なLinuxコマンド
- AWSの基本的な知識（特にEC2インスタンスに関連するもの）
- WinSCPの基本的な使用法

### ステップ1: sudo権限の設定
まず、サーバにsudo権限を持つユーザーが必要です。
これを設定するには、以下の手順を実行します。

1. サーバーにSSHでログイン
2. `sudo visudo` コマンドを実行
3. visudoエディタが開いたら、以下の行を追加
   ```
   ユーザー名    ALL=NOPASSWD:    sftp-serverのパス
   ```
   例:
   ```
   ec2-user    ALL=NOPASSWD:    /usr/libexec/openssh/sftp-server
   ```

:::note warn
注意
ここで指定するsftp-serverのパスはサーバーによって異なる場合があります。
パスが不明な場合は、サーバーで `cat /etc/ssh/sshd_config | grep sftp` を実行して確認できます。
:::


### ステップ2: WinSCPの設定
WinSCPでrootファイルを編集するには、以下の手順に従います。

1. WinSCPを開き、対象のサーバーの編集
2. 高度なサイト設定画面が表示されたら、左側のメニューから `[環境]` -> `[SFTP]` を選択
3. 右側にある「SFTPサーバ」欄に、先ほど設定したsftp-serverのパスの前に `sudo` を付けて入力

   例:
   ```
   sudo /usr/libexec/openssh/sftp-server
   ```

## 結論
以上の手順に従って設定すれば、WinSCPを使用してサーバー上のrootファイルを安全かつ効率的に編集できます。
この方法は特にAWS環境での作業に有効ですが、他のLinuxベースのサーバーにも応用可能です。
AWS DBS備忘録






## RDS
#### リードレプリカ
〇リードレプリカを持つDBインスタンスを停止したい場合

→リードレプリカを削除したのち、DBインスタンスを停止させます。**リードレプリカを持ったままDBインスタンスは停止できません。** 

https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_StopInstance.html

#### ポイントインタイムリカバリ（PITR）
〇ポイントインタイムリカバリを有効にしたい場合

・自動バックアップを設定する必要があり
→バックアップ保持期間を0以外に設定する。

→その上で以下の設定が必要。
【MySQL】…バイナリログ記録（バイナリロギング）を有効にする。




## Aurora MySQL DB 
#### ■ 最大接続数（max_connections）
〇最大接続数（max_connections）を増やしたい場合

DBクラスターへの接続が多い場合、接続エラーが起きる場合があります。
インスタンスクラスによって最大接続数のデフォルト値が決まっているため、それ以上の接続を受け付けたい場合は、**このインスタンスをメモリ量のより多いDBインスタンスクラスにスケールする**ことで最大接続数を増やすことができます。
別の言い方だと、**インスタンスサイズを大きくする**必要があります。

また、接続制限のデフォルトをカスタマイズする新しいパラメータグループを作成することによって、最大接続数を増やすことも可能？


https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Managing.Performance.html


## DynamoDB

#### ■ グローバルテーブル

複数リージョンにまたがるマルチマスタのデータベース
データの変更が各レプリカへ自動レプリケートされるため高可用性が担保される。
災害対策などにも用いられる。

グローバルテーブルを構築後、各テーブルのポイントインタイムリカバリーを有効にすることで、数分での復旧時間目標（RTO）・復旧ポイント目標（RPO）を確保できる。


#### ■ DAX
〇リクエストの処理方法

・リクエストが**結果整合性**（デフォルト）
→DAX内に該当の項目がある場合（キャッシュヒット）、DynamoDBにはアクセスせずにアプリケーションに応答を返します。
　
→DAX内に該当の項目がない場合（キャッシュミス）、リクエストをDynamoDBに渡し、DynamoDBからの応答を受信後、アプリケーションに応答を返します。
同時にDAX内にキャッシュとして保持します。

・リクエストが**強力な整合性**
→そもそもDAX内でキャッシュを保持することをしないので、リクエストをそのままDynamoDBに渡し、DynamoDBからの応答を受信後、アプリケーションに応答を返します。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DAX.concepts.html


#### ■ IAM

アクセス制御を問われている場合は基本的にIAM関連の問題。

〇外部アプリケーションが特定のパーティションキー値にアクセスしたい場合
「dynamodb:LeadingKeys条件キー」
→ユーザーが特定のパーティションキー値を持つ項目にアクセスできるようにします。



https://repost.aws/ja/knowledge-center/dynamodb-table-restrict-attributes

#### TTL

・TTL 属性の値は、Number型であることが必須。
ほかのBinary型やString型を設定してもTTLは機能しない。

・TTL 属性の値は、Unix エポック時間形式のタイムスタンプ (秒単位) である必要があります。

・有効期限は5年以上前の値に設定すれば、無期限となりTTLでの削除はされなくなります。はるか未来日を設定して実質的な無制限を設定するよりも、0を設定したほうが簡単かつ値の間違いなどがなく安心です。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/time-to-live-ttl-before-you-start.html


## 暗号化

どのDBにおいても、構築または移行後に暗号化の設定で有効化・無効化することはできません。

〇暗号化したいDBがある場合

【[RDS](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/USER_CopySnapshot.html "DB スナップショットのコピー")、[Aurora](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Overview.Encryption.html#Overview.Encryption.Limitations "Amazon Aurora DB クラスターの暗号化")、】
①　暗号化したいDBインスタンスのスナップショットを作成

②　そのスナップショットのコピー作成時にオプションで「暗号化を有効化」を設定し、KMS暗号化キーを指定してコピー

③　コピーしたスナップショットから新しいDBインスタンスとしてリストア

【[DocumentDB](https://docs.aws.amazon.com/ja_jp/documentdb/latest/developerguide/encryption-at-rest.html#encryption-at-rest-limits "Amazon DocumentDB クラスターで保管時の暗号化を有効にする")】
①　暗号化したいDocumentDBクラスターのスナップショットを作成

②　スナップショット保管時にオプションで「暗号化を有効化」に設定

③　リストア時にKMS暗号化キーを指定し、暗号化されたクラスターとして新規に作成

【[DynamoDB](https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/encryption.howitworks.html "保管時の DynamoDB 暗号化")】

デフォルトでKMS暗号化キーによる暗号化が実施されている。
復号は透過的に行われているため、そこについての使用者の意識はあまりない。

## AWS Backup

最短で**1時間ごと**にバックアップを自動取得可能

## 移行

〇100TB規模のデータ移行を行う場合

・AWS DMS＋AWS Snowball Edge端末2台が安心して移行できる
→ネットワーク経由でも可能（VPN経由）だが、ネットワーク帯域幅の問題で移行期限に間に合わないことがある。
高校生がAWSの試験を受けに行ったら失格になりかけた話

# 言いたいこと

:::note info
未成年のみんな！
AWSの認定試験に行くときは未成年の申込みだけでなく同意書もテストセンターに持っていこうな！
:::

# なんで起こったの？

https://aws.amazon.com/jp/certification/faqs/

このサイトを確認して未成年の手続きを済ませたんですよね...
同意書もメールで送信してあとはテストを受けるだけ！
そう思っていた時期が私にもありました。

サイトにも返信のメールにも身分証を持って来いという文言しかなく
安心していた僕は同意書を持っていかなかったのです。
今思うと一応で持っていくだけで済んだのに。

# それからどしたの

テストセンターに開始20分前に到着したあと手続きを開始しました。
順調に進む中「もしかして未成年ですか？」と受付の方からの一言。
自分はサイトをしっかり確認して予習していたので

- 親の身分証明書
- 子供の身分証明書

この2つを意気揚々と出しました。大丈夫これで通ると思った束の間
「同意書はお持ちでしょうか？」

メールで同意書を送信済みでかつサイトにも載っていなかったのでいらないと思ってました...
すると受付の方はAWSの方に電話をかけ重苦しい雰囲気が漂います。
「はい、はい、はい...　そうですか わかりました...」

＼(^o^)／ｵﾜﾀ

終わった... 車で2時間かけてきたのに...
絶望して受付の方の声に耳を傾けたら

「今回はメールで送信済みで画像も確認できたので 特例 で受験を可能にします。」

なんと今回だけ許されました！
危なかった :innocent:

# 結末

受験後10時間後には結果が見れてました。
結果は...

🎉 SAA合格 🎉

高校生でクラウドを使える人が少ないので自分が引っ張っていきたいですね！
ワンピース (One Piece) と呪術廻戦 (Jujutsu Kaisen)：日本の人気アニメと漫画の魅力

ワンピースと呪術廻戦は、日本のアニメや漫画の世界で非常に人気のある作品であり、多くのファンを魅了しています。それぞれ異なるストーリー、キャラクター、そして独自の魅力を持っているこれらの作品は、日本国内だけでなく、世界中で高い評価を得ています。

この記事では、ワンピースと呪術廻戦の基本的な情報や魅力、そして日本のアニメや漫画文化における彼らの重要性について探っていきます。

<h2>ワンピース</h2>

ワンピースは、尾田栄一郎によって創作された長寿の漫画シリーズであり、1997年から連載がスタートしました。物語は、主人公モンキー・D・ルフィが、伝説の宝である「ワンピース」を手に入れ、海賊王になるという夢を追い求める冒険を描いています。ワンピースは、世界中で最も売れた漫画の一つであり、アニメ化もされています。

ワンピースの魅力の一つは、その巧妙な世界観とキャラクターデザインにあります。多くの種族や国々が存在する広大な海域を舞台に、様々な冒険や戦いが展開されます。また、登場人物たちの成長や友情、仲間たちとの絆など、感動的なストーリーが多くの読者や視聴者を引き込んでいます。

さらに、ワンピースは社会や政治に対するメッセージを含んでおり、物語を通じて様々なテーマに触れています。友情や冒険だけでなく、正義や悪、戦争、差別など、深いメッセージが散りばめられています。これらの要素が<a href="https://xn--raw-3r6gu2x.net/category/one-piece-raw">ワンピースRaw</a> を単なる冒険漫画を超えた作品へと昇華させています。

<h2>呪術廻戦</h2>

<a href="https://xn--raw-3r6gu2x.net/category/jujutsu-kaisen-raw/">呪術廻戦 Raw</a> は、芥見下々によって創作された漫画で、2018年に連載が始まりました。物語は、呪いと呼ばれる怪異な存在と戦う呪術師たちを描いており、主人公虎杖悠仁が友人の死をきっかけに呪術師の道に進む姿が中心となっています。呪術廻戦もまた、非常に人気があり、アニメ化も成功しています。

呪術廻戦の魅力の一つは、その独特でダークな世界観と、キャラクターたちの戦いにあります。呪いという未知の力に立ち向かう呪術師たちの姿勢や、彼らが抱える過去や葛藤などが、物語に深みを与えています。また、戦闘シーンは非常に派手で迫力があり、読者や視聴者を引き込む要因となっています。

呪術廻戦はまた、現代日本の文化や風習を上手に取り入れており、それが作品のリアリティを増しています。学生たちが巻き込まれる戦いや、呪術師たちが巧妙な術を駆使する様子は、読者にとって親しみやすく、同時に新鮮な印象を与えています。

  <h2>ワンピースと呪術廻戦の共通点</h2>

ワンピースと呪術廻戦は、ジャンルやストーリーが異なるものの、いくつかの共通点を持っています。まず、どちらも主人公が成長していくというテーマが共通しています。ワンピースではルフィが海賊王への夢を追い求め、呪術廻戦では悠仁が呪術師としての力を身につけていきます。成長のプロセスやそれに伴う困難に直面する姿勢が、読者や視聴者に感動を与えています。

また、仲間や友情の重要性も両作品で強調されています。ワンピースではルフィが仲間たちと共に冒険し、様々な試練を乗り越える姿勢が描かれています。呪術廻戦でも悠仁が仲間たちと協力して強大な敵と戦う様子が、作品に熱いドラマを与えています。

さらに、ワンピースと呪術廻戦は、物語の中で様々なメッセージやテーマを掘り下げています。ワンピースでは正義や仲間との絆、平和の重要性が語られ、呪術廻戦では生死や人間の弱さと向き合うことの意味が描かれています。これらの深いテーマが作品を通じて伝えられることで、読者や視聴者は単なるエンターテインメント以上の価値を見出しています。

<h2>日本のアニメと漫画文化への影響</h2>
 
ワンピースと呪術廻戦は、日本のアニメと漫画文化において重要な位置を占めています。日本国内外で多くのファンを持ち、両作品は数々の賞を受賞しています。その影響は単なるエンターテインメントにとどまらず、日本のアニメや漫画が持つ表現力や深いメッセージを広く知らしめる一翼を担っています。

ワンピースは特に、その長寿の連載と成功したアニメ化によって、日本のみならず世界中にその名を知らしめました。キャラクターたちの個性的なデザインや、冒険の先に待ち受ける謎めいた宝「ワンピース」への探求心は、多くのファンを引きつけています。また、ワンピースの成功は、長期にわたる物語やキャラクターの成長を描くことができるアニメや漫画の可能性を広げ、他の作品にも影響を与えています。

呪術廻戦は比較的新しい作品でありながら、その独特なストーリーと迫力あるアクションが若い読者や視聴者に支持されています。ワンピースと同様に、呪術廻戦も日本のアニメや漫画が持つ幅広い表現力を示し、異なるジャンルやテーマ性を探求する作品が多様なファン層に受け入れられる可能性を示しています。

<h2>結論</h2>

ワンピースと呪術廻戦は、日本のアニメと漫画文化において特筆すべき存在であり、両作品は多くのファンに愛されています。それぞれ異なる世界観やストーリーを持ちながら、成長や仲間との絆といった共通のテーマを掲げ、深いメッセージを伝えています。また、両作品は日本国内外で高い評価を受け、アニメや漫画の表現力の幅を広げる一助となっています。

ワンピースと呪術廻戦の成功は、単なるエンターテインメントを超えて、物語やキャラクターを通じて伝えられるメッセージや価値に読者や視聴者が共感していることを示しています。これからも、日本のアニメと漫画は新しい才能やアイディアによって進化し続け、世界中の人々に感動と興奮を提供していくことでしょう。

https://ko-fi.com/davidsmith35284
https://www.quora.com/profile/David-Smith-15862
https://community.cisco.com/t5/switching/port-aggregation-etherchannel/td-p/682554
https://rawmanga4.wordpress.com/
https://vocal.media/authors/raw-manga
https://community.fabric.microsoft.com/t5/user/viewprofilepage/user-id/676587
https://coub.com/raw-manga
https://starity.hu/profil/420771-rawmanga/
https://www.pinterest.jp/rawmanga123/
https://community.windy.com/user/david-james-12
https://issuu.com/mangaraw1
https://form.jotform.com/rawmanga9/manga-raw-
https://anyflip.com/homepage/xkzkv
Polars の `DataFrame.plot` を Google Colaboratory で動かす

[Polars 0.20.3](https://github.com/pola-rs/polars/releases/tag/py-0.20.3) で `DataFrame.plot` が追加されました 🎉

2024-01-23現在、Google Colaboratory で動かすには細工が必要だったのでメモを残します。
これをやらないと一回目の `DataFrame.plot` ではグラフが表示されるのに二回目は表示されないです。

# コード

```py
%pip -q install -U hvplot holoviews

def _render(self, **kwargs):
    # https://github.com/holoviz/holoviews/issues/3551#issuecomment-578394636
    import holoviews as hv
    hv.extension("bokeh")  # type: ignore
    return hv.Store.render(self)

__import__("holoviews").core.Dimensioned._repr_mimebundle_ = _render
```

```py
%pip -q install -U polars[numpy,plot]
import numpy as np
import polars as pl

df = (
    pl.DataFrame({"x": np.linspace(0, 2 * np.pi)})
    .with_columns(
        y=np.sin(pl.col("x")),
        日本語も使える=np.cos(pl.col("x"))
    )
)

df.plot(x="x", y=["y", "日本語も使える"], subplots=True).cols(1)
```

![bokeh_plot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64912/7ea305c9-6a5f-01e4-c681-61fc1b19c3d9.png)

# なんでなん

セキュリティ上の都合ならしゃーない

https://github.com/holoviz/holoviews/issues/3551

https://github.com/googlecolab/colabtools/issues/967
Google Apps Script と LINEを使ったオウム返しBotの作成方法

オウム返しBotは、入力されたメッセージをそのまま返すシンプルなBotです。この記事では、Google Apps Script (GAS) と LINEを使用して、10分程度でオウム返しBotを作成する方法をご紹介します。LINE botの基本設定は、[こちらのリンク](https://hamaruki.com/how-to-easily-and-completely-free-create-a-parroting-bot-using-line-bot-and-google-colab/) にて詳しく説明しています。

https://hamaruki.com/how-to-easily-and-completely-free-create-a-parroting-bot-using-line-bot-and-google-colab/


## はじめに 

オウム返しBotを作成する前に、LINEでチャネルアクセストークンを生成し、GASのスクリプトプロパティに設定する必要があります。これにより、BotとLINEプラットフォーム間の認証が可能になります。
## LINEでチャネルを設定する 

LINE Developersコンソールにアクセスし、新しいプロバイダとチャネルを作成します。

https://developers.line.biz/ja/

![file](https://hamaruki.com/wp-content/uploads/2024/01/image-1705997078956.png)

ここでチャネルアクセストークンを生成し、後で使用するためにメモしておきましょう。

![file](https://hamaruki.com/wp-content/uploads/2024/01/image-1705997138900.png)

## Google Apps Scriptを設定する 

Googleドライブに新しいスクリプトファイルを作成し、必要なコードを記述します。LINEからのリクエストを処理し、返信するための基本的な機能を実装します。

![file](https://hamaruki.com/wp-content/uploads/2024/01/image-1705997165629.png)

## スクリプトプロパティにトークンを設定する 

GASのスクリプトエディタから、[ファイル] > [プロジェクトのプロパティ] > [スクリプトプロパティ]にアクセスし、ステップ1で生成したチャネルアクセストークンを設定します。

![file](https://hamaruki.com/wp-content/uploads/2024/01/image-1705997205357.png)

## Webアプリとしてデプロイ 

スクリプトをWebアプリケーションとしてデプロイします。

![file](https://hamaruki.com/wp-content/uploads/2024/01/image-1705997241245.png)

この辺りはこちらのサイトで詳しく解説してます。

https://hamaruki.com/create-with-google-apps-script-gpts-actions-api-that-returns-the-dish-name-from-the-dish-number/

LINE DevelopersコンソールにそのURLをWebhook URLとして設定します。

![file](https://hamaruki.com/wp-content/uploads/2024/01/image-1705997338241.png)

## Botのテスト 

全ての設定が完了したら、LINEアプリからBotにメッセージを送信して、正しくオウム返しが行われるかをテストします。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">Google Apps Script と LINE（Messaging API）を使ったオウム返しBot作ってみました！！ <a href="https://t.co/sNmgxjDFll">https://t.co/sNmgxjDFll</a> <a href="https://t.co/Ld2RWwbCuE">pic.twitter.com/Ld2RWwbCuE</a></p>&mdash; Maki@Sunwood AI Labs. (@hAru_mAki_ch) <a href="https://twitter.com/hAru_mAki_ch/status/1749708467441717323?ref_src=twsrc%5Etfw">January 23, 2024</a></blockquote> 

## まとめ 

以上が、Google Apps Script と LINEを使ったオウム返しBotの作成方法です。このシンプルなプロセスを通じて、LINE Botの基本的な構築方法を学ぶことができます。この知識を基に、さらに高度なBotを開発することも可能です。興味がある方は、ぜひ挑戦してみてください。


## 参考サイト

https://tech-lab.sios.jp/archives/33512

https://tetsuooo.net/gas/1101/

<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Thymeleafをちょっとだけまとめてみた


SpringでWebアプリケーションを開発するにあたって
Thymeleafというテンプレートエンジンを使っています。
こちらについてまとめました。

# 1. Thymeleafについて

既に書きましたがSpringで主流のテンプレートエンジンです。
Laravelでいうbladeみたいなものです。
公式サイトでは日本語対応しています。やさしいですね。

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf_ja.html

# 2. コードを見てみる

```html:Thymeleaf

<p th:text="${message}"></p>
<table border="1">
　<tr>
    <th>名前</th>
    <th>年齢</th>
　</tr>
　<tr th:each="user : ${users}">
    <td th:text="${user.id}"></td>
    <td th:text="${user.name}"></td>
    <td th:text="${user.age}"></td>
　</tr>
</table>
  
```

HTMLでは見慣れない「th」や「"$~~~~"」などの記述がみられます。
これらはサーバから受け取ったデータを出力する場所になります。
${message}ではコントローラで以下のコードを動かすことで

```java:java
model.addAttribute("message", "タイムリーフ");
```

このように表示されます！

![tmp.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3495456/be2e50da-a1e6-95c1-20a7-f1e8f73314d0.png)


このようにしてサーバからの情報を画面上に表示することができます。
そして実際の自社開発でもこのような方法で画面上にDB上から抽出した情報を表示しています。

なによりすっごく簡単です。
画面に情報を渡す、画面上に受け取った情報を表示する、
これらは上記にあるように書くだけで実装することができます。

Thymeleafに限った話ではありませんがテンプレートエンジンは偉大です。
Web開発の味方。


# 3. Thymeleafを使えるようにする

ここではWeb上でSpringプロジェクトを作る方法から進めます
Eclipceからでもプロジェクトを作成できるらしいですが自分で試したことが無いので割愛

↓にアクセスすると

https://start.spring.io/

↓のような画面が表示されます。
画面上左上の「ADD DEPENDENCIES」を押下

![キャプチャspring.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3495456/ea7473d2-1408-d964-01d4-5b6eac213585.png)

↓検索用の画面が表示されるので「Thymeleaf」と検索し、結果を押下する

![thy.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3495456/c8881876-257a-dba5-37fb-f0284e25bb90.png)

↓そうするとこれから作られるSpringプロジェクトでThymeleafを使うとことができます！

![init.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3495456/f362948c-be41-e94b-38e9-8c13cfde4966.png)

# 4. もうちょい深堀してみる

Thymeleafの主な属性をまとめてみました！
（ちゃっかり個人的なメモの役割も果たしている）



| 属性名 | 詳細 |
| --- | --- |
| th:each | ループを作成してリストや配列の各要素を処理する |
| th:if, th:unless | 条件に基づいて要素を表示または非表示にする |
| th:object | フォームのバインディングオブジェクトを指定する |
| th:text | 要素のテキストコンテンツを設定する |
| th:src, th:href | 画像やリンクのソースやリンク先を設定する |
| th:attr | HTML属性を設定する |
| th:class, th:id | 要素のクラスやIDを動的に設定します |
| th:style | 要素のスタイルを設定する |

https://qiita.com/opengl-8080/items/eb3bf3b5301bae398cc2#%E5%BC%8F%E3%81%AE%E6%A7%8B%E6%96%87

↑の記事ですがタイトルにあるようにThymeleafの使い方が綺麗にまとめられています。
めっちゃ感謝です。これからの開発に重宝する予定です！！

# 5. 終わりに

テンプレートエンジンはWeb開発するにあたって必須（だよね！？）なのでしっかり身に付けようと思います。

# 6. 予告
次回の投稿は2月2日の予定です！
Googleでのログインについて書こうかな
【Publisher】Easy! Let's publish Excel reports on the web browser

# Introduction #
Have you ever wished to directly publish a report created in Microsoft Excel on an intranet or the internet? It seems that Sharperlight has added such functionality, so I would like to give it a try promptly.

# Creating a Report in Excel #
I have posted an article for creating a report with Sharperlight Excel Add-in before [[↗]](https://qiita.com/Miki_Yokohata/items/4e8b3cd5200281cef61e/) so please have a look it and prepare a Excel report for publishing. 



# Publish Excel Report #
Click on the "Publish Workbook" icon in the Sharperlight ribbon.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/b3fde821-405d-4ddf-51f2-f5d9e9e6724e.png)
The Web Report Definition dialog will appear.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/b69d46bb-8978-c7dc-6a11-20e88fe9ceb5.png)
Modify the **Code** and **Group** to your preferred values.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/a80d1df6-153f-16d5-f3d8-41689cccf8a6.png)
First, click the **Apply** button to save the definition. Then, click the **View** button to preview the report in the browser.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/d82d1028-9d84-82a7-928d-32cf41ba9e6c.png)
If the Sharperlight service is already running, a web report like this will be displayed. It's well-suited for immediate publication to various departments within the company, especially in an intranet setting. Of course, with appropriate configurations for Sharperlight service and user settings, it can also be made accessible to the public.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/33af3c3a-02cd-6da4-abe1-c9aa1cc28e64.png)
When you modify the parameters,...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/6001e954-e6de-9ce9-a0f0-466a0235ef27.png)
...the result is immediately updated.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2530698/d3d5e678-079b-740d-3ae2-61f3c320d79e.png)

# Conclusion #
Isn't this a solution to the inconvenience of reusing valuable Excel reports stored individually on each computer and the challenges of file sharing when there is a need for centralized management of reports?
AWS CLIインストール手順

# はじめに
Amazon LinuxではデフォルトでAWS CLIがインストールされていますが、他のOSでは手動でのインストールが必要なものもあります。今回は新規にAWS CLIをRHEL8にインストールする手順を記載します。

# 目次
- curlコマンドでawscli2.zipダウンロード
- zip、unzipをインストール
- awscli2.zipを解凍
- 解凍したawscli2を実行してインストール
- バージョン確認

# 手順
1.以下コマンドを実行してawscli2.zipをダウンロードしてください。
```
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
```

2.以下コマンドを実行してzip、unzipパッケージをインストールしてください。
```
sudo dnf install zip unzip
```

3.以下コマンドを実行してawscli2.zipファイルを解凍してください。
```
unzip awscliv2.zip
```

4.以下コマンドを実行してAWS CLIをインストールしてください。
```
sudo ./aws/install
```
5.以下コマンドを実行して、正常にインストールできていることとインストールされているバージョンを確認してください。
```
aws --version
```

# 参考URL
[AWS CLI の最新バージョンを使用してインストールまたは更新を行う](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/getting-started-install.html)
AWS Identity Center へのプロビジョニングで SystemForCrossDomainIdentityManagementServiceIncompatibleFiltering が発生した場合の解決策について

## 環境

- IdP として Azure AD を利用している
- AWS Identity Center(旧 AWS SSO)で Azure AD を外部プロビジョニング元として設定している

## 起きた事象

- Azure AD で異なるドメインの外部ユーザを削除してしまった
- AWS Identity Center でも該当の外部ユーザが無効化された
- Azure AD 側で削除した外部ユーザを再招待し、外部ユーザを新規作成した
- AWS Identity Center へのプロビジョニング時に該当のユーザの新規作成に失敗し、SystemForCrossDomainIdentityManagementServiceIncompatibleFiltering というプロビジョニングエラーが発生した。
    - その結果、外部ユーザは AWS SSO だけ使えない、という状況が発生した

## 解決策

- AWS Identity Center 側で該当の外部ユーザを削除し、再プロビジョニングを行って該当のユーザを復活させた
    - 外部プロビジョニングを設定している場合、ユーザとグループを作成/変更することは出来ないが、削除することだけは可能である
    - AWS Identity Center では外部ユーザが削除された場合、該当のユーザを無効化する。無効化する際にはユーザ名(メールアドレス)を「hieki@example.com」から「a1b2c3d4e5hieki@example.com」のように Azure AD の Object ID を先頭にくっつけた状態に変更してから無効化する。
        - そのため、前方一致検索しか対応していない AWS Identity Center のユーザ一覧画面では、メールアドレスだけでは無効化されたユーザを検索する事が出来ない。ユーザ名ではなく、表示名で検索するのが望ましい。
        - ユーザ名を「hieki@example.com」から「a1b2c3d4e5hieki@example.com」に変更にしているのだから、「hieki@example.com」が復活した場合は「a1b2c3d4e5hieki@example.com」とは別のユーザとして扱って「hieki@example.com」を新規作成して欲しいが、どのような理由があるかはわからない(恐らくセキュリティリスクの都合だとは思う)がエラーになってしまう。


---
AWS Identity Center が外部ユーザをどのように扱うかについての情報が少なかったので記録しておく。
【Amazon SES】サプレッションリストからメールアドレスを削除する方法


### イントロダクション
Amazon SES（Simple Email Service）を利用する際、特定のメールアドレスがサプレッションリストに追加されることがあります。この記事では、SESのサプレッションリストからメールアドレスを削除する簡単な手順を解説します。

### サプレッションリストとは？
Amazon SESのサプレッションリストは、バウンスや苦情が報告されたメールアドレスが自動的に追加されるリストです。これにより、SESは不要なメール送信を防ぎます。

### アドレスをリストから削除する理由
サプレッションリストに追加されたアドレスへのメール送信はSESによってブロックされますが、誤って追加された場合や受信者が再度メールの受信を希望する場合、リストから削除することが必要です。

### 削除のステップ
1. **AWS マネジメントコンソールにログイン**：
   まず、SESを管理しているAWSアカウントでマネジメントコンソールにログインします。

2. **サプレッションリストの確認**：
   SESダッシュボード内でサプレッションリストにアクセスし、削除したいメールアドレスを探します。

3. **Eメールアドレスの削除**：
   削除したいメールアドレスを見つけたら、「Eメールアドレスの削除」ボタンをクリックして削除を行います。

4. **テストメールの送信**：
   削除が完了したら、該当のメールアドレスにテストメールを送信し、正常に配信されることを確認します。

### 注意点
- メールアドレスがサプレッションリストに追加された原因を理解し、再発防止のために送信プラクティスを見直すことが重要です。
- スパム規制やプライバシー法規への準拠を常に意識しましょう。

### まとめ
Amazon SESのサプレッションリストからメールアドレスを削除することで、重要なメールコミュニケーションを維持し、誤ってブロックされた受信者とのコミュニケーションを回復することができます。この簡単な手順に従うことで、効率的かつスムーズに問題を解決することが可能です。

---
Redashの大掃除をしたい時のメモ

Redashは放っておくとクエリがドンドン増えていきます。
それ自体が悪いことではなく、むしろ良い傾向だと思いますが、それが放置されているのは問題です。
クエリが探しにくくなることや、定期実行が増えることでRedashが詰まることは定期的な棚卸しで防ぎましょう。
この記事では、いくつかのポイントを紹介します。
なお、この記事はRedash v8で動作確認を行なっています。

## 直近実行されていないクエリを確認する

しばらく使われていない、もしくは閲覧されていないなどのクエリは管理の邪魔になります。

以下のクエリで直近1年以上使われていないクエリを確認できます。

```sql

SELECT queries.id AS query_id,
       queries.name AS query_name,
       data_sources.name AS data_sources_name,
       max(events.created_at) AS last_executed_at
FROM queries
INNER JOIN EVENTS ON queries.is_archived = FALSE
AND events.action = '{{view or execute}}'
AND events.object_type = 'query'
AND queries.id = cast(events.object_id AS integer)
INNER JOIN data_sources ON queries.data_source_id = data_sources.id
WHERE events.created_at <= now() - interval '1 year'
GROUP BY query_name,
         data_sources_name,
         queries.id
ORDER BY last_executed_at
```

このクエリを記述すると、以下の画像のようなテキストボックスが出ますが、viewだと過去1年以上閲覧していないクエリが、executeだと過去1年以上実行されていないクエリが確認できます。


![スクリーンショット 2024-01-23 15.48.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/359721/46725e68-5f70-9f68-7eb5-38d98bfe7a77.png)

がっつり使ってないクエリを掃除したいけど、UPDATE文で一気にやるのは怖い場合に検証としてお使いください。

## 定期実行を棚卸しする

Redashには定期実行の機能が存在し、ダッシュボードやクエリ単体で気軽に利用することができますが、増えてしまうとインスタンスのリソースを圧迫してしまいます。
また、BigQueryのような従量課金体型のデータソースの場合、余計なお金がかかってしまいます。
利用されなくなったら、都度定期実行を止めるのが理想ですが、それはなかなか難しいので、機会を見つけてまとめて掃除してしまいましょう。

詳細はエムスリーさんのこちらの以下の記事をご確認ください。
[年末だしRedashのクエリ棚卸しでもしましょう (調査用サンプルクエリ付き) - エムスリーテックブログ](https://www.m3tech.blog/entry/2023/12/09/110000)

## 利用されなくなったデータソースのクエリをまとめてアーカイブする

長くRedashを利用していると、何らかの理由で利用されなくなるデータソースが出てくることがあります。
これらのクエリはまとめてアーカイブしてしまいましょう。

```sql
UPDATE queries
SET is_archived = TRUE
FROM data_sources
WHERE queries.data_source_id = {{data_source_id}}
  AND queries.is_archived = FALSE
```

データソースの詳細ページのURLでIDは確認できる他、このようなクエリでも可能です。

```sql
select id, name, type from data_sources
```

なお、データソースを消す場合はゴミ捨て場のようなデータソースを作成し、以下のようなクエリでそちらに移してから行いましょう。
```sql
UPDATE queries
SET data_source_id = <移行先のデータソースID>
WHERE data_source_id = <移行元のデータソースID>;
```

もし移行せずに消してしまった場合クエリが一覧から見られなくなります。

もし消してしまった場合はこちらの記事を参考に復旧しましょう。
[RedashのData Sourcesを解除してQueriesが吹き飛んだときの対処 - VTRyo Blog](https://blog.vtryo.me/entry/redash-queries-restore)

## まとめ
Redashは冒頭にも書いた通り、何もしないとドンドンクエリが増えていき管理が難しくなっていきます。
定期的に見直しをして、快適なデータ分析・集計を行えるようにしましょう。
また、今回は厳選して3点のみ紹介しましたが、こういうのもするといいよ！というものはたくさんあると思うので、気軽にコメントで教えていただけたら幸いです。
右方向の配列への代入（Bash, Zsh）

# はじめに

　shellscriptで配列の末尾に、右方向への代入を用いて要素を追加する方法を述べる。

# 環境
PC: MacBookPro (2016)
bash: GNU bash, バージョン 5.2.26(1)
zsh: 5.8.1 (x86_64-apple-darwin21.0)

# 準備（zshの場合）

 　zshでは配列の先頭の配列番号は1である（0ではなく!）。それでは都合が悪いので、`setopt ksharrays`で配列番号が0から始まるようにする。

 　また、コードの一部がglob表現として認識されてしまうのか、「no matches found」というエラーが出るため、それを回避するために`setopt nonomatch`とする。

# コード（zshの場合）

　以下のようにすれば、右方向代入で、配列末尾に要素を追加できる。

 ```zsh
#!/bin/zsh
# 準備
setopt nonomatch
setopt ksharrays

#配列を準備
arr=(1 2)

#3をarrの末尾に加える
echo '3' | read -d '' arr[${#arr[@]}]

#全要素を確認
echo ${arr[@]} #結果: 1 2 3

#要素数を確認
echo ${#arr[@]} #結果: 3

 ```


# 準備（bash）の場合

　bashの場合はzshと異なり、配列番号は0から始まるので、zshの時のような操作は不要。

　ただし、bashはzshと異なり、最後のパイプもサブプロセスとなるため、そのサブプロセス内の変数をカレントプロセスから取り出せない。bashでもzshと同様の動作をさせるために`shopt -s lastpipe`を用いる。

　また、現在のmacのデフォルトシェルはzshであるためか、macのデフォルト（/bin/bash）のbashはバージョン「GNU bash, version 3.2.57」と古いバージョンである。上記の「lastpipe」機能はBash 4.2以降らしいので（ChatGPTより）、ここでエラーが出る。であるため、`brew install bash`で新しいバージョンをインストールしておく。インストールした新しいbashのパスは/usr/local/bin/bashであった。

# コード（bash）

```bash
#!/usr/local/bin/bash
# 準備
shopt -s lastpipe

# 配列を準備
arr=(1 2)

# 3をarrの末尾に加える
echo '3' | read -d '' arr[${#arr[@]}]

# 全要素を確認
echo ${arr[@]}

# 要素数を確認
echo ${#arr[@]}

```

#
Javaで標準入出力を利用して外部コマンドをフィルターとして利用する

# はじめに

Java言語で外部コマンドの呼び出しは出来れば避けたいものです。

今回は古いPostscriptファイルの内容をApache Solrに投げ込む必要があり、PDFに変換すればそれ以上の処理を追加する必要がないためGhostscriptパッケージに含まれる**ps2pdf**コマンドを利用することにしました。

検証のため、標準入力にtest.psの内容を書き込み、標準出力からデータを読み出した上でtest.pdfとして保存するコードを作成してみました。実際のファイル形式は*.ps.Zになっているためcommons-compressを利用してdecompressしたbyte配列で取得したPostscriptデータを標準入力に渡しています。

標準入出力では全てのデータをstdinに書き込んでからstdoutへの出力が初まるわけではありません。内部ではstdinに書き込みつつ、制御できないタイミングで発生するstdoutからの読み出し処理を同時に実行する必要があります。内部バッファに収まる程度にファイルサイズが小さければ問題ないかもしれませんが、実際のファイルサイズは小さくはないでしょうから多くの用途でThread化は必須と思われます。

Java言語もずいぶんと簡略化した記法を受け付けてくれるようになっているので、予想よりもずっと完結にコードを書くことができました。

# 作成した検証用コード

あらかじめ適当にa2psコマンドで作成したtest.psファイルを配置しておきます。

```java:Main.java(検証用コード)
import java.io.*;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world! (" + System.getProperty("user.dir") + ")");
        try {
            ProcessBuilder procbuild = new ProcessBuilder("ps2pdf", "-", "-");
            Process proc = procbuild.start();
            
            // save the output data as "test.pdf"
            new Thread(() -> {
                    try (InputStream inputStream = proc.getInputStream()) {
                        byte[] inbuff = new byte[4096];
                        int inByteSize;
                        FileOutputStream fos = new FileOutputStream("test.pdf");
                        while ((inByteSize = inputStream.read(inbuff)) != -1) {
                            fos.write(inbuff, 0, inByteSize);
                        }
                    } catch(Exception e) {
                        System.out.println(e.toString());
                    }
            }).start();
            
            // pass the postscript data to stdin
            new Thread(() -> {
                    try (OutputStream outputStream = proc.getOutputStream()) {
                        byte[] outbuff = new byte[4096];
                        int outByteSize;
                        FileInputStream fis = new FileInputStream("test.ps");
                        while ((outByteSize = fis.read(outbuff)) != -1) {
                            outputStream.write(outbuff, 0, outByteSize);
                        }
                        fis.close();
                    } catch(Exception e) {
                        System.out.println(e.toString());
                    }
            }).start();

            proc.waitFor();
        } catch(Exception e) {
            System.out.println(e.toString());
        }
    }
}
```

Threadを使うことで現実的なスピードで動作するようになりました。

# さいごに

Postscriptの処理は商用ライブラリでもネットワーク経由で処理を投げていたり、Javaコードだけで完結しているものはほとんどなさそうです。

Apache Tika 2.8.0以降ではMIMEタイプで"application/illustrator+ps"に対応していますが動作については確認していません。PDFに埋め込まれたEPSファイルの処理がメインのようなのでテキストの抽出は難しそうです。

Ghost4jはghostscriptライブラリへのC言語バインディングで、処理自体はghostscriptで実行されるため外部コマンドの呼び出しよりは細やかな制御が可能ですが、コマンド呼び出しと似たりよったりといった感じです。

無償で入手可能な手段を利用する前提では、ghostscriptを呼び出す方法以外に有力なものはないと思われます。

古いPostscriptの中にはghostscriptで正しく処理できないものがありますが、Adobe Acrobat Proの変換では印刷可能な形式には変換できている状態です。

最終的には古いPostscriptファイルはDistillerの監視フォルダに投入して自動変換する必要があるのかなと思っています。
VIVE Pro EyeのEyeTracking機能をUnityEditorで叩くとEditorが落ちる問題の対策

#その他に解決できる問題
SRanipalRuntimeの目が黄色（アイドリング）のまま動かない

# 解決法
VIVE Eye and Facial Tracking SDK最新版（v1.3.6.6）を使うな
VIVE Eye and Facial Tracking SDK 1.3.3.0を使おう
DLリンク：https://developer.vive.com/resources/vive-sense/eye-and-facial-tracking-sdk/download/archive/1_3_3_0/

# 動作環境
Unity 2019.4.39f1
SteamVR Plugin 2.7.3or2.8.0
Vive SRanipalRuntime Plugin 1.3.2.0

### 以上

# 参考サイト
https://qiita.com/RyoyaHase/items/024f3589547d1af84a92

https://qiita.com/RyoyaHase/items/5af948666a039d48a68d

# 追記
DLリンクが1.3.3.0なのは1.3.2.0がDLできなくなってたから

2024/07/25
Vive SRanipalRuntime Plugin 1.3.3.0がDLできなくなってるっぽい？
HTCさん…
VIVE SR Plugin (Unity)もDLできなさそう…？

ここから行けるっぽいが，
https://developer.vive.com/resources/downloads/
アクセスするとPage Not Foundを伝えてくる
https://developer.vive.com/resources/vive-sense/srworks-sdk/
もしくはOpenXRのページに飛ばされるので，OpenVR時代の環境だと動かせない可能性がある
https://developer.vive.com/resources/openxr/

# 追記2

VIVE Eye and Facial Tracking SDK 最新版はVIVE Setup でVIVE Pro Eyeを選択すると勝手に最新版がインストールされるっぽい
しかし，上記とおり，環境によってはエラーを吐くので、VIVE ProとしてDLするのが良いかも
（Unity最新版とかを使用できる環境であれば，エラーを吐かないかもしれないが，未検証）


# 追記3
VIVE Pro Eyeを研究で使用するなら，Unity 2021.2.19f1（2021.2系列）が安定でした このバージョンだけUnity 2021が必要なAPIと両立ができる（場合がある）
動作環境
SteamVR Plugin 2.7.3 or 2.8.0
Vive SRanipalRuntime Plugin 1.3.2.0
SlackにAPI経由でファイルをアップロードする(Python)

# 背景
- SlackにAPI経由でファイルをアップロードし、ユーザーにダウンロードさせたいケースです
- 既存のincoming webhook 経由ではファイルのアップロードできないようです

https://api.slack.com/legacy/custom-integrations/messaging/webhooks#additional-limitations

> *Please note: it's not possible to send files via webhook. The files.upload API method is the method of choice for this task.*

- Slackアプリを使ったfile uploadをpythonで実装していきます

# まずはSlack Appを作成
https://api.slack.com/start/quickstart

- こちらの手順通りに作成していきます
- ファイルのuploadをする場合は `files:write` の権限を付与することを忘れないようにしてください
- 作成の設定が面倒な場合は、以下のリンクページに用意されている `create app` ボタンから作成すると、デフォルトで色々な権限がついた状態でアプリを作成できるので楽です(※強めの権限なので注意してください)

https://api.slack.com/tutorials/tracks/getting-a-token

# File Uploadの実装
- TokenはSlackアプリの設定から取得できます
![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f31343035332f33346262633731372d313562622d613463382d383436362d3834333631636662663963612e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20307/95283638-0e2c-9cb1-da7d-916d83204285.png)

### 実装
```py
import requests

# Slack APIトークン
token = 'xoxb-xxxxxxxxxx'

# アップロードするファイルのパス
file_path = './hoge.csv'

# アップロード先のチャンネルID
channel_id = 'XXXXX'

# ファイルを開いてアップロード
with open(file_path, 'rb') as file:
    response = requests.post(
        url='https://slack.com/api/files.upload',
        headers={'Authorization': f'Bearer {token}' },
        data={'channels': channel_id},
        files={'file': file}
    )

# レスポンスの確認
print(response.text)

```

## API Reference

https://api.slack.com/methods/files.upload


## 参考
https://qiita.com/yaju/items/2e1ab8a25b6e207bfbe6
【React】オブジェクトにkey名と同じ変数をセットしたらエラーが出た

Youtubeを参考にTypeScriptを使ってReactのTodoアプリを作成していたところ、エラー`Expected property shorthand  object-shorthand`に遭遇した。
エラー：

原因は`handleSubmit`の`newTodo`で`inputValue: inputValue,`としているのがいけなかった模様。変数名がキー名と同じである場合、キー名を記入してはいけないらしい。

なおコードは以下の通り。
```App.tsx
const [inputValue, setInputValue] = useState('');

...

interface Todo {
  inputValue: string;
  id: number;
  completed: boolean;
}
  
...

const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
  e.preventDefault();
  const newTodo: Todo = {
    inputValue: inputValue,
    id: inputValue.length,
    completed: false,
  };
  setTodos([newTodo, ...todos]);
  setInputValue('');
};
```
参考：[エラー「Expected property shorthand object-shorthand」の対処方法](https://www.danroo.com/web/post-356/)
[シンプル] Window11でのPythonインストール

# Windows11でPython環境構築
自分用の記録として、PythonをWindows11でインストールする手順をまとめました。 
 2024/1/22現在の最新版である3.12.1をインストールしました。

### 使用したPCの情報
OS | CPU
-|-
Windows11 Home | Core i7 12世代

## ダウンロード
1. [Python公式サイト](https://www.python.org/)にアクセスする。
1. Downloadsから、Download for Windowsをクリックすると"python-3.12.1-amd64.exe"がダウンロードされる

## インストール
1. ダウンロードされた"python-3.12.1-amd64.exe"を実行するとインストーラが起動する。
1. インストーラの画面で、"add python to Path"にチェックを入れ"install now"を選択するとインストールが始まる。
1. インストールされたバージョンのPythonは、ホームディレクトリの\AppData\Local\Programs\Python\Python312に格納される。(AppDataは隠しフォルダなので注意)
ホームディレクトリ -> C:\Users\ [ユーザ名]のこと

## パスの確認
設定アプリを開き、システム->バージョン情報->システムの詳細設定->環境変数から確認できる。ユーザ環境変数にPython関連のパスが記述されてればOK

## 動作確認
Power Shellで、`python --version`を実行し、以下のようにインストールしたバージョンが出力されればOK！
```:output
Python 3.12.1
```
サイトを開いた時に前回の情報を元に表示する (localStorage)

## 1. やりたいこと


画面のスクロール位置や入力していた値などを記録しておいて、次回ページを開いたときに記録された情報を元に同じ画面を復元するようにしたい


## 2. 実現方法


方法としては以下の3つがあると思います
1. サーバー側でDBなどに記録する
2. cookieを使ってサーバーに情報を保持する方法
3. localStorageでユーザーPCのブラウザに保持してもらう方法

今回はセキュリティに関わらない情報を保存するので手軽に使えるlocalStorageを使います


## 3. localStorageについて


### 3-1. どういうものか


localStorageはhtml5から導入された<a href="https://developer.mozilla.org/ja/docs/Web/API/Web_Storage_API">Web Storage API</a>の機能です。Web Storage APIにはブラウザでページを閉じてセッションが終わるまでの間保持するsessionStorageと、永続的に保存されるlocalStorageの2つがあり、今回はセッション終了後も残っていてほしいのでlocalStorageを利用します


### 3-2. cookieとの違い


ログインしていないユーザーの情報を扱えるという点でcookieと似ている部分がありますが、サーバー側に情報を持つcookieとブラウザ側に情報を保存するWeb Storage API、容量が4kBしかないcookieと5MB持てるWeb Storage APIと位置づけがかなり変わるようです
https://zenn.dev/sjbworks/articles/cookie-webstorage


### 3-3. 容量の制約


Web Storage APIはオリジン単位で容量制限があり、これを超過して保存しようとするとQuotaExceededErrorが出て保存できません。また、ブラウザごとにサブドメイン単位での容量制限もあるのであまり大きい容量の情報を持つような使い方は想定されていないようです。最初から大きな容量を置かないようにするか削除しながら使うかになりますね
https://qiita.com/non_cal/items/b8a3779f93a252f0f796


### 3-4. 注意点


シンプルで便利なWeb Storage APIですが、JavaScriptからは置いてある情報が丸見えなので、XSS攻撃などによりJavaScriptがすり替えられると情報を奪われるリスクがありますのでセッション情報などのセキュリティに関わる情報は保存すべきでないと警告されています
https://techracho.bpsinc.jp/hachi8833/2019_10_09/80851


## 4. 使い方


使い方については以下のドキュメントに書かれています
https://developer.mozilla.org/ja/docs/Web/API/Storage


### 4-1. 保存する


```javascript:JavaScript
localStorage.setItem(keyName, keyValue)
```


### 4-2. 読み込む


当該keyNameで保存がない場合はnullが返ってきます


```javascript:JavaScript
localStorage.getItem(keyName)
```



### 4-3. 削除する


```javascript:JavaScript
localStorage.removeItem(keyName)
```


### 4-4. まとめて削除する


```javascript:JavaScript
localStorage.clear()
```


## まとめ


いろいろ注意点はありますが圧倒的に簡単です
問題のない用途も結構あると思うので、上手く使いたいと思います

レッツトライ
Draperの使い方：モデルがファットにならないようデコレーターを活用する

## gem draperをインストールする
gemfileにgemを記載
```
gem 'draper'
```

bundle installする（下記はdocker使用の場合）
```
docker compose run web bundle install
```
システムにデコレーター層を追加
```
rails generate draper:install
```
デコレーターのファイルを追加
```
rails generate decorator ○○(モデル名)
```

## モデル名_decorator.rbにコードを書く
```
lass UserDecorator < Draper::Decorator

 delegate_all

 def full_name
 "#{object.first_name} #{object.last_name}"
 end
end
```

## viewファイルに記述を加える
```
<%= current_user.decorate.full_name %>
```

※サーバーの再起動を忘れずに・・
【node】nodebrewでインストールできないverがあった話


# はじめに
普段nodeのバージョンはnodebrewで管理しているが、参加しているプロジェクトでv14.21.3を使っていたので、nodebrewでインストールしてみたらエラーになったので備忘録。


# いつものインストールの方法
いつもnodebrewでnodeをver指定してインストールするときは下記のコマンドでインストールする。
```
nodebrew install-binary v00.00.00
```

ちなみに現状インストールされているverを確認する方法はこれ。
```
nodebrew ls
```

しかし、下記のエラーが出てインストールできない。
```
Can not fetch: https://nodejs.org/dist/v14.21.3/node-v14.21.3-darwin-arm64.tar.gz
```

# 原因
M1macのようなarm64に対応していないバージョンのNode.jsはそのままだとインストールできないらしい。

# 解決方法
compileを使うとインストールできる！
```
nodebrew compile v00.00.00
```
ただinstall-binaryよりも時間がかかるので注意。
laravelでフォルダ内の動画を表示させたいが、動画を読み込めない。

laravelで動画投稿機能を実装しようとしています。
public/strage/videosディレクトリに保存した動画をビューで表示させたいのですが、
動画のウィンドウは表示されるものの、動画が読み込まれません。

検証ツールのコンソールを確認したところ、下記エラーが表示されていました。
GET http://localhost:8080/storage/videos/5.mp4 net::ERR_ABORTED 404 (Not Found)

解決法を教えていただきたいです。

```profile.blade.php
@foreach ($posts as $post)
    <video width="640" height="360" controls>
      <source src="{{ asset('storage/videos/'.$post->post_id.'.mp4') }}" type="video/mp4">
      Your browser does not support the video tag.
    </video>
@endforeach
```

```HomeController.php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Support\Facades\Auth;
use App\Models\PostsModel;
/**
     * プロフィール画面表示
     * return view
     */
    public function profile()
    {
        $user = Auth::user();
        $posts_data = new PostsModel();
        $posts = $posts_data->getPosts()->where('user_id', '=', $user->id)->all();//ユーザーIDで絞り込み
        // dd($posts);
        return view('TrickPost.profile', compact('user','posts'));
    }
```

```PostsModel.php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Http\Request;

class PostsModel extends Model
{
    use HasFactory;

    /**
     * 動画データを取得
     */
    public function getPosts(){
        //データベースの投稿データ取得
        $posts = DB::table('posts')->get();
        return $posts;
    }
}
```
ディープロPython3エンジニア認定基礎試験 解いてみた2

# ディープロPython3エンジニア認定基礎試験
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3663180/6d8a99fb-039a-0745-f48b-cfd0477915b8.png)

https://diver.diveintocode.jp/dive_into_exam/1/result/583515

## 間違えた問題の見直し

**1.Pythonの変数に関する記述として正しいものを選択肢から選びなさい。**
【正答】
関数内で変数に代入を行うと、その値がローカル変数のシンボル表に記録される

:::note info
解説
関数を 実行 (execution) するとき、関数のローカル変数のために使われる新たなシンボルテーブル (symbol table) が用意されます。もっと正確にいうと、関数内で変数への代入を行うと、その値はすべてこのローカルなシンボルテーブルに記憶されます。
一方、変数の参照を行うと、まずローカルなシンボルテーブルが検索され、次にさらに外側の関数のローカルなシンボルテーブルを検索し、その後グローバルなシンボルテーブルを調べ、最後に組み込みの名前テーブルを調べます。 従って、関数の中では (グローバル変数が global 文で指定されていたり、外側の関数の変数が nonlocal 文で指定されていない限り) グローバル変数や外側の関数の変数に直接値を代入できませんが、参照することはできます。
:::

**2.以下のプログラムを実行した際の出力結果を選びなさい。**
```
d = 'dive\ninto\ncode\t'

print(len(d))
```
【正答】
15

:::note info
解説
len()関数について
「\n」や「\t」などのエスケープシーケンスはひとつで1文字
:::

**3.条件についての説明で誤っているものを選択肢から選びなさい。**

【正答】
比較はブール演算のand及びorによって組み合わせることができ、また比較の結論はnotにより否定ができる。これらの優先順位は比較演算子よりも高い。

:::note info
解説
論理演算子の優先順位は、not > and > or
「<」,「>」などの比較演算子はnotよりもさらに優先順位が高い

:::

**4.次のprint文のうち、「こんにちは！山田さん」と出力される記述はどれかを選びなさい。**

【正答】
```
print(‘こんにちは!{}さん’.format(‘山田’))
```
:::note info
解説
formatメソッドを使った文字列の書式設定
置換フィールドを含む文字列.format(値1, 値2, ...)
:::

**5.問題文のprint文を実行した場合の、出力結果を選びなさい。**
```
print("出力結果:")
print('円周率は%5.3fである。'%math.pi)
```
【正答】
出力結果:円周率は3.142である。

:::note info
解説
5.3f の 5 はフォーマット後の文字列が 5 桁に満たなければ左にスペースを挿入して 5 桁にするという意味です。5 桁以上の場合は何もしません。
3 は小数点以下の数字を 4 桁目で四捨五入して 3 桁にするという意味です。
f は小数であることを示します。
:::

**6.以下のプログラムを実行した際の出力結果を選びなさい。**
```
for i in range(20):
    if i%3 == 0:
        print("{}は3で割り切れます".format(i), end=' ')
    elif i>8 and i%2 == 0:
        break
    else:
        continue
```
【正答】
0は3で割り切れます 3は3で割り切れます 6は3で割り切れます 9は3で割り切れます

**7.Pythonインタプリタにて以下のように入力した場合の出力結果として正しいものを選びなさい。**
```
>>>import reprlib
>>>reprlib.repr(set('diveintocode'))
```
【正答】
"{'c', 'd', 'e', 'i', 'n', 'o', ...}"

:::note info
解説
**reprlib**
出力文字列の長さを制御するモジュール
**reprlib.Repr**
各オブジェクトの表示方法を指定することが出来るclass。
ここからサブクラスとかを作って、カスタマイズさせたい場合は、これを使用する
**reprlib.aRepr**
reprlib.repr関数を提供するinstance。
**reprlib.repr**
これを使って、出力の長さを制限する
**@reprlib.recursive_repr(fillvalue="...")**
再帰的な出力が合った場合に出力数を制限するデコレーター

問題では、
set('diveintocode')
で重複を削除した集合にし、
{'v', 'n', 'o', 'i', 'c', 'e', 't', 'd'}
recursive_repr(set('diveintocode'))
で出力文字列を制御している。
{'c', 'd', 'e', 'i', 'n', 'o', ...}
:::

## 正解したが見直す問題
**1.以下のプログラムを実行した際の出力結果として正しいものを選択しなさい。**
```
dive_into_code = [(1, 'Noro'), (2, 'Nakao'), (3, 'Miyaoka'), (4, 'Kimura')]
dic = dive_into_code
dic.sort(key=lambda dic: dic[1])

print(dic)
```
【正答】
[(4, 'Kimura'), (3, 'Miyaoka'), (2, 'Nakao'), (1, 'Noro')]

:::note info
解説
sort の key として lambda dic[1] を使っています。dic[1] はリストの名前の部分ですので、名前の昇順で並び替えられているものが正解になります。
:::

# PRIME STUDY 第1回 Python 3 基礎 模擬試験
スコアは 95 点/ 100点満点です。
https://study.prime-strategy.co.jp/study/py3ba1/
PC初期設定 備忘録

# 目次
・[Mac風キーボード](#mac風キーボード)
・[開発タブを表示させる](#開発タブを表示させる)
・[VBEおすすめ設定](#vbeおすすめ設定)
・[VBEおすすめ表示色](#vbeおすすめ表示色)
・[VBEおすすめ文字スタイル](#vbeおすすめ文字スタイル)
・[VBEおすすめショートカット](#vbeおすすめショートカット)
・[Excelおすすめ設定](#excelおすすめ設定)
# Mac風キーボード
タスクバーの『A』または『あ』のアイコンを右クリック→設定→キーとタッチのカスタマイズ
|項目|登録内容|説明|
|:-|:-|:-|
無変換キー|IME-オフ|無変換ボタンで半角に切り替え可能
変換キー|IME-オン|変換ボタンで全角に切り替え可能

# 開発タブを表示させる
Excel画面→ファイルタブ→その他のオプション→オプション→リボンのユーザー設定→
画面右側の『開発』にチェック→OK

# VBEおすすめ設定
VBEを開く(Alt＋F11)→ツールタブ→オプション→編集タブ
・自動構文チェックoff
・変数の宣言を強制するon

# VBEおすすめ表示色
VBEを開く(Alt＋F11)→ツールタブ→オプション→エディターの設定タブ
|種類|前景|背景|
|:-|:-|:-|
標準コード|ピンク|黒
コメント|黄緑|黒
キーワード|水|黒
識別子|黄|黒

### イメージ
![スクリーンショット 2024-02-01 22.40.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682265/5ff332f2-0694-95a4-9367-178c7b1a104e.png)



# VBEおすすめ文字スタイル
VBEを開く(Alt＋F11)→ツールタブ→オプション→エディターの設定タブ
・フォント名：Meiryo UI(日本語)

# VBEおすすめショートカット
|No|コマンド|名前に入力する内容|実行方法
|:-:|:-|:-|:-:|
①|コメントブロック|(&C)|Alt+c
②|非コメントブロック|(&X)|Alt+x
③|やり直し[^1]|(&Z)[^2]|Alt+z

:::note info
#### 登録方法
VBEを開く(Alt＋F11)→画面上部で右クリック→ユーザー設定→コマンドタブ→編集→上記①②のアイコンを画面上部にドラッグ＆ドロップ→
アイコンを右クリック(ユーザー設定はまだ閉じてはいけない)→
名前を消して(&C)を入力→『イメージとテキストを表示』を選択→
アイコンの横に(C)と表示されていれば成功→②③も同様に実行
:::

# Excelおすすめ設定
#### リンクを絶対参照で保存できるようにする
〇365の場合
Excel画面→ファイルタブ→その他のオプション→オプション→詳細設定→画面下部のWebオプション押下→ファイルタブ→「保存するときにリンクを更新する」のチェックを外す

〇2016の場合
F12→下部のツール→Webオプション→ファイルタブ→「保存するときにリンクを更新する」のチェックを外す

:::note info
「保存するときにリンクを更新する」がチェックのままだと、ファイル保存時にハイパーリンクが絶対参照から相対参照に勝手に置き換わる事象が発生する。ファイルの場所を移動すると、ハイパーリンクがダメになってしまう可能性あり。
:::

[^1]: 右回りの矢印アイコン
[^2]: 『イメージとテキストを表示』を選択すると『(&R)』(Alt+rで実行)が既に設定されているが、『実行(R)』とバッティングするので変更推奨
VSCodeのコマンドをまとめてみた

## 前書き
よく使っているVSCodeのコマンドをまとめてみました。


## コマンド

Windowsでは「cmd」を「ctrl」・「option」を「alt」と読み替えてください。

### コピー
```
cmd + c
```

範囲選択をしない場合1行丸々コピーできる

### 切り取り
```
cmd + x
```
範囲選択をしない場合1行丸々コピーできる


### ペースト
```
cmd + p
```

### 一行コピーして貼り付け
```
option + shift + カーソル上下
```

### 行削除
```
cmd + shift + k
```

### 元に戻す
```
cmd + z
```

### やり直す
```
cmd + shift + z
```

### ファイル内検索
```
cmd + f
```

### ファイル横断検索
```
cmd + shift + f
```

### ファイル検索
```
cmd + p
```

### タブ移動
```
cmd + option + 左右
```

### タブを閉じる
```
cmd + w
```

### 直前に閉じたタブを復元
```
cmd + shift + t
```

### ファイルを保存する
```
cmd + s
```

### 別名でファイルを保存する
```
cmd + shift + s
```

### 範囲選択：キーボード上で範囲の選択ができます
```
shift + カーソール
```
### 行の入れ替え
```
option + 上下
```

### 複数選択
```
cmd + d
```

一回押すごとに選択範囲が一つ増える


### 全ての検索結果を一括選択
```
cmd + shift + l / cmd + F2
```

### ファイル内の文字列を置換
```
cmd + option + f
```

### クイックフィックス
```
cmd + .
```

### トグルラインコメント
```
cmd　+ /
```

### トグルブロックコメント
```
option + shift + a
```

### コマンドパレットを表示 
```
cmd + shift + p / F1
```

### 新しいウィンドウ 
```
cmd + shift + n / cmd + k → f  
```

### 定義元を参照
```
F12
```

### ピークで定義元を参照
```
option + F12
```

### リファレンスを表示
```
shift +  F12
```

## MacとWindowsでコマンドが違うもの
### 端に移動
* Mac：`cmd + カーソル`

* Windows
    * 左端：`Home`
    * 右端：`End`
    * 最上部に移動：`ctrl + Home`
    * 最下部に移動：`ctrl + End`

### 単語移動
* Mac：`option + 左右`
* Windows：`ctrl + 左右`

### 単語を範囲選択
* Mac：`option +  shift + 左右`
* Windows：`ctrl +  shift + 左右`


### 直前の編集ファイルを開く
Mac：`cntr + -`

### 端まで範囲選択
Mac：`cmd + shift + カーソル`

### 編集履歴を閲覧
Windows：`ctrl + tab`


## おまけ 便利な拡張機能
### Vrailing Spaces
末尾にあるスペースの検知してくれる

### Zenkaku / Live ServerEvilInspector
全角スペースを検知してくれる

### HTML CSS Support
CSSで使われているクラス名をHTML側が自動補完してくれる

### Auto Rename Tag
開始タグと終了タグを自動補完してくれる

### indent-rainbow
インデント毎に色が付いて見やすい

### Code Spell Checker
タイポが分かりやすい

### Bracket Pair Colorizer 
if文などの()に色がつく

### Auto Close Tag 
終了タグの自動補完

### DotENV
DotENVファイルが見やすくなる

### Material Icon Theme
フォルダやファイルにアイコンがついて見やすくなる。

### Prettier
設定をすることでファイルの保存時に自動でフォーマットをしてくれる。

### Git History または Git Graph
Gitの履歴の確認が視覚的に行える

### GitLens
特定の行を誰が書いたのかを可視化したりすることができる。
GitHub Actionsを使用してJOBSのステータスをSlackに通知する

開発プロジェクトでは、継続的インテグレーション（CI）や継続的デリバリー（CD）のプロセスが重要です。GitHub Actionsはこれらのプロセスを自動化するのに役立ちます。この記事では、GitHub Actionsを使って、ワークフローの実行結果をSlackに通知する方法を説明します。

### 必要なもの

1. GitHubリポジトリ
2. Slackワークスペース
3. SlackでのIncoming Webhook URL

#### 1: SlackでIncoming Webhookを設定する

1. SlackのアプリディレクトリでIncoming Webhooksを検索し、インストールします。
1. 新しいWebhookを作成し、通知を受け取りたいチャンネルを選択します。
1. Webhook URLをコピーして安全な場所に保存します。


#### 2: GitHubリポジトリにSecretを追加する

1. GitHubリポジトリにアクセスします。
1. 「Settings」→「Secrets」→「New repository secret」の順に進みます。
1. 名前にSLACK_WEBHOOK_URLと入力し、値にSlackのWebhook URLを貼り付けます。
1. 「Add secret」をクリックして保存します。

#### 3: GitHub Actionsワークフローを作成する

`.github/workflows` ディレクトリに新しいYAMLファイルを作成します。

##### JOB実行ステータス種類
1. success, 
1. failure, 
1. cancelled, 
1. skipped

以下は基本的なワークフローの例です。JOB `失敗` と`成功` だけをSlackに通知する

```
....
jobs:
  job-one:
    runs-on: ubuntu-latest
    .....
  job-two:
    runs-on: ubuntu-latest
    .....
  job-three:
    runs-on: ubuntu-latest
    ..... 
  slack-notification:
    runs-on: ubuntu-latest
    needs:
      - job-one
      - job-two
      - job-three
    # success, failure, cancelled, or skipped
    if: always() && (failure() || success())
    steps:
      - name: "Send Notification to Slack"
        uses: rtCamp/action-slack-notify@v2
        env:
          SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }}
          SLACK_CHANNEL: "your channel name"
          SLACK_USERNAME: "GitHub Actions"
          SLACK_COLOR: ${{ (needs.job-one.result == 'success' && needs.job-two.result == 'success' && needs.job-three.result == 'success') && 'good' || 'danger' }}
          SLACK_MESSAGE: ${{ (needs.job-one.result == 'success' && needs.job-two.result == 'success' && needs.job-three.result == 'success') && '実行成功。' || '<!channel> 実行失敗. ご確認ください。' }}
          SLACK_TITLE: "Slack Notification"
          SLACK_FOOTER:
            "Action URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}\n
            Branch URL: ${{ github.server_url }}/${{ github.repository }}/tree/${{ github.ref_name }}"
          SLACK_ICON: "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png"
```