Skip to content

Commit 24e64c9

Browse files
authored
Add Japanese translation of Advanced concepts pages (#354)
1 parent f84bc94 commit 24e64c9

13 files changed

+561
-3
lines changed

docs/_advanced/errors.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ order: 3
66
---
77

88
<div class="section-content">
9-
If an error occurs in a listener, you can handle it directly using a `try`/`except` block. Errors associated with your app will be of type `BoltError`. Errors associated with calling Slack APIs will be of type `SlackApiError`.
9+
If an error occurs in a listener, you can handle it directly using a try/except block. Errors associated with your app will be of type `BoltError`. Errors associated with calling Slack APIs will be of type `SlackApiError`.
1010

1111
By default, the global error handler will log all non-handled exceptions to the console. To handle global errors yourself, you can attach a global error handler to your app using the `app.error(fn)` function.
1212
</div>

docs/_advanced/ja_adapters.md

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
---
2+
title: アダプター
3+
lang: ja-jp
4+
slug: adapters
5+
order: 0
6+
---
7+
8+
<div class="section-content">
9+
アダプターは Slack から届く受信イベントの受付とパーズを担当し、それらのイベントを <a href="https://github.com/slackapi/bolt-python/blob/main/slack_bolt/request/request.py">`BoltRequest`</a> の形式に変換して Bolt アプリに引き渡します。
10+
11+
デフォルトでは、Bolt の組み込みの <a href="https://docs.python.org/3/library/http.server.html">`HTTPServer`</a> アダプターが使われます。このアダプターは、ローカルで開発するのには問題がありませんが、<b>本番環境での利用は推奨されていません</b>。Bolt for Python には複数の組み込みのアダプターが用意されており、必要に応じてインポートしてアプリで使用することができます。組み込みのアダプターは Flask、Django、Starlette をはじめとする様々な人気の Python フレームワークをサポートしています。これらのアダプターは、あなたが選択した本番環境で利用可能な Webサーバーとともに利用することができます。
12+
13+
アダプターを使用するには、任意のフレームワークを使ってアプリを開発し、そのコードに対応するアダプターをインポートします。その後、アダプターのインスタンスを初期化して、受信イベントの受付とパーズを行う関数を呼び出します。
14+
15+
すべてのアダプターの一覧と、設定や使い方のサンプルは、リポジトリの <a href="https://github.com/slackapi/bolt-python/tree/main/examples">`examples` フォルダ</a>をご覧ください。
16+
</div>
17+
18+
```python
19+
from slack_bolt import App
20+
app = App(
21+
signing_secret=os.environ.get("SIGNING_SECRET"),
22+
token=os.environ.get("SLACK_BOT_TOKEN")
23+
)
24+
25+
# ここには Flask 固有の記述はありません
26+
# App はフレームワークやランタイムに一切依存しません
27+
@app.command("/hello-bolt")
28+
def hello(body, ack):
29+
ack(f"Hi <@{body['user_id']}>!")
30+
31+
# Flask アプリを初期化します
32+
from flask import Flask, request
33+
flask_app = Flask(__name__)
34+
35+
# SlackRequestHandler は WSGI のリクエストを Bolt のインターフェイスに合った形に変換します
36+
# Bolt レスポンスからの WSGI レスポンスの作成も行います
37+
from slack_bolt.adapter.flask import SlackRequestHandler
38+
handler = SlackRequestHandler(app)
39+
40+
# Flask アプリへのルートを登録します
41+
@flask_app.route("/slack/events", methods=["POST"])
42+
def slack_events():
43+
# handler はアプリのディスパッチメソッドを実行します
44+
return handler.handle(request)
45+
```

docs/_advanced/ja_async.md

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
title: Async(asyncio)の使用
3+
lang: ja-jp
4+
slug: async
5+
order: 2
6+
---
7+
8+
<div class="section-content">
9+
非同期バージョンの Bolt を使用する場合は、`App` の代わりに `AsyncApp` インスタンスをインポートして初期化します。`AsyncApp` では <a href="https://docs.aiohttp.org/">AIOHTTP</a> を使って API リクエストを行うため、`aiohttp` をインストールする必要があります(`requirements.txt` に追記するか、`pip install aiohttp` を実行します)。
10+
11+
非同期バージョンのプロジェクトのサンプルは、リポジトリの <a href="https://github.com/slackapi/bolt-python/tree/main/examples">`examples` フォルダ</a>にあります。
12+
</div>
13+
14+
```python
15+
# aiohttp のインストールが必要です
16+
from slack_bolt.async_app import AsyncApp
17+
app = AsyncApp()
18+
19+
@app.event("app_mention")
20+
async def handle_mentions(event, client, say): # 非同期関数
21+
api_response = await client.reactions_add(
22+
channel=event["channel"],
23+
timestamp=event["ts"],
24+
name="eyes",
25+
)
26+
await say("What's up?")
27+
28+
if __name__ == "__main__":
29+
app.start(3000)
30+
```
31+
32+
<details class="secondary-wrapper">
33+
<summary class="section-head" markdown="0">
34+
<h4 class="section-head">他のフレームワークを使用する</h4>
35+
</summary>
36+
37+
<div class="secondary-content" markdown="0">
38+
39+
`AsyncApp#start()` では内部的に [`AIOHTTP`](https://docs.aiohttp.org/) のWebサーバーが実装されています。必要に応じて、受信リクエストの処理に `AIOHTTP` 以外のフレームワークを使用することができます。
40+
41+
この例では [Sanic](https://sanicframework.org/) を使用しています。すべてのアダプターのリストについては、[`adapter` フォルダ](https://github.com/slackapi/bolt-python/tree/main/slack_bolt/adapter) を参照してください。
42+
43+
以下のコマンドを実行すると、必要なパッケージをインストールして、Sanic サーバーをポート 3000 で起動します。
44+
45+
```bash
46+
# 必要なパッケージをインストールします
47+
pip install slack_bolt sanic uvicorn
48+
# ソースファイルを async_app.py として保存します
49+
uvicorn async_app:api --reload --port 3000 --log-level debug
50+
```
51+
</div>
52+
53+
```python
54+
from slack_bolt.async_app import AsyncApp
55+
app = AsyncApp()
56+
57+
# ここには Sanic に固有の記述はありません
58+
# AsyncApp はフレームワークやランタイムに依存しません
59+
@app.event("app_mention")
60+
async def handle_app_mentions(say):
61+
await say("What's up?")
62+
63+
import os
64+
from sanic import Sanic
65+
from sanic.request import Request
66+
from slack_bolt.adapter.sanic import AsyncSlackRequestHandler
67+
68+
# App のインスタンスから Sanic 用のアダプターを作成します
69+
app_handler = AsyncSlackRequestHandler(app)
70+
# Sanic アプリを作成します
71+
api = Sanic(name="awesome-slack-app")
72+
73+
@api.post("/slack/events")
74+
async def endpoint(req: Request):
75+
# app_handler では内部的にアプリのディスパッチメソッドが実行されます
76+
return await app_handler.handle(req)
77+
78+
if __name__ == "__main__":
79+
api.run(host="0.0.0.0", port=int(os.environ.get("PORT", 3000)))
80+
```
81+
</details>

docs/_advanced/ja_authorization.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
title: 認可(Authorization)
3+
lang: ja-jp
4+
slug: authorization
5+
order: 5
6+
---
7+
8+
<div class="section-content">
9+
認可(Authorization)は、Slack からの受信イベントを処理するにあたって、どのようなSlack
10+
クレデンシャル (ボットトークンなど) を使用可能にするかを決定するプロセスです。
11+
12+
単一のワークスペースにインストールされるアプリでは、`token` パラメーターを使って `App` のコンストラクターにボットトークンを渡すという、シンプルな方法が使えます。それに対して、複数のワークスペースにインストールされるアプリでは、次の 2 つの方法のいずれかを使用する必要があります。簡単なのは、組み込みの OAuth サポートを使用する方法です。OAuth サポートは、OAuth フロー用のURLのセットアップとstateの検証を行います。詳細は「[OAuth を使った認証](#authenticating-oauth)」セクションを参照してください。
13+
14+
よりカスタマイズできる方法として、`App` をインスタンス化する関数に`authorize` パラメーターを指定する方法があります。`authorize` 関数から返される [`AuthorizeResult` のインスタンス](https://github.com/slackapi/bolt-python/blob/main/slack_bolt/authorization/authorize_result.py)には、どのユーザーがどこで発生させたイベントかを示す情報が含まれます。
15+
16+
`AuthorizeResult` には、いくつか特定のプロパティを指定する必要があり、いずれも `str` 型です。
17+
18+
19+
- **`bot_token`**(xoxb)*または* **`user_token`**(xoxp): どちらか一方が**必須**です。ほとんどのアプリでは、デフォルトの `bot_token` を使用すればよいでしょう。トークンを渡すことで、`say()` などの組み込みの関数を機能させることができます。
20+
- **`bot_user_id`** および **`bot_id`** : `bot_token` を使用する場合に指定します。
21+
- **`enterprise_id`** および **`team_id`** : アプリに届いたイベントから見つけることができます。
22+
- **`user_id`** : `user_token` を使用する場合に必須です。
23+
</div>
24+
25+
```python
26+
import os
27+
from slack_bolt import App
28+
# AuthorizeResult クラスをインポートします
29+
from slack_bolt.authorization import AuthorizeResult
30+
31+
# これはあくまでサンプル例です(ユーザートークンがないことを想定しています)
32+
# 実際にはセキュアな DB に認可情報を保存してください
33+
installations = [
34+
{
35+
"enterprise_id":"E1234A12AB",
36+
"team_id":"T12345",
37+
"bot_token": "xoxb-123abc",
38+
"bot_id":"B1251",
39+
"bot_user_id":"U12385"
40+
},
41+
{
42+
"team_id":"T77712",
43+
"bot_token": "xoxb-102anc",
44+
"bot_id":"B5910",
45+
"bot_user_id":"U1239",
46+
"enterprise_id":"E1234A12AB"
47+
}
48+
]
49+
50+
def authorize(enterprise_id, team_id, logger):
51+
# トークンを取得するためのあなたのロジックをここに記述します
52+
for team in installations:
53+
# 一部のチームは enterprise_id を持たない場合があります
54+
is_valid_enterprise = True if (("enterprise_id" not in team) or (enterprise_id == team["enterprise_id"])) else False
55+
if ((is_valid_enterprise == True) and (team["team_id"] == team_id)):
56+
# AuthorizeResult のインスタンスを返します
57+
# bot_id と bot_user_id を保存していない場合、bot_token を使って `from_auth_test_response` を呼び出すと、自動的に取得できます
58+
return AuthorizeResult(
59+
enterprise_id=enterprise_id,
60+
team_id=team_id,
61+
bot_token=team["bot_token"],
62+
bot_id=team["bot_id"],
63+
bot_user_id=team["bot_user_id"]
64+
)
65+
66+
logger.error("No authorization information was found")
67+
68+
app = App(
69+
signing_secret=os.environ["SLACK_SIGNING_SECRET"],
70+
authorize=authorize
71+
)
72+
```

docs/_advanced/ja_context.md

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
title: コンテキストの追加
3+
lang: ja-jp
4+
slug: context
5+
order: 7
6+
---
7+
8+
<div class="section-content">
9+
すべてのリスナーは `context` ディクショナリにアクセスできます。リスナーはこれを使ってイベントの付加情報を得ることができます。受信イベントに含まれる `user_id``team_id``channel_id``enterprise_id` などの情報は、Bolt によって自動的に設定されます。
10+
11+
`context` は単純なディクショナリで、変更を直接加えることもできます。
12+
</div>
13+
14+
```python
15+
# ユーザーID を使って外部のシステムからタスクを取得するリスナーミドルウェア
16+
def fetch_tasks(context, event, next):
17+
user = event["user"]
18+
try:
19+
# get_tasks は、ユーザー ID に対応するタスクのリストを DB から取得します
20+
user_tasks = db.get_tasks(user)
21+
tasks = user_tasks
22+
except Exception:
23+
# タスクが見つからなかった場合 get_tasks() は例外を投げます
24+
tasks = []
25+
finally:
26+
# ユーザーのタスクを context に設定します
27+
context["tasks"] = tasks
28+
next()
29+
30+
# section のブロックのリストを作成するリスナーミドルウェア
31+
def create_sections(context, next):
32+
task_blocks = []
33+
# 先ほどのミドルウェアを使って context に追加した各タスクについて、処理を繰り返します
34+
for task in context["tasks"]:
35+
task_blocks.append(
36+
{
37+
"type": "section",
38+
"text": {
39+
"type": "mrkdwn",
40+
"text": f"*{task['title']}*
41+
{task['body']}"
42+
},
43+
"accessory": {
44+
"type": "button",
45+
"text": {
46+
"type": "plain_text",
47+
"text":"See task"
48+
},
49+
"url": task["url"],
50+
}
51+
}
52+
)
53+
# ブロックのリストを context に設定します
54+
context["blocks"] = task_blocks
55+
next()
56+
57+
# ユーザーがアプリのホームを開くのをリッスンします
58+
# fetch_tasks ミドルウェアを含めます
59+
@app.event(
60+
event = "app_home_opened",
61+
middleware = [fetch_tasks, create_sections]
62+
)
63+
def show_tasks(event, client, context):
64+
# ユーザーのホームタブにビューを表示します
65+
client.views_publish(
66+
user_id=event["user"],
67+
view={
68+
"type": "home",
69+
"blocks": context["blocks"]
70+
}
71+
)
72+
```
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
---
2+
title: カスタムのアダプター
3+
lang: ja-jp
4+
slug: custom-adapters
5+
order: 1
6+
---
7+
8+
<div class="section-content">
9+
[アダプター](#adapters)はフレキシブルで、あなたが使用したいフレームワークに合わせた調整も可能です。アダプターでは、次の 2 つの要素が必須となっています。
10+
11+
- `__init__(app:App)` : コンストラクター。Bolt の `App` のインスタンスを受け取り、保持します。
12+
- `handle(req:Request)` : Slack からの受信リクエストを受け取り、解析を行う関数。通常は `handle()` という名前です。リクエストを [`BoltRequest`](https://github.com/slackapi/bolt-python/blob/main/slack_bolt/request/request.py) のインスタンスに合った形にして、保持している Bolt アプリに引き渡します。
13+
14+
`BoltRequest` のインスタンスの作成では、以下の 4 種類のパラメーターを指定できます。
15+
16+
| パラメーター | 説明 | 必須 |
17+
|-----------|-------------|-----------|
18+
| `body: str` | そのままのリクエストボディ | **Yes** |
19+
| `query: any` | クエリストリング | No |
20+
| `headers:Dict[str, Union[str, List[str]]]` | リクエストヘッダー | No |
21+
| `context:BoltContext` | リクエストのコンテキスト情報 | No |
22+
23+
アダプターは、Bolt アプリからの [`BoltResponse` のインスタンス](https://github.com/slackapi/bolt-python/blob/main/slack_bolt/response/response.py)を返します。
24+
25+
カスタムのアダプターに関連した詳しいサンプルについては、[組み込みのアダプター](https://github.com/slackapi/bolt-python/tree/main/slack_bolt/adapter)の実装を参考にしてください。
26+
</div>
27+
28+
```python
29+
# Flask で必要なパッケージをインポートします
30+
from flask import Request, Response, make_response
31+
32+
from slack_bolt.app import App
33+
from slack_bolt.request import BoltRequest
34+
from slack_bolt.response import BoltResponse
35+
36+
# この例は Flask アダプターを簡略化したものです
37+
# もう少し詳しい完全版のサンプルは、adapter フォルダをご覧ください
38+
# github.com/slackapi/bolt-python/blob/main/slack_bolt/adapter/flask/handler.py
39+
40+
# HTTP リクエストを取り込み、標準の BoltRequest に変換します
41+
def to_bolt_request(req:Request) -> BoltRequest:
42+
return BoltRequest(
43+
body=req.get_data(as_text=True),
44+
query=req.query_string.decode("utf-8"),
45+
headers=req.headers,
46+
)
47+
48+
# BoltResponse を取り込み、標準の Flask レスポンスに変換します
49+
def to_flask_response(bolt_resp:BoltResponse) -> Response:
50+
resp:Response = make_response(bolt_resp.body, bolt_resp.status)
51+
for k, values in bolt_resp.headers.items():
52+
for v in values:
53+
resp.headers.add_header(k, v)
54+
return resp
55+
56+
# アプリからインスタンス化します
57+
# Flask アプリを受け取ります
58+
class SlackRequestHandler:
59+
def __init__(self, app:App):
60+
self.app = app
61+
62+
# Slack からリクエストが届いたときに
63+
# Flask アプリの handle() を呼び出します
64+
def handle(self, req:Request) -> Response:
65+
# この例では OAuth に関する部分は扱いません
66+
if req.method == "POST":
67+
# Bolt へのリクエストをディスパッチし、処理とルーティングを行います
68+
bolt_resp:BoltResponse = self.app.dispatch(to_bolt_request(req))
69+
return to_flask_response(bolt_resp)
70+
71+
return make_response("Not Found", 404)
72+
```

docs/_advanced/ja_errors.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
---
2+
title: エラーの処理
3+
lang: ja-jp
4+
slug: errors
5+
order: 3
6+
---
7+
8+
<div class="section-content">
9+
リスナー内でエラーが発生した場合に try/except ブロックを使用して直接エラーを処理することができます。アプリに関連するエラーは、`BoltError` 型です。Slack API の呼び出しに関連するエラーは、`SlackApiError` 型となります。
10+
11+
デフォルトでは、すべての処理されなかった例外のログはグローバルのエラーハンドラーによってコンソールに出力されます。グローバルのエラーを開発者自身で処理するには、`app.error(fn)` 関数を使ってグローバルのエラーハンドラーをアプリに設定します。
12+
</div>
13+
14+
```python
15+
@app.error
16+
def custom_error_handler(error, body, logger):
17+
logger.exception(f"Error: {error}")
18+
logger.info(f"Request body: {body}")
19+
```

0 commit comments

Comments
 (0)