JetBrains Space ヘルプ

カスタムメニュー項目

アプリケーションは、Space のコンテキストメニューにカスタムメニュー項目を追加できます。ユーザーがカスタム項目をクリックすると、Space はアプリケーションにメッセージを送信します。メッセージには、MenuActionPayload タイプのペイロードが含まれています。

Custom menu item

カスタムメニュー項目を追加できる場所

現在、次の Space エンティティのコンテキストメニューはカスタム項目で拡張できます。

  • 課題

  • チャットメッセージ

  • コードレビュー

  • 文書

  • ドキュメントフォルダー

  • 会議

カスタムメニュー項目を追加する

カスタムメニュー項目を追加するには、アプリケーションは setUiExtensions API 呼び出しを行う必要があります。例: これは、課題のコンテキストメニューに項目を追加する方法です。

// using Kotlin SDK spaceClient.applications.setUiExtensions( // add issue menu item globally, for all projects contextIdentifier = GlobalPermissionContextIdentifier, // list of extensions: just a single menu item extensions = listOf( IssueMenuItemUiExtensionIn( // item name shown in the context menu displayName = "Remove assignee", // menu item description for the app home page description = "Remove assignee for current issue", // identify the menu item when it's clicked menuItemUniqueCode = "remove-assignee", // show the item only to users who can edit the issue visibilityFilters = listOf(IssueEditableByMe) ) ) )

可能な拡張子のリストについては、API PlaygroundSet UI Extensions メソッドを参照してください。メソッドの呼び出し方法の詳細については、サンプルアプリケーション(英語)を参照してください。

追加されたメニュー項目は、Space のアプリケーションのページ、つまり許可タブに表示されます。

Added custom menu items

Space ユーザーのカスタムメニュー項目を有効にする

アプリケーションのインストール直後は、アプリケーション所有者 (アプリケーションをインストールしたユーザー) に対してのみメニュー項目が有効になります。すべての Space ユーザーは、アプリケーションの許可タブで自分自身のメニュー項目を有効 / 無効にすることができます。アプリケーションを作成するときは、必要なコンテキストでメニュー項目を有効にする方法についての手順を必ずユーザーに提供してください (将来的には、この設定の見つけやすさを改善する予定です)。

システム管理者ロールを持つ管理者は、Space 組織内のすべてのユーザーのメニュー項目を有効にすることができます。これを行うには、すべてのユーザーに対してデフォルトで有効になっていますをオンにします。

プロジェクトまたはチャネル管理者は、対応するプロジェクトまたはチャネルの項目を有効にすることができます。

  1. インコンテキスト認証では、プロジェクトで承認またはチャネルで承認するボタンを使用して、必要なコンテキストでアプリケーションを承認します。

  2. プロジェクトまたはチャネルの認証設定を開き、拡張機能を有効にします。

メニュー項目のクリックを処理する

1. ハンドル MenuActionPayload

ユーザーがカスタムメニュー項目をクリックすると、Space は MenuActionPayload ペイロードをアプリケーションに送信します。アプリケーションは AppUserActionExecutionResult で応答する必要があります。

  • AppUserActionExecutionResult.Success – アクションは正常に実行されました。

  • AppUserActionExecutionResult.Failure – アクションの実行に失敗しました。

  • AppUserActionExecutionResult.AuthCodeFlowRequired – このアクションにはユーザーに代わって承認が必要ですが、アプリケーションにはまだ承認トークンがありません。詳細については、次のステップを参照してください。

例:

fun Routing.routes() { post("api/myapp") { // `processPayload` is a helper function that processes payload from Space // `KtorRequestAdapter` is an instance of `RequestAdapter` that is // used to read HTTP body and headers from the incoming requests. // // `ktorClient` is an HTTP client that will be used by the application // to make all requests to Space. // // `AppInstanceStorage` is an instance of `SpaceAppInstanceStorage` that stores // data on application's client ID, secret, and URL of the Space instance. Space.processPayload(KtorRequestAdapter(call), ktorClient, AppInstanceStorage) { payload -> when (payload) { // ... is MenuActionPayload -> { // If the app performs the action on behalf of itself // (the action doesn't require user permissions), // respond with `AppUserActionExecutionResult.Success` or // `AppUserActionExecutionResult.Failure`. For example: // // doSomething() // SpaceHttpResponse.RespondWithResult(AppUserActionExecutionResult.Success) // If the app requires user permissions to perform the action // and doesn't have an authorization token yet, // respond with `AppUserActionExecutionResult.AuthCodeFlowRequired` // and require the permissions in this response. // `result` must return some `AppUserActionExecutionResult`. // For example, to perform the action on behalf of the user, it must // return `AppUserActionExecutionResult.AuthCodeFlowRequired` // with required permissions. // If the application already has an authorization token, `result` must // perform the action and return `AppUserActionExecutionResult.Success`. val result = reactToMenuItem(payload) SpaceHttpResponse.RespondWithResult(result) } // ... } } } }

アクションが成功した場合は、次の JSON ペイロードで応答します。

{ "className": "AppUserActionExecutionResult.Success", "message": "message to the user" }

失敗した場合:

{ "className": "AppUserActionExecutionResult.Failure", "message": "message to the user" }

ユーザー権限が必要な場合、アプリケーションは AppUserActionExecutionResult.AuthCodeFlowRequired で応答し、この応答で権限を要求する必要があります。詳細については、次のステップを参照してください。

この時点で、アプリケーションは、それ自体またはユーザーに代わって Space でアクションを実行できます。ユーザーに代わってアクションを実行するには、アプリケーションは最初にユーザーの同意を得る必要があります ( 権限について詳しくは、こちらを参照してください )。同意を得るには、アプリケーションは AppUserActionExecutionResult.AuthCodeFlowRequiredMenuActionPayload に応答する必要があります。

// this code extends the example from the previous step suspend fun ProcessingScope.reactToMenuItem(payload: MenuActionPayload): AppUserActionExecutionResult { // Check if we already have a token for this particular user for this app instance. // If not, make `permissionRequest` to Space. // // The implementation of `findRefreshTokenData` may vary depending on how you want to store token data. val refreshTokenAndScope = findRefreshTokenData(payload.clientId, payload.userId) ?: return permissionsRequest // If we have a valid token, make requests to Space. // If the token is invalid, make `permissionRequest` to Space. val client = clientWithRefreshToken(refreshTokenAndScope.refreshToken, refreshTokenAndScope.scope) return try { doSomethingInSpace(client, payload) AppUserActionExecutionResult.Success(null) } catch (e: PermissionDeniedException) { permissionsRequest } catch (e: RefreshTokenRevokedException) { permissionsRequest } } // The `AppUserActionExecutionResult` class lists possible application responses. // `AuthCodeFlowRequired` is an app response that requests required permissions. private val permissionsRequest = AppUserActionExecutionResult.AuthCodeFlowRequired( permissionsToRequest = listOf( AuthCodeFlowPermissionsRequest( // define permission scope: operations you need to perform on behalf of the user scope = PermissionScope.build( // e.g., the app requires a global permission to view project details PermissionScopeElement( GlobalPermissionContextIdentifier, PermissionIdentifier.ViewProjectDetails ), // a project permission to view issues (in the MY-PRJ project) PermissionScopeElement( ProjectPermissionContextIdentifier(ProjectIdentifier.Key("MY-PRJ")), PermissionIdentifier.ViewIssues ), // and a project permission to update issues (in the MY-PRJ project) PermissionScopeElement( ProjectPermissionContextIdentifier(ProjectIdentifier.Key("MY-PRJ")), PermissionIdentifier.UpdateIssues ) ), purpose = "Don't ask me why, just give me the permissions" ) ) )

AuthCodeFlowRequired は、必要なアクセス許可を要求するアプリケーションの応答です。以下の例は、プロジェクトの詳細を表示するためのグローバル権限と、課題を表示および更新するためのプロジェクト権限 (MY-PRJ プロジェクトの場合) を要求する応答内の JSON ペイロードを示しています。

{ "className": "AppUserActionExecutionResult.AuthCodeFlowRequired", "permissionsToRequest": [ { "purpose": "Don't ask me why, just give me the permissions", "scope": "global:Project.View project:key:MY-PRJ:Project.Issues.View project:key:MY-PRJ:Project.Issues.Update" } ] }

権限スコープの形式の詳細については、こちらを参照する

3. ユーザーアクセストークンを保存する

Space が許可リクエストを受信すると、ユーザーに同意ダイアログが表示されます。

Grant permissions

同意すると、Space はアプリケーションに RefreshTokenPayload を送信します。リフレッシュトークンを使用すると、アプリケーションはユーザーに代わって時間制限なしで (またはユーザーが承認を取り消すまで) Space にアクセスできます。リフレッシュトークンを保存するには:

// this code extends the Kotlin SDK example from the previous steps // ... when (payload) { // ... is RefreshTokenPayload -> { // Save refresh token in a persistent storage. // You should implement this method by yourself. saveRefreshTokenData(payload) // respond with HTTP 200 OK SpaceHttpResponse.RespondWithOk } }

4. アクションコンテキストを取得してアクションを実行する

アプリケーションがリフレッシュトークンを正常に取得した後 (Space は HTTP 200 OK を受信)、Space はもう一度 MenuActionPayload を送信します。これは、ユーザーがメニュー項目を 2 回目にクリックする必要をなくすために行われます。今回は、アプリケーションはリフレッシュトークンを使用して必要なアクションを実行できます。

MenuActionPayload にはコンテキスト、つまりメニュー項目が呼び出されたオブジェクトが含まれています。例: アプリケーションが課題のコンテキストメニューを拡張していることがわかっているため、コンテキストは IssueMenuActionContext であり、対応する課題に関するデータが含まれている必要があります。コンテキストを使用して、課題の更新などのアクションを実行できます。

// this code extends the Kotlin SDK example from the previous steps suspend fun doSomethingInSpace(client: SpaceClient, payload: MenuActionPayload) { // get the context - issue details val context = payload.context as IssueMenuActionContext // update the issue to remove assignee client.projects.planning.issues.updateIssue( context.projectIdentifier, context.issueIdentifier, assignee = Option.None ) }

関連ページ:

Space HTTP API

Space HTTP API を使用すると、チャット、チームディレクトリ、プロジェクト、ドキュメント、パッケージなどの任意の Space モジュールにプログラムでアクセスできます。特定の API リクエストの実行の詳細については、API 参照を参照するか、API Playground(下記を参照) を使用してください。HTTP API をすぐに使い始めるには、Space SDK を使用します。API Playground:API Playground を使用すると、次のことが可能になります。Spac...

権限のリクエスト

特定の Space エンドポイントにアクセスするには、アプリケーションはまず対応するアクセス許可を取得する必要があります。例: アプリケーションがプロジェクトの課題を作成する場合、アプリケーションには課題の作成権限が必要です。課題の詳細を表示するには、課題を表示する権限が必要です。アプリケーションに必要な権限のセット全体は、権限スコープと呼ばれます。アプリケーションがアクセス許可を要求する方法は、アプリケーション自体の代わりに動作するアプリケーションと、Space ユーザーの代わりに動作するアプ...

はじめにページ

複数組織アプリケーションでは、ユーザーを「はじめに」ページにリダイレクトできます。このページには、アプリケーション、その機能、使用方法に関する情報を含めることができます。アプリケーションのインストール後、ダイアログにはユーザーをオンラインドキュメントページにリダイレクトするボタンが含まれます。アプリケーション開発者は、ボタンのテキストとページの URL をカスタマイズできます。カスタムメニュー項目を追加するには、アプリケーションは API 呼び出しを行う必要があります。例:// The URL o...

チャットメッセージ

チュートリアル (Kotlin) チャットボットの作成方法、(.NET) チャットボットの作成方法、(Kotlin) インタラクティブ UI をメッセージに追加する方法、サンプル Kotlin で書かれたシンプルなチャットボット、C# で書かれたシンプルなチャットボット、アプリケーション (チャットボットなど) は、アプリケーションチャットチャネルを通じて Space ユーザーと対話できます。アプリケーションチャットチャネルでは、Space ユーザーは次のことができます。アプリケーションコマンドのリ...