Microsoft Teams の共有チャネルとプライベート チャネルにより、チーム内および組織間での柔軟なコラボレーションが可能になります。 現在、エージェント アプリとタブ アプリは、共有チャネルとプライベート チャネルでサポートされています。 この更新プログラムを使用すると、複数のメリットを体験できます。
共有チャネル: ユーザーのコンテキストを変更することなく、内部または外部のメンバーとのシームレスな通信を可能にします。 これらのチャネルにより、安全なきめ細かなアクセス制御とリアルタイムのメンバーシップ同期が保証されます。
プライベート チャネル: 選択したチーム メンバーが機密性の高いコンテンツや機密性の高いコンテンツで共同作業するための安全なスペースを提供し、プライバシーを確保し、チーム内で集中的なディスカッションを行います。
注:
共有チャネルのタブ アプリは、Government Community Cloud (GCC)、GCC High、国防総省 (DoD)、21Vianet 環境で運用されている Teams で利用できます。 SharePoint および SharePoint ページ アプリは、21Vianet 環境が運用する GCC、GCC High、DoD、Teams の共有チャネルではサポートされていません。
アプリ統合のチャネルについて
さまざまなチャネルによって、アプリの可視性、ユーザー アクセス、データ ストレージの動作が決まります。
| チャネル | Access | グループ作業 | ファイルの保存場所 |
|---|---|---|---|
| 標準 | 既定ではすべてのチーム メンバー | エージェントまたはタブをすべてのユーザーが利用できるようにする必要があるチーム全体のコラボレーションに最適です | チームの SharePoint サイト |
| プライベート | 選択したチーム メンバーのみ | エージェント、コネクタ、またはファイルへのアクセスを制限する必要があるシナリオに適しています | プライベート チャネルの SharePoint サイト |
| 共有 | cross-team and cross-organization | ホスト チーム外のユーザーとチームに参加しなくても対話できます | 共有チャネルの SharePoint サイト |
チャネル間の機能
さまざまなチャネルの概要と、さまざまなパラメーターにわたる機能は次のとおりです。
| モデル | チャネル機能 | 標準チャネル | 共有チャネルとプライベート チャネル |
|---|---|---|---|
| メンバーシップ | ホスト チームに追加せずにチャネルにユーザーを追加できます | ❌ | ✔️ (プライベート チャネルではサポートされていません) |
| チャネル メンバーシップは、ホスト チームのサブセットに制限できます | ❌ | ✔️ | |
| チャネルは他のチームと共有してメンバーを継承できる | ❌ | ✔️ (プライベート チャネルではサポートされていません) |
|
| チャンネルを親チームと直接共有できる | 該当なし | ✔️ (プライベート チャネルではサポートされていません) |
|
| 外部ユーザーがチャネルに参加できる | ✔️ (B2B コラボレーション ユーザー) |
✔️ | |
| チャネルがホスト チームの下でホストされている | ✔️ | ✔️ | |
| ストレージ | 各チャネルには専用の SharePoint サイトがあります | ❌ (チーム サイトを継承) |
✔️ |
| アプリ モデル | アプリはホスト チームにインストールする必要があります | ✔️ | ✔️ |
| ホスト チームにインストールされたアプリがチャネルで自動的に利用可能 | ✔️ | ❌ | |
| 各チャネルにアプリを追加する必要があります | ❌ | ✔️ |
重要
- アプリ ロジックについてチャネルの種類の値に依存しないようにします。
- Teams のチャネル エクスペリエンスは進化し続けます。 アプリの互換性を長期間維持するために、Microsoft Graph、Agents SDK、または Teams SDK によって返される特定の
membershipType値やchannelType値に依存するロジックを構築しないでください。 代わりに、プラットフォームが提供する機能ベースの API とイベントに依存して、チャネル内でアプリがどのように動作するかを決定します。
注:
- 共有チャネルとプライベート チャネルのサポートを有効にする前に、メンバーシップの境界、ストレージの場所、外部アクセスなどのアプリの機能を確認してください。
- 個人用スコープでのみ動作するメッセージ拡張機能専用のアプリでは、共有チャネルとプライベート チャネルのユーザーが更新プログラムを利用できるようにする必要はありません。
さまざまなチャネルがアプリの機能を決定する方法を理解する
チャネルによってアプリの機能、メンバーシップ、ストレージ、プライバシーがどのように決まるかを理解しておく必要があります。 これを行わないと、機能が壊れたり、意図しないデータが漏洩したりする可能性があります。
チャネル固有のメンバーシップ API を使用する
チーム メンバーシップがチャネル メンバーシップと等しいと想定しないでください。 チャネルに追加したメンバーのみが、共有チャネルとプライベート チャネルに参加できます。
ユーザーとロールを区別する
チャネル メンバーには、テナント内ユーザー、ゲスト、またはクロステナント ユーザー (他のテナントからの外部ユーザー) が含まれる場合があります。 アクセス、データの可視性、機能の可用性を管理するためにアプリでさまざまなユーザーを区別する必要がある場合は、アクセス許可を付与する前にユーザー ロールとテナント ID を検証する必要があります。
単一の SharePoint サイトがチームに関連付けられると想定しないでください
SharePoint サイトをチームと共有する標準チャネルとは異なり、プライベート チャネルと共有チャネルには独自の SharePoint サイトがあります。 ファイルの不足や不正アクセス エラーを避けるために、チャネルごとに常に正しい URL を使用します。
データの範囲をチャネルに保持する
偶発的な漏洩を防ぐために、必要な場合にのみチャネル間でデータを集約またはクロスポストします。 たとえば、分析アプリでは、アクセス許可が明確に定義されていない限り、チーム全体のレポートにプライベート チャネル データを含めないでください。
共有チャネルとプライベート チャネル用のアプリを有効にする
ほとんどのアプリは、簡単なマニフェスト更新で共有チャネルとプライベート チャネルをサポートできます。 次のいずれかのシナリオに基づいて、アプローチを決定します。
重要
アプリ マニフェスト v1.25 以降では、supportedChannelTypes ではなく supportsChannelFeatures を使用します。 アプリ マニフェストで supportedChannelTypes を宣言した場合、アプリをアップロードまたは提出することはできません。 詳細については、「 supportedChannelTypes からの移行」を参照してください。
指定したパラメーターに依存しないアプリ
アプリで実行されない場合:
- チャネルまたはチーム メンバーシップを使用して、メッセージ配信、タスクの割り当て、またはアクセス許可を決定する
- Teams または SharePoint に保存されているファイルにアクセスまたは管理する
- 複数のチャネルまたはチーム間でデータを結合または共有する
- ユーザー (内部、ゲスト、または外部メンバー) に基づいてエクスペリエンスをカスタマイズする
次に、次のことのみを行う必要があります。
- Add
supportsChannelFeatures:tier1to your app manifest - 予期される動作を確認し、チャネル間でアプリをテストする
supportsChannelFeatures: tier1 については、クラシック アクセスと管理者アクセスには依存しません。
指定したパラメーターに依存するアプリ
アプリが高度なシナリオを処理する場合、 または指定されたパラメーターに依存しないアプリ セクションに一覧表示されている指定されたパラメーターに依存する場合は、対象を絞った更新プログラムとベスト プラクティスについて、このガイドを読んでください。 コードを書き換えないでください。
supportedChannelTypes から移行する
以前のバージョンのアプリ マニフェストでは、省略可能な supportedChannelTypes プロパティを使用して、プライベート チャネルと共有チャネルでアプリを有効にしていました。
"supportedChannelTypes": [
"sharedChannels",
"privateChannels"
]
アプリ マニフェストを v1.25 以降に更新するときに、 supportedChannelTypes を supportsChannelFeatures に置き換えます。 それ以前のバージョンのアプリ マニフェストで既に公開されているアプリは、引き続き動作します。
アプリを移行するには:
- アプリ マニフェストを v1.25 以降に更新します。
- アプリ マニフェストから
supportedChannelTypesプロパティを削除します。 - Add
supportsChannelFeatures:tier1to the app manifest. - エージェントがチャネル メンバーシップ情報を必要とする場合は、
ChannelMember.Read.Groupリソース固有の同意 (RSC) のアクセス許可を要求します。 詳細については、「 エージェントメンバーシップの変更に関するアプリ通知の取得」を参照してください。 - 標準チャネル、プライベート チャネル、および共有チャネルでアプリをテストします。 詳細については、「 チャネル間でアプリをテストする」を参照してください。
次の表は、移行時の変更点をまとめたものです。
| 分野 |
supportedChannelTypes (アプリ マニフェスト v1.24 以前) |
supportsChannelFeatures (アプリ マニフェスト v1.25 以降) |
|---|---|---|
| アプリケーション マニフェスト宣言 | チャンネルの種類ごとの値: sharedChannels、 privateChannels |
単一の準備フラグ: tier1 |
| サポートされているアプリの機能 | タブのみ | エージェントとタブ |
共有チャネルとプライベート チャネルのコンテキストを取得する
共有チャネルまたはプライベート チャネルでユーザー エクスペリエンスを読み込む場合は、共有チャネルまたはプライベート チャネルの getContext 呼び出しから受信したデータを使用します。
getContext呼び出しは、ホスト チームとホスト テナントを識別する 2 つのプロパティを発行します。これは、Microsoft Graph API を使用してチャネル メンバーシップを取得するために使用されます。 すべてのチャネルはホスト チーム内で作成されます。 詳細については、「 共有チャネルのコンテキストを取得する 」および「 プライベート チャネルのタブのコンテキストを取得する」を参照してください。
TeamsJS v1 と TeamsJS v2 の間でプロパティ名が異なります。
| 値 | TeamsJS v1 (getContext) |
TeamsJS v2 (app.getContext()) |
|---|---|---|
| ホスト チーム グループ ID | hostTeamGroupId |
channel.ownerGroupId |
| ホスト テナント ID | hostTenantId |
channel.ownerTenantId |
この記事では、TeamsJS v2 の名前を使用します。 アプリで TeamsJS v1 を使用している場合は、同じコンテキスト オブジェクトから hostTeamGroupId と hostTenantId を読み取ります。
チャネル タイプ間でのグループ ID
アプリは、インストールと使用においてクロステナントで機能する必要があります。 チャネル コンテキストで返されるグループ ID は、チャネルの種類によって異なります。
| チャネルの種類 | team.groupId |
channel.ownerGroupId (TeamsJS v1 のhostTeamGroupId ) |
|---|---|---|
| 標準 | チーム Microsoft Entra グループ ID | チーム Microsoft Entra グループ ID |
| 共有 | Empty | ホスト チーム Microsoft Entra グループ ID |
この記事で説明する Microsoft Graph チャネル API を呼び出すときは、常に channel.ownerGroupId (または TeamsJS v1 の hostTeamGroupId ) を {team-id} として使用します。
チャネルのメンバーシップを管理する
allMembers API を使用して、標準、共有、プライベート チャネルにわたるチャネル メンバーシップを管理および監視します。 直接メンバと間接メンバを正しく反映することで精度を高めます。 詳細については、「 allMembers の一覧表示」を参照してください。
GET /teams/{team-id}/channels/{channel-id}/allMembers
注:
以前のガイダンスでは、共有チャネルの名簿を 3 つの手順で構築しました。直接のメンバーを GET /teams/{host-team-group-id}/channels/{channel-id}/members で一覧表示し、共有チームを GET /teams/{host-team-group-id}/channels/{channel-id}/sharedWithTeams で一覧表示してから、各共有チームのメンバーを GET /teams/{host-team-group-id}/channels/{channel-id}/sharedWithTeams/{team-id}/members で一覧表示します。 このパターンは、1 回の allMembers 呼び出しで置き換えられます。
@microsoft.graph.originalSourceMembershipUrl 注釈を使用して直接メンバーと間接メンバーを区別し、doesUserHaveAccess API を使用して、削除後もユーザーが引き続きアクセスできるかどうかを確認します。
メンバーを識別する
- 直接メンバー: 他のテナント (クロステナント) のユーザーを含む、チャネルに直接追加されたユーザー。
- 間接メンバー: 同じテナントまたはクロステナントのチームを含む、チャネルが共有されているチームのメンバーであるユーザー。
@microsoft.graph.originalSourceMembershipUrl 注釈を確認することで、共有チャネルまたはプライベート チャネルのメンバーが直接か間接かを識別できます。 このプロパティは、メンバーのチャネルへのアクセスのソースを識別します。
| メンバーの種類 | 注釈の適用範囲 |
|---|---|
| 直接メンバー |
@microsoft.graph.originalSourceMembershipUrl プロパティは、ユーザーがチャネルに直接追加されることを示しています |
| 間接メンバー |
@microsoft.graph.originalSourceMembershipUrl プロパティには、ソース チームを指す URL が含まれ、間接メンバーシップを示します。 |
注:
メンバーが共有チャネルに追加されると、重複する通知を受け取る可能性があります。 このシナリオは、メンバーが既に直接的または間接的に共有チャネルに含まれている場合に発生する可能性があります。
allMembers API を使用して、すべての直接メンバーと間接メンバーを表示します。 メンバーが直接的または間接的に既に存在する場合は、通知を無視します。
チャネル間での間接メンバーシップの管理
次の Microsoft Graph API を使用して、チャネルの間接メンバーシップを管理できます。
allMembersAPI を使用して、特定のチャネルのメンバーであるすべてのユーザーを取得します。GET /teams/{team-id}/channels/{channel-id}/allMembersdoesUserHaveAccessAPI を使用してユーザーがチャネルから削除されたかどうかをチェックし、すべてのユーザー アクセスと関連するアクセス許可を表示できます。 クラシック アプリケーションのアクセス許可と RSC アクセス許可を持つアプリでは、この API を使用できます。GET /teams/{team-id}/channels/{channel-id}/doesUserHaveAccess(userId='@userid',tenantId='@TenantID',userPrincipalName='@UserPrincipalName')sharedWithTeamsAPI を使用して、チャネルが共有されているすべてのチームを一覧表示します。GET /teams/{team-id}/channels/{channel-id}/sharedWithTeamsallowedMembersAPI を使用して、共有チャネルにアクセスできる共有チームからユーザーを取得します。GET /teams/{team-id}/channels/{channel-id}/sharedWithTeams/{sharewithteamsId}/allowedMembers注:
allowedMembersAPI は新しく関連付けられたユーザーのみを返し、共有されていないイベントには適用されません。
Microsoft Graph メンバーシップの変更に関するアプリ通知を受け取る
共有チャネルとプライベート チャネルにインストールされたアプリは、チャネルを共有するチームにユーザーが追加または削除されたときに通知を受け取ります。
アプリの通知を受信するには、次の操作を行う必要があります。
- ホスト チームにアプリをインストールし、共有チャネルまたはプライベート チャネルに対して有効にします。 アプリのインストールの詳細については、「 アプリのインストール」を参照してください。
- サポートされている API を使用して、有効な Microsoft Graph 変更通知サブスクリプションを作成して、関連するチーム メンバーシップの変更および共有イベントまたは非共有イベントを監視します。
直接および間接の両方のメンバー更新通知を受信するには、サブスクリプションの作成時に両方のクエリ文字列パラメーターを含める必要があります。 クエリ文字列を指定しない場合、サブスクリプションは直接メンバーの更新に関する通知のみを配信します。 詳細については、「 チャネル メンバーシップへのアクセス」を参照してください。
/teams/{team-id}/channels/getAllMembers?notifyOnIndirectMembershipUpdate=true&suppressNotificationWhenSharedUnsharedWithTeam=true
このサブスクリプションを使用すると、アプリはチャネルとそれに関連するチームのメンバーシップの変更を監視できます。 Microsoft Graph の変更通知サブスクリプションを作成する方法の詳細については、「サブスクリプションの作成」を参照してください。
エージェント メンバーシップの変更に関するアプリ通知を受け取る
エージェントは、追加されたチームのメンバーシップの更新に関する通知を受け取ると、 conversationUpdate イベントを受け取ります。 直接および間接の両方のメンバー更新通知を受け取るには、次の前提条件でエージェントを設定します。
アプリ マニフェストを v1.25 に更新します。
supportsChannelFeaturesを追加: アプリの準備状態を宣言するtier1。Resource-Specific 同意 (RSC) アクセス許可を要求する
アプリは、チャネル メンバーシップ情報にアクセスするために、次の RSC アクセス許可を要求する必要があります。
{ "authorization": { "permissions": { "resourceSpecific": [ { "name": "ChannelMember.Read.Group", "type": "Application" } ] } } }共有チャネルにエージェントを追加する
メンバー イベントの通知を受け取るには、Teams レベルでエージェントをインストールし、共有チャネルで手動で許可します。
このプロセスにより、エージェントがアクティブであり、直接メンバーと間接メンバーの両方の通知を受け取る権限が確保されます。
メンバーの追加と削除されたイベントを管理する
メンバー追加イベントは、次のシナリオでエージェントに送信されます:
- エージェントをインストールして会話に追加するとき。
- エージェントがインストールされている会話にユーザーを追加するとき。
エージェントは、次のシナリオでメンバー削除イベントを受け取ります。
- エージェントをアンインストールして会話から削除した場合。
- エージェントがインストールされている会話からユーザーを削除した場合。
詳細については、「 会話イベント」を参照してください。
チームまたはチャネルにエージェントをインストールすると、共有チャネルを別のチームに追加するときに、エージェント SDK は OnConversationUpdateActivityAsync メソッドを通じてconversationUpdateアクティビティを受け取ります。
共有チャネルに新しいメンバーを追加すると、 OnMembersAddedAsync メソッドが呼び出されます。 このメソッドは、追加されたユーザーのコンテキストと詳細を提供するため、エージェントはそれに応じて応答できます。
次のエージェント SDK の例は、直接および間接の両方のメンバー追加および削除イベントに適用されます。
メンバー追加イベント
public async Task OnMembersAddedAsync(ITurnContext turnContext, AppState turnState, CancellationToken cancellationToken)
{
var membersAdded = turnContext.Activity.MembersAdded;
List<string> addedMembers = new List<string>();
foreach (var member in membersAdded)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
addedMembers.Add($"Member {member.Name} (ID {member.Id}) added.");
}
}
await ActivityUtils.SendAdaptiveCard(
"Member Added",
addedMembers,
new List<object> { "membersAdded", membersAdded },
turnContext,
cancellationToken).ConfigureAwait(false);
メンバー削除イベント
public async Task OnMembersRemovedAsync(ITurnContext turnContext, AppState turnState, CancellationToken cancellationToken)
{
var membersRemoved = turnContext.Activity.MembersRemoved;
List<string> removedMembers = new List<string>();
foreach (var member in membersRemoved)
{
if (member.Id != turnContext.Activity.Recipient.Id)
{
removedMembers.Add($"Member {member.Name} (ID {member.Id}) removed.");
}
}
await ActivityUtils.SendAdaptiveCard(
"Member Removed",
removedMembers,
new List<object> { "membersRemoved", membersRemoved },
turnContext,
cancellationToken).ConfigureAwait(false);
}
Handle bulk membership changes for graph (グラフのメンバーシップの一括変更を処理する)
一括メンバーシップの変更がある場合、チャネルがチームと共有または共有解除されたときに、Teams は個々のメンバーシップの更新通知を抑制します。 数千人のメンバーを持つチームに共有チャネルが追加または削除される場合など、メンバーシップの更新中に通知の過負荷を軽減するには、 sharedWithTeams サブスクリプション リソースを使用します。
/teams/{team-id}/channels/{channel-id}/sharedWithTeams
sharedWithTeams サブスクリプションでは、チャネルがチームと共有または共有解除されると、1 つの通知が送信されます。 ユーザーごとの何千もの通知を回避し、メンバーシップの変更を監視するアプリのパフォーマンスを向上させます。 チームで共有またはチームからの共有解除通知を受け取った後、allMembers API を使用して共有チャネル メンバー リストを更新してください。
Graph メンバーシップの更新に対するユーザー アクセスの検証
アプリが間接メンバーシップの更新について のメンバー削除 通知を受信した場合、ユーザーがチャネルから削除されたかどうかを確認することが重要です。特に、同じユーザーが直接メンバーシップと間接メンバーシップの両方を持っている可能性があるためです。 たとえば、チャネルを共有しているチームからユーザーが削除された場合、アプリは、ユーザーの共有チャネルへのアクセスが取り消されているかどうかを確認する必要があります。
doesUserHaveAccess API を使用して、ユーザーが共有チャネルから削除されているかどうかを判断します。 ユーザー アクセスと関連するアクセス許可の詳細については、 doesUserHaveAccess API を参照してください。
GET /teams/{team-id}/channels/{channel-id}/doesUserHaveAccess(userId='@userid',tenantId='@TenantID',userPrincipalName='@UserPrincipalName')
アプリが間接メンバーシップの更新に関する メンバー追加通知 を受信したら、 allMembers API を参照してすべてのメンバーのリストを更新します。
GET /teams/{team-id}/channels/{channel-id}/allMembers
メンバーをテナント内またはテナント外として分類する
次のように、メンバーまたはチームの TenantId を ownerTenantId と比較することで、メンバーをテナント内またはテナント外に分類できます。
比較するメンバーの
TenantIdを取得します。GET /teams/{host-team-group-id}/channels/{channel-id}/allMembersTeams JavaScript クライアント ライブラリからタブで
microsoftTeams.app.getContext()を呼び出す。 getContext() 呼び出しは、displayName、membershipType、ownerGroupId、ownerTenantIdなどの詳細を含む共有チャネルのコンテキストを返します。メンバーの
TenantIdをownerTenantIdプロパティと比較し、メンバーがテナント内か外テナントかを判断します。
共有チャネルのアプリのアクセス許可について
共有チャネルを使用して、organization 外の外部メンバーと共同作業できます。 共有チャネルでのアプリのアクセス許可は、ホスト チームのアプリ名簿とホスト テナントのアプリ ポリシーに従います。
注:
アクティビティ フィード通知 API は、共有チャネル内のアプリに対するクロス テナント通知をサポートしていません。
チャネルでのエージェントのインストールを確認する
共有チャネルが別のチームに追加されると、エージェント SDK は、エージェントがチームにインストールされている場合にのみ、OnConversationUpdateActivityAsync メソッドを通じてconversationUpdateアクティビティを受け取ります。 アプリがチャネルの一部であるかどうかをチェックするための専用 API はありません。 エージェントは、アプリがチャネルに追加されたタイミングを間接的に検出できます。
この channelMemberAdded イベントを使用して、次のようなアプリ固有のロジックをトリガーします。
- ウェルカム メッセージを送信する
- チャンネル名簿を取得する
- タブの構成
- スケジュールされたジョブの開始
protected override async Task OnConversationUpdateActivityAsync(
ITurnContext<IConversationUpdateActivity> turnContext,
CancellationToken cancellationToken)
{
var tcd = turnContext.Activity.GetChannelData<TeamsChannelData>();
var eventType = tcd?.EventType?.ToLowerInvariant();
var extended = turnContext.Activity.GetChannelData<SharedChannelChannelData>();
var raw = turnContext.Activity.ChannelData as JObject
?? (turnContext.Activity.ChannelData != null
? JObject.FromObject(turnContext.Activity.ChannelData)
: new JObject());
_logger.LogInformation("ConversationUpdate eventType={EventType}, channelId={ChannelId}, teamId={TeamId}",
eventType, tcd?.Channel?.Id, tcd?.Team?.Id);
switch (eventType)
{
case "channelshared":
{
var hostTeam = extended?.Team;
var sharedWith = extended?.SharedWithTeams ?? new List<TeamInfoEx>();
_logger.LogInformation("ChannelShared: hostTeam={HostTeamId}, sharedWithCount={Count}",
hostTeam?.Id, sharedWith.Count);
foreach (var team in sharedWith)
{
_logger.LogInformation("SharedWithTeam: id={Id}, name={Name}, aadGroupId={AadGroupId}, tenantId={TenantId}",
team.Id, team.Name, team.AadGroupId, team.TenantId);
}
await turnContext.SendActivityAsync(
MessageFactory.Text($" Channel shared with {sharedWith.Count} team(s)."),
cancellationToken);
break;
}
case "channelunshared":
{
var unsharedFrom = extended?.UnsharedFromTeams ?? new List<TeamInfoEx>();
_logger.LogInformation("ChannelUnshared: unsharedFromCount={Count}", unsharedFrom.Count);
foreach (var team in unsharedFrom)
{
_logger.LogInformation("UnsharedFromTeam: id={Id}, name={Name}, aadGroupId={AadGroupId}, tenantId={TenantId}",
team.Id, team.Name, team.AadGroupId, team.TenantId);
}
await turnContext.SendActivityAsync(
MessageFactory.Text($" Channel unshared from {unsharedFrom.Count} team(s)."),
cancellationToken);
break;
}
default:
break;
}
await base.OnConversationUpdateActivityAsync(turnContext, cancellationToken);
}
外部ユーザーを認証して SharePoint のアプリ コンテンツにアクセスする
チャネルをホストするテナントの SharePoint サイトにアプリがコンテンツを保存し、SharePoint トークンを要求する場合は、この手順を完了します。
- タブが構成されている共有チャネルのホスト テナント ID を保存します。
- TeamsJS v2 で
channel.ownerTenantIdを使用するか、TeamsJS v1 のgetContext呼び出しからhostTenantIdを使用してホスト テナント ID を取得します。
ここで、保存されたホスト tenantIdをtenantIdgetAuthToken呼び出しのパラメーター内で送信して、クロステナント ユーザーが共有チャネルに接続されている SharePoint サイト内でホストされているコンテンツにアクセスできるようにします。
Graph API を使用してチャネル内のゲスト ユーザーを識別する
チャネルのメンバーの一覧表示内の各オブジェクトの roles プロパティを使用して、チャネルのメンバーが外部organizationからテナントに招待されたゲスト ユーザーであるかどうかを確認できます。
ゲストの場合は、 roles = guest。
チャネル内のすべてのゲスト ユーザーを正確に取得するには、次の allMembers API を使用します。
GET /teams/{team-id}/channels/{channel-id}/allMembers
この API は、標準チャネルとその他のチャネルで機能し、ゲスト メンバーを確実に識別するために推奨されます。
共有チャネルとプライベート チャネルの SharePoint データにアクセスする
SharePoint Framework を使用してアプリを構築する場合は、ホスト チーム グループにリンクされているチャネルではなく、共有チャネルにリンクされている SharePoint in Microsoft 365 (SPO) サイトを使用する必要があります。 共有チャネルとプライベート チャネルの両方に、その特定の共有チャネルまたはプライベート チャネルのメンバーのみがアクセスできる独自の SharePoint サイトがあります。
Microsoft Graph 招待 API を使用して、共有チャネルまたはプライベート チャネルにリンクされている Microsoft 365 の SharePoint サイトのドキュメント ライブラリにアクセスします。
注:
Mailbox または Calendar のシナリオの要件については、「機能の要求と一般的なヘルプ」を参照してください。
Graph API を使用してチャネル ファイルの SharePoint ストレージにアクセスする
チャネルの SharePoint ファイルのルートにアクセスするには、次の API を使用します。
GET /teams/{teamId}/channels/{channelId}/filesFolder
この API は、そのチャネルのファイル ルートの DriveItem オブジェクトを返します。 詳細については、「 チャネル ファイル」を参照してください。
以降のすべてのファイル操作には、次のプロパティを使用します。
-
parentReference.driveId: チャネルのサイトの SharePoint driveId。 -
itemId: チャネルのルートのフォルダー ID。
チャネルで想定されるドライブ動作は次のとおりです。
- Standard チャネルでは、チーム サイトの driveId を使用します。
- 他のチャネルでは、サイトごとに別の
driveIdを使用します。
注:
API によって返される driveId と itemId は常に格納して再利用します。
チーム サイトの場所は変更される可能性があるため、チーム サイトに関する前提に基づいてライブラリ名または URL をハードコードしないでください。
すべてのチャネル タイプにこの GET /teams/{teamId}/channels/{channelId}/filesFolder API を使用します。
Graph API を使用して外部ユーザーまたはゲスト ユーザーのファイル アクセスを管理する
外部ユーザーは、ホスト チャネルの SharePoint サイトにアクセスするときにテナントにとどまります。 アクセスを有効にするには:
- 両側でクロス テナント アクセスを構成します。
- アプリがマルチテナントであり、ホスト テナントで同意を受け取ることを確認します。
タブまたはタスク モジュールで外部ユーザーを認証する
タブまたはタスク モジュールがチャネルのホーム テナント内の SharePoint リソースにアクセスする必要がある場合は、次の手順を実行します。
外部ユーザーを検出する
getContext()を使用してチャネル コンテキストを取得します。user.tenant.idをchannel.ownerTenantId(TeamsJS v1 のhostTenantId) と比較します。 異なる場合、ユーザーは外部ユーザーです。ホーム テナントからのトークンの要求 外部ユーザーのテナント ID (
user.tenant.idまたはtid) を使用して getAuthToken() を呼び出して、ホーム テナントからトークンが発行されていることを確認します。
チャネル間でアプリをテストする
更新情報を公開する前に、実際の状況において、アプリがすべてのチャネル タイプで正しく動作することを確認してください。
標準チャネル
変更後も既存の機能がそのまま残っていることを確認します。 タブ、ボット、メッセージング拡張機能が引き続き期待どおりに動作することを確認します。
共有チャネル
プライベート チャネル
チーム A に、少なくとも 2 人のメンバー (所有者とメンバー) を持つプライベート チャネルを作成します。
次の手順を実行して、プライベート チャネルのサポートを検証します。
- アプリをチーム A に追加してから、プライベート チャネルに追加します。
- タブがプライベート チャネルに正しく読み込まれることを確認します。
- アプリにメンバーを一覧表示したり、タスクを割り当てたりする場合は、チーム全体ではなくチャネル メンバーのみを使用していることを確認します。
- プライベート チャネルに新しいメンバーを追加し、次をチェックします。
- アプリがメンバーシップ変更イベントを受け取るかどうか
- メンバーシップ API が新しいメンバーを反映しているかどうか
これらのシナリオでテストすると、機能、アクセス許可、およびユーザー エクスペリエンスに関する問題を見つけるのに役立ちます。
すべてのチャネルをサポートするためのベスト プラクティス
すべきこと
- アクションを実行する前に、必ず現在のチャネルのメンバー リストとロールを取得してください。 たとえば、通知を送信したり、タスクを割り当てたりする場合は、チーム全体ではなく、実際のチャネル メンバーのみを対象にします。
- チャネル メンバーシップとアクセス許可に基づいてデータ アクセスと共有を制御します。 詳細については、「 チャネル メンバーシップの管理」を参照してください。
- ユーザーが内部、ゲスト、外部 (クロステナント) のいずれであるかを判断し、ホーム テナントで認証します。 特にファイルにアクセスする場合は、クロステナント シナリオのアクセス許可を常に検証します。 詳細については、「Graph API を使用したチャネルのゲスト ユーザーの識別」を参照してください。
- ヘルプ テキストとユーザー ガイドを更新 して、ゲストや外部ユーザーの制限など、さまざまなチャネルの種類でのアプリの動作について説明します。
- Teams のドキュメントと変更ログを確認し て、API、権限、チャネル構成の最新の更新プログラムに合わせてください。
してはいけないこと
- 機密性の高いアクションを 所有者または内部ユーザーに制限し、ゲストまたは外部参加者に限定された機能を提供します。
- 明示的に許可されていない限り、プライベート チャネルのデータを詳細レポートやパブリック チャネルに含めないでください。
よく寄せられる質問
チャネルに追加しようとしてもアプリが表示されないのはなぜですか?
マニフェストに必要なサポート ( supportsChannelFeatures: tier1 など) が見つからない場合は、アプリが表示されないことがあります。 また、インストーラーに十分なアクセス許可がない可能性があります。 チーム メンバーまたは所有者のみがアプリを追加でき、ローカル ポリシーでアプリのインストールが許可される必要があります。 チャネルが受信共有チャネル (チームに共有) である場合、その場所から直接アプリを追加することはできません。 このような場合は、ホスト チームに切り替えてアプリをチャネルに追加します。 ホスト チーム ID のチャネル メタデータを確認することで、チャネルが共有されているかどうかを検出できます。
チャネル API を呼び出すときに、"アプリはこのチャネルでは有効になっていません" という 403 エラーが発生するのはなぜですか?
このエラーは、アプリがチーム レベルでインストールされているが、チャネルに追加されていない場合に発生します。 この問題を解決するには、アプリがチャネルに追加されていることを確認します。 アプリでリソース固有の同意 (RSC) を使用している場合は、マニフェストで宣言されているアクセス許可が、チャネル メンバーシップを読み取るための ChannelMember.Read.Group など、実行しようとしている API 呼び出しと一致していることを確認します。 アプリを追加したら、操作を再試行します。 エージェントの場合、エージェントが channelMemberAdded イベントを受信したときにチャネル固有のロジックを開始して、チャネルへの追加が成功したことを確認します。
チャネル名簿が不完全に表示され、所有者のみが表示されたり、ユーザーが表示されないのはなぜですか?
適切なチャネル固有の API の代わりにチーム メンバー API が使用されているため、チャネル名簿が不完全に見えます。 この問題を解決するには、 /channels/{id}/allMembers API を使用して、完全なチャネル名簿を取得します。 応答に所有者のみが表示される場合、アプリはチャネルに追加されていない可能性があります。 アプリをチャネルに追加するようにユーザーに求めてから、更新された名簿を取得する要求を再試行します。
チャネルに参加しているユーザーによっては、ファイル アクセスが失敗するのはなぜですか?
このエラーは、アプリがチャネルの特定のサイトではなく、チームのメインの SharePoint サイトを使用している場合に発生する可能性があります。 organization の共有ポリシーがリンクの種類をブロックしたり、外部ユーザーに必要なアクセス許可がなかったりする可能性があります。 この問題を解決するには、アプリでチャネルの filesFolder プロパティを使用して、ファイル操作の正しい driveId と itemId を取得するようにしてください。 ファイルを共有するときは、既存のアクセス リンクまたは招待 API を持つユーザー を使用して、特定のユーザーまたはグループにアクセス権を付与します。
タブまたはタスク モジュールで外部ユーザーに認証の問題が発生しているのはなぜですか?
認証の問題は、多くの場合、アプリがユーザーのホーム テナントではなくホスト テナントのトークンを要求した場合に発生します。 この問題を解決するには、context.user.tenant.idをホストまたは所有者のテナント ID と比較して、ユーザーが外部かどうかをチェックします。 異なる場合、ユーザーは外部であり、アプリはユーザーのホーム テナントのトークンを要求する必要があります。 この手順を実行するには、 getAuthToken を呼び出すときに正しいテナント ID (tid) を渡します。
アプリがチャネルに追加されたことを知る操作方法
この問題は、アプリがチャネル レベルでインストールされているアプリの一元的なリストを想定している場合、またはチーム レベルのインストール動作に依存している場合に発生する可能性があります。 現在、チャネル レベルの installedApps リストはありません。 代わりに、エージェントはチャネル内の channelMemberAdded イベントをリッスンして、いつ追加されたかを検出する必要があります。 アプリで 403 エラーが発生してイベントを見逃すと、ユーザーにエージェントをチャネルに追加するように求め、エラーを管理します。
アプリが共有チャネルまたはプライベート チャネルでメッセージ変更通知を作成できないのはなぜですか?
共有チャネルまたはプライベート チャネルでは、これらの種類のチャネルでリソース固有の同意 (RSC) を使用すると /channels/{id}/messages へのサブスクリプションがブロックされるため、メッセージ変更通知が失敗する可能性があります。 アプリでサブスクリプションを作成しようとしたときに 403 エラーが発生した場合、この動作は想定されます。 この問題を解決するには、アプリがチャネルに正常に追加された後のオンデマンド メッセージ読み取りを使用します。
アプリがチャネルに追加された後も、外部ユーザーのファイル リンクが失敗するのはなぜですか?
メッセージ変更通知エラーは、テナントの共有ポリシーによってリンクの種類がブロックされている場合、またはチャネルのメンバーであってもユーザーがアイテムにアクセスできない場合に発生します。 もう 1 つの一般的な原因は、チャンネルの専用ドライブではなく、チーム ドライブを指すリンクがアプリによって生成される可能性があることです。 この問題を解決するには、[ 既存のアクセス権を持つユーザー ] オプションを使用してリンクを再発行するか、招待 API を使用して特定のユーザーにアクセス権を付与します。 また、リンクがチーム サイトではなく、 filesFolder プロパティを使用して識別できるチャネル ドライブを参照していることを確認します。
コード サンプル
| サンプルの名前 | 説明 | .NET | Node.js | Python |
|---|---|---|---|---|
| エージェントの共有チャネル イベント | このサンプル アプリは、Teams エージェントの推移的なメンバーの共有チャネルの追加と削除イベントを表示します。 | 表示 | 該当なし | 該当なし |
| メンバーシップ変更通知 | サンプル アプリケーションでは、Teams で共有チャネル イベントの通知を送信する方法を示します。 シナリオには、ユーザーの追加、削除、メンバーシップの更新、チャネルがチームと共有または共有解除される場合が含まれます。 | 表示 | 表示 | 表示 |
関連項目
Platform Docs