tres-import-contacts について
tres-import-contactsは、CSVまたはXLSXのアドレスラベルをTRESのアドレス帳に取り込むスキルです。連絡先を一括管理するユーザー向けに、検証、重複排除、取り込み前のプレビューを行います。
主な機能
- 01CSVとXLSXの解析
- 02項目の検証とアドレス重複排除
- 03連絡先名とタグの取り込み
- 04取り込み前のデータプレビュー
- 05重複や取り込み失敗への対応
活用シーン
- 01入力済みのアドレス対応表をTRESに取り込む
- 02複数のブロックチェーンアドレスに名前を付ける
- 03連絡先タグを一括更新する
MCP 対応
user-tres-finance MCP サーバーの`execute`ツールからGraphQLを呼び出し、セッション確認とTRESの連絡先名・タグの登録を行います。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ anthropics/ claude-plugins-community --skill tres-import-contactsインストール後、Claude Code で/tres-import-contactsを入力して読み込まれたか確認します。
詳細
TRES Finance — CSV/XLSX から連絡先をインポート
目標
アドレスと名前の対応を含む、ユーザー提供の CSV または XLSX ファイルを読み込み、TRES のアドレス帳に連絡先としてインポートします。これは連絡先ワークフローの後半です。ユーザーは以前、識別されていないアドレスをエクスポートスキルでエクスポートし、名前とタグを入力しており、今度はそのラベルを TRES に反映しようとしています。
MCP サーバー
すべての GraphQL 呼び出しには user-tres-finance MCP サーバーの execute ツールを使用します。
想定されるファイル形式
ファイルには次の列が必要です(ヘッダー名は大文字と小文字を区別せず照合します)。
| 連絡先名 | 連絡先アドレス | 連絡先タグ |
|---|---|---|
| Binance Hot Wallet | 0xABC... | Exchange |
| Vendor X | 0xDEF... | Vendor |
- 連絡先名 — アドレスに割り当てるラベルです(インポートに必須。名前のない行はスキップされます)
- 連絡先アドレス — ブロックチェーンアドレスです(必須)
- 連絡先タグ — 連絡先に付ける任意のタグです。複数のタグはカンマで区切ることができます(例:
Exchange, Custodian)
列の順序は問いません。このスキルはヘッダー名で照合します。ファイルには追加の列(エクスポートスキルの「Address details」拡張列など)が含まれていてもかまいません。これらは無視されます。
ワークフロー
ステップ 1 — 認証
引数なしで get_viewer を呼び出し、セッションが有効であることを確認して、組織名を記録します。
ステップ 2 — ファイルの読み込みと解析
ユーザーが CSV または XLSX ファイルを提供します。ファイル拡張子から形式を判定します。
XLSX ファイルの場合:
openpyxl==3.1.5 を使って Python を実行します。インストールされていない場合は処理を停止し、次を表示します。
"openpyxl is not installed. Please run:
python3 -m venv .venv && .venv/bin/pip install openpyxl==3.1.5"
- ワークブックに複数のシートがある場合は、「Contacts」という名前のシートを探します(大文字と小文字は区別しません)。見つからない場合は、最初のシートを使用します。
- ヘッダー行を読み込み、「Contact Name」、「Contact Address」、「Contact Tag」の列インデックスを特定します(大文字と小文字を区別せず照合し、前後の空白を削除します)。
- すべてのデータ行を読み込みます。
- 末尾の空行を除外します。openpyxl は、シートの末尾に余分な
None行を読み込むことがあります。すべてのセルがNoneまたは空文字列である行はスキップします。
CSV ファイルの場合:
Python 組み込みの csv モジュールを使用します。
- Excel が CSV の保存時に追加する BOM(バイトオーダーマーク)に対応するため、
encoding='utf-8-sig'を指定してファイルを開きます。これを指定しないと、最初のヘッダーが\ufeffContact Nameのようになり、一致しなくなります。 - まずカンマ区切りで試します。ヘッダー行に想定される列が含まれていない場合は、セミコロン区切りで再試行します(ヨーロッパのロケールでの Excel エクスポートでよく使われます)。
- ヘッダー行を読み込み、上記と同じ照合方法で列インデックスを特定します。
- すべてのデータ行を読み込みます。
ステップ 3 — 検証とフィルタリング
各行について、次の処理を行います。
- Contact Name が空欄または欠落している場合はスキップします — ユーザーはまだこのアドレスを特定していないため、インポートするものはありません。
- Contact Address が空欄または欠落している場合はスキップします — 存在しないアドレスにはラベルを付けられません。
- 名前、アドレス、タグの値から前後の空白を削除します。
- タグを解析します:Contact Tag にカンマが含まれている場合は、複数のタグに分割します。各タグの前後の空白を削除し、空文字列を取り除きます。
- アドレスで重複を除去します(大文字と小文字を区別しません)。同じアドレスが複数回出現する場合は、最後の出現を残します(ユーザーが修正した可能性があります)。重複について警告します。
フィルタリング後、次の内容をユーザーに報告します。
- ファイル内の合計行数
- スキップした行数(名前が空欄)
- インポートする行数
- 見つかった重複
次に、インポート対象の最初の 10 行(アドレス、名前、タグ)のプレビュー表を表示し、続行する前にユーザーに確認を求めます。
ステップ 4 — 既存の連絡先を確認する(50 行以上のインポートのみ)
少量のインポート(50 件未満)の場合、このステップはスキップしてインポートに進んでください。少数の連絡先のためにアドレス帳全体を取得すると、不必要に時間がかかります。
大規模なインポートの場合、現在のアドレス帳を取得して、すでにラベルが付いているアドレスを特定します。これにより、ユーザーは新規作成される項目と更新される項目を把握できます。
query AddressBook($limit: Int, $offset: Int) {
customAccountNameLabel(limit: $limit, offset: $offset) {
results {
originalIdentifier
labelValue
tags
}
totalCount
}
}
結果をすべてページネーションで取得します(1 回あたり 500 件)。originalIdentifier.lower() をキーにした検索用辞書を作成します。
インポートリストと照合し、次の項目を報告します。
- 新規連絡先 — 現在のアドレス帳にないアドレス
- 更新 — すでに存在するが、新しい名前またはタグが設定されるアドレス
重要:setCustomAccountNameLabelTags は追加ではなく、置き換えの操作です。連絡先に現在 ["Exchange", "Custodian"] のタグがあり、インポートファイルのタグが ["Vendor"] の場合、以前のタグは上書きされます。タグがすでに設定されている連絡先を更新する場合は、ユーザーにその旨を警告してください。
続行する前に、この内訳をユーザーに提示してください。更新がある場合は、内容を確認できるよう、旧名 → 新名の例をいくつか挙げてください。
ステップ 5 — 連絡先をインポートする
検証済みの各行について、API を 2 回呼び出します。
5a. 連絡先の名前を設定する:
mutation SetContactName($identifier: String, $labelValue: String) {
setCustomAccountName(identifier: $identifier, labelValue: $labelValue) {
accountTxsSummary {
accountIdentifier
displayName
}
}
}
変数:
{
"identifier": "<the address>",
"labelValue": "<the contact name>"
}
5b. タグを設定する(その行にタグがある場合のみ):
mutation SetContactTags($identifier: String!, $tags: [String]!) {
setCustomAccountNameLabelTags(identifier: $identifier, tags: $tags) {
accountTxsSummary {
accountIdentifier
displayName
}
}
}
変数:
{
"identifier": "<the address>",
"tags": ["Exchange", "Custodian"]
}
バッチ処理の方針: API に一括処理用のエンドポイントはありません。少量のインポート(連絡先 20 件未満)では、名前の変更をすべて並列で実行してから、タグの変更をすべて並列で実行します。これは高速で安全です。大規模なインポートの場合、API に過剰な負荷をかけないよう、並列呼び出しを 10 件ずつ処理し、25 件ごとにユーザーに進捗を表示してください(例:「25/142 件をインポートしました...」)。
エラー処理: 特定のアドレスに対する変更に失敗した場合、エラーを記録し、次の行の処理を続けてください。インポート全体を中止しないでください。失敗した項目はすべて、最後の概要に含めてください。
ステップ 6 — 概要
すべての変更が完了したら、次の概要を提示してください。
- インポートに成功した連絡先の合計数(名前を設定済み)
- タグを設定した連絡先の合計数
- 失敗した項目(アドレスとエラーメッセージを列挙)
失敗があった場合は、同じファイルを使ってスキルを再実行すれば再試行できることを提案してください。すでにインポート済みの連絡先は更新されるだけです(名前の変更は冪等です)。
エッジケース
- ファイルにヘッダー行がない:最初の行に認識可能な列名が含まれていない場合は、期待される形式をユーザーに伝え、ファイルを修正するよう依頼します。
- ファイルの列が不適切:「Contact Address」列が見つからない場合、そのファイルは使用できません。見つかった列と期待される列を報告します。
- 空のファイル:ヘッダーはあるもののデータ行がない場合は、その旨をユーザーに伝えます。
- 名前がすべて空欄:すべての行で Contact Name が空欄の場合は、ユーザーに伝えます。おそらく未記入のテンプレートを誤ってアップロードしています。
- 非常に大きなファイル(500 行超):処理に時間がかかることをユーザーに警告し、続行するか確認します。
- 名前に特殊文字が含まれる:そのまま渡します。TRES はラベル内の Unicode を処理できます。
- 大文字と小文字が混在するアドレス:
setCustomAccountNameミューテーションはアドレスをそのまま受け付けます。大文字と小文字を正規化せず、ファイル内の元の値を渡します。 - 余分なスペースを含むタグ:
" Exchange , Custodian "→["Exchange", "Custodian"]にトリミングします。 - どのトランザクションにも含まれないアドレス:TRES がトランザクションで確認したことのないアドレスでも、ミューテーションは機能します。アドレス帳のエントリはそのまま作成されます。
- タグの上書き:
setCustomAccountNameLabelTagsは既存のタグをすべて置き換えます。タグの追加だけを希望する場合は、まず既存のタグと結合する必要があります(このスキルは自動的には行いません。置き換え操作です)。タグがすでに付いている既存の連絡先を更新する場合は、ユーザーにこの点を伝えてください。 - CSV の BOM プレフィックス:Excel で保存した CSV には UTF-8 BOM(
\ufeff)が含まれ、最初の列ヘッダーが破損します。CSV は必ずencoding='utf-8-sig'で開いてください。 - セミコロン区切りの CSV:ヨーロッパの Excel エクスポートでは、
,の代わりに;が使われます。カンマ区切りで期待されるヘッダーが見つからない場合は、セミコロン区切りで再試行します。 - XLSX の末尾にある空行:openpyxl はシート末尾の空行を読み込みます。すべての値が
Noneまたは空の行はスキップしてください。