# 概要 (/docs/)
mixi2 Developer Platform へようこそ。
mixi2 Developer Platform は、mixi2 上で動作するアプリケーションを開発するためのプラットフォームです。
このドキュメントでは、アプリケーションを開発するために必要な情報を提供しています。
## はじめに [#はじめに]
mixi2 Developer Platform を利用するには、mixi2 アカウントに対して開発者登録を行う必要があります。
その後、クイックスタートに沿ってアプリケーションを作成できます。
## 開発ガイド [#開発ガイド]
アプリケーション開発に必要な知識を学びます。
## リファレンス [#リファレンス]
API の仕様や制限事項を確認できます。
## リソース [#リソース]
# アプリケーションの概念 (/docs/getting-started/concepts)
## アプリケーションとは [#アプリケーションとは]
プログラムで動作する mixi2 アカウントです。mixi2 上では 1 ユーザーとしてプロフィールを持ちメンション、リプライ、DM などに自動で応答やポストを行います。実態は API サーバーのような常駐型プロセス(アプリケーションサーバー)です。
### アプリケーションの種類 [#アプリケーションの種類]
| 種類 | 説明 | 反応するイベント | 提供状況 |
| ------ | --------------------------- | ---------------------------------- | ---- |
| Bot | ユーザーにサービスを提供する基本的なアプリケーション | リプライ、メンション、DM | 提供中 |
| Plugin | コミュニティにインストールされる拡張型アプリケーション | Bot の全イベント + コミュニティ内のポスト、メンバーの出入り等 | 提供中 |
## 次のステップ [#次のステップ]
* [クイックスタート](/getting-started/quickstart) - 最初のアプリケーションを作成する
* [コミュニティプラグイン](/guides/plugin) - コミュニティにインストールする Plugin を開発する
# クイックスタート (/docs/getting-started/quickstart)
このガイドでは、mixi2 Developer Platform でアプリケーション(Bot)を作成し、イベントを受信して応答する基本的な流れを説明します。
## 前提条件 [#前提条件]
* [開発者登録](/getting-started/registration)が完了していること
* [アプリケーションの概念](/getting-started/concepts)を理解していること
## Step 1: アプリケーションを作成する [#step-1-アプリケーションを作成する]
mixi2 Developer Platform にログインし、「新規アプリケーション」をクリックします。
以下の情報を入力してアプリケーションを作成します。
| 項目 | 説明 |
| --------- | -------------------------------------------------- |
| ID | mixi2 上で表示される ID です。ユーザー全体でユニークである必要があり、後から変更できません |
| 表示名 | アプリケーションの表示名です。後から変更できます |
| インストールタイプ | アプリケーションの種別です。このガイドでは **Bot** を選択してください |
アプリケーションを作成すると、mixi2 上に指定した ID のアカウントが生成されます。mixi2 アプリで `@ID` を検索すると、アカウントが作成されていることが確認できます。
## Step 2: 認証情報を取得する [#step-2-認証情報を取得する]
アプリケーションを作成すると、アプリケーション詳細画面に遷移します。
サイドバーで「認証情報」を選択し、Client Secret を生成します。
以下の情報が、後の手順で必要になります。
### クライアント認証情報 [#クライアント認証情報]
| 項目 | 説明 |
| ------------- | ------------------------------- |
| Client ID | OAuth 2.0 認証に使用するクライアント ID |
| Client Secret | OAuth 2.0 認証に使用するシークレット。再発行可能です |
### 接続先情報 [#接続先情報]
| 項目 | 説明 |
| -------------- | ------------------------ |
| Token URL | アクセストークン取得用のエンドポイント URL |
| API Address | API 呼び出し用のサーバーアドレス |
| Stream Address | gRPC ストリーミング接続用のサーバーアドレス |
Client Secret は秘密情報です。ソースコードにハードコーディングしたり、ログ出力したり、リポジトリにコミットしないでください。
## Step 3: アプリケーションサーバーのセットアップ [#step-3-アプリケーションサーバーのセットアップ]
アプリケーションサーバーのサンプルコードをセットアップします。
### サンプルコードリポジトリをクローン [#サンプルコードリポジトリをクローン]
```bash
git clone https://github.com/mixigroup/mixi2-application-sample-go.git
cd mixi2-application-sample-go
```
このクイックスタートではサンプルコードリポジトリを使用しますが、SDK や API 定義など他の公開リポジトリもあります。詳しくは [GitHub リポジトリ](/resource/github)を参照してください。
### 認証情報を設定 [#認証情報を設定]
リポジトリ内の `.env.example` を `.env` にコピーし、Step 2 で生成した認証情報を設定します。
```bash
cp .env.example .env
```
`.env` ファイルを編集し、以下の環境変数を設定してください。
| 変数名 | 説明 |
| ---------------- | -------------------------------------------------- |
| `CLIENT_ID` | mixi2 Developer Platform で発行した OAuth2 クライアント ID |
| `CLIENT_SECRET` | mixi2 Developer Platform で発行した OAuth2 クライアントシークレット |
| `TOKEN_URL` | mixi2 Developer Platform で確認したトークンエンドポイント URL |
| `API_ADDRESS` | mixi2 Developer Platform で確認した API サーバーアドレス |
| `STREAM_ADDRESS` | mixi2 Developer Platform で確認した Stream サーバーアドレス |
サンプルコードの詳細は[SDK ガイド](/guides/sdk#サンプルアプリケーション)を参照してください。
## Step 4: アプリケーションサーバーを起動する [#step-4-アプリケーションサーバーを起動する]
アプリケーションサーバーと mixi2 のサーバーを接続する方法は、gRPC ストリーム接続と Webhook URL 登録の 2 種類があります。
ローカル環境から検証する場合は、外部からアクセス可能な URL が不要な gRPC ストリーム接続が便利です。以下のコマンドでアプリケーションサーバーを起動します。
```bash
source .env
go run cmd/stream/main.go
```
起動すると、mixi2 のサーバーに gRPC ストリーム接続を確立し、イベントの待ち受けを開始します。
## Step 5: 動作を確認する [#step-5-動作を確認する]
アプリケーションサーバーが正しく動作しているか確認します。
mixi2 アプリで、Step 1 で作成したアプリケーションに DM を送信してください。
ターミナルにイベント受信のログが表示され、送信した内容と同じメッセージが返ってくれば成功です。
## 次のステップ [#次のステップ]
* [アプリケーション開発](/guides/application) - アプリケーションの詳細な開発方法
* [コミュニティプラグイン](/guides/plugin) - コミュニティに対する機能を提供する Plugin を開発する場合
* [Webhook でイベントを受信する](/guides/webhook) - Webhook 方式の実装・署名検証・デプロイ
* [gRPC ストリームでイベントを受信する](/guides/grpc-stream) - gRPC 方式の実装・再接続
* [GitHub リポジトリ](/resource/github) - SDK・API 定義・サンプルコードの公開リポジトリ一覧
# 開発者登録 (/docs/getting-started/registration)
mixi2 Developer Platform を利用するには、mixi2 アカウントに対して開発者登録を行う必要があります。
mixi2 アカウントを持っているだけでは利用できません。別途、開発者登録の申請と審査が必要です。
このガイドでは、利用申請から初回ログインまでの手順を説明します。
## 開発者登録とは [#開発者登録とは]
開発者登録とは、既存の mixi2 アカウントに mixi2 Developer Platform へのアクセス権限を追加する手続きです。新しいアカウントが作成されるわけではなく、お持ちの mixi2 アカウントに開発者としての権限が付与されます。
登録が完了すると、同じ mixi2 アカウントで mixi2 Developer Platform にログインし、アプリケーションを作成できるようになります。
## 前提条件 [#前提条件]
* mixi2 のアカウントを持っていること
## Step 1: 利用申請 [#step-1-利用申請]
mixi2 Developer Platform にアクセスし、利用申請を行います。
1. 「利用申請」ボタンをクリックします
2. 申請フォームに必要事項を入力します
3) 内容を確認し、送信します
## Step 2: 審査 [#step-2-審査]
申請後、運営による審査が行われます。
* 審査は申請の到着順に実施されますが、順番が前後する場合があります
* システムの状況により、審査に時間がかかる場合や、新規受付を一時停止する場合があります
* 審査状況についてのお問い合わせにはお答えできません
## Step 3: 審査完了・ログイン [#step-3-審査完了ログイン]
審査が完了すると、mixi2 上で [mixi2 公式アカウント](https://mixi.social/@mixi2)からメッセージが届きます。
1. [mixi2 公式アカウント](https://mixi.social/@mixi2)からの審査完了メッセージを確認します
2. mixi2 Developer Platform にアクセスします
3. 「ログイン」ボタンをクリックします
4. 電話番号が未登録の場合は、画面の案内に従って電話番号を登録します
5. 利用規約・プライバシーポリシーの同意画面が表示されたら、内容を確認のうえ同意します
6. ダッシュボードにアクセスできることを確認します
mixi2 Developer Platform を利用するには、mixi2 アカウントに電話番号の登録が必要です。mixi2 はメールアドレスのみでアカウントを作成できますが、初回ログイン時に電話番号が未登録の場合は登録が求められます。
ログイン後は、ダッシュボードからアプリケーションを作成できます。
## 次のステップ [#次のステップ]
ログインできたら、以下のドキュメントを参照してアプリケーション開発を始めましょう。
* [アプリケーションの概念](/getting-started/concepts) - アプリケーションの基本概念を理解する
* [クイックスタート](/getting-started/quickstart) - 最初のアプリケーションを作成する
# API の使い方 (/docs/guides/api-usage)
このガイドでは、mixi2 API を使用してアプリケーションから各種操作を行う方法を解説します。
## 前提条件 [#前提条件]
* [開発者登録](/getting-started/registration)が完了していること
* [クイックスタート](/getting-started/quickstart)を完了していること
## 主要 API 一覧 [#主要-api-一覧]
| RPC | 説明 |
| ------------------------- | ------------------------- |
| `CreatePost` | ポストを作成(返信/引用/メディア添付対応) |
| `DeletePost` | ポストを削除 |
| `SendChatMessage` | チャットメッセージを送信(テキスト/メディア添付) |
| `InitiatePostMediaUpload` | メディアアップロードを開始 |
| `GetPostMediaStatus` | メディアのアップロード/処理状況を取得 |
| `GetStamps` | スタンプ一覧を取得 |
| `AddStampToPost` | ポストにスタンプを付与 |
| `GetUsers` | ユーザー情報を取得 |
| `GetPosts` | ポスト情報を取得 |
このページでは Bot・Plugin 共通の API を説明します。Plugin 固有の API(`GetCommunityTimeline`、`GetCommunityMemberList` など)は [コミュニティプラグイン](/guides/plugin#plugin-固有の-api) を参照してください。
## 共通の初期化処理 [#共通の初期化処理]
各 API のサンプルコードは、以下のクライアント、認証、接続の初期化が完了している前提で記述しています。
```go
import (
"context"
"crypto/tls"
"log"
"os"
"github.com/mixigroup/mixi2-application-sdk-go/auth"
application_apiv1 "github.com/mixigroup/mixi2-application-sdk-go/gen/go/social/mixi/application/api/v1"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
)
// 認証の設定
authenticator, err := auth.NewAuthenticator(
os.Getenv("CLIENT_ID"),
os.Getenv("CLIENT_SECRET"),
os.Getenv("TOKEN_URL"),
)
if err != nil {
log.Fatal(err)
}
// API サーバーへの接続
apiConn, err := grpc.NewClient(
os.Getenv("API_ADDRESS"),
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
)
if err != nil {
log.Fatal(err)
}
defer apiConn.Close()
// API クライアントの作成
client := application_apiv1.NewApplicationServiceClient(apiConn)
// 認証済みコンテキストの取得
authCtx, err := authenticator.AuthorizedContext(context.Background())
if err != nil {
log.Fatal(err)
}
```
## ポストの作成 [#ポストの作成]
`CreatePost` RPC を使用してポストを作成します。
### 基本的なポスト [#基本的なポスト]
```go
_, err := client.CreatePost(authCtx, &application_apiv1.CreatePostRequest{
Text: "こんにちは!",
})
if err != nil {
log.Fatal(err)
}
```
### リプライ [#リプライ]
受信したポストに返信する場合は、`in_reply_to_post_id` を指定します。
```go
inReplyToPostId := event.Post.PostId
_, err := client.CreatePost(authCtx, &application_apiv1.CreatePostRequest{
Text: "これは面白いポストですね!",
InReplyToPostId: &inReplyToPostId,
})
if err != nil {
log.Fatal(err)
}
```
### 引用ポスト [#引用ポスト]
他のポストを引用する場合は、`quoted_post_id` を指定します。
```go
quotedPostId := originalPostId
_, err := client.CreatePost(authCtx, &application_apiv1.CreatePostRequest{
Text: "これは面白いポストですね!",
QuotedPostId: "edPostId,
})
if err != nil {
log.Fatal(err)
}
```
`in_reply_to_post_id` と `quoted_post_id` は同時に指定できません。
### マスク付きポスト [#マスク付きポスト]
センシティブなコンテンツやネタバレを含むポストには、マスクを適用できます。
```go
caption := "映画のネタバレ注意"
_, err := client.CreatePost(authCtx, &application_apiv1.CreatePostRequest{
Text: "ネタバレを含む内容です...",
PostMask: &modelv1.PostMask{
MaskType: constv1.PostMaskType_POST_MASK_TYPE_SPOILER,
Caption: &caption,
},
})
if err != nil {
log.Fatal(err)
}
```
| マスク種別 | 説明 |
| -------------------------- | ----------------- |
| `POST_MASK_TYPE_SENSITIVE` | 刺激的なコンテンツに対する注意喚起 |
| `POST_MASK_TYPE_SPOILER` | ネタバレ防止のための注意喚起 |
**ユースケース:**
* センシティブな可能性があるコンテンツに予防的にマスクを適用
* ゲーム攻略・レビューボットでネタバレを含む返信にスポイラーマスクを適用
* ユーザーが「ネタバレあり」などのキーワードを含めた場合に自動でマスクを適用
### 配信設定 [#配信設定]
ポストの配信範囲を制御できます。
```go
publishingType := constv1.PostPublishingType_POST_PUBLISHING_TYPE_NOT_PUBLISHING
_, err := client.CreatePost(authCtx, &application_apiv1.CreatePostRequest{
Text: "このポストはプロフィールにのみ表示されます",
PublishingType: &publishingType,
})
if err != nil {
log.Fatal(err)
}
```
| 配信設定 | 説明 |
| ------------------------------------- | ---------------------- |
| `POST_PUBLISHING_TYPE_UNSPECIFIED` | フォロワーのタイムラインに公開(デフォルト) |
| `POST_PUBLISHING_TYPE_NOT_PUBLISHING` | プロフィールにのみ公開 |
`NOT_PUBLISHING` は、特定ユーザーへの返信時にフォロワー全体のタイムラインに流さない場合や、テストポストに便利です。
### ポスト作成の制限 [#ポスト作成の制限]
| 項目 | 制限 |
| --------- | ------------- |
| テキスト最大文字数 | 149 文字 |
| メディア添付 | 最大 4 件 |
| メンション数 | 文字数に収まる限り制限なし |
## ポストの削除 [#ポストの削除]
`DeletePost` RPC を使用して、アプリケーションが作成したポストを削除します。
```go
// 作成したポストのIDを使用
createResp, err := client.CreatePost(authCtx, &application_apiv1.CreatePostRequest{
Text: "テストポスト",
})
if err != nil {
log.Fatal(err)
}
// ポストを削除
_, err = client.DeletePost(authCtx, &application_apiv1.DeletePostRequest{
PostId: createResp.Post.PostId,
})
if err != nil {
log.Fatal(err)
}
```
### ユースケース [#ユースケース]
* **デバッグポストの削除**: アプリケーション開発時にテストで投稿した内容を削除
* **誤ったポストの削除**: アプリケーションが誤って投稿した内容を削除
* **期間限定コンテンツ**: 一定期間後に自動削除するポスト(例: 限定告知)
### ポスト削除の制限 [#ポスト削除の制限]
| 項目 | 制限 |
| --------- | ---------------------------- |
| 削除可能なポスト | アプリケーション自身が作成したポストのみ |
| 削除の不可逆性 | 削除したポストは復元できない |
| 関連データへの影響 | 返信・引用は残るが、削除されたポストの内容は表示されない |
ポストを削除すると復元できません。また、存在しないポストや削除権限のないポストを指定した場合はエラーが返されます。
## DM の送信 [#dm-の送信]
`SendChatMessage` RPC を使用して DM を送信します。
```go
text := "メッセージを受け取りました!"
_, err := client.SendChatMessage(authCtx, &application_apiv1.SendChatMessageRequest{
RoomId: event.Message.RoomId,
Text: &text,
})
if err != nil {
log.Fatal(err)
}
```
アプリケーションから先に DM を送ることはできません。ユーザーから DM を受信した際に、イベントに含まれる `room_id` を使用して返信できます。
### DM 送信の制限 [#dm-送信の制限]
| 項目 | 制限 |
| ------- | --------------------------- |
| 先送り可否 | 不可(ユーザーからの DM 受信後のみ返信可能) |
| 必須フィールド | `text` または `media_id` のいずれか |
## メディアのアップロード [#メディアのアップロード]
ポストや DM にメディア(画像・動画)を添付するには、以下のフローで処理します。
### Step 1: アップロードの開始 [#step-1-アップロードの開始]
`InitiatePostMediaUpload` を呼び出して、`media_id` と `upload_url` を取得します。
```go
// メディアデータを準備(例: ファイルから読み込み)
imageData, err := os.ReadFile("image.jpg")
if err != nil {
log.Fatal(err)
}
description := "画像の説明(任意)"
resp, err := client.InitiatePostMediaUpload(authCtx, &application_apiv1.InitiatePostMediaUploadRequest{
MediaType: application_apiv1.InitiatePostMediaUploadRequest_TYPE_IMAGE,
ContentType: "image/jpeg",
DataSize: uint64(len(imageData)),
Description: &description,
})
if err != nil {
log.Fatal(err)
}
mediaId := resp.MediaId
uploadUrl := resp.UploadUrl
```
### Step 2: メディアのアップロード [#step-2-メディアのアップロード]
取得した `upload_url` にメディアデータを POST で送信します。Authorization ヘッダーにアクセストークンを設定する必要があります。
Step 1 の `InitiatePostMediaUpload` に渡す `ContentType` は、メディア登録開始時に、アップロード対象のファイル種別を mixi2 API に伝える値です。一方、`upload_url` への `Content-Type` ヘッダーは、実際に送る HTTP リクエストのボディ形式を示すもので、この例ではバイナリデータをそのまま送るため `application/octet-stream` を指定します。
```go
// アクセストークンを取得
accessToken, err := authenticator.GetAccessToken(authCtx)
if err != nil {
log.Fatal(err)
}
// アップロードリクエストを作成
uploadReq, err := http.NewRequest(http.MethodPost, uploadUrl, bytes.NewReader(imageData))
if err != nil {
log.Fatal(err)
}
uploadReq.Header.Set("Authorization", "Bearer "+accessToken)
uploadReq.Header.Set("Content-Type", "application/octet-stream")
// タイムアウト付きでアップロードを実行
httpClient := &http.Client{
Timeout: 30 * time.Second,
}
uploadResp, err := httpClient.Do(uploadReq)
if err != nil {
log.Fatal(err)
}
defer uploadResp.Body.Close()
// レスポンスステータスを確認
if uploadResp.StatusCode != http.StatusOK && uploadResp.StatusCode != http.StatusAccepted {
respBody, _ := io.ReadAll(uploadResp.Body)
log.Fatalf("media upload failed with status %s: %s", uploadResp.Status, string(respBody))
}
```
### Step 3: 処理状況の確認 [#step-3-処理状況の確認]
`GetPostMediaStatus` でメディアの処理状況を確認します。異常時に待ち続けないよう、全体のタイムアウトを設けたうえで `STATUS_COMPLETED` になるまでポーリングしてください。
```go
pollCtx, cancel := context.WithTimeout(authCtx, 2*time.Minute)
defer cancel()
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
pollLoop:
for {
select {
case <-pollCtx.Done():
log.Fatalf("timed out waiting for media processing: %v", pollCtx.Err())
case <-ticker.C:
statusResp, err := client.GetPostMediaStatus(pollCtx, &application_apiv1.GetPostMediaStatusRequest{
MediaId: mediaId,
})
if err != nil {
log.Fatal(err)
}
if statusResp.Status == application_apiv1.GetPostMediaStatusResponse_STATUS_COMPLETED {
break pollLoop
}
if statusResp.Status == application_apiv1.GetPostMediaStatusResponse_STATUS_FAILED {
log.Fatal("media processing failed")
}
}
}
```
| ステータス | 説明 |
| ----------------------- | --------- |
| `STATUS_UPLOAD_PENDING` | アップロード待機中 |
| `STATUS_PROCESSING` | 処理中 |
| `STATUS_COMPLETED` | 完了 |
| `STATUS_FAILED` | 失敗 |
### Step 4: ポストへの添付 [#step-4-ポストへの添付]
処理が完了したら、`CreatePost` で `media_id` を指定してポストを作成します。
```go
_, err := client.CreatePost(authCtx, &application_apiv1.CreatePostRequest{
Text: "画像を添付しました!",
MediaIdList: []string{mediaId},
})
if err != nil {
log.Fatal(err)
}
```
### メディアアップロードの制限 [#メディアアップロードの制限]
| 項目 | 制限 |
| -------------- | ---------------------- |
| 画像最大サイズ | 15 MB |
| 動画最大サイズ | 50 MB |
| 対応フォーマット | JPEG, PNG, GIF, MP4 など |
| アップロード有効期限(画像) | 200 秒 |
| アップロード有効期限(動画) | 600 秒 |
`STATUS_FAILED` になったメディアは再利用できません。`InitiatePostMediaUpload` からやり直してください。
## スタンプの付与 [#スタンプの付与]
`AddStampToPost` RPC を使用して、ポストにスタンプを付与できます。
```go
// 利用可能なスタンプ一覧を取得
language := constv1.LanguageCode_LANGUAGE_CODE_JP
stampsResp, err := client.GetStamps(authCtx, &application_apiv1.GetStampsRequest{
OfficialStampLanguage: &language,
})
if err != nil {
log.Fatal(err)
}
// スタンプを付与
_, err = client.AddStampToPost(authCtx, &application_apiv1.AddStampToPostRequest{
PostId: postId,
StampId: stampsResp.OfficialStampSets[0].Stamps[0].StampId,
})
if err != nil {
log.Fatal(err)
}
```
### スタンプ付与の制限 [#スタンプ付与の制限]
| 項目 | 制限 |
| --------- | ----------------------- |
| 対象ポスト | アプリケーションにメンションしているポストのみ |
| 使用可能なスタンプ | 公式スタンプのみ |
| 付与回数 | 同じポストに複数回付与不可 |
アプリケーションが付与したスタンプを取り消す機能は現在提供されていません。
### ユースケース [#ユースケース-1]
* ユーザーからのメンションに対して「確認しました」の意味でスタンプを付与
* 特定のキーワードを含むメンションにリアクションスタンプを付与
* 返信の代わりに軽量なリアクションとして使用
## ユーザー情報の取得 [#ユーザー情報の取得]
`GetUsers` RPC を使用して、ユーザー情報を取得できます。
```go
resp, err := client.GetUsers(authCtx, &application_apiv1.GetUsersRequest{
UserIdList: []string{event.Post.CreatorId},
})
if err != nil {
log.Fatal(err)
}
for _, user := range resp.Users {
fmt.Printf("ユーザー名: %s\n", user.DisplayName)
}
```
### ユースケース [#ユースケース-2]
* イベントで受信したユーザーの詳細情報(表示名、アイコン URL)を取得
* ポスト作成者の情報を取得してログ出力や管理画面に表示
アプリケーションがアクセス可能なユーザー情報のみ取得できます。
## ポスト情報の取得 [#ポスト情報の取得]
`GetPosts` RPC を使用して、ポスト情報を取得できます。
```go
resp, err := client.GetPosts(authCtx, &application_apiv1.GetPostsRequest{
PostIdList: []string{event.Post.GetInReplyToPostId()},
})
if err != nil {
log.Fatal(err)
}
for _, post := range resp.Posts {
fmt.Printf("ポスト本文: %s\n", post.Text)
}
```
### ユースケース [#ユースケース-3]
* リプライや引用ポストを受信した際に、元のポスト情報(本文、メディア、スタンプ等)を取得
* メンションされたポストの添付メディアやスタンプ情報を確認
アプリケーションがアクセス可能なポストのみ取得可能です。
## 次のステップ [#次のステップ]
* [アプリケーション開発](/guides/application) - Webhook URL の設定、デプロイ
* [イベント](/guides/events) - イベントの種類と構造
* [Webhook でイベントを受信する](/guides/webhook) - Webhook 方式の実装
* [gRPC ストリームでイベントを受信する](/guides/grpc-stream) - gRPC 方式の実装
* [API リファレンス](/reference/api-document) - API の完全な仕様
# アプリケーション開発 (/docs/guides/application)
このガイドでは、アプリケーション設定から、デプロイ、テストまでの流れを解説します。
## 前提条件 [#前提条件]
* [開発者登録](/getting-started/registration)が完了していること
* [クイックスタート](/getting-started/quickstart)でアプリケーションを作成済みであること
## イベント受信方式 [#イベント受信方式]
アプリケーションはイベントを受信して処理を行います。2 つのイベント受信方式から選択できます。
| 方式 | 推奨シーン |
| ------------ | --------------- |
| gRPC ストリーム | ローカル開発、プロトタイピング |
| HTTP Webhook | 本番環境、サーバーレス環境 |
各方式の詳細は [Webhook](/guides/webhook)、[gRPC ストリーム](/guides/grpc-stream) をそれぞれ参照してください。
## Webhook の設定 [#webhook-の設定]
Webhook 方式を使用する場合、mixi2 Developer Platform で URL を登録し、検証を完了させる必要があります。
### 設定手順 [#設定手順]
1. mixi2 Developer Platform の管理画面でアプリケーションの「Webhook」を開きます
2. Webhook URL を登録します
3. 「接続確認を実行」を押します
URL の要件、署名検証の仕様、検証の仕組みの詳細は [Webhook でイベントを受信する](/guides/webhook) を参照してください。
### Webhook の状態 [#webhook-の状態]
| 状態 | 説明 |
| ---- | --------------------- |
| 無効 | 初期状態、または無効にした状態 |
| 確認中 | 「接続確認を実行」を押した後の接続確認中 |
| 確認失敗 | 接続確認に失敗した状態 |
| 有効 | 接続確認が完了し、イベントを受信できる状態 |
「有効」から「無効にする」にするとステータスは「無効」に戻ります。エンドポイントを再設定した場合も「無効」に戻るため、再度接続確認を実行する必要があります。
## 環境変数 [#環境変数]
アプリケーションサーバーの動作には、認証情報や接続先情報を環境変数として設定する必要があります。取得方法と設定手順は[クイックスタート](/getting-started/quickstart#step-2-認証情報を取得する)を参照してください。
## デプロイ [#デプロイ]
Webhook 方式を使用する場合、HTTPS に対応した URL でリクエストを受信できる環境が必要です。デプロイの詳細は [Webhook でイベントを受信する - デプロイ](/guides/webhook#デプロイ) を参照してください。
## エラーハンドリング [#エラーハンドリング]
API 呼び出し時にエラーが発生した場合は、エラーの種類に応じて適切に対処してください。
| エラー種別 | 対処法 |
| --------------- | ----------------------------- |
| 認証エラー | トークンを再取得してリトライ(SDK は自動で対応) |
| レート制限超過 | `retry-after` ヘッダーに従って待機後リトライ |
| サーバーエラー | 指数バックオフでリトライ(最大 3 回程度) |
| クライアントエラー (4xx) | リトライせずログ出力、リクエスト内容を確認 |
レート制限の詳細(制限値、レスポンスヘッダー、エラーレスポンス)は[レート制限](/reference/rate-limits)を参照してください。
## テスト方法 [#テスト方法]
開発中のテストは以下の手順で行います。
1. gRPC ストリーム方式でアプリケーションを起動
2. mixi2 アプリから実際にメンション・DM を送信
3. ログでイベント受信と処理結果を確認
テスト用のサンドボックス環境やイベントシミュレート機能は現在提供されていません。
## 開発リソース [#開発リソース]
アプリケーション開発に必要なリソースは GitHub で公開しています。詳細は [GitHub リポジトリ](/resource/github)を参照してください。
| リポジトリ | 説明 |
| --------------------------------------------------------------------------------------- | ------------------------ |
| [mixi2-api](https://github.com/mixigroup/mixi2-api) | API 定義(Protocol Buffers) |
| [mixi2-application-sdk-go](https://github.com/mixigroup/mixi2-application-sdk-go) | Go 向け公式 SDK |
| [mixi2-application-sample-go](https://github.com/mixigroup/mixi2-application-sample-go) | サンプルアプリケーション |
## 次のステップ [#次のステップ]
* [コミュニティプラグイン](/guides/plugin) - コミュニティにインストールする Plugin の作成・設定
* [Webhook でイベントを受信する](/guides/webhook) - Webhook 方式の実装・署名検証・デプロイ
* [gRPC ストリームでイベントを受信する](/guides/grpc-stream) - gRPC 方式の実装・再接続
* [イベント](/guides/events) - イベントの種類と構造
* [SDK ガイド](/guides/sdk) - SDK の基本(認証、イベントハンドラ)
* [API の使い方](/guides/api-usage) - ポストの作成、DM の送信、メディアのアップロード
* [API リファレンス](/reference/api-document) - API の完全な仕様
* [レート制限](/reference/rate-limits) - API のレート制限
# イベント (/docs/guides/events)
mixi2 では、ユーザーがアプリケーションにメンションしたり、DM を送信したりすると、その情報がイベントとしてアプリケーションサーバーに配信されます。このページでは、イベントの種類と構造について説明します。
## 前提条件 [#前提条件]
* [アプリケーションの概念](/getting-started/concepts)を理解していること
* [クイックスタート](/getting-started/quickstart)を完了していること
## イベントの種類 [#イベントの種類]
アプリケーションが受信できるイベントは以下の通りです。
| イベント種別 | 説明 |
| ------------------------------------- | ------------------------------------------------- |
| `EVENT_TYPE_PING` | 接続確認用のイベント |
| `EVENT_TYPE_POST_CREATED` | ポストが作成されたときに発生 |
| `EVENT_TYPE_CHAT_MESSAGE_RECEIVED` | チャット/DM メッセージを受信したときに発生 |
| `EVENT_TYPE_COMMUNITY_MEMBER_CHANGED` | コミュニティのメンバーが参加・退出したときに発生(Plugin のみ) |
| `EVENT_TYPE_COMMUNITY_PLUGIN_MANAGED` | Plugin がコミュニティにインストール・アンインストールされたときに発生(Plugin のみ) |
### ポスト作成イベント(PostCreatedEvent) [#ポスト作成イベントpostcreatedevent]
ユーザーがアプリケーションにメンション、リプライ、または引用を行った場合に発生します。Plugin の場合はこれらに加えて、Plugin がインストールされているコミュニティで新規ポストが作成されたときにも発生します(`EVENT_REASON_POST_COMMUNITY`)。
| フィールド | 型 | 説明 |
| ------------------- | ------------------ | --------------------------------------- |
| `event_reason_list` | EventReason\[] | イベントが発生した理由のリスト |
| `post` | Post | 作成されたポストの情報 |
| `issuer` | User | ポストを作成したユーザーの情報 |
| `posted_community` | optional Community | 投稿先のコミュニティ情報(Plugin でコミュニティのポストを受信した場合) |
`event_reason_list` には、イベントが発生した理由が含まれます。
| イベント理由(EventReason) | 説明 |
| ----------------------------- | ------------------------------- |
| `EVENT_REASON_POST_REPLY` | アプリケーションのポストに返信された |
| `EVENT_REASON_POST_MENTIONED` | ポスト内でメンションされた |
| `EVENT_REASON_POST_QUOTED` | アプリケーションのポストが引用された |
| `EVENT_REASON_POST_COMMUNITY` | インストール済みコミュニティに投稿された(Plugin のみ) |
### チャットメッセージ受信イベント(ChatMessageReceivedEvent) [#チャットメッセージ受信イベントchatmessagereceivedevent]
ユーザーがアプリケーションに DM を送信した場合に発生します。
| フィールド | 型 | 説明 |
| ------------------- | -------------- | ----------------- |
| `event_reason_list` | EventReason\[] | イベントが発生した理由のリスト |
| `message` | ChatMessage | 受信したメッセージの情報 |
| `issuer` | User | メッセージを送信したユーザーの情報 |
`event_reason_list` には、イベントが発生した理由が含まれます。
| イベント理由(EventReason) | 説明 |
| -------------------------------------- | -------------------- |
| `EVENT_REASON_DIRECT_MESSAGE_RECEIVED` | チャット/ダイレクトメッセージを受信した |
### コミュニティメンバー変更イベント(CommunityMemberChangedEvent) [#コミュニティメンバー変更イベントcommunitymemberchangedevent]
Plugin がインストールされたコミュニティでメンバーが参加・退出した場合に発生します。Requirement に `Community.Member.Joined` を宣言した Plugin のみが受信できます。
| フィールド | 型 | 説明 |
| ------------------- | -------------- | --------------------- |
| `event_reason_list` | EventReason\[] | イベントが発生した理由のリスト |
| `member` | User | コミュニティに参加・退出したユーザーの情報 |
| `community` | Community | 対象コミュニティの情報 |
| イベント理由(EventReason) | 説明 |
| -------------------------------------- | ----------------- |
| `EVENT_REASON_COMMUNITY_MEMBER_JOINED` | コミュニティにメンバーが参加した |
| `EVENT_REASON_COMMUNITY_MEMBER_LEFT` | コミュニティからメンバーが退出した |
### コミュニティプラグイン管理イベント(CommunityPluginManagedEvent) [#コミュニティプラグイン管理イベントcommunitypluginmanagedevent]
Plugin がコミュニティにインストール、またはアンインストールされたときに発生します。Plugin アプリケーションのみが受信できます。
| フィールド | 型 | 説明 |
| ------------------- | -------------- | ----------------------------------------------------------------------------------------- |
| `event_reason_list` | EventReason\[] | `EVENT_REASON_COMMUNITY_PLUGIN_INSTALLED` または `EVENT_REASON_COMMUNITY_PLUGIN_UNINSTALLED` |
| `community` | Community | 対象コミュニティの情報 |
| イベント理由(EventReason) | 説明 |
| ------------------------------------------- | --------------------------- |
| `EVENT_REASON_COMMUNITY_PLUGIN_INSTALLED` | Plugin がコミュニティにインストールされた |
| `EVENT_REASON_COMMUNITY_PLUGIN_UNINSTALLED` | Plugin がコミュニティからアンインストールされた |
このイベントを受信して初期処理やクリーンアップを行ってください。詳細は [コミュニティプラグイン](/guides/plugin) を参照してください。
## イベントの受信方式 [#イベントの受信方式]
イベントを受信するには、**gRPC ストリーム方式**と **Webhook 方式**の 2 つの方法があります。それぞれの詳細は以下のページを参照してください。
| 方式 | 用途 | ガイド |
| ------------ | ---------------------- | --------------------------------- |
| gRPC ストリーム | リアルタイム監視。ローカル開発に適しています | [gRPC ストリーム](/guides/grpc-stream) |
| HTTP Webhook | HTTPS に対応したサーバー環境 | [Webhook](/guides/webhook) |
## イベント配信の特性 [#イベント配信の特性]
イベント処理を実装する際は、以下の特性を考慮してください。
### 順序保証 [#順序保証]
イベントの処理順序は保証されません。イベントが発生した順序とは異なる順番で届く可能性があるため、特定の順序に依存しない設計にしてください。
### 配信保証 [#配信保証]
イベントは Best-effort で配信されます。
* gRPC ストリーム方式で接続が切れた場合、その間に発生したイベントは失われます
* Webhook 方式では、配信失敗時に最大 3 回までリトライされます。リトライにより同じイベントが複数回届く可能性があります
Webhook 方式ではリトライによりイベントが重複して届く場合があるため、アプリケーション側で冪等性を考慮した設計を行ってください。
## 次のステップ [#次のステップ]
* [Webhook でイベントを受信する](/guides/webhook) - Webhook 方式の実装・署名検証・デプロイ
* [gRPC ストリームでイベントを受信する](/guides/grpc-stream) - gRPC 方式の実装・再接続
* [SDK ガイド](/guides/sdk) - SDK の基本(認証、イベントハンドラ)
* [API の使い方](/guides/api-usage) - イベントを受信した後の応答方法
* [API リファレンス](/reference/api-document) - イベントの詳細な型定義
# gRPC ストリームでイベントを受信する (/docs/guides/grpc-stream)
gRPC ストリーム方式では、mixi2 のサーバーに常時接続し、リアルタイムでイベントを受信します。外部公開 URL が不要なため、ローカル開発やプロトタイピングに適した受信方式です。
## 前提条件 [#前提条件]
* [SDK ガイド](/guides/sdk) で SDK のインストールと認証の実装が完了していること
## gRPC ストリーム方式の特徴 [#grpc-ストリーム方式の特徴]
**メリット:**
* 外部公開 URL が不要
* ローカル開発で即座にテスト可能
* リアルタイム性が高い
**デメリット:**
* 常時接続が必要
* 接続が切れた場合、その間のイベントは失われる
* スケールアウトが難しい
**推奨シーン:** ローカル開発、プロトタイピング、単一インスタンスで十分な小規模アプリケーション
## SDK による実装 [#sdk-による実装]
```go
package main
import (
"context"
"crypto/tls"
"log"
"os"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"github.com/mixigroup/mixi2-application-sdk-go/auth"
"github.com/mixigroup/mixi2-application-sdk-go/event/stream"
application_streamv1 "github.com/mixigroup/mixi2-application-sdk-go/gen/go/social/mixi/application/service/application_stream/v1"
modelv1 "github.com/mixigroup/mixi2-application-sdk-go/gen/go/social/mixi/application/model/v1"
)
type MyHandler struct{}
func (h *MyHandler) Handle(ctx context.Context, ev *modelv1.Event) error {
log.Printf("Received event: %v", ev)
return nil
}
func main() {
authenticator, err := auth.NewAuthenticator(
os.Getenv("CLIENT_ID"),
os.Getenv("CLIENT_SECRET"),
os.Getenv("TOKEN_URL"),
)
if err != nil {
log.Fatal(err)
}
conn, err := grpc.NewClient(
os.Getenv("STREAM_ADDRESS"),
grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{})),
)
if err != nil {
log.Fatal(err)
}
defer conn.Close()
client := application_streamv1.NewApplicationServiceClient(conn)
watcher := stream.NewStreamWatcher(client, authenticator)
if err := watcher.Watch(context.Background(), &MyHandler{}); err != nil {
log.Fatal(err)
}
}
```
イベントハンドラ(`EventHandler` インターフェース)の詳細は [SDK ガイド - イベントハンドラの実装](/guides/sdk#イベントハンドラの実装) を参照してください。
## 再接続の仕様 [#再接続の仕様]
ストリーミング接続が切断された場合、SDK は自動的に再接続を試みます。
| 項目 | 値 |
| -------- | ------------------- |
| 再接続方式 | 指数バックオフ(1秒, 2秒, 4秒) |
| 最大リトライ回数 | 3 回 |
再接続中に発生したイベントは失われます。イベントの厳密な到達保証が必要な場合は、[Webhook 方式](/guides/webhook)の使用を検討してください。
## Ping イベント [#ping-イベント]
gRPC ストリーム方式では、イベントがない状態が 20 秒続くと Ping イベントが送信されます。Ping イベントは SDK 内部で処理されるため、`Handle` メソッドには渡されません。開発者が特別な対応をする必要はありません。
## 次のステップ [#次のステップ]
* [Webhook でイベントを受信する](/guides/webhook) - もう一つのイベント受信方式
* [イベント](/guides/events) - イベントの種類と構造
* [SDK ガイド](/guides/sdk) - SDK の基本(認証、イベントハンドラ)
* [API の使い方](/guides/api-usage) - イベントを受信した後の応答方法
# コミュニティプラグイン (/docs/guides/plugin)
Plugin(コミュニティプラグイン)は、mixi2 のコミュニティにインストールして動作する拡張型アプリケーションです。Bot の機能に加え、コミュニティ固有のイベント受信や API 操作が行えます。
## Bot との違い [#bot-との違い]
| 項目 | Bot | Plugin |
| --------- | ------------- | --------------------------------------------------- |
| 提供対象 | ユーザー | ユーザー + コミュニティ |
| 受信できるイベント | リプライ・メンション・DM | リプライ・メンション・DM・コミュニティ内のポスト・メンバー参加/退出・インストール/アンインストール |
| 使える API | 基本 API | 基本 API + コミュニティ操作 API |
| インストール | 不要 | コミュニティ管理者がインストール(最大 10 コミュニティ) |
Plugin は Bot のすべての機能を持ちつつ、コミュニティ固有の機能も利用できるアプリケーションです。コミュニティに対してポストしたい、コミュニティメンバーに DM を送りたい、コミュニティのタイムラインを取得したいといった用途には Plugin を選択してください。
## 前提条件 [#前提条件]
* [開発者登録](/getting-started/registration)が完了していること
* [アプリケーションの概念](/getting-started/concepts)を理解していること
## Plugin アプリケーションを作成する [#plugin-アプリケーションを作成する]
「アプリケーションを作成」フォームで、インストールタイプに **Plugin** を選択します。Plugin を選択すると「インストール範囲」の設定が表示されるので、適切なインストール範囲を選択してください。
### インストール範囲 [#インストール範囲]
| 選択肢 | 説明 |
| ----------------------- | ----------------------------- |
| 全てのコミュニティでインストール可能 | 任意のコミュニティ管理者がインストールできます |
| 自分が管理人のコミュニティのみインストール可能 | 開発者自身が管理するコミュニティのみにインストールできます |
## Requirement を設定する [#requirement-を設定する]
Requirement は Plugin 固有の概念で、Plugin がコミュニティに要求する**パーミッション**と受信したい**イベント**のセットです。
Requirement の設定は「Requirement」設定画面から行います。必要なパーミッションとイベントを選択してください。
### パーミッション [#パーミッション]
コミュニティに対する操作権限です。使用する API に対応したパーミッションを宣言する必要があります。
| パーミッション | 説明 | 対応 API |
| --------------------------------------- | ----------------------- | ------------------------------------ |
| `Community.Post.Read` | コミュニティのタイムラインを閲覧できます | `GetCommunityTimeline` |
| `Community.Post.Create` | コミュニティへポストを投稿できます | `CreatePost`(`community_id` 指定時) |
| `Community.Post.Restrict` | コミュニティのポストを非表示にできます | `RestrictCommunityPost` |
| `Community.MemberList.Read` | コミュニティのメンバー一覧を取得できます | `GetCommunityMemberList` |
| `Community.Post.Stamp.Create` | コミュニティのポストにスタンプを付与できます | `AddStampToPost` |
| `Community.Member.DirectMessage.Create` | コミュニティのメンバーに DM を送信できます | `SendDirectMessageToCommunityMember` |
### イベント [#イベント]
受信したいイベントを宣言します。宣言していないイベントは配信されません。
| イベント | 説明 |
| --------------------------------- | ----------------------------- |
| `Reaction.Post.Replied` | 作成したポストにリプライが付いたとき |
| `Reaction.Post.Mentioned` | メンション付きのポストが作成されたとき |
| `Reaction.DirectMessage.Received` | DM を受け取ったとき |
| `Community.Post.Created` | インストール済みコミュニティにポストが作成されたとき |
| `Community.Member.Joined` | インストール済みコミュニティにメンバーが参加・退出したとき |
Plugin のインストール・アンインストールイベント(CommunityPluginManagedEvent)は Requirement への宣言なしに、Plugin アプリケーション全てに自動で配信されます。詳しくは [イベント](/guides/events) を参照してください。
### バージョン管理と後方互換性 [#バージョン管理と後方互換性]
Requirement を保存するたびに新しい**バージョン**が作成されます。
新しいバージョンを作成しても、すでに Plugin をインストール済みのコミュニティは、コミュニティ管理者がアップデートを行うまで古いバージョンの権限のままで動作します。Requirement を変更する際は後方互換性を維持してください。
インストール済みのコミュニティとそのコミュニティが利用しているバージョンは `GetCommunitiesUsingApplication` で確認できます。
### 新バージョンを告知する [#新バージョンを告知する]
Requirement を更新して新しいバージョンを作成した後、古いバージョンを利用しているコミュニティの管理者に最新バージョンの存在を通知することができます。
Requirement 設定画面の「現在のVersion」の横に表示される **「新バージョンを告知」** ボタンから告知を送信します。
* 告知を送ると、最新バージョンになっていないコミュニティの管理者へ通知が届きます
* **告知後は 3 日間、再告知できません**(ボタンが無効になり、次回告知可能日時が表示されます)
## コミュニティへのインストール [#コミュニティへのインストール]
Plugin のインストールはコミュニティ管理者が行います。Plugin のプロフィールページに表示されるインストール動線から、自身が管理するコミュニティを選択してインストールします。
開発者がコミュニティの管理者を務めている場合は、自身でインストールできます。
インストール動線は**モバイルアプリ(iOS / Android)でのみ表示**されます。Web ブラウザ版では表示されません。
開発時の動作確認には、自身が管理するコミュニティにインストールして確認するのが有効です。
## Plugin 固有の API [#plugin-固有の-api]
サンプルコードは [API の使い方](/guides/api-usage#共通の初期化処理) と同じクライアント・認証の初期化が完了している前提で記述しています。
### インストール済みコミュニティの一覧を取得する(GetCommunitiesUsingApplication) [#インストール済みコミュニティの一覧を取得するgetcommunitiesusingapplication]
Plugin がインストールされているコミュニティの一覧と、各コミュニティが使用しているバージョンを取得します。
```go
resp, err := client.GetCommunitiesUsingApplication(authCtx, &application_apiv1.GetCommunitiesUsingApplicationRequest{})
```
ページングが必要な場合は、レスポンスの `next_cursor` を次のリクエストの `cursor` に指定してください。
### コミュニティのタイムラインを取得する(GetCommunityTimeline) [#コミュニティのタイムラインを取得するgetcommunitytimeline]
インストール済みコミュニティのタイムライン(ポスト一覧)を取得します。`Community.Post.Read` パーミッションが必要です。
```go
resp, err := client.GetCommunityTimeline(authCtx, &application_apiv1.GetCommunityTimelineRequest{
CommunityId: "YOUR_COMMUNITY_ID",
// UntilCursor: &cursor, // 古いページを取得する場合
})
```
| フィールド | 型 | 説明 |
| -------------- | --------------- | -------------------- |
| `community_id` | string | タイムラインを取得するコミュニティ ID |
| `until_cursor` | optional string | 指定したポストより古いポストを返します |
| `since_cursor` | optional string | 指定したポストより新しいポストを返します |
### コミュニティのメンバー一覧を取得する(GetCommunityMemberList) [#コミュニティのメンバー一覧を取得するgetcommunitymemberlist]
インストール済みコミュニティのメンバー一覧を取得します。`Community.MemberList.Read` パーミッションが必要です。
```go
resp, err := client.GetCommunityMemberList(authCtx, &application_apiv1.GetCommunityMemberListRequest{
CommunityId: "YOUR_COMMUNITY_ID",
// PaginationCursor: &cursor, // 次ページを取得する場合
})
```
次ページを取得する場合は、レスポンスの `next_pagination_cursor` を `pagination_cursor` に指定してください。
### コミュニティのポストを非表示にする(RestrictCommunityPost) [#コミュニティのポストを非表示にするrestrictcommunitypost]
指定したポストをコミュニティのタイムラインから非表示にします。ポストは削除されません。`Community.Post.Restrict` パーミッションが必要です。
```go
_, err := client.RestrictCommunityPost(authCtx, &application_apiv1.RestrictCommunityPostRequest{
PostId: "YOUR_POST_ID",
})
```
### コミュニティメンバーに DM を送信する(SendDirectMessageToCommunityMember) [#コミュニティメンバーに-dm-を送信するsenddirectmessagetocommunitymember]
インストール済みコミュニティのメンバーにダイレクトメッセージを送信します。`Community.Member.DirectMessage.Create` パーミッションが必要です。`text` または `media_ids` のいずれかは必須です。
```go
resp, err := client.SendDirectMessageToCommunityMember(authCtx, &application_apiv1.SendDirectMessageToCommunityMemberRequest{
ReceiverId: "YOUR_USER_ID",
CommunityId: "YOUR_COMMUNITY_ID",
Text: proto.String("メッセージ本文"),
})
```
### コミュニティスタンプを取得する(GetStamps) [#コミュニティスタンプを取得するgetstamps]
インストール済みコミュニティ固有のスタンプを取得します。`community_ids` に対象コミュニティの ID を指定します。指定コミュニティには Plugin がインストールされている必要があります。
```go
resp, err := client.GetStamps(authCtx, &application_apiv1.GetStampsRequest{
CommunityIds: []string{"YOUR_COMMUNITY_ID"},
})
```
取得したコミュニティスタンプは `AddStampToPost` でポストに付与できます(`Community.Post.Stamp.Create` パーミッションが必要です)。詳しくは [API の使い方 - スタンプの付与](/guides/api-usage#スタンプの付与) を参照してください。
## レート制限 [#レート制限]
Plugin 固有の API を含む全 RPC は、1 分あたり 20 リクエストの制限が適用されます。制限に達した場合の対処方法は [レート制限](/reference/rate-limits) を参照してください。
## 次のステップ [#次のステップ]
* [イベント](/guides/events) - イベントの種類と構造
* [Webhook でイベントを受信する](/guides/webhook) - Webhook 方式の実装
* [gRPC ストリームでイベントを受信する](/guides/grpc-stream) - gRPC 方式の実装
* [SDK ガイド](/guides/sdk) - SDK の基本(認証、イベントハンドラ)
* [API の使い方](/guides/api-usage) - Bot 共通の API(ポスト作成、DM 送信など)
* [API リファレンス](/reference/api-document) - API の完全な仕様
# SDK ガイド (/docs/guides/sdk)
mixi2 Developer Platform では、アプリケーション開発を効率化するための公式 SDK を提供しています。SDK を使用すると、認証管理やイベント受信の実装を簡略化できます。
## 前提条件 [#前提条件]
* Go 1.24.6 以上
* 開発者登録が完了していること
* クライアント ID・クライアントシークレットを取得済みであること
## インストール [#インストール]
```bash
go get github.com/mixigroup/mixi2-application-sdk-go
```
## パッケージ構造 [#パッケージ構造]
SDK は以下のパッケージで構成されています。
| パッケージ | 機能 |
| --------------- | ---------------------------------------------------- |
| `auth` | OAuth2 Client Credentials 認証(アクセストークンの取得・キャッシュ・自動更新) |
| `event` | イベントハンドリングのインターフェース定義 |
| `event/webhook` | HTTP Webhook サーバーによるイベント受信 |
| `event/stream` | gRPC ストリーミングによるイベント受信 |
| `gen` | Protocol Buffers 生成コード(型定義、gRPC クライアント等) |
```
github.com/mixigroup/mixi2-application-sdk-go/
├── auth/ # 認証(OAuth2 Client Credentials)
├── event/ # EventHandler インターフェース定義
│ ├── webhook/ # Webhook サーバー
│ └── stream/ # gRPC ストリーミング
└── gen/ # protobuf 生成コード
```
## SDK が提供する機能 [#sdk-が提供する機能]
### 認証管理 [#認証管理]
| 機能 | 説明 |
| ------------ | -------------------------------------------------- |
| OAuth 2.0 認証 | Client Credentials フローによるアクセストークン取得 |
| トークンキャッシュ | 有効期限の 1 分前までキャッシュし、自動更新 |
| gRPC メタデータ付与 | `Authorization` ヘッダに `Bearer {access_token}` を自動設定 |
### イベント受信 [#イベント受信]
SDK は 2 つのイベント受信方式をサポートしています。各方式の詳細な実装方法は個別のガイドを参照してください。
| 方式 | パッケージ | ガイド |
| ------------ | --------------- | --------------------------------- |
| HTTP Webhook | `event/webhook` | [Webhook](/guides/webhook) |
| gRPC ストリーム | `event/stream` | [gRPC ストリーム](/guides/grpc-stream) |
SDK は以下の処理を内部で行うため、開発者が個別に実装する必要はありません。
| 機能 | 方式 | 説明 |
| --------------------- | ---------- | ------------------------------- |
| Ed25519 署名検証 | Webhook | リクエストの改ざん検知。検証失敗時は HTTP 401 を返却 |
| タイムスタンプ検証 | Webhook | ±5 分以上ずれたリクエストを拒否(リプレイ攻撃対策) |
| Webhook URL 検証リクエスト応答 | Webhook | 3 種類の Ping に対して適切なレスポンスを自動返却 |
| 再接続 | gRPC ストリーム | 接続切断時に指数バックオフで自動再接続(最大 3 回) |
| Ping イベント処理 | 両方 | SDK 内部で処理し、`Handle` には渡さない |
## 認証の実装 [#認証の実装]
`auth.Authenticator` は OAuth2 Client Credentials フローによるアクセストークンの取得・キャッシュ・自動更新を行います。
```go
package main
import (
"context"
"log"
"os"
"github.com/mixigroup/mixi2-application-sdk-go/auth"
)
func main() {
authenticator, err := auth.NewAuthenticator(
os.Getenv("CLIENT_ID"),
os.Getenv("CLIENT_SECRET"),
os.Getenv("TOKEN_URL"),
)
if err != nil {
log.Fatal(err)
}
// gRPC リクエスト用のコンテキストを取得
ctx, err := authenticator.AuthorizedContext(context.Background())
if err != nil {
log.Fatal(err)
}
// ctx を使って gRPC リクエストを送信
_ = ctx
}
```
## イベントハンドラの実装 [#イベントハンドラの実装]
イベントハンドラは `Handle` メソッドを実装したインターフェースです。Webhook・gRPC ストリームの両方式で共通して使用します。
```go
import modelv1 "github.com/mixigroup/mixi2-application-sdk-go/gen/go/social/mixi/application/model/v1"
type EventHandler interface {
Handle(ctx context.Context, event *modelv1.Event) error
}
```
### 注意事項 [#注意事項]
| 項目 | 説明 |
| -------------- | ------------------------------------------------------------ |
| 並列実行 | `Handle` は複数の goroutine から並列に呼び出される可能性があります。スレッドセーフに実装してください |
| Ping イベント | SDK 内部で処理されるため、`Handle` には渡されません |
| Best-effort 処理 | `Handle` の結果にかかわらず、Webhook は常に `204 No Content` を返します |
| エラーハンドリング | `Handle` から返されたエラーはログに出力されますが、処理は継続します |
## サンプルアプリケーション [#サンプルアプリケーション]
SDK の使い方を理解するためのサンプルアプリケーションを提供しています。実際に動作するコードを参考に開発を始めることができます。
### プロジェクト構成 [#プロジェクト構成]
| ディレクトリ | 説明 |
| -------------- | ----------------------------- |
| `cmd/stream/` | gRPC ストリーミングモードで動作するアプリケーション |
| `cmd/webhook/` | HTTP Webhook モードで動作するアプリケーション |
| `api/` | Vercel サーバーレス関数のエントリーポイント |
| `handler/` | イベントを処理するハンドラ |
| `config/` | 環境変数から設定を読み込む |
### 環境変数 [#環境変数]
| 変数名 | 必須 | 説明 |
| ---------------------- | -- | ------------------------------------------- |
| `CLIENT_ID` | ○ | OAuth2 クライアント ID |
| `CLIENT_SECRET` | ○ | OAuth2 クライアントシークレット |
| `TOKEN_URL` | ○ | トークンエンドポイント URL |
| `API_ADDRESS` | ○ | API サーバーアドレス |
| `STREAM_ADDRESS` | △ | Stream サーバーアドレス ※ gRPC ストリーミング時のみ必須 |
| `SIGNATURE_PUBLIC_KEY` | △ | イベント署名検証用の公開鍵(Base64)※ Webhook・Vercel でのみ必須 |
| `PORT` | | Webhook サーバーポート(デフォルト: `8080`) |
### 対応イベント [#対応イベント]
サンプルアプリケーションは以下のイベントに反応します。
| イベント | 動作 |
| ---------------------------------- | -------------------------- |
| `EVENT_TYPE_POST_CREATED` | ポスト作成イベントをログ出力 |
| `EVENT_TYPE_CHAT_MESSAGE_RECEIVED` | 受信した DM のテキストをそのまま返信(Echo) |
### 使い方 [#使い方]
```bash
# リポジトリをクローン
git clone https://github.com/mixigroup/mixi2-application-sample-go.git
cd mixi2-application-sample-go
# 環境変数を設定
cp .env.example .env
# .env を編集して環境変数を設定
source .env
go mod tidy
# gRPC ストリームモード(ローカル開発向け)
go run cmd/stream/main.go
# HTTP Webhook モード(デプロイ向け)
go run cmd/webhook/main.go
```
ローカル開発では gRPC ストリームモードがおすすめです。外部公開 URL なしでイベントを受信できます。
## SDK を使わない開発 [#sdk-を使わない開発]
SDK を使用せずに開発する場合は、Protocol Buffers 定義から直接コードを生成できます。
```bash
# API Proto リポジトリをクローン
git clone https://github.com/mixigroup/mixi2-api.git
# buf を使用してコード生成
cd mixi2-api
buf generate
```
SDK を使用しない場合、認証管理、署名検証、再接続処理などを自前で実装する必要があります。
## リポジトリ [#リポジトリ]
| リポジトリ | 説明 |
| ------------------------------------------------------------------------ | ------------------- |
| [SDK(Go)](https://github.com/mixigroup/mixi2-application-sdk-go) | 公式 SDK |
| [サンプルアプリケーション](https://github.com/mixigroup/mixi2-application-sample-go) | サンプルアプリケーション |
| [API Proto](https://github.com/mixigroup/mixi2-api) | Protocol Buffers 定義 |
## 次のステップ [#次のステップ]
* [Webhook でイベントを受信する](/guides/webhook) - Webhook 方式の実装・署名検証・デプロイ
* [gRPC ストリームでイベントを受信する](/guides/grpc-stream) - gRPC 方式の実装・再接続
* [イベント](/guides/events) - イベントの種類・構造・配信仕様
* [API の使い方](/guides/api-usage) - 各 API の使用方法
# Webhook でイベントを受信する (/docs/guides/webhook)
Webhook 方式では、mixi2 からアプリケーションサーバーの HTTPS エンドポイントにイベントが POST されます。本番環境やサーバーレス環境でのデプロイに適した受信方式です。
## 前提条件 [#前提条件]
* [SDK ガイド](/guides/sdk) で SDK のインストールと認証の実装が完了していること
* HTTPS で公開された URL が用意できること
## Webhook 方式の特徴 [#webhook-方式の特徴]
**メリット:**
* サーバーレス環境に適合
* スケールアウトが容易
* 接続管理が不要
**デメリット:**
* HTTPS で公開された URL が必要
* 有効な CA 証明書が必要(自己署名証明書は不可)
1 つのアプリケーションに対して、同時に複数の Webhook URL を設定することはできません。
## SDK による実装 [#sdk-による実装]
Webhook サーバーは以下のエンドポイントを提供します。
| エンドポイント | 説明 |
| -------------- | -------------- |
| `POST /events` | イベント受信エンドポイント |
| `GET /healthz` | ヘルスチェックエンドポイント |
```go
package main
import (
"context"
"crypto/ed25519"
"encoding/base64"
"log"
"os"
"github.com/mixigroup/mixi2-application-sdk-go/event/webhook"
modelv1 "github.com/mixigroup/mixi2-application-sdk-go/gen/go/social/mixi/application/model/v1"
)
type MyHandler struct{}
func (h *MyHandler) Handle(ctx context.Context, ev *modelv1.Event) error {
log.Printf("Received event: %v", ev)
return nil
}
func main() {
publicKeyBase64 := os.Getenv("SIGNATURE_PUBLIC_KEY")
publicKey, err := base64.StdEncoding.DecodeString(publicKeyBase64)
if err != nil {
log.Fatal(err)
}
server := webhook.NewServer(
":8080",
ed25519.PublicKey(publicKey),
&MyHandler{},
)
if err := server.Start(); err != nil {
log.Fatal(err)
}
}
```
イベントハンドラ(`EventHandler` インターフェース)の詳細は [SDK ガイド - イベントハンドラの実装](/guides/sdk#イベントハンドラの実装) を、環境変数の一覧は [SDK ガイド - 環境変数](/guides/sdk#環境変数) を参照してください。
## 署名検証 [#署名検証]
Webhook 方式では、受信したリクエストが mixi2 サーバーから送信された正当なものであることを、Ed25519 署名で検証する必要があります。**署名検証は必須です。**
SDK を使用している場合は、イベント受信時の署名検証と Webhook URL 登録時の検証リクエスト応答がいずれも SDK 内部で処理されます。
SDK を使用しない場合は、以下の仕様に基づいて自前で実装してください。
### 検証に使用するヘッダとパラメータ [#検証に使用するヘッダとパラメータ]
| 項目 | 値 |
| ---------- | --------------------------------------------------- |
| 署名ヘッダ | `x-mixi2-application-event-signature`(Base64 エンコード) |
| タイムスタンプヘッダ | `x-mixi2-application-event-timestamp`(Unix 秒) |
| 署名対象 | リクエストボディ + タイムスタンプ |
| 許容時刻ズレ | ±300 秒(5 分) |
| 公開鍵形式 | Base64 エンコード |
### 接続確認時の署名検証 [#接続確認時の署名検証]
Webhook URL を登録して「接続確認を実行」を押すと、3 種類の Ping リクエストがランダムな順で送信されます。署名検証が正しく動作しているかを確認するため、それぞれ以下のレスポンスが期待されます。
| リクエスト | 期待されるレスポンス |
| --------- | ---------- |
| 正しい署名 | HTTP 204 |
| 不正な署名 | HTTP 401 |
| 古いタイムスタンプ | HTTP 401 |
URL の登録手順や検証状態の確認方法は [アプリケーション開発 - Webhook の設定](/guides/application#webhook-の設定) を参照してください。
## タイムアウトとリトライ [#タイムアウトとリトライ]
Webhook 方式では、以下のポリシーが適用されます。
| 項目 | 値 |
| ------ | ------ |
| タイムアウト | 3 秒 |
| リトライ回数 | 最大 3 回 |
| リトライ間隔 | 30 秒 |
イベントを受信したら速やかにレスポンスを返し、アプリケーションのロジックは非同期で処理してください。3 秒以内にアプリケーションの処理を完了させる必要はありません。
## Webhook URL の設定 [#webhook-url-の設定]
### URL の要件 [#url-の要件]
* HTTPS 必須
* 有効な CA 証明書(自己署名証明書は不可)
* SDK を使用している場合、パスは `/events` です(例: `https://YOUR_HOST_NAME/events`)
### URL の登録 [#url-の登録]
Webhook URL の登録手順は [アプリケーション開発 - Webhook の設定](/guides/application#webhook-の設定) を参照してください。
## デプロイ [#デプロイ]
Webhook 方式を使用するには、HTTPS エンドポイントを用意できる環境が必要です。クラウドサービス・自前のサーバーなど任意の環境にデプロイしてください。
* [サンプルアプリケーション](https://github.com/mixigroup/mixi2-application-sample-go)には [Vercel](https://vercel.com) にデプロイするためのコードが含まれています。README の手順に沿ってすぐにデプロイが可能です。
* 構成・環境変数の詳細は [SDK ガイド - サンプルアプリケーション](/guides/sdk#サンプルアプリケーション) を参照してください。
**レスポンス後にプロセスが終了する環境での注意**
[タイムアウトとリトライ](/guides/webhook#タイムアウトとリトライ) で案内している「速やかにレスポンスを返し、ロジックは非同期で処理する」というやり方は、レスポンスを返した時点でプロセスが終了する環境では行えません。そのような環境にデプロイする場合は、3 秒以内に同期的に処理を完了できるアプリケーションが適しています。
## 次のステップ [#次のステップ]
* [gRPC ストリームでイベントを受信する](/guides/grpc-stream) - もう一つのイベント受信方式
* [イベント](/guides/events) - イベントの種類と構造
* [SDK ガイド](/guides/sdk) - SDK の基本(認証、イベントハンドラ)
* [アプリケーション開発](/guides/application) - Webhook URL の登録手順
* [API の使い方](/guides/api-usage) - イベントを受信した後の応答方法
# API リファレンス (/docs/reference/api-document)
## 共通仕様 [#共通仕様]
### プロトコル [#プロトコル]
gRPC を使用します。
Protocol Buffers 定義は以下のリポジトリで公開しています。
* [mixi2-api](https://github.com/mixigroup/mixi2-api)
### 認証 [#認証]
OAuth 2.0 による認証が必要です。認証情報の取得方法は[クイックスタート](/getting-started/quickstart)を参照してください。
## RPC一覧 [#rpc一覧]
### GetUsers [#getusers]
指定したユーザーIDリストに対応するユーザー情報を取得します。
#### GetUsersRequest [#getusersrequest]
ユーザー情報取得リクエストです。
| Field | Type | Description |
| -------------- | --------------- | --------------------- |
| user\_id\_list | repeated string | 取得対象のユーザーIDを指定してください。 |
#### GetUsersResponse [#getusersresponse]
ユーザー情報取得レスポンスです。
| Field | Type | Description |
| ----- | ------------- | ------------ |
| users | repeated User | ユーザー情報の一覧です。 |
### GetPosts [#getposts]
指定したポストIDリストに対応するポスト情報を取得します。
#### GetPostsRequest [#getpostsrequest]
ポスト情報取得リクエストです。
| Field | Type | Description |
| -------------- | --------------- | -------------------- |
| post\_id\_list | repeated string | 取得対象のポストIDを指定してください。 |
#### GetPostsResponse [#getpostsresponse]
ポスト情報取得レスポンスです。
| Field | Type | Description |
| ----- | ------------- | ----------- |
| posts | repeated Post | ポスト情報の一覧です。 |
### GetCommunities [#getcommunities]
指定したコミュニティIDリストに対応するコミュニティ情報を取得します。
#### GetCommunitiesRequest [#getcommunitiesrequest]
コミュニティ情報取得リクエストです。
| Field | Type | Description |
| ------------------- | --------------- | ----------------------- |
| community\_id\_list | repeated string | 取得対象のコミュニティIDを指定してください。 |
#### GetCommunitiesResponse [#getcommunitiesresponse]
コミュニティ情報取得レスポンスです。
| Field | Type | Description |
| ----------- | ------------------ | ------------ |
| communities | repeated Community | コミュニティの一覧です。 |
### CreatePost [#createpost]
ポストを作成します(返信/引用/コミュニティポスト・メディア添付等に対応)。
#### CreatePostRequest [#createpostrequest]
ポスト作成リクエストです。
in\_reply\_to\_post\_id と quoted\_post\_id は同時に指定できません。
| Field | Type | Description |
| ----------------------- | --------------------------- | ---------------------------- |
| text | string | ポストの本文を指定してください。 |
| in\_reply\_to\_post\_id | optional string | 返信先ポストIDを指定してください(任意)。 |
| quoted\_post\_id | optional string | 引用対象ポストIDを指定してください(任意)。 |
| community\_id | optional string | 投稿先コミュニティIDを指定してください(任意)。 |
| media\_id\_list | repeated string | 添付するメディアID一覧を指定してください(最大4件)。 |
| post\_mask | optional PostMask | ポストに適用するマスクを指定してください(任意)。 |
| publishing\_type | optional PostPublishingType | ポストの配信設定を指定してください。 |
#### CreatePostResponse [#createpostresponse]
ポスト作成レスポンスです。
| Field | Type | Description |
| ----- | ---- | ------------- |
| post | Post | 作成されたポスト情報です。 |
### DeletePost [#deletepost]
指定したポストを削除します。
#### DeletePostRequest [#deletepostrequest]
ポスト削除リクエストです。
| Field | Type | Description |
| -------- | ------ | -------------------- |
| post\_id | string | 削除対象のポストIDを指定してください。 |
#### DeletePostResponse [#deletepostresponse]
ポスト削除レスポンスです。
| Field | Type | Description |
| ------- | ---- | ------------------- |
| deleted | bool | ポストが削除されたかどうかを示します。 |
### InitiatePostMediaUpload [#initiatepostmediaupload]
ポストやメッセージ(ルーム送信/DM)に添付するメディアのアップロードを開始し、アップロード先URLを発行します。
#### InitiatePostMediaUploadRequest [#initiatepostmediauploadrequest]
メディアアップロード開始リクエストです。
| Field | Type | Description |
| ------------- | --------------- | ---------------------------------- |
| content\_type | string | アップロードするデータのContent-Typeを指定してください。 |
| data\_size | uint64 | アップロードするデータサイズ(バイト)を指定してください。 |
| media\_type | Type | メディア種別を指定してください。 |
| description | optional string | メディアの説明を指定してください(任意)。 |
#### InitiatePostMediaUploadResponse [#initiatepostmediauploadresponse]
メディアアップロード開始レスポンスです。
| Field | Type | Description |
| ----------- | ------ | ------------------------------------------- |
| media\_id | string | アップロード状況確認や、ポスト/メッセージに送信時にメディアを添付するためのIDです。 |
| upload\_url | string | メディアデータをアップロードするためのURLです。 |
### GetPostMediaStatus [#getpostmediastatus]
指定したメディアIDのアップロード/処理状況を取得します。
#### GetPostMediaStatusRequest [#getpostmediastatusrequest]
メディアアップロード状況取得リクエストです。
| Field | Type | Description |
| --------- | ------ | -------------------------------- |
| media\_id | string | アップロード状況を確認する対象のメディアIDを指定してください。 |
#### GetPostMediaStatusResponse [#getpostmediastatusresponse]
メディアアップロード状況取得レスポンスです。
| Field | Type | Description |
| ------ | ------ | ------------------- |
| status | Status | メディアのアップロード/処理状況です。 |
### GetCommunityTimeline [#getcommunitytimeline]
指定したコミュニティのタイムライン(ポスト一覧)を取得します。
#### GetCommunityTimelineRequest [#getcommunitytimelinerequest]
コミュニティのタイムライン取得リクエストです。
カーソルにはポストIDを指定してください。
未指定の場合は最新のポストから取得します。
| Field | Type | Description |
| ------------- | --------------- | ------------------------------------------------------------------- |
| community\_id | string | タイムラインを取得する対象のコミュニティIDを指定してください。 |
| until\_cursor | optional string | ページング用カーソルを指定してください(任意)。
指定したポストより古いポストを返します(指定したポスト自体は含まれません)。 |
| since\_cursor | optional string | ページング用カーソルを指定してください(任意)。
指定したポストより新しいポストを返します(指定したポスト自体は含まれません)。 |
#### GetCommunityTimelineResponse [#getcommunitytimelineresponse]
コミュニティのタイムライン取得レスポンスです。
| Field | Type | Description |
| ----- | ------------- | ----------------------- |
| posts | repeated Post | コミュニティのタイムライン上のポスト一覧です。 |
### GetCommunityMemberList [#getcommunitymemberlist]
指定したコミュニティのメンバー一覧をページング付きで取得します。
#### GetCommunityMemberListRequest [#getcommunitymemberlistrequest]
コミュニティのメンバー一覧取得リクエストです。
| Field | Type | Description |
| ------------------ | --------------- | -------------------------------------------------------------------------------------------- |
| community\_id | string | メンバー一覧を取得する対象のコミュニティIDを指定してください。 |
| pagination\_cursor | optional string | ページング用カーソルを指定してください(任意)。
指定したカーソルの次のページを取得します。
カーソルには next\_pagination\_cursor を使用します。 |
#### GetCommunityMemberListResponse [#getcommunitymemberlistresponse]
コミュニティのメンバー一覧取得レスポンスです。
| Field | Type | Description |
| ------------------------ | --------------- | -------------------- |
| members | repeated User | コミュニティメンバーの一覧です。 |
| next\_pagination\_cursor | optional string | 次ページ取得用のページングカーソルです。 |
### RestrictCommunityPost [#restrictcommunitypost]
指定したポストをコミュニティのタイムラインから非表示にします(削除ではありません)。
#### RestrictCommunityPostRequest [#restrictcommunitypostrequest]
コミュニティポスト制限リクエストです。
指定したポストをコミュニティのタイムラインから非表示にします。ポストが削除されるわけではありません。
| Field | Type | Description |
| -------- | ------ | -------------------- |
| post\_id | string | 制限対象のポストIDを指定してください。 |
#### RestrictCommunityPostResponse [#restrictcommunitypostresponse]
コミュニティポスト制限レスポンスです。
*(no fields)*
### GetCommunitiesUsingApplication [#getcommunitiesusingapplication]
アプリケーションが導入されているコミュニティ一覧と、各コミュニティが利用しているアプリケーションバージョン情報を取得します。
#### GetCommunitiesUsingApplicationRequest [#getcommunitiesusingapplicationrequest]
プラグインがインストールされているコミュニティ一覧取得リクエストです。
| Field | Type | Description |
| ------ | --------------- | ------------------------ |
| cursor | optional string | ページング用カーソルを指定してください(任意)。 |
#### GetCommunitiesUsingApplicationResponse [#getcommunitiesusingapplicationresponse]
プラグインがインストールされているコミュニティ一覧取得レスポンスです。
| Field | Type | Description |
| ------------------------------- | ---------------------------------- | --------------------------- |
| communities\_using\_application | repeated CommunityUsingApplication | アプリケーションが導入されているコミュニティ一覧です。 |
| application\_versions | repeated ApplicationVersion | 各コミュニティのバージョン一覧です。 |
| next\_cursor | optional string | 次ページ取得用のページングカーソルです。 |
### SendChatMessage [#sendchatmessage]
指定したルームにチャットメッセージを送信します(テキスト/メディア添付)。
#### SendChatMessageRequest [#sendchatmessagerequest]
text または media\_id のいずれかは必須です。
| Field | Type | Description |
| --------- | --------------- | ------------------------ |
| room\_id | string | 送信先ルームIDを指定してください。 |
| text | optional string | 送信するテキストを指定してください(任意)。 |
| media\_id | optional string | 添付するメディアIDを指定してください(任意)。 |
#### SendChatMessageResponse [#sendchatmessageresponse]
チャットメッセージ送信レスポンスです。
| Field | Type | Description |
| ------- | ----------- | ------------- |
| message | ChatMessage | 送信されたメッセージです。 |
### GetStamps [#getstamps]
スタンプ一覧を取得します。
#### GetStampsRequest [#getstampsrequest]
スタンプ一覧取得リクエストです。
| Field | Type | Description |
| ------------------------- | --------------------- | -------------------------------------------------------------------------------- |
| official\_stamp\_language | optional LanguageCode | 取得する公式スタンプの言語を指定してください(任意)。
未指定の場合、公式スタンプ一覧は空で返されます。 |
| community\_ids | repeated string | コミュニティ固有スタンプを取得する場合、コミュニティIDを指定してください。
指定するコミュニティIDは、アプリケーションが導入されている必要があります。 |
#### GetStampsResponse [#getstampsresponse]
スタンプ一覧取得レスポンスです。
| Field | Type | Description |
| ---------------------- | -------------------------- | -------------------- |
| official\_stamp\_sets | repeated OfficialStampSet | 指定言語の公式スタンプセット一覧です。 |
| community\_stamp\_sets | repeated CommunityStampSet | コミュニティ固有スタンプセット一覧です。 |
### AddStampToPost [#addstamptopost]
指定したポストにスタンプを付与します。
#### AddStampToPostRequest [#addstamptopostrequest]
ポストへのスタンプ付与リクエストです。
| Field | Type | Description |
| --------- | ------ | ------------------------------------------------------------------------------------------------------------- |
| post\_id | string | スタンプを付与する対象のポストIDを指定してください。指定可能なポストIDは次の通りです。
• アプリケーションが導入されているコミュニティ内のポストID
• アプリケーションにメンションしているポストID |
| stamp\_id | string | 付与するスタンプIDを指定してください。指定可能なスタンプIDは次の通りです。
• 公式スタンプID
• コミュニティスタンプID(コミュニティポストの場合のみ利用可能) |
#### AddStampToPostResponse [#addstamptopostresponse]
ポストへのスタンプ付与レスポンスです。
| Field | Type | Description |
| ----- | ---- | ----------- |
| post | Post | 更新されたポストです。 |
### SendDirectMessageToCommunityMember [#senddirectmessagetocommunitymember]
コミュニティメンバーにダイレクトメッセージを送信します。
#### SendDirectMessageToCommunityMemberRequest [#senddirectmessagetocommunitymemberrequest]
コミュニティメンバーへのダイレクトメッセージ送信リクエストです。
text または media\_ids のいずれかは必須です。
| Field | Type | Description |
| ------------- | --------------- | ---------------------------------------------------------------- |
| receiver\_id | string | 受信者ユーザーIDを指定してください。 |
| community\_id | string | 受信者が所属するコミュニティIDを指定してください。
対象コミュニティにはアプリケーションが導入されている必要があります。 |
| text | optional string | 本文テキストを指定してください(任意)。 |
| media\_ids | repeated string | 添付するメディアID一覧を指定してください(最大4件)。 |
| post\_id | optional string | ポストを引用してDMを送信する場合、ポストIDを指定してください(任意)。 |
#### SendDirectMessageToCommunityMemberResponse [#senddirectmessagetocommunitymemberresponse]
コミュニティメンバーへのダイレクトメッセージ送信レスポンスです。
| Field | Type | Description |
| ------- | ----------- | ------------- |
| message | ChatMessage | 送信されたメッセージです。 |
### SubscribeEvents [#subscribeevents]
イベントをストリーミングで購読します。
#### SubscribeEventsRequest [#subscribeeventsrequest]
イベント購読リクエストです。
*(no fields)*
#### SubscribeEventsResponse [#subscribeeventsresponse]
イベント購読レスポンスです。
| Field | Type | Description |
| ------ | -------------- | -------------- |
| events | repeated Event | 受信したイベントの情報です。 |
## メッセージ型 [#メッセージ型]
### ApplicationVersion [#applicationversion]
アプリケーションのバージョン情報です。
アプリケーションは複数のバージョンを持つことができ、アプリケーションの要件を変更する際に新しいバージョンを作成します。
| field\_name | field\_type | field\_description |
| ------------------------ | ------------------------------- | ------------------ |
| application\_version\_id | string | アプリケーションバージョンIDです。 |
| application\_id | string | アプリケーションIDです。 |
| requirements | repeated ApplicationRequirement | アプリケーションの要件一覧です。 |
### Community [#community]
コミュニティを表します。
| field\_name | field\_type | field\_description |
| ------------- | -------------------- | --------------------------- |
| community\_id | string | コミュニティIDです。 |
| name | string | コミュニティの名前です。 |
| purpose | string | コミュニティノートです。 |
| is\_archived | bool | コミュニティがアーカイブされているかどうかを示します。 |
| visibility | CommunityVisibility | コミュニティの情報を閲覧可能かどうかを示します。 |
| access\_level | CommunityAccessLevel | コミュニティの公開設定を示します。 |
### CommunityUsingApplication [#communityusingapplication]
コミュニティが利用しているアプリケーションの情報を表します。
| field\_name | field\_type | field\_description |
| ------------------------ | ----------- | ---------------------------------- |
| community | Community | コミュニティの情報です。 |
| application\_version\_id | string | そのコミュニティが利用しているアプリケーションのバージョンIDです。 |
### ChatMessageReceivedEvent [#chatmessagereceivedevent]
チャットメッセージを受信したことを通知するイベントです。
| field\_name | field\_type | field\_description |
| ------------------- | -------------------- | ------------------ |
| event\_reason\_list | repeated EventReason | イベントが発生した理由を示します。 |
| message | ChatMessage | 受信したメッセージの情報です。 |
| issuer | User | メッセージを送信したユーザーです。 |
### CommunityMemberChangedEvent [#communitymemberchangedevent]
コミュニティメンバーの増減を通知するイベントです。
| field\_name | field\_type | field\_description |
| ------------------- | -------------------- | ------------------------ |
| event\_reason\_list | repeated EventReason | イベントが発生した理由を示します。 |
| member | User | コミュニティに参加/退出したユーザーの情報です。 |
| community | Community | コミュニティの情報です。 |
### CommunityPluginManagedEvent [#communitypluginmanagedevent]
コミュニティにプラグインがインストール/アンインストールされたことを通知するイベントです。
| field\_name | field\_type | field\_description |
| ------------------- | -------------------- | ------------------ |
| event\_reason\_list | repeated EventReason | イベントが発生した理由を示します。 |
| community | Community | コミュニティの情報です。 |
### Event [#event]
アプリケーションが受信するイベントを表します。
| field\_name | field\_type | field\_description |
| --------------------------------- | ---------------------------------------- | ----------------------------------------------------------------- |
| event\_id | string | イベントIDです。 |
| event\_type | EventType | イベントの種別です。 |
| ping\_event | oneof (body) PingEvent | event\_type が EVENT\_TYPE\_PING の場合に設定されます。 |
| post\_created\_event | oneof (body) PostCreatedEvent | event\_type が EVENT\_TYPE\_POST\_CREATED の場合に設定されます。 |
| community\_member\_changed\_event | oneof (body) CommunityMemberChangedEvent | event\_type が EVENT\_TYPE\_COMMUNITY\_MEMBER\_CHANGED の場合に設定されます。 |
| chat\_message\_received\_event | oneof (body) ChatMessageReceivedEvent | event\_type が EVENT\_TYPE\_CHAT\_MESSAGE\_RECEIVED の場合に設定されます。 |
| community\_plugin\_managed\_event | oneof (body) CommunityPluginManagedEvent | event\_type が EVENT\_TYPE\_COMMUNITY\_PLUGIN\_MANAGED の場合に設定されます。 |
### PingEvent [#pingevent]
疎通確認用のイベントです。
*(no fields)*
### PostCreatedEvent [#postcreatedevent]
ポストが作成されたことを通知するイベントです。
| field\_name | field\_type | field\_description |
| ------------------- | -------------------- | ------------------ |
| event\_reason\_list | repeated EventReason | イベントが発生した理由を示します。 |
| post | Post | 作成されたポストの情報です。 |
| issuer | User | ポストしたユーザーの情報です。 |
| posted\_community | optional Community | コミュニティの情報です。 |
### Media [#media]
メディアを表します。
| field\_name | field\_type | field\_description |
| ----------- | -------------------------- | -------------------------------------------- |
| media\_type | MediaType | メディアの種別です。 |
| image | oneof (content) MediaImage | media\_type が MEDIA\_TYPE\_IMAGE の場合に設定されます。 |
| video | oneof (content) MediaVideo | media\_type が MEDIA\_TYPE\_VIDEO の場合に設定されます。 |
### MediaImage [#mediaimage]
画像の情報を表します。
| field\_name | field\_type | field\_description |
| ------------------------ | ----------- | --------------------- |
| large\_image\_url | string | 大きいサイズの画像のURLです。 |
| large\_image\_mime\_type | string | 大きいサイズの画像のMIMEタイプです。 |
| large\_image\_height | uint32 | 大きいサイズの画像の高さ(ピクセル)です。 |
| large\_image\_width | uint32 | 大きいサイズの画像の幅(ピクセル)です。 |
| small\_image\_url | string | 小さいサイズの画像のURLです。 |
| small\_image\_mime\_type | string | 小さいサイズの画像のMIMEタイプです。 |
| small\_image\_height | uint32 | 小さいサイズの画像の高さ(ピクセル)です。 |
| small\_image\_width | uint32 | 小さいサイズの画像の幅(ピクセル)です。 |
### MediaStamp [#mediastamp]
スタンプ画像の情報を表します。
| field\_name | field\_type | field\_description |
| ----------- | ----------- | ------------------ |
| url | string | スタンプ画像のURLです。 |
| mime\_type | string | スタンプ画像のMIMEタイプです。 |
| height | uint32 | スタンプ画像の高さ(ピクセル)です。 |
| width | uint32 | スタンプ画像の幅(ピクセル)です。 |
### MediaVideo [#mediavideo]
動画の情報を表します。
| field\_name | field\_type | field\_description |
| -------------------------- | ----------- | ---------------------- |
| video\_url | string | 動画のURLです。 |
| video\_mime\_type | string | 動画のMIMEタイプです。 |
| video\_height | uint32 | 動画の高さ(ピクセル)です。 |
| video\_width | uint32 | 動画の幅(ピクセル)です。 |
| preview\_image\_url | string | 動画のプレビュー画像のURLです。 |
| preview\_image\_mime\_type | string | 動画のプレビュー画像のMIMEタイプです。 |
| preview\_image\_height | uint32 | 動画のプレビュー画像の高さ(ピクセル)です。 |
| preview\_image\_width | uint32 | 動画のプレビュー画像の幅(ピクセル)です。 |
| duration | float | 動画の再生時間(秒)です。 |
### ChatMessage [#chatmessage]
チャットメッセージを表します。
| field\_name | field\_type | field\_description |
| ----------- | --------------- | --------------------- |
| room\_id | string | メッセージが送信されたルームのIDです。 |
| message\_id | string | メッセージIDです。 |
| creator\_id | string | メッセージ送信者のユーザーIDです。 |
| text | string | メッセージのテキストです。 |
| created\_at | Timestamp | メッセージ送信日時です。 |
| media\_list | repeated Media | メッセージに添付されたメディア一覧です。 |
| post\_id | optional string | メッセージに引用されているポストIDです。 |
### Post [#post]
ポストを表します。
| field\_name | field\_type | field\_description |
| ----------------------- | ------------------ | ------------------------------------------------------------- |
| post\_id | string | ポストIDです。 |
| is\_deleted | bool | ポストが削除されているかどうかを示します。削除されている場合、post\_id 以外のフィールドはデフォルト値を返します。 |
| creator\_id | string | ポスト作成者のユーザーIDです。 |
| text | string | ポストの本文です。 |
| created\_at | Timestamp | ポスト作成日時です。 |
| post\_media\_list | repeated PostMedia | ポストに添付されたメディア一覧です。 |
| in\_reply\_to\_post\_id | optional string | 返信先のポストIDです。 |
| post\_mask | optional PostMask | ポストに適用されるマスク情報です。 |
| community\_id | optional string | ポストが投稿されたコミュニティIDです。 |
| visibility | PostVisibility | ポストを閲覧可能かどうかを示します。 |
| access\_level | PostAccessLevel | ポストの公開設定を示します。 |
| stamps | repeated PostStamp | ポストに付与されたスタンプの一覧です。 |
| reader\_stamp\_id | optional string | 現在のアプリケーションがすでにこのポストに付与したスタンプIDです。 |
### PostMask [#postmask]
ポストに適用されるマスク情報を表します。
| field\_name | field\_type | field\_description |
| ----------- | ------------ | ------------------ |
| mask\_type | PostMaskType | マスクのタイプです。 |
| caption | string | マスクのキャプションです。 |
### PostMedia [#postmedia]
ポストに添付されたメディアを表します。
| field\_name | field\_type | field\_description |
| ----------- | ------------------------------ | -------------------------------------------------- |
| media\_type | PostMediaType | メディアの種別です。 |
| image | oneof (content) PostMediaImage | media\_type が POST\_MEDIA\_TYPE\_IMAGE の場合に設定されます。 |
| video | oneof (content) PostMediaVideo | media\_type が POST\_MEDIA\_TYPE\_VIDEO の場合に設定されます。 |
### PostMediaImage [#postmediaimage]
ポストに添付された画像の情報を表します。
| field\_name | field\_type | field\_description |
| ------------------------ | ----------- | --------------------- |
| large\_image\_url | string | 大きいサイズの画像のURLです。 |
| large\_image\_mime\_type | string | 大きいサイズの画像のMIMEタイプです。 |
| large\_image\_height | uint32 | 大きいサイズの画像の高さ(ピクセル)です。 |
| large\_image\_width | uint32 | 大きいサイズの画像の幅(ピクセル)です。 |
| small\_image\_url | string | 小さいサイズの画像のURLです。 |
| small\_image\_mime\_type | string | 小さいサイズの画像のMIMEタイプです。 |
| small\_image\_height | uint32 | 小さいサイズの画像の高さ(ピクセル)です。 |
| small\_image\_width | uint32 | 小さいサイズの画像の幅(ピクセル)です。 |
### PostMediaVideo [#postmediavideo]
ポストに添付された動画の情報を表します。
| field\_name | field\_type | field\_description |
| -------------------------- | ----------- | ---------------------- |
| video\_url | string | 動画のURLです。 |
| video\_mime\_type | string | 動画のMIMEタイプです。 |
| video\_height | uint32 | 動画の高さ(ピクセル)です。 |
| video\_width | uint32 | 動画の幅(ピクセル)です。 |
| preview\_image\_url | string | 動画のプレビュー画像のURLです。 |
| preview\_image\_mime\_type | string | 動画のプレビュー画像のMIMEタイプです。 |
| preview\_image\_height | uint32 | 動画のプレビュー画像の高さ(ピクセル)です。 |
| preview\_image\_width | uint32 | 動画のプレビュー画像の幅(ピクセル)です。 |
| duration | float | 動画の再生時間(秒)です。 |
### PostStamp [#poststamp]
ポストに付与されたスタンプを表します。
| field\_name | field\_type | field\_description |
| ----------- | ----------- | ------------------ |
| stamp | MediaStamp | スタンプの情報です。 |
| count | uint64 | スタンプが押された回数です。 |
### CommunityStamp [#communitystamp]
コミュニティスタンプを表します。
| field\_name | field\_type | field\_description |
| ------------ | --------------- | ------------------ |
| stamp\_id | string | スタンプIDです。 |
| url | string | スタンプの画像のURLです。 |
| search\_tags | repeated string | スタンプの検索用タグの一覧です。 |
### CommunityStampSet [#communitystampset]
コミュニティスタンプセットを表します。
| field\_name | field\_type | field\_description |
| ------------- | ----------------------- | ------------------ |
| community\_id | string | コミュニティIDです。 |
| stamps | repeated CommunityStamp | コミュニティ固有スタンプの一覧です。 |
### OfficialStamp [#officialstamp]
公式スタンプを表します。
| field\_name | field\_type | field\_description |
| ------------ | --------------- | ----------------------- |
| stamp\_id | string | スタンプIDです。 |
| index | uint32 | スタンプセット(スプライト)内での並び順です。 |
| search\_tags | repeated string | スタンプの検索用タグの一覧です。 |
| url | string | スタンプの画像のURLです。 |
### OfficialStampSet [#officialstampset]
公式スタンプセットを表します。
| field\_name | field\_type | field\_description |
| ---------------- | ---------------------- | -------------------------------------------- |
| name | string | スタンプセットの名前です。 |
| sprite\_url | string | スタンプセットのスプライト画像のURLです。 |
| stamps | repeated OfficialStamp | スタンプセットに含まれるスタンプ一覧です。 |
| stamp\_set\_id | string | スタンプセットIDです。 |
| start\_at | optional Timestamp | スタンプセットが利用可能になる開始日時です。未指定の場合、開始日時は限定されません。 |
| end\_at | optional Timestamp | スタンプセットが利用可能でなくなる終了日時です。未指定の場合、終了日時は限定されません。 |
| stamp\_set\_type | StampSetType | スタンプセットのタイプです。 |
### User [#user]
ユーザーを表します。
| field\_name | field\_type | field\_description |
| ------------- | --------------- | ------------------------------------------ |
| user\_id | string | ユーザーIDです。 |
| is\_disabled | bool | ユーザーが無効化されているかどうかを示します(無効化は退会やBANなどを含みます)。 |
| name | string | ユーザーの名前です。 |
| display\_name | string | ユーザーの表示名です。 |
| profile | string | ユーザーのプロフィールです。 |
| user\_avatar | UserAvatar | ユーザーのアバター情報です。 |
| visibility | UserVisibility | ユーザーの情報を閲覧可能かどうかを示します。 |
| access\_level | UserAccessLevel | ユーザーの公開設定を示します。 |
### UserAvatar [#useravatar]
ユーザーのアバター画像の情報を表します。
| field\_name | field\_type | field\_description |
| ------------------------ | ----------- | ------------------------- |
| large\_image\_url | string | 大きいサイズのアバター画像のURLです。 |
| large\_image\_mime\_type | string | 大きいサイズのアバター画像のMIMEタイプです。 |
| large\_image\_height | uint32 | 大きいサイズのアバター画像の高さ(ピクセル)です。 |
| large\_image\_width | uint32 | 大きいサイズのアバター画像の幅(ピクセル)です。 |
| small\_image\_url | string | 小さいサイズのアバター画像のURLです。 |
| small\_image\_mime\_type | string | 小さいサイズのアバター画像のMIMEタイプです。 |
| small\_image\_height | uint32 | 小さいサイズのアバター画像の高さ(ピクセル)です。 |
| small\_image\_width | uint32 | 小さいサイズのアバター画像の幅(ピクセル)です。 |
## 列挙型 [#列挙型]
### ApplicationRequirement [#applicationrequirement]
アプリケーションが必要とする権限や受信するイベントの種別を示す列挙型
* APPLICATION\_REQUIREMENT\_PERMISSION は、コミュニティプラグインがコミュニティに対して要求する権限
* APPLICATION\_REQUIREMENT\_EVENT は、アプリケーション/コミュニティプラグインが受信するイベントの種別
| field | type | description |
| -------------------------------------------------------------------------------- | ---- | ---------------------------- |
| APPLICATION\_REQUIREMENT\_UNSPECIFIED | 0 | 未指定 |
| APPLICATION\_REQUIREMENT\_PERMISSION\_COMMUNITY\_POST\_READ | 1 | コミュニティのポストを取得する権限 |
| APPLICATION\_REQUIREMENT\_PERMISSION\_COMMUNITY\_POST\_CREATE | 2 | コミュニティにポストする権限 |
| APPLICATION\_REQUIREMENT\_PERMISSION\_COMMUNITY\_POST\_RESTRICT | 3 | コミュニティのポストを制限(非表示)にする権限 |
| APPLICATION\_REQUIREMENT\_PERMISSION\_COMMUNITY\_MEMBER\_LIST\_READ | 4 | コミュニティのメンバー一覧を取得する権限 |
| APPLICATION\_REQUIREMENT\_PERMISSION\_COMMUNITY\_POST\_STAMP\_CREATE | 10 | コミュニティのポストにスタンプを付与する権限 |
| APPLICATION\_REQUIREMENT\_PERMISSION\_COMMUNITY\_MEMBER\_DIRECT\_MESSAGE\_CREATE | 11 | コミュニティメンバーにダイレクトメッセージを送信する権限 |
| APPLICATION\_REQUIREMENT\_EVENT\_REACTION\_REPLY | 5 | ポストに返信されたことを示すイベント |
| APPLICATION\_REQUIREMENT\_EVENT\_REACTION\_MENTION | 6 | ポストでメンションされたイベント |
| APPLICATION\_REQUIREMENT\_EVENT\_COMMUNITY\_POST\_CREATED | 7 | コミュニティにポストが作成されたイベント |
| APPLICATION\_REQUIREMENT\_EVENT\_COMMUNITY\_MEMBER\_JOINED | 8 | コミュニティメンバーが参加/退出したイベント |
| APPLICATION\_REQUIREMENT\_EVENT\_DIRECT\_MESSAGE\_RECEIVED | 9 | メッセージを受信したイベント |
### CommunityAccessLevel [#communityaccesslevel]
コミュニティの公開設定を示す列挙型
| field | type | description |
| -------------------------------------------- | ---- | ------------------- |
| COMMUNITY\_ACCESS\_LEVEL\_UNSPECIFIED | 0 | 未指定 |
| COMMUNITY\_ACCESS\_LEVEL\_PUBLIC | 1 | 公開コミュニティ |
| COMMUNITY\_ACCESS\_LEVEL\_APPROVAL\_REQUIRED | 2 | 承認制コミュニティ(参加に承認が必要) |
### CommunityVisibility [#communityvisibility]
コミュニティを閲覧できるか示す列挙型
| field | type | description |
| ---------------------------------- | ---- | ------------- |
| COMMUNITY\_VISIBILITY\_UNSPECIFIED | 0 | 未指定 |
| COMMUNITY\_VISIBILITY\_VISIBLE | 1 | コミュニティを閲覧できる |
| COMMUNITY\_VISIBILITY\_INVISIBLE | 2 | コミュニティを閲覧できない |
### EventReason [#eventreason]
イベントの発生理由を示す列挙型
| field | type | description |
| --------------------------------------------- | ---- | -------------------- |
| EVENT\_REASON\_UNSPECIFIED | 0 | 未指定 |
| EVENT\_REASON\_PING | 1 | 接続確認 |
| EVENT\_REASON\_POST\_REPLY | 2 | ポストに返信された |
| EVENT\_REASON\_POST\_MENTIONED | 3 | ポストでメンションされた |
| EVENT\_REASON\_POST\_QUOTED | 4 | ポストが引用された |
| EVENT\_REASON\_POST\_COMMUNITY | 5 | コミュニティに新しいポストが投稿された |
| EVENT\_REASON\_COMMUNITY\_MEMBER\_JOINED | 6 | コミュニティにメンバーが参加した |
| EVENT\_REASON\_COMMUNITY\_MEMBER\_LEFT | 7 | コミュニティにメンバーが退出した |
| EVENT\_REASON\_DIRECT\_MESSAGE\_RECEIVED | 8 | チャット/ダイレクトメッセージを受信した |
| EVENT\_REASON\_COMMUNITY\_PLUGIN\_INSTALLED | 9 | コミュニティにプラグインが導入された |
| EVENT\_REASON\_COMMUNITY\_PLUGIN\_UNINSTALLED | 10 | コミュニティからプラグインが削除された |
### EventType [#eventtype]
イベントの種別を示す列挙型
| field | type | description |
| --------------------------------------- | ---- | ------------------------ |
| EVENT\_TYPE\_UNSPECIFIED | 0 | 未指定 |
| EVENT\_TYPE\_PING | 1 | 接続確認 |
| EVENT\_TYPE\_POST\_CREATED | 2 | ポスト作成 |
| EVENT\_TYPE\_COMMUNITY\_MEMBER\_CHANGED | 3 | コミュニティメンバー変更(参加/退出) |
| EVENT\_TYPE\_CHAT\_MESSAGE\_RECEIVED | 4 | メッセージ受信(チャット/ダイレクトメッセージ) |
| EVENT\_TYPE\_COMMUNITY\_PLUGIN\_MANAGED | 5 | コミュニティプラグイン管理(導入/削除) |
### LanguageCode [#languagecode]
言語コードを示す列挙型
| field | type | description |
| --------------------------- | ---- | ----------- |
| LANGUAGE\_CODE\_UNSPECIFIED | 0 | 未指定 |
| LANGUAGE\_CODE\_JP | 1 | 日本語 |
| LANGUAGE\_CODE\_EN | 2 | 英語 |
### MediaType [#mediatype]
メッセージに添付されるメディア種別を示す列挙型
| field | type | description |
| ------------------------ | ---- | ----------- |
| MEDIA\_TYPE\_UNSPECIFIED | 0 | 未指定 |
| MEDIA\_TYPE\_IMAGE | 1 | 画像 |
| MEDIA\_TYPE\_VIDEO | 2 | 動画 |
### PostAccessLevel [#postaccesslevel]
ポストの公開設定を示す列挙型
| field | type | description |
| -------------------------------- | ---- | ------------------ |
| POST\_ACCESS\_LEVEL\_UNSPECIFIED | 0 | 未指定 |
| POST\_ACCESS\_LEVEL\_PUBLIC | 1 | 公開 |
| POST\_ACCESS\_LEVEL\_PRIVATE | 2 | 非公開(特定のユーザーのみ閲覧可能) |
### PostMaskType [#postmasktype]
ポストに適用するマスク種別を示す列挙型
| field | type | description |
| ----------------------------- | ---- | ----------------- |
| POST\_MASK\_TYPE\_UNSPECIFIED | 0 | 未指定 |
| POST\_MASK\_TYPE\_SENSITIVE | 1 | 刺激的なコンテンツに対する注意喚起 |
| POST\_MASK\_TYPE\_SPOILER | 2 | ネタバレ防止のための注意喚起 |
### PostMediaType [#postmediatype]
ポストに添付されるメディア種別を示す列挙型
| field | type | description |
| ------------------------------ | ---- | ----------- |
| POST\_MEDIA\_TYPE\_UNSPECIFIED | 0 | 未指定 |
| POST\_MEDIA\_TYPE\_IMAGE | 1 | 画像 |
| POST\_MEDIA\_TYPE\_VIDEO | 2 | 動画 |
### PostPublishingType [#postpublishingtype]
ポストの投稿先設定を示す列挙型
| field | type | description |
| --------------------------------------- | ---- | ----------------------------------------- |
| POST\_PUBLISHING\_TYPE\_UNSPECIFIED | 0 | 未指定(自分のフォロワーのタイムライン、もしくはコミュニティのタイムラインに公開) |
| POST\_PUBLISHING\_TYPE\_NOT\_PUBLISHING | 1 | ポストを自分のプロフィールにのみ公開 |
### PostVisibility [#postvisibility]
ポストを閲覧できるかどうかを示す列挙型
| field | type | description |
| ----------------------------- | ---- | ----------- |
| POST\_VISIBILITY\_UNSPECIFIED | 0 | 未指定 |
| POST\_VISIBILITY\_VISIBLE | 1 | ポストを閲覧できる |
| POST\_VISIBILITY\_INVISIBLE | 2 | ポストを閲覧できない |
### StampSetType [#stampsettype]
公式スタンプセットの種別を示す列挙型
| field | type | description |
| ----------------------------- | ---- | ------------- |
| STAMP\_SET\_TYPE\_UNSPECIFIED | 0 | 未指定 |
| STAMP\_SET\_TYPE\_DEFAULT | 1 | デフォルトのスタンプセット |
| STAMP\_SET\_TYPE\_SEASONAL | 2 | 季節限定のスタンプセット |
### UserAccessLevel [#useraccesslevel]
ユーザーの公開設定を示す列挙型
| field | type | description |
| -------------------------------- | ---- | ----------- |
| USER\_ACCESS\_LEVEL\_UNSPECIFIED | 0 | 未指定 |
| USER\_ACCESS\_LEVEL\_PUBLIC | 1 | 公開ユーザー |
| USER\_ACCESS\_LEVEL\_PRIVATE | 2 | 非公開ユーザー |
### UserVisibility [#uservisibility]
ユーザーを閲覧できるか示す列挙型
| field | type | description |
| ----------------------------- | ---- | ----------- |
| USER\_VISIBILITY\_UNSPECIFIED | 0 | 未指定 |
| USER\_VISIBILITY\_VISIBLE | 1 | ユーザーを閲覧できる |
| USER\_VISIBILITY\_INVISIBLE | 2 | ユーザーを閲覧できない |
### GetPostMediaStatusResponse.Status [#getpostmediastatusresponsestatus]
メディアのアップロード/処理状況を表します。
| field | type | description |
| ----------------------- | ---- | ----------- |
| STATUS\_UNSPECIFIED | 0 | 未指定 |
| STATUS\_UPLOAD\_PENDING | 1 | アップロード待機中 |
| STATUS\_PROCESSING | 2 | 処理中 |
| STATUS\_COMPLETED | 3 | 完了 |
| STATUS\_FAILED | 4 | 失敗 |
### InitiatePostMediaUploadRequest.Type [#initiatepostmediauploadrequesttype]
アップロードするメディアの種別を指定してください。
| field | type | description |
| ----------------- | ---- | ----------- |
| TYPE\_UNSPECIFIED | 0 | 未指定 |
| TYPE\_IMAGE | 1 | 画像 |
| TYPE\_VIDEO | 2 | 動画 |
# レート制限 (/docs/reference/rate-limits)
mixi2 API では、プラットフォームの安定性を維持するために、各 API にレート制限が設けられています。このページでは、レート制限の仕様と制限超過時の挙動について説明します。
## 適用単位 [#適用単位]
レート制限は**アプリケーション単位**で適用されます。同一アプリケーションからのリクエストは、すべて同じレート制限のカウントに加算されます。
## API ごとのレート制限 [#api-ごとのレート制限]
### リクエスト回数の制限 [#リクエスト回数の制限]
各 API のリクエスト回数の制限は以下の通りです。
| RPC | 制限 | ウィンドウ |
| ------------------------------------ | ----: | ----- |
| `CreatePost` | 20 回 | 1 分 |
| `DeletePost` | 20 回 | 1 分 |
| `SendChatMessage` | 20 回 | 1 分 |
| `InitiatePostMediaUpload` | 20 回 | 1 分 |
| `InitiatePostMediaUpload` | 200 回 | 1 時間 |
| `AddStampToPost` | 20 回 | 1 分 |
| `GetStamps` | 20 回 | 1 分 |
| `GetUsers` | 20 回 | 1 分 |
| `GetPosts` | 20 回 | 1 分 |
| `GetPostMediaStatus` | 20 回 | 1 分 |
| `GetCommunities` | 20 回 | 1 分 |
| `GetCommunitiesUsingApplication` | 20 回 | 1 分 |
| `GetCommunityTimeline` | 20 回 | 1 分 |
| `GetCommunityMemberList` | 20 回 | 1 分 |
| `RestrictCommunityPost` | 20 回 | 1 分 |
| `SendDirectMessageToCommunityMember` | 20 回 | 1 分 |
`InitiatePostMediaUpload` には 1 分あたりと 1 時間あたりの 2 つの制限が適用されます。いずれかの制限に達した場合、リクエストが制限されます。
`SubscribeEvents` にはリクエスト回数のレート制限はありません。
### メディアアップロードの制限 [#メディアアップロードの制限]
メディアのアップロードには、リクエスト回数の制限に加えて、データ量の制限があります。
| 項目 | 制限 |
| -------- | -------- |
| アップロード容量 | 1 GB / 日 |
各メディアファイルのサイズ制限については、[API の使い方 - メディアアップロードの制限](/guides/api-usage#メディアアップロードの制限)を参照してください。
## レスポンスヘッダー [#レスポンスヘッダー]
すべての API レスポンスには、現在のレート制限の状況を示す以下のヘッダーが含まれます。
| ヘッダー | 説明 |
| --------------------- | ---------------------- |
| `ratelimit-limit` | リクエスト回数の上限値 |
| `ratelimit-remaining` | 現在のウィンドウ内で残っているリクエスト回数 |
| `ratelimit-reset` | 制限がリセットされる時刻(UNIX 秒) |
制限を超過した場合は、上記に加えて以下のヘッダーが返されます。
| ヘッダー | 説明 |
| ------------- | -------------------- |
| `retry-after` | 再試行まで待機すべき秒数(最小 1 秒) |
## 制限超過時のレスポンス [#制限超過時のレスポンス]
レート制限に達した場合、リクエストはハンドラ実行前に拒否され、以下のエラーレスポンスが返されます。
| 項目 | 値 |
| ------------- | ---------------------------- |
| gRPC ステータスコード | `RESOURCE_EXHAUSTED`(code 8) |
| エラーメッセージ | `rate limit exceeded` |
レート制限の判定はハンドラ実行前に行われるため、制限超過時は業務処理は実行されません。
## 制限超過時の対処 [#制限超過時の対処]
レート制限を超過した場合は、以下の手順で対処してください。
1. **`retry-after` ヘッダーの値に従って待機する** — 即時リトライは避けてください
2. **`retry-after` がない場合は `ratelimit-reset` の時刻まで待機する**
3. **再試行にはジッター(ランダムな遅延)付きバックオフを使用する** — 複数のクライアントが同時にリトライすることを避けられます
レート制限を含むエラーハンドリング全般については、[アプリケーション開発 - エラーハンドリング](/guides/application#エラーハンドリング)を参照してください。
レート制限は予告なく変更される場合があります。最新の情報はこのページで確認してください。
## 関連ページ [#関連ページ]
* [API の使い方](/guides/api-usage) - 各 API の使用方法とコード例
* [API リファレンス](/reference/api-document) - API の完全な仕様
* [アプリケーション開発](/guides/application) - エラーハンドリングのベストプラクティス
# よくある質問 (/docs/resource/faq)
## アカウント・ログイン [#アカウントログイン]
以下のパターンが考えられます。
| 原因 | 対処法 |
| -------------------- | ---------------------------------------------- |
| 開発者登録が完了していない | [開発者登録](/getting-started/registration)を行ってください |
| 別の MIXI ID でログインしている | 開発者登録時に使用した MIXI ID でログインしてください |
mixi2 に登録しているアカウントで、別途[開発者登録](/getting-started/registration)が必要です。
複数のメールアドレスで mixi2 を利用している場合、それぞれ別の MIXI ID となります。開発者登録した MIXI ID と異なる MIXI ID でログインしようとするとエラーになります。
また、株式会社MIXI が提供する他サービスに別の MIXI ID でログイン済みの場合、その MIXI ID で認証されてエラーになることがあります。
現在ログイン中の MIXI ID は [MIXI ID セキュリティ設定](https://account.mixi.com/id/security)から確認できます。
mixi2 アカウントと MIXI ID の関係は、以下のヘルプページを参照してください。
[mixi2アカウントとMIXI IDの関係](https://support.mixi.social/support/solutions/articles/154000212165-mixi2%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88%E3%81%A8mixi-id%E3%81%AE%E9%96%A2%E4%BF%82)
申請の到着順に審査を実施しますが、順番が前後する場合があります。システムの状況により、審査に時間がかかる場合や、新規受付を一時停止する場合があります。
詳細は[開発者登録](/getting-started/registration)をご確認ください。
mixi2 上で [mixi2 公式アカウント](https://mixi.social/@mixi2)からメッセージで審査完了の連絡が届きます。
メッセージはアプリ版でのみ確認できます(Web 版では確認できません)。
はい、電話番号の登録が必要です。
mixi2 はメールアドレスのみでアカウントを作成できますが、mixi2 Developer Platform を利用するには電話番号の登録が必要です。初回ログイン時に電話番号が未登録の場合は、登録を求められます。
## イベント受信 [#イベント受信]
用途に応じて選択してください。
| 方式 | 推奨シーン |
| ---------- | --------------------------- |
| gRPC ストリーム | ローカル開発、プロトタイピング、小規模アプリケーション |
| Webhook | 本番環境、サーバーレス環境 |
詳細は [Webhook](/guides/webhook)、[gRPC ストリーム](/guides/grpc-stream) の各ガイドをご確認ください。
以下の要件を満たす URL を設定してください。
* HTTPS の公開 URL であること
* 有効な CA 証明書を使用していること(自己署名証明書は不可)
* SDK を使用している場合、パスは `/events` になります(例: `https://YOUR_HOST_NAME/events`)
3 秒です。イベントを受信したら速やかにレスポンスを返し、アプリケーションのロジックは非同期で処理してください。
SDK を使用している場合は、レスポンスが自動で返されるため、タイムアウトを意識する必要はありません。
はい、リトライされます。
| 項目 | 値 |
| ------ | ---- |
| リトライ回数 | 3 回 |
| リトライ間隔 | 30 秒 |
## API 利用 [#api-利用]
149 文字です。
4 件までです。
いいえ、同時に指定できません。
`in_reply_to_post_id` と `quoted_post_id` はどちらか一方のみ指定可能です。
いいえ、先送りはできません。
ユーザーからの DM を受信した後のみ返信が可能です。
| メディアタイプ | 最大サイズ |
| ------- | ----- |
| 画像 | 15MB |
| 動画 | 50MB |
| メディアタイプ | 有効期限 |
| ------- | ----- |
| 画像 | 200 秒 |
| 動画 | 600 秒 |
メディアは再利用できません。`InitiatePostMediaUpload` からやり直してください。
いいえ、以下の制限があります。
| 制限項目 | 内容 |
| -------- | ----------------------- |
| 対象ポスト | アプリケーションにメンションしているポストのみ |
| 使用可能スタンプ | 公式スタンプのみ |
いいえ、取り消せません。
現状、スタンプの取り消し機能は提供されていません。
いいえ、受信しません。
自身のポストのイベントは送信されないように mixi2 側で制御されています。
## SDK [#sdk]
現状は Go のみです。
はい、可能です。
[mixi2-api](https://github.com/mixigroup/mixi2-api) リポジトリから proto ファイルを取得し、buf コマンドでコード生成できます。
SDK を使用しない場合は、認証管理や署名検証などを自前で実装する必要があります。
## Webhook 署名検証 [#webhook-署名検証]
はい、必須です。
SDK を使用している場合は自動で検証されます。SDK を使用しない場合は、署名検証を自前で実装する必要があります。
Webhook URL が設定された際に、アプリケーションサーバーが正しく実装されているか確認するために、正しい Ping イベントと無効な Ping イベントの両方が送信されます。署名検証が正しくハンドリングされている必要があります。
mixi2 Developer Platform のアプリケーション設定画面から取得できます。
## テスト・開発環境 [#テスト開発環境]
現状、サンドボックス環境は提供されていません。
現状、イベントシミュレート用の API やツールは提供されていません。
1. gRPC ストリーム方式で接続
2. mixi2 アプリから実際にメンションや DM を送信
詳細は[クイックスタート](/getting-started/quickstart)をご確認ください。
## 関連ページ [#関連ページ]
* [開発者登録](/getting-started/registration) - 開発者登録の詳細
* [クイックスタート](/getting-started/quickstart) - 最初のアプリケーション作成
* [SDK ガイド](/guides/sdk) - SDK の使い方
* [API の使い方](/guides/api-usage) - 各 API の使用方法
* [イベント](/guides/events) - イベントの種類と構造
* [Webhook](/guides/webhook) - Webhook 方式の実装
* [gRPC ストリーム](/guides/grpc-stream) - gRPC 方式の実装
* [アプリケーション開発](/guides/application) - アプリケーション構築の詳細
# GitHub リポジトリ (/docs/resource/github)
mixi2 Developer Platform では、アプリケーション開発に必要なリソースを GitHub で公開しています。
## 公式リポジトリ [#公式リポジトリ]
| リポジトリ | 説明 | 言語 |
| --------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ | ---------------- |
| [mixi2-api](https://github.com/mixigroup/mixi2-api) | API 定義です。API 仕様の詳細は [API リファレンス](/reference/api-document)を参照してください | Protocol Buffers |
| [mixi2-application-sdk-go](https://github.com/mixigroup/mixi2-application-sdk-go) | Go 向け公式 SDK です。詳しい使い方は [SDK ガイド](/guides/sdk)を参照してください | Go |
| [mixi2-application-sample-go](https://github.com/mixigroup/mixi2-application-sample-go) | サンプルアプリケーションです。詳細は [SDK ガイド - サンプルアプリケーション](/guides/sdk#サンプルアプリケーション)を参照してください | Go |
## コミュニティによるリポジトリ [#コミュニティによるリポジトリ]
有志の開発者の方々が作成・公開してくださっているリポジトリです。
mixi2 が品質・メンテナンスを保証するものではないため、ご利用の際は各リポジトリの状況をご確認ください。
| リポジトリ | 言語 | 作者 |
| ------------------------------------------------------------------------------- | ----------------------- | -------- |
| [mixi2-application-sdk-ts](https://github.com/mst-mkt/mixi2-application-sdk-ts) | TypeScript / JavaScript | mst-mkt |
| [mixi2-js](https://github.com/otnc/mixi2-js) | TypeScript / JavaScript | otnc |
| [swift-mixi2](https://github.com/ainame/swift-mixi2) | Swift | ainame |
| [kmixi2](https://github.com/uakihir0/kmixi2) | Kotlin | uakihir0 |
## 関連ページ [#関連ページ]
* [クイックスタート](/getting-started/quickstart) - サンプルコードを使った開発の始め方
* [SDK ガイド](/guides/sdk) - SDK の詳しい使い方
* [Webhook](/guides/webhook) - Webhook 方式の実装
* [gRPC ストリーム](/guides/grpc-stream) - gRPC 方式の実装
* [API リファレンス](/reference/api-document) - API の仕様