CINXE.COM
トピックベースのメッセージング | Amazon Device Messaging
<!doctype html><!--[if IE 8]><html data-19ax5a9jf="dingo" lang="ja_JP" class="a-no-js a-lt-ie10 a-lt-ie9 a-ie8"><![endif]--><!--[if IE 9]><html data-19ax5a9jf="dingo" lang="ja_JP" class="a-no-js a-lt-ie10 a-ie9"><![endif]--><!--[if !(IE 8)&!(IE 9)]><!--><html data-19ax5a9jf="dingo" lang="ja_JP" class="a-no-js"><!--<![endif]--> <head><script>var aPageStart = (new Date()).getTime();</script><meta charset="utf-8"/> <link rel="stylesheet" href="https://images-na.ssl-images-amazon.com/images/I/11KpeNaLkYL._RC|01Gdis3QUIL.css,01lF2n-pPaL.css,41YB-4vQfqL.css,31iNSIr1kuL.css,011DCEwfbwL.css,013z33uKh2L.css,01R9dtRDQdL.css,01rhj7BIeEL.css,410iOIpxjqL.css,11TIuySqr6L.css,01ElnPiDxWL.css,114oHnH0QRL.css,01crd53+KxL.css,01IdKcBuAdL.css,01y-XAlI+2L.css,01RgENaJKWL.css,219sMS379pL.css,01oDR3IULNL.css,51CguxBmgsL.css,01XPHJk60-L.css,01lN1FNc-RL.css,21Z4Q-IpuWL.css,11MrAKjcAKL.css,21qHKSTSJCL.css,11Zh8bU-hoL.css,01F7oM-p7IL.css,31jsrAUX5KL.css,11WHSxzwhML.css,11MO3b1rxzL.css,11ylgxpE+pL.css,11b-GR26DVL.css,01j2JE3j7aL.css,11maZ3sCvAL.css,21fXaeFAbUL.css,11TxiWYBNOL.css,01chhhuYckL.css,21Q7cg1AwNL.css,1128pDOWgAL.css,11mA7+zB7BL.css,01G+-woTSUL.css,01890+Vwk8L.css,01b3+vZ+YbL.css,01cbS3UK11L.css,21kdNu0AlvL.css,0116OOHSwvL.css_.css?AUIClients/AmazonUI#jp.trident" /> <link rel="stylesheet" href="https://images-na.ssl-images-amazon.com/images/I/71cTjwDJRNL.css?AUIClients/DeXWebsiteAUIAssets" /> <meta charset="utf-8"> <title>トピックベースのメッセージング | Amazon Device Messaging </title> <meta name="description" content="トピックベースのメッセージング トピックベースのメッセージング(TBM)を使用すると、同じト..."> <meta name="keywords" content=""> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="icon" type="image/x-icon" href="https://amzndevresources.com/jekyll/css/favicon.ico"> <!-- FontAwesome (GPL license) --> <link rel="stylesheet" type="text/css" href="https://amzndevresources.com/jekyll/css/font-awesome/css/font-awesome.min.css"> <meta name="google-site-verification" content="wfEDah_6uJe9Y7uIfLrVycd_efr8wQ9YO-fM_5MI5w0" /> <meta name="google-site-verification" content="Eu8BqTWMhRRdfCAdqUh2RYb3SjAiuFp4wmgTtGcteM0" /> <link rel="alternate" href="https://developer.amazon.com/ja/docs/adm/topic-based-messaging.html" hreflang="en_US" /> <link rel="canonical" href="https://developer.amazon.com/ja/docs/adm/topic-based-messaging.html" /> <meta name="google-site-verification" content="KHmp6TUPKc1gHlM9TuB842pcV7TxZVV6TgenZtsYoNY" /> <meta name="msvalidate.01" content="9761B379C1B64F587D71BA40337FDD07" /> <script language="JavaScript" type="text/javascript"> var digitalData ={ page:{ pageInfo: { pageInstanceID: "ja\/docs\/adm\/topic\-based\-messaging.html", path: "\/ja\/docs\/adm\/topic\-based\-messaging.html", pageID: "", pageTitle: "", pageType: "DeX", primaryCategory: "appstore", pageName: "", language: "en_US" } }, user:{ userID: "", ipAddress: "8.222.208.146" } }; var urlSplit = "\/ja\/docs\/adm\/topic\-based\-messaging.html".split("/"); var trailingSlash = urlSplit.pop(); var pTitle = trailingSlash; if (trailingSlash == ""){ pTitle = urlSplit.pop() } if ("".indexOf("search") !== -1) { digitalData.page.pageInfo.searchResultsNum = ""; } if ("".indexOf("dex-home") !== -1){ digitalData.page.pageInfo.pageID = "Home"; digitalData.page.pageInfo.pageTitle = "Home"; digitalData.page.pageInfo.primaryCategory = "Home"; } else { digitalData.page.pageInfo.pageID = pTitle; pTitle = pTitle.replace(/(^|-)[a-z]/g,function(f){return f.toUpperCase();}); pTitle = pTitle.replace(/-/g, ''); digitalData.page.pageInfo.pageTitle = pTitle; var pCat = digitalData.page.pageInfo.primaryCategory; pCat = pCat.replace(/(^|-)[a-z]/g,function(f){return f.toUpperCase();}); pCat = pCat.replace(/-/g, ''); digitalData.page.pageInfo.primaryCategory = pCat; } var pageNameStr = "" + digitalData.page.pageInfo.primaryCategory; //Todo: add in logic for sub-categories when AOI is implemented. if (digitalData.page.pageInfo.pageTitle != null){ if (pageNameStr != ""){ pageNameStr += ":"; } pageNameStr += digitalData.page.pageInfo.pageTitle; } digitalData.page.pageInfo.pageName = pageNameStr; (function (w) { w.URLSearchParams = w.URLSearchParams || function (searchString) { var self = this; self.searchString = searchString; self.get = function (name) { var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(self.searchString); if (results == null) { return null; } else { return decodeURI(results[1]) || 0; } }; } })(window); </script> <script src="https://m.media-amazon.com/images/G/01/envImprovement/js/jquery/jquery-3.5.1.min.js" crossorigin="anonymous"></script> <script src="https://ds6yc8t7pnx74.cloudfront.net/content/dam/developer-portal/analytics/prod/launch-EN968f8a7401fc4ccea43ced61e7b0c2bb.min.js" async></script> <link rel="stylesheet" type="text/css" href="https://d20632htc2msyc.cloudfront.net/static/css/main.css" /> <script defer src="https://d20632htc2msyc.cloudfront.net/static/js/main.js"></script> <script type="text/javascript"> (function() { var didInit = false; function initMunchkin() { if(didInit === false) { didInit = true; Munchkin.init('365-EFI-026'); } } var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true; s.src = '//munchkin.marketo.net/munchkin.js'; s.onreadystatechange = function() { if (this.readyState == 'complete' || this.readyState == 'loaded') { initMunchkin(); } }; s.onload = initMunchkin; document.getElementsByTagName('head')[0].appendChild(s); })(); </script> </head> <body class="a-m-jp a-aui_72554-c a-aui_a11y_1_699934-c a-aui_a11y_4_835613-c a-aui_a11y_6_837773-c a-aui_a11y_sr_678508-c a-aui_killswitch_csa_logger_372963-c a-aui_pci_risk_banner_210084-c a-aui_preload_261698-c a-aui_rel_noreferrer_noopener_309527-c a-aui_template_weblab_cache_333406-c a-aui_tnr_v2_180836-c"><div id="a-page"><script type="a-state" data-a-state="{"key":"a-wlab-states"}">{"AUI_A11Y_6_837773":"C","AUI_TNR_V2_180836":"C","AUI_PRELOAD_261698":"C","AUI_TEMPLATE_WEBLAB_CACHE_333406":"C","AUI_72554":"C","AUI_A11Y_1_699934":"C","AUI_A11Y_4_835613":"C","AUI_KILLSWITCH_CSA_LOGGER_372963":"C","AUI_A11Y_SR_678508":"C","AUI_REL_NOREFERRER_NOOPENER_309527":"C","AUI_PCI_RISK_BANNER_210084":"C"}</script> <link rel="stylesheet" type="text/css" href="https://m.media-amazon.com/images/G/01/Fonts/FontAwesome/css/font-awesome.min._V516135338_.css"> <header class='dpHeader dphThemedark'> <div class='dphTopBar clearfix'> <div class='dphLeft'> <div class='dphMenuToggle'> <i class='dphMenuIcon'></i> <i class='dphMenuBackIcon'></i> </div> <a class='dphLogo' href='/ja/apps-and-games'> <img src="https://m.media-amazon.com/images/G/01/mobile-apps/dex/logos/amazonAppstoreLogoDarkBG1x_new.png" srcset="https://m.media-amazon.com/images/G/01/mobile-apps/dex/logos/amazonAppstoreLogoDarkBG1x_new.png 1x, https://m.media-amazon.com/images/G/01/mobile-apps/dex/logos/amazonAppstoreLogoDarkBG2x.png 2x" alt="Amazon開発者ポータルのロゴ"> </a> </div> <div class='dphRight'> <div class="dphSearchBarWrap"> <!-- Used in tech docs to hide side bar search results when we rollout new search --> <script type="text/javascript"> window.newSearch = true; </script> <div hidden style="display: none;" class="new-search-flag" data-val="enabled"></div> <div hidden style="display: none;" class="new-search-metadata"> {"settingsUrl":"https://ds6yc8t7pnx74.cloudfront.net/devportal-digital-assets/cf/developer-portal/getDeXSearchData"} </div> <div id="dex-search-header-bar"> </div> </div> <a href="/ja/home.html" class='dphConsole dphLink'>開発者コンソール</a> <div class='dphUserInfo'> <a class="dphLink" href="/settings/console/registration?return_to=/ja/docs/adm/topic-based-messaging.html">ログイン</a> </div> <style> #notification-counter { position: absolute; top: 2px; padding: 0 2px; min-width: 20px; background: #BF2727; color: white; font-size: 11px; border-radius: 3px; line-height: 20px; text-align: center; } #notification_click_icon { width: 32px; height: 32px; background-color: #31465f; text-align: center; line-height: 32px; border-radius: 50%; margin-right: 15px; color: white; font-weight: 300; cursor: pointer; } #notification-placeholder { position: absolute; top:45px; } #notification_flyout_iframe_id { display: none; position: absolute; width: 425px; border: none; transform: translate(-80%); transition: all 0.2s; } @media screen and (max-width: 992px) { #notification_click_icon { position: fixed; display: inline-block; right: 44px; } #notification_click_icon ~ .dphSearch.active { position: relative; z-index: 0; } #notification-placeholder { top:28px; } #notification-counter { top: -6px; } } @media screen and (max-width: 414px) { #notification_flyout_iframe_id { transform: none; right: -99px; width: 100vw; } #notification_click_icon ~ .dphSearch.active { position: relative; z-index: 0; } } </style> <div id='navFlyout?' class='dphFlyoutItem dphDevConsoleLinkTopBar dphButton'> <span class='dphConsole dphLink'>?</span> <div class='dphDropdownWrap'> <nav class='dphDropdown accrItem'> <div class='dpIconArrow accrHandle'></div> <ul class='dphDropdownList'> <li class='dphdItem'><a href='/support/'>サポート</a></li> <li class='dphdItem'><a href='/documentation/'>ドキュメント</a></li> <li class='dphdItem'><a href='/support/contact-us'>お問い合わせ</a></li> <li class='dphdItem'><a href='/support/cases'>Amazonアプリストアのケース</a></li> </ul> </nav> </div> </div> </div> </div> <div class='dphNavigation accordion' data-accr_active_width='327'> <div class='dphnWrap'> <div class='dphUserInfo'> <a class="dphLink" href="/settings/console/registration?return_to=/ja/docs/adm/topic-based-messaging.html">ログイン</a> </div> <a href="/ja/home.html" class='dphConsole dphLink'>開発者コンソール</a> <nav class="dpPrimaryNav"> <ul class="dppnItems"> <li class="dppnItem accrItem"> <span class="dppnLink"> デバイス </span> <div class='dpIconArrow accrHandle'></div> <div class='dppnFlyoutWrap'> <div class='dppnSecondaryNavWrap'> <ul class="dppnFlyout dppnSecondaryNav"> <li class="dppnfItem accrItem"> <span class="dppnfLink"> <span class="dppnfTitle">Fire TV</span> <span class="dppnfSubtitle"></span> </span> <div class='dpIconArrow accrHandle'></div> <div class='dppnLevel3NavWrap'> <ul class="dppnFlyout dppnLevel3Nav"> <li class="dppnfItem "> <a href="/ja/apps-and-games/fire-tv" class="dppnfLink"> <span class="dppnfTitle">概要</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tv/getting-started-developing-apps-and-games.html" class="dppnfLink"> <span class="dppnfTitle">開発</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tv/device-specifications.html" class="dppnfLink"> <span class="dppnfTitle">デバイス仕様</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tv/device-specifications-comparison-table.html" class="dppnfLink"> <span class="dppnfTitle">デバイスの比較</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tv/fire-os-overview.html" class="dppnfLink"> <span class="dppnfTitle">Fire TV向けFire OS</span> <span class="dppnfSubtitle"></span> </a> </li> </ul> </div> </li> <li class="dppnfItem accrItem"> <span class="dppnfLink"> <span class="dppnfTitle">Fireタブレット</span> <span class="dppnfSubtitle"></span> </span> <div class='dpIconArrow accrHandle'></div> <div class='dppnLevel3NavWrap'> <ul class="dppnFlyout dppnLevel3Nav"> <li class="dppnfItem "> <a href="/ja/apps-and-games/fire-tablets" class="dppnfLink"> <span class="dppnfTitle">概要</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tablets/ft-get-started.html" class="dppnfLink"> <span class="dppnfTitle">開発</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tablets/ft-device-specifications.html" class="dppnfLink"> <span class="dppnfTitle">デバイス仕様</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tablets/fire-os-8.html" class="dppnfLink"> <span class="dppnfTitle">Fireタブレット向けFire OS</span> <span class="dppnfSubtitle"></span> </a> </li> </ul> </div> </li> </ul> </div> </div> </li> <li class="dppnItem accrItem"> <span class="dppnLink"> ビルド </span> <div class='dpIconArrow accrHandle'></div> <div class='dppnFlyoutWrap'> <div class='dppnSecondaryNavWrap'> <ul class="dppnFlyout dppnSecondaryNav"> <li class="dppnfItem accrItem"> <span class="dppnfLink"> <span class="dppnfTitle">Fire TV対応アプリ</span> <span class="dppnfSubtitle"></span> </span> <div class='dpIconArrow accrHandle'></div> <div class='dppnLevel3NavWrap'> <ul class="dppnFlyout dppnLevel3Nav"> <li class="dppnfItem "> <a href="/ja/docs/fire-tv/getting-started-developing-apps-and-games.html" class="dppnfLink"> <span class="dppnfTitle">開発</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tv/design-and-user-experience-guidelines.html" class="dppnfLink"> <span class="dppnfTitle">UX設計ガイドライン</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tv/remote-input.html" class="dppnfLink"> <span class="dppnfTitle">リモコン入力</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tv/connecting-adb-to-device.html" class="dppnfLink"> <span class="dppnfTitle">ADBを使用した接続</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tv/self-service-advertising.html" class="dppnfLink"> <span class="dppnfTitle">Fire TV対応アプリの宣伝</span> <span class="dppnfSubtitle"></span> </a> </li> </ul> </div> </li> <li class="dppnfItem accrItem"> <span class="dppnfLink"> <span class="dppnfTitle">Fireタブレット対応</br>アプリ</span> <span class="dppnfSubtitle"></span> </span> <div class='dpIconArrow accrHandle'></div> <div class='dppnLevel3NavWrap'> <ul class="dppnFlyout dppnLevel3Nav"> <li class="dppnfItem "> <a href="/ja/docs/fire-tablets/ft-get-started.html" class="dppnfLink"> <span class="dppnfTitle">開発</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tablets/ft-ux-specifications.html" class="dppnfLink"> <span class="dppnfTitle">UX設計ガイドライン</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/fire-tablets/connecting-adb-to-device.html" class="dppnfLink"> <span class="dppnfTitle">ADBを使用した接続</span> <span class="dppnfSubtitle"></span> </a> </li> </ul> </div> </li> <li class="dppnfItem accrItem"> <a href="/ja/docs/apps-and-games/sdk-downloads.html" class="dppnfLink"> <span class="dppnfTitle">SDK</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <a href="/ja/docs/app-submission/migrate-existing-app.html" class="dppnfLink"> <span class="dppnfTitle">Androidアプリの</br>移植</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <a href="/ja/apps-and-games/services-and-apis/monetization" class="dppnfLink"> <span class="dppnfTitle">アプリの収益化</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <a href="/ja/apps-and-games/services-and-apis" class="dppnfLink"> <span class="dppnfTitle">サービス・API</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <a href="/ja/apps-and-games/blogs/tag.best-practices" class="dppnfLink"> <span class="dppnfTitle">ベストプラクティス</span> <span class="dppnfSubtitle"></span> </a> </li> </ul> </div> </div> </li> <li class="dppnItem accrItem"> <span class="dppnLink"> アプリテスト </span> <div class='dpIconArrow accrHandle'></div> <div class='dppnFlyoutWrap'> <div class='dppnSecondaryNavWrap'> <ul class="dppnFlyout dppnSecondaryNav"> <li class="dppnfItem accrItem"> <a href="/ja/docs/app-testing/test-criteria.html" class="dppnfLink"> <span class="dppnfTitle">テスト基準</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <a href="/ja/docs/app-testing/live-app-testing-getting-started.html" class="dppnfLink"> <span class="dppnfTitle">ライブアプリテスト (LAT)</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <a href="/ja/docs/in-app-purchasing/iap-testing-overview.html" class="dppnfLink"> <span class="dppnfTitle">アプリ内課金の</br>テスト</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <span class="dppnfLink"> <span class="dppnfTitle">パフォーマンスの</br>向上</span> <span class="dppnfSubtitle"></span> </span> <div class='dpIconArrow accrHandle'></div> <div class='dppnLevel3NavWrap'> <ul class="dppnFlyout dppnLevel3Nav"> <li class="dppnfItem "> <a href="/ja/docs/app-testing/test-criteria.html#test-criteria-group-2-key-app-performance-indicators" class="dppnfLink"> <span class="dppnfTitle">重要業績評価指標 (KPI)</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem "> <a href="/ja/docs/app-testing/app-performance-scripts.html" class="dppnfLink"> <span class="dppnfTitle">アプリの</br>パフォーマンス</br>スクリプト</span> <span class="dppnfSubtitle"></span> </a> </li> </ul> </div> </li> </ul> </div> </div> </li> <li class="dppnItem accrItem"> <span class="dppnLink"> アプリの公開 </span> <div class='dpIconArrow accrHandle'></div> <div class='dppnFlyoutWrap'> <div class='dppnSecondaryNavWrap'> <ul class="dppnFlyout dppnSecondaryNav"> <li class="dppnfItem accrItem"> <a href="/ja/docs/app-submission/understanding-submission.html" class="dppnfLink"> <span class="dppnfTitle">公開の概要</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <a href="/ja/docs/policy-center/understanding-content-policy.html" class="dppnfLink"> <span class="dppnfTitle">アプリストアの</br>コンテンツポリシー</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <a href="/ja/docs/reports-promo/UI-reports-dashboard.html" class="dppnfLink"> <span class="dppnfTitle">収益レポート</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <a href="/ja/docs/app-submission/manage-account-and-permissions.html" class="dppnfLink"> <span class="dppnfTitle">開発者アカウントの管理</span> <span class="dppnfSubtitle"></span> </a> </li> </ul> </div> </div> </li> <li class="dppnItem accrItem"> <span class="dppnLink"> 関連情報 </span> <div class='dpIconArrow accrHandle'></div> <div class='dppnFlyoutWrap'> <div class='dppnSecondaryNavWrap'> <ul class="dppnFlyout dppnSecondaryNav"> <li class="dppnfItem accrItem"> <a href="/ja/apps-and-games/blogs" class="dppnfLink"> <span class="dppnfTitle">ブログ</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <a href="/ja/docs/apps-and-games/release-notes.html" class="dppnfLink"> <span class="dppnfTitle">リリースノート</span> <span class="dppnfSubtitle"></span> </a> </li> <li class="dppnfItem accrItem"> <a href="https://community.amazondeveloper.com/" class="dppnfLink"> <span class="dppnfTitle">アプリストア</br>開発者コミュニティ</span> <span class="dppnfSubtitle"></span> </a> </li> </ul> </div> </div> </li> <li class="dppnItem accrItem"> <a href="/ja/apps-and-games/documentation" class="dppnLink"> ドキュメント </a> </li> </ul> </nav> <nav class="dpPrimaryNav dphDevConsoleLinkNavBar"> <ul class="dppnItems"> <li class="dppnItem accrItem"> <span class='dppnLink'>サポート</span> <div class="dpIconArrow accrHandle"></div> <div class="dppnFlyoutWrap"> <div class="dppnSecondaryNavWrap"> <ul class='dppnFlyout dppnSecondaryNav'> <li class='dppnfItem accrItem'><a class="dppnfLink" href='/support/'><span class="dppnfTitle">サポート</span></a></li> <li class='dppnfItem accrItem'><a class="dppnfLink" href='/documentation/'><span class="dppnfTitle">ドキュメント</span></a></li> <li class='dppnfItem accrItem'><a class="dppnfLink" href='/support/contact-us'><span class="dppnfTitle">お問い合わせ</span></a></li> <li class='dppnfItem accrItem'><a class="dppnfLink" href='/support/cases'><span class="dppnfTitle">Amazonアプリストアのケース</span></a></li> </ul> </div> </div> </li> </ul> </nav> </div> </div> </header> <div id='dpHeaderPlaceholder'></div> <script> (function(){ //Set placeholder height as soon as possible to eliminate page jump "use strict"; var setHeaderPlaceholderHeight = function(header){ var placeholder = document.getElementById('dpHeaderPlaceholder'); var headerHeight = header[0].offsetHeight + "px"; placeholder.style.height = headerHeight; } var checkForHeader = function(){ var header = document.querySelectorAll('.dpHeader'); if(header.length){ setHeaderPlaceholderHeight(header); window.clearInterval(checkForHeaderInterval); } } var checkForHeaderInterval = window.setInterval(checkForHeader, 10); checkForHeader(); //Run once immediately }()); </script> <script> (function(a,b,c,d){if((a=a.AmazonUIPageJS||a.P)&&a.when&&a.register)throw Error("A copy of P has already been loaded on this page.");})(window,document,Date);(function(a,b,c,d){"use strict";a._pSetI=function(){return null}})(window,document,Date);(function(a,c,d,e){"use strict";a._sw=function(){var b;return function(a,c,d,e,f,g,h,k,l,m){b||(b=!0)}}()})(window,document,Date);(function(c,e,I,B){"use strict";c._pd=function(){var a,u;return function(C,f,h,k,b,D,v,E,F){function w(d){try{return d()}catch(J){return!1}}function l(){if(m){var d={w:c.innerWidth||b.clientWidth,h:c.innerHeight||b.clientHeight};5<Math.abs(d.w-q.w)||50<d.h-q.h?(q=d,n=4,(d=a.mobile||a.tablet?450<d.w&&d.w>d.h:1250<=d.w)?k(b,"a-ws"):b.className=v(b,"a-ws")):0<n&&(n--,x=setTimeout(l,16))}}function G(d){(m=d===B?!m:!!d)&&l()}function H(){return m}if(!u){u=!0;var r=function(){var d=["O","ms","Moz","Webkit"], c=e.createElement("div");return{testGradients:function(){return!0},test:function(a){var b=a.charAt(0).toUpperCase()+a.substr(1);a=(d.join(b+" ")+b+" "+a).split(" ");for(b=a.length;b--;)if(""===c.style[a[b]])return!0;return!1},testTransform3d:function(){return!1}}}(),y=b.className,z=/(^| )a-mobile( |$)/.test(y),A=/(^| )a-tablet( |$)/.test(y);a={audio:function(){return!!e.createElement("audio").canPlayType},video:function(){return!!e.createElement("video").canPlayType},canvas:function(){return!!e.createElement("canvas").getContext}, svg:function(){return!!e.createElementNS&&!!e.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect},offline:function(){return navigator.hasOwnProperty&&navigator.hasOwnProperty("onLine")&&navigator.onLine},dragDrop:function(){return"draggable"in e.createElement("span")},geolocation:function(){return!!navigator.geolocation},history:function(){return!(!c.history||!c.history.pushState)},webworker:function(){return!!c.Worker},autofocus:function(){return"autofocus"in e.createElement("input")}, inputPlaceholder:function(){return"placeholder"in e.createElement("input")},textareaPlaceholder:function(){return"placeholder"in e.createElement("textarea")},localStorage:function(){return"localStorage"in c&&null!==c.localStorage},orientation:function(){return"orientation"in c},touch:function(){return"ontouchend"in e},gradients:function(){return r.testGradients()},hires:function(){var a=c.devicePixelRatio&&1.5<=c.devicePixelRatio||c.matchMedia&&c.matchMedia("(min-resolution:144dpi)").matches;E("hiRes"+ (z?"Mobile":A?"Tablet":"Desktop"),a?1:0);return a},transform3d:function(){return r.testTransform3d()},touchScrolling:function(){return f(/Windowshop|android|OS ([5-9]|[1-9][0-9]+)(_[0-9]{1,2})+ like Mac OS X|SOFTWARE=([5-9]|[1-9][0-9]+)(.[0-9]{1,2})+.*DEVICE=iPhone|Chrome|Silk|Firefox|Trident.+?; Touch/i)},ios:function(){return f(/OS [1-9][0-9]*(_[0-9]*)+ like Mac OS X/i)&&!f(/trident|Edge/i)},android:function(){return f(/android.([1-9]|[L-Z])/i)&&!f(/trident|Edge/i)},mobile:function(){return z}, tablet:function(){return A},rtl:function(){return"rtl"===b.dir}};for(var g in a)a.hasOwnProperty(g)&&(a[g]=w(a[g]));for(var t="textShadow textStroke boxShadow borderRadius borderImage opacity transform transition".split(" "),p=0;p<t.length;p++)a[t[p]]=w(function(){return r.test(t[p])});var m=!0,x=0,q={w:0,h:0},n=4;l();h(c,"resize",function(){clearTimeout(x);n=4;l()});b.className=v(b,"a-no-js");k(b,"a-js");!f(/OS [1-8](_[0-9]*)+ like Mac OS X/i)||c.navigator.standalone||f(/safari/i)||k(b,"a-ember"); h=[];for(g in a)a.hasOwnProperty(g)&&a[g]&&h.push("a-"+g.replace(/([A-Z])/g,function(a){return"-"+a.toLowerCase()}));k(b,h.join(" "));b.setAttribute("data-aui-build-date",F);C.register("p-detect",function(){return{capabilities:a,localStorage:a.localStorage&&D,toggleResponsiveGrid:G,responsiveGridEnabled:H}});return a||{}}}}()})(window,document,Date);(function(g,l,C,D){function E(a){n&&n.tag&&n.tag(p(":","aui",a))}function m(a,b){n&&n.count&&n.count("aui:"+a,0===b?0:b||(n.count("aui:"+a)||0)+1)}function F(a){try{return a.test(navigator.userAgent)}catch(b){return!1}}function G(a){return"function"===typeof a}function u(a,b,c){a.addEventListener?a.addEventListener(b,c,!1):a.attachEvent&&a.attachEvent("on"+b,c)}function p(a,b,c,f){b=b&&c?b+a+c:b||c;return f?p(a,b,f):b}function y(a,b,c){try{Object.defineProperty(a,b,{value:c,writable:!1})}catch(f){a[b]= c}return c}function O(a,b){a.className=P(a,b)+" "+b}function P(a,b){return(" "+a.className+" ").split(" "+b+" ").join(" ").replace(/^ | $/g,"")}function ca(a,b,c){var f=c=a.length,e=function(){f--||(H.push(b),I||(q?q.set(z):setTimeout(z,0),I=!0))};for(e();c--;)Q[a[c]]?e():(v[a[c]]=v[a[c]]||[]).push(e)}function da(a,b,c,f,e){var d=l.createElement(a?"script":"link");u(d,"error",f);e&&u(d,"load",e);a?(d.type="text/javascript",d.async=!0,c&&/AUIClients|images[/]I/.test(b)&&d.setAttribute("crossorigin", "anonymous"),d.src=b):(d.rel="stylesheet",d.href=b);l.getElementsByTagName("head")[0].appendChild(d)}function R(a,b){return function(c,f){function e(){da(b,c,d,function(b){J?m("resource_unload"):d?(d=!1,m("resource_retry"),e()):(m("resource_error"),a.log("Asset failed to load: "+c));b&&b.stopPropagation?b.stopPropagation():g.event&&(g.event.cancelBubble=!0)},f)}if(S[c])return!1;S[c]=!0;m("resource_count");var d=!0;return!e()}}function ea(a,b,c){for(var f={name:a,guard:function(c){return b.guardFatal(a, c)},guardTime:function(a){return b.guardTime(a)},logError:function(c,d,e){b.logError(c,d,e,a)}},e=[],d=0;d<c.length;d++)A.hasOwnProperty(c[d])&&(e[d]=K.hasOwnProperty(c[d])?K[c[d]](A[c[d]],f):A[c[d]]);return e}function w(a,b,c,f,e){return function(d,k){function n(){var a=null;f?a=k:G(k)&&(q.start=r(),a=k.apply(g,ea(d,h,l)),q.end=r());if(b){A[d]=a;a=d;for(Q[a]=!0;(v[a]||[]).length;)v[a].shift()();delete v[a]}q.done=!0}var h=e||this;G(d)&&(k=d,d=D);b&&(d=d?d.replace(T,""):"__NONAME__",L.hasOwnProperty(d)&& h.error(p(", reregistered by ",p(" by ",d+" already registered",L[d]),h.attribution),d),L[d]=h.attribution);for(var l=[],m=0;m<a.length;m++)l[m]=a[m].replace(T,"");var q=x[d||"anon"+ ++fa]={depend:l,registered:r(),namespace:h.namespace};d&&ha.hasOwnProperty(d);c?n():ca(l,h.guardFatal(d,n),d);return{decorate:function(a){K[d]=h.guardFatal(d,a)}}}}function U(a){return function(){var b=Array.prototype.slice.call(arguments);return{execute:w(b,!1,a,!1,this),register:w(b,!0,a,!1,this)}}}function M(a,b){return function(c, f){f||(f=c,c=D);var e=this.attribution;return function(){h.push(b||{attribution:e,name:c,logLevel:a});var d=f.apply(this,arguments);h.pop();return d}}}function B(a,b){this.load={js:R(this,!0),css:R(this)};y(this,"namespace",b);y(this,"attribution",a)}function V(){l.body?k.trigger("a-bodyBegin"):setTimeout(V,20)}"use strict";var t=C.now=C.now||function(){return+new C},r=function(a){return a&&a.now?a.now.bind(a):t}(g.performance),ia=r(),ha={},n=g.ue;E();E("aui_build_date:3.24.1-2024-10-06");var W={getItem:function(a){try{return g.localStorage.getItem(a)}catch(b){}}, setItem:function(a,b){try{return g.localStorage.setItem(a,b)}catch(c){}}},q=g._pSetI(),H=[],ja=[],I=!1,ka=navigator.scheduling&&"function"===typeof navigator.scheduling.isInputPending;var z=function(){for(var a=q?q.set(z):setTimeout(z,0),b=t();ja.length||H.length;)if(H.shift()(),q&&ka){if(150<t()-b&&!navigator.scheduling.isInputPending()||50<t()-b&&navigator.scheduling.isInputPending())return}else if(50<t()-b)return;q?q.clear(a):clearTimeout(a);I=!1};var Q={},v={},S={},J=!1;u(g,"beforeunload",function(){J= !0;setTimeout(function(){J=!1},1E4)});var T=/^prv:/,L={},A={},K={},x={},fa=0,X=String.fromCharCode(92),h=[],Y=!0,Z=g.onerror;g.onerror=function(a,b,c,f,e){e&&"object"===typeof e||(e=Error(a,b,c),e.columnNumber=f,e.stack=b||c||f?p(X,e.message,"at "+p(":",b,c,f)):D);var d=h.pop()||{};e.attribution=p(":",e.attribution||d.attribution,d.name);e.logLevel=d.logLevel;e.attribution&&console&&console.log&&console.log([e.logLevel||"ERROR",a,"thrown by",e.attribution].join(" "));h=[];Z&&(d=[].slice.call(arguments), d[4]=e,Z.apply(g,d))};B.prototype={logError:function(a,b,c,f){b={message:b,logLevel:c||"ERROR",attribution:p(":",this.attribution,f)};if(g.ueLogError)return g.ueLogError(a||b,a?b:null),!0;console&&console.error&&(console.log(b),console.error(a));return!1},error:function(a,b,c,f){a=Error(p(":",f,a,c));a.attribution=p(":",this.attribution,b);throw a;},guardError:M(),guardFatal:M("FATAL"),guardCurrent:function(a){var b=h[h.length-1];return b?M(b.logLevel,b).call(this,a):a},guardTime:function(a){var b= h[h.length-1],c=b&&b.name;return c&&c in x?function(){var b=r(),e=a.apply(this,arguments);x[c].async=(x[c].async||0)+r()-b;return e}:a},log:function(a,b,c){return this.logError(null,a,b,c)},declare:w([],!0,!0,!0),register:w([],!0),execute:w([]),AUI_BUILD_DATE:"3.24.1-2024-10-06",when:U(),now:U(!0),trigger:function(a,b,c){var f=t();this.declare(a,{data:b,pageElapsedTime:f-(g.aPageStart||NaN),triggerTime:f});c&&c.instrument&&N.when("prv:a-logTrigger").execute(function(b){b(a)})},handleTriggers:function(){this.log("handleTriggers deprecated")}, attributeErrors:function(a){return new B(a)},_namespace:function(a,b){return new B(a,b)},setPriority:function(a){Y?Y=!1:this.log("setPriority only accept the first call.")}};var k=y(g,"AmazonUIPageJS",new B);var N=k._namespace("PageJS","AmazonUI");N.declare("prv:p-debug",x);k.declare("p-recorder-events",[]);k.declare("p-recorder-stop",function(){});y(g,"P",k);V();if(l.addEventListener){var aa;l.addEventListener("DOMContentLoaded",aa=function(){k.trigger("a-domready");l.removeEventListener("DOMContentLoaded", aa,!1)},!1)}var ba=l.documentElement,la=g._pd(k,F,u,O,ba,W,P,m,"3.24.1-2024-10-06");F(/UCBrowser/i)||la.localStorage&&O(ba,W.getItem("a-font-class"));k.declare("a-event-revised-handling",!1);g._sw(N,p,F,X,m,n,E,G,u,k);k.declare("a-fix-event-off",!1);m("pagejs:pkgExecTime",r()-ia)})(window,document,Date); (window.AmazonUIPageJS ? AmazonUIPageJS : P).load.js('https://images-na.ssl-images-amazon.com/images/I/61ZS63EQSsL._RC|11Y+5x+kkTL.js,51-UZWCmY3L.js,11yKORv-GTL.js,11na7Dl1tFL.js,21uGjv2MRDL.js,01VRMV3FBdL.js,21BJeD9yjcL.js,01cS+tLhj4L.js,11rRjDLdAVL.js,51UOrPXYGsL.js,11YA5PIFcPL.js,11UNP9ncXuL.js,11qGWmpSUoL.js,11EWRk6r74L.js,21paGe30x-L.js,01490L6yBnL.js,51Xt+PG12aL.js,01JYHc2oIlL.js,31nfKXylf6L.js,01ezj5Rkz1L.js,11bEz2VIYrL.js,31o2NGTXThL.js,01rpauTep4L.js,01RMmNcPMuL.js_.js?AUIClients/AmazonUI#trident'); (window.AmazonUIPageJS ? AmazonUIPageJS : P).load.js('https://images-na.ssl-images-amazon.com/images/I/616qGtYUw7L.js?AUIClients/DeXWebsiteAUIAssets'); </script> <div class="content-section"> <div class="docs"> <!-- jQuery (MIT license)--> <script src="https://amzndevresources.com/jekyll/js/jquery-3.6.0.min.js"></script> <!-- Bootstrap 4.4 css --> <link rel="stylesheet" href="https://amzndevresources.com/jekyll/css/bootstrap4.css"> <link rel="stylesheet" href="https://amzndevresources.com/jekyll/css/styleoverrides.css"> <link rel="stylesheet" href="https://amzndevresources.com/jekyll/css/popovers.css"> <!-- Navgoco --> <script src="https://amzndevresources.com/jekyll/js/jquery.navgoco.min.js"></script> <!-- jQuery cookie (MIT license)--> <script type="text/javascript" src="https://amzndevresources.com/jekyll/js/jquery.cookie.js"></script> <!-- Bootstrap (MIT license)--> <script src="https://amzndevresources.com/jekyll/js/bootstrap.4.4.1.bundle.min.js"></script> <!-- Anchor JS (MIT license)--> <script src="https://amzndevresources.com/jekyll/js/anchor.min.js"></script> <!-- Initialization scripts --> <script src="https://amzndevresources.com/jekyll/js/initialization_scripts.js"></script> <!-- Tech doc css fixes now incorporated into stylesheet --> <div class="container"> <!-- sidebar --> <div id="sidebar"> <!-- sidebar_hide_weblab --> <div class="mydocsidebar"> <div id="search-searchbar"></div> <div class="productTitle">Amazon Device Messaging(ADM)</div> <p class="external"> <a href="#" id="collapseAll">すべて折りたたむ</a> | <a href="#" id="expandAll">すべて展開する</a> </p> <ul id="docnavsidebar" class="docnav"> <li class="level1 folderTitle"> <a class="subfoldersTitle" href="#">概要</a> <ul> <li class="level1items"><a href="../adm/overview.html">Amazon Device Messaging(ADM)について</a></li> <li class="level1items"><a href="../adm/release-notes.html">リリースノート</a></li> <li class="level1items"><a href="../adm/message-types.html">ADMメッセージのタイプ</a></li> <li class="level1items"><a href="../adm/obtain-credentials.html">認証情報の取得方法</a></li> <li class="level1items"><a href="../adm/set-up.html">Amazon Device Messaging(ADM)のセットアップ方法</a></li> <li class="level1items"><a href="../adm/integrate-your-app.html">アプリの統合方法</a></li> <li class="level1items"><a href="../adm/request-access-token.html">アクセストークンのリクエスト方法</a></li> <li class="level1items"><a href="../adm/send-message.html">メッセージの送信方法</a></li> <li class="level1items open"><a href="../adm/topic-based-messaging.html">トピックベースのメッセージング</a></li> <li class="level1items"><a href="../adm/group-based-messaging.html">グループベースのメッセージング</a></li> <li class="level1items"><a href="../adm/faq-adm.html">よくある質問(FAQ)</a></li> </ul> </li><li class="level1 folderTitle"> <a class="subfoldersTitle" href="#">FCMからの移行</a> <ul> <li class="level1items"><a href="../app-porting/device-messaging.html">移行について</a></li> <li class="level1items"><a href="../app-porting/device-messaging-explore.html">手順1: 検討する</a></li> <li class="level1items"><a href="../app-porting/device-messaging-choose.html">手順2: 選択する</a></li> <li class="level2 folderTitle"> <a class="subfoldersTitle" href="#">手順3: 調整する</a> <ul> <li class="level2items"><a href="../app-porting/device-messaging-fit-update-manifest.html">アプリのマニフェストの更新</a></li> <li class="level2items"><a href="../app-porting/device-messaging-fit-obtain-api-key.html">APIキーの取得と保存</a></li> <li class="level2items"><a href="../app-porting/device-messaging-fit-implement.html">登録とメッセージの処理</a></li> </ul> </li> <li class="level1items"><a href="../app-porting/device-messaging-verify-push.html">検証・公開</a></li> </ul> </li> </ul> <hr class="resourceSeparator"> <div class="relatedResources">関連リソース</div> <ul id="entrypages"> <li><a href="https://amzndevresources.com/adm/sdk/AmazonDeviceMessaging.zip">ADM SDKのダウンロード</a></li> <li><a href="https://amzndevresources.com/adm/API-Reference/API-Reference/index.html">ADM APIリファレンス</a></li> <li><a href="../a3l-messaging/understanding-a3l-messaging.html">A3L Messagingについて</a></li> <li><a href="https://community.amazondeveloper.com/tag/appstore-adm">Amazon Device Messaging(ADM)に関するフォーラム</a></li> <li><a href="https://developer.amazon.com/ja/documentation">テクニカルドキュメント一覧</a></li> <li><a href="https://developer.amazon.com/ja/blogs/">Amazonアプリストア公式ブログ</a></li> <li><a href="https://developer.amazon.com/ja/docs/apps-and-games/sdk-downloads.html">SDKのダウンロード</a></li> </ul> </div> <script> $("li.open").parents('li').toggleClass("open"); </script> </div> <!-- main area --> <div class="mainColumn"> <div id="content"> <h1>トピックベースのメッセージング</h1> <style> .docs ul#markdown-toc::before { content: "目次" } .docs ul.onPageSectiontoc::before { content: "このセクションのページ" } .docs h1, .docs h2, .docs h3, .docs h4, .docs h5 { font-family: Helvetica; sans-serif; } </style> <style> div.page_title{ display: none; }</style> <meta charset="UTF-8"> <div class="page_title">トピックベースのメッセージング</div> <!--body content starts here--> <p>トピックベースのメッセージング(TBM)を使用すると、同じトピックをサブスクライブしているユーザーのグループにメッセージを送信できます。このメッセージは、マルチキャスト通信を通じて送信されます。アプリがデバイスにインストールされると、そのアプリのインスタンスにデバイス登録IDと呼ばれる一意の識別子が割り当てられます。このIDを使用して個々のデバイスにトピックベースのメッセージを配信することで、単一のAPI呼び出しで複数のアプリインスタンスにメッセージを送信できます。メッセージは、個々のデバイス登録IDではなくトピックに対して送信されます。ユーザーがそのトピックをサブスクライブしていれば、Amazon Device Messaging(ADM)がそのトピックに関連付けられたすべてのデバイス登録IDにメッセージをルーティングします。メッセージの種類には、データメッセージ、通知メッセージ、データを含む通知メッセージがあります。</p> <p>トピックを使用することで、特定のユーザーセグメントのエンゲージメントを高めることができます。たとえば、天気予報アプリの場合、ユーザーは自分の所在地のトピックを選択して、その地域の天気の変化に関する通知を受信することができます。ビデオストリーミングアプリの場合は、ユーザーが興味のあるジャンルを登録すれば、そのジャンルの新しい映画やシリーズがリリースされるたびに自動的に最新情報を受け取ることができます。</p> <ul id="markdown-toc"> <li><a href="#considerations-for-topic-based-messaging" id="markdown-toc-considerations-for-topic-based-messaging">トピックベースのメッセージングに関する考慮事項</a></li> <li><a href="#register-a-security-profile-for-topic-based-messaging" id="markdown-toc-register-a-security-profile-for-topic-based-messaging">トピックベースのメッセージングへのセキュリティプロファイルの登録</a> <ul> <li><a href="#prerequisites" id="markdown-toc-prerequisites">前提条件</a></li> <li><a href="#request-format" id="markdown-toc-request-format">リクエスト形式</a></li> <li><a href="#request-requirements" id="markdown-toc-request-requirements">リクエスト要件</a> <ul> <li><a href="#header-fields" id="markdown-toc-header-fields">ヘッダーフィールド</a></li> <li><a href="#message-body-parameter" id="markdown-toc-message-body-parameter">メッセージ本文のパラメーター</a></li> </ul> </li> <li><a href="#response-format" id="markdown-toc-response-format">レスポンス形式</a></li> <li><a href="#adm-error-status-codes" id="markdown-toc-adm-error-status-codes">ADMエラーのステータスコード</a></li> <li><a href="#response-header-fields" id="markdown-toc-response-header-fields">レスポンスヘッダーフィールド</a></li> <li><a href="#make-a-tbm-registration-request" id="markdown-toc-make-a-tbm-registration-request">TBMの登録リクエスト</a></li> </ul> </li> <li><a href="#subscribe-the-client-app-instance-to-a-topic-or-unsubscribe-it-from-a-topic" id="markdown-toc-subscribe-the-client-app-instance-to-a-topic-or-unsubscribe-it-from-a-topic">クライアントアプリインスタンスによるトピックのサブスクライブ/サブスクライブ解除</a> <ul> <li><a href="#subscribe-example" id="markdown-toc-subscribe-example">サブスクライブの例</a></li> <li><a href="#unsubscribe-example" id="markdown-toc-unsubscribe-example">サブスクライブ解除の例</a></li> <li><a href="#callback-method-description" id="markdown-toc-callback-method-description">コールバックメソッドの説明</a></li> <li><a href="#error-id-and-description" id="markdown-toc-error-id-and-description">エラーIDと説明</a></li> <li><a href="#sample-code-for-callback-methods" id="markdown-toc-sample-code-for-callback-methods">コールバックメソッドのサンプルコード</a></li> <li><a href="#receive-and-handle-topic-messages" id="markdown-toc-receive-and-handle-topic-messages">トピックメッセージの受信と処理</a></li> </ul> </li> <li><a href="#send-a-message-to-topic" id="markdown-toc-send-a-message-to-topic">トピックへのメッセージの送信</a> <ul> <li><a href="#prerequisites-1" id="markdown-toc-prerequisites-1">前提条件</a></li> <li><a href="#request-format-1" id="markdown-toc-request-format-1">リクエスト形式</a></li> <li><a href="#request-requirements-1" id="markdown-toc-request-requirements-1">リクエスト要件</a> <ul> <li><a href="#header-fields-1" id="markdown-toc-header-fields-1">ヘッダーフィールド</a></li> <li><a href="#message-body-parameters" id="markdown-toc-message-body-parameters">メッセージ本文のパラメーター</a></li> </ul> </li> <li><a href="#response-format-1" id="markdown-toc-response-format-1">レスポンス形式</a></li> <li><a href="#adm-error-status-codes-1" id="markdown-toc-adm-error-status-codes-1">ADMエラーのステータスコード</a></li> <li><a href="#response-header-fields-1" id="markdown-toc-response-header-fields-1">レスポンスヘッダーフィールド</a></li> <li><a href="#send-a-message-to-a-topic-and-handle-the-response" id="markdown-toc-send-a-message-to-a-topic-and-handle-the-response">トピックへのメッセージの送信とレスポンスの処理</a></li> </ul> </li> </ul> <h2 id="considerations-for-topic-based-messaging">トピックベースのメッセージングに関する考慮事項</h2> <p>トピックベースのメッセージに関する重要な考慮事項を以下に示します。</p> <ul> <li>トピックベースのメッセージは特定の<a href="#register-a-security-profile-for-topic-based-messaging">セキュリティプロファイル</a>をターゲットにします。つまり、同じセキュリティプロファイルに登録された複数のアプリのインスタンスにトピックからメッセージを送信できます。</li> <li>Amazon Device Messaging(ADM)では、トピックに関して以下の制限が適用されます。 <ul> <li>1つのセキュリティプロファイルに割り当てることができるトピックの数は、最大100個です。</li> <li>1つのアプリインスタンスがサブスクライブできるトピックの数は、最大100個です。</li> <li>1つのトピックをサブスクライブできるアプリインスタンスの数は、最大10000個です。</li> </ul> </li> <li>トピックベースのメッセージでは、レイテンシの低減よりもスループットの向上が重視されます。個々のデバイスにメッセージを送信するには、トピックではなく<a href="send-message.html">デバイス登録IDをメッセージのターゲットに設定</a>してください。</li> <li>トピックベースのメッセージングは、天気予報や株価など、一般に公開されているリソースに最適です。</li> </ul> <h2 id="register-a-security-profile-for-topic-based-messaging">トピックベースのメッセージングへのセキュリティプロファイルの登録</h2> <p>トピックベースのメッセージングでは、以下の操作を実行できます。</p> <ul> <li>デバイス登録IDによるトピックのサブスクライブ</li> <li>デバイス登録IDによるトピックのサブスクライブ解除</li> <li>トピックへのメッセージの送信</li> </ul> <h3 id="prerequisites">前提条件</h3> <p>トピックベースのメッセージングを使用するには、以下の前提条件を満たす必要があります。</p> <ul> <li>アプリインスタンスの登録IDを取得・保存していること。このプロセスのアプリ側での詳細については、<a href="integrate-your-app.html">アプリの統合方法</a>を参照してください。</li> <li>クライアント認証情報と現在のアクセストークンが交換済みであること。詳細については、<a href="request-access-token.html">アクセストークンのリクエスト方法</a>を参照してください。</li> </ul> <p>これらの前提条件を満たしたら、プログラムで<code class="language-plaintext highlighter-rouge">TopicBasedMessaging</code>に対して、生成された<code class="language-plaintext highlighter-rouge">accessToken</code>に関連付けられた<a href="#register-a-security-profile-for-topic-based-messaging">セキュリティプロファイルを登録</a>できます。</p> <h3 id="request-format">リクエスト形式</h3> <p>セキュリティプロファイルをトピックベースのメッセージングに登録するには、サーバーコンポーネント(以降「サーバー」と呼びます)から以下のようなHTTP POSTリクエストを発行する必要があります。</p> <div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">POST</span> <span class="nn">/v1/messaging/topic/registrations</span> <span class="k">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="na">Host</span><span class="p">:</span> <span class="s">api.amazon.com</span> <span class="na">Authorization</span><span class="p">:</span> <span class="s">Bearer (アクセストークン)</span> <span class="na">Content-Type</span><span class="p">:</span> <span class="s">application/json</span> <span class="na">Accept</span><span class="p">:</span> <span class="s">application/json</span> <span class="p">{</span><span class="w"> </span><span class="nl">"clientSecret"</span><span class="p">:</span><span class="s2">"クライアントシークレット"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre></div></div> <p>POST URLは2行目(Host)と1行目(POST)で構成されます。これらを組み合わせると、以下のような完全なURLを取得できます。</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://api.amazon.com/v1/messaging/topic/registrations </code></pre></div></div> <h3 id="request-requirements">リクエスト要件</h3> <p>リクエスト自体は、ヘッダーとメッセージ本文で構成されています。</p> <h4 id="header-fields">ヘッダーフィールド</h4> <p>ヘッダーには、以下のフィールドを含める必要があります。</p> <table> <colgroup> <col width="20%"> <col width="40%"> <col width="40%"> </colgroup> <tbody><tr> <th>フィールド</th> <th>概要</th> <th>例</th> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">Authorization</code></td> <td>現在のアクセストークンを指定します。有効値: <code class="language-plaintext highlighter-rouge">Bearer (アクセストークン)</code></td> <td><code class="language-plaintext highlighter-rouge">Authorization: Bearer <アクセストークン></code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">Content-Type</code></td> <td>有効値:<code class="language-plaintext highlighter-rouge">application/json</code></td> <td><code class="language-plaintext highlighter-rouge">Content-Type: application/json</code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">Accept</code></td> <td>有効値:<code class="language-plaintext highlighter-rouge">application/json</code></td> <td><code class="language-plaintext highlighter-rouge">Accept: application/json</code></td> </tr> </tbody></table> <h4 id="message-body-parameter">メッセージ本文のパラメーター</h4> <p>メッセージ本文のコンテンツとして、<code class="language-plaintext highlighter-rouge">JSONObject</code>に以下のパラメーターを含む文字列を指定します。</p> <table> <colgroup> <col width="20%"> <col width="40%"> <col width="40%"> </colgroup> <tbody><tr> <th>パラメーター</th> <th>説明</th> <th>例</th> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">clientSecret</code></td> <td>クライアント認証情報の「クライアントシークレット」部分。</td> <td><code class="language-plaintext highlighter-rouge">clientSecret=<クライアントシークレット></code></td> </tr> </tbody></table> <h3 id="response-format">レスポンス形式</h3> <p>ADMサーバーは、POSTリクエストメッセージを正常に受信して解釈した後、以下のようなHTTPレスポンスメッセージを送信します。</p> <div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="m">200</span> <span class="na">X-Amzn-RequestId</span><span class="p">:</span> <span class="s"><Amazon RequestId></span> <span class="na">Content-Type</span><span class="p">:</span><span class="s">application/json</span> <span class="na">content-length</span><span class="p">:</span><span class="s">140</span> <span class="p">{</span><span class="w"> </span><span class="nl">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"The security profile amzn1.application.<32個の16進文字> is registered with TopicBasedMessaging."</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre></div></div> <p>クライアント認証情報のセキュリティプロファイルが<code class="language-plaintext highlighter-rouge">TopicBasedMessaging</code>に登録された場合、ADMからステータスコード200が返されます。ステータスコード200を受け取った場合は、レスポンスメッセージの<code class="language-plaintext highlighter-rouge">JSONObject</code>に以下のパラメーターが含まれています。</p> <ul> <li><code class="language-plaintext highlighter-rouge">message</code>: <code class="language-plaintext highlighter-rouge">accessToken</code>の作成に使用した認証情報とメッセージ本文で使用された<code class="language-plaintext highlighter-rouge">clientSecret</code>に関連付けられたセキュリティプロファイルが記載されます。セキュリティプロファイルが<code class="language-plaintext highlighter-rouge">TopicBasedMessaging</code>に登録されていることを示すレスポンスになります。</li> </ul> <p>クライアント認証情報のセキュリティプロファイルが<code class="language-plaintext highlighter-rouge">TopicBasedMessaging</code>に登録されなかった場合、ADMからエラーコードが返されます。200以外のコードの場合は、レスポンスメッセージの<code class="language-plaintext highlighter-rouge">JSONObject</code>本文に以下のパラメーターが含まれていることがあります。</p> <ul> <li><code class="language-plaintext highlighter-rouge">reason</code>: リクエストが受理されなかった理由。</li> </ul> <p>各エラーのステータスコードの詳細については、以下を参照してください。</p> <h3 id="adm-error-status-codes">ADMエラーのステータスコード</h3> <table> <colgroup> <col width="10%"> <col width="53%"> <col width="37%"> </colgroup> <tbody><tr> <th>コード</th> <th>説明</th> <th>例</th> </tr> <tr> <td>400</td> <td>メッセージ本文の<code class="language-plaintext highlighter-rouge">clientSecret</code>が、<code class="language-plaintext highlighter-rouge">accessToken</code>の作成に使用したものとは異なります。送信元は、<code class="language-plaintext highlighter-rouge">accessToken</code>の作成に使用したものと同じ<code class="language-plaintext highlighter-rouge">clientSecret</code>をメッセージ本文で使用する必要があります。</td> <td><code class="language-plaintext highlighter-rouge">"reason": "The given clientSecret is not associated with the security profile amzn1.application.<32個の16進文字>"</code></td> </tr> <tr> <td>401</td> <td>提供されたアクセストークンが無効です。送信元は、アクセストークンを更新する必要があります。更新の手順については、<a href="request-access-token.html">アクセストークンのリクエスト方法</a>を参照してください。</td> <td><code class="language-plaintext highlighter-rouge">"reason":"AccessTokenExpired"</code></td> </tr> <tr> <td>429</td> <td>リクエスト側が、許容されている最大メッセージレートを超過しました。送信元は、レスポンスに含まれている<code class="language-plaintext highlighter-rouge">Retry-After</code>ヘッダーの指示に従って、後で再試行できます。ADMでは、一定時間内に送信されるメッセージ数を制限することで、高可用性が確保されています。具体的なキャパシティ要件がある場合は、<a href="https://developer.amazon.com/public/support/contact/contact-us">お問い合わせ</a>から以下の情報をお知らせください。<br> - 氏名<br> - 会社名<br> - Eメールアドレス<br> - 必要なTPS(1秒あたりのトランザクション数)制限<br> - 理由</td> <td><code class="language-plaintext highlighter-rouge">"reason":"MaxRateExceeded"</code></td> </tr> <tr> <td>500</td> <td>内部サーバーエラーが発生しました。リクエスト側は、レスポンスに含まれている<code class="language-plaintext highlighter-rouge">Retry-After</code>ヘッダーに従って、後で再試行できます。</td> <td>なし</td> </tr> <tr> <td>503</td> <td>サーバーが一時的に利用できない状態になっています。リクエスト側は、レスポンスに含まれている<code class="language-plaintext highlighter-rouge">Retry-After</code>ヘッダーの指示に従って、後で再試行できます。</td> <td>なし</td> </tr> </tbody></table> <h3 id="response-header-fields">レスポンスヘッダーフィールド</h3> <table> <colgroup> <col width="20%"> <col width="40%"> <col width="40%"> </colgroup> <tbody><tr> <th>フィールド</th> <th>概要</th> <th>例</th> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">X-Amzn-RequestId</code></td> <td>リクエストを一意に識別するためにADMによって作成された値。万が一、ADMに問題が発生した場合は、Amazon側でこの値を用いてトラブルシューティングを行います。</td> <td><code class="language-plaintext highlighter-rouge">X-Amzn-RequestId: <Amazon RequestId></code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">Retry-After</code></td> <td>エラーレスポンス429、500、503が発生した場合に、このフィールドが返されます。Retry-Afterは、サービスが利用できない時間の長さ(予測)を示します。有効値は、レスポンス後の10進法の秒数またはHTTP形式の日付です。この値の有効な形式については、HTTP/1.1仕様の<a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-retry-after">セクション10.2.3</a>を参照してください。</td> <td><code class="language-plaintext highlighter-rouge">Retry-After: 30</code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">Content-Type</code></td> <td>リソースのコンテンツタイプ:<code class="language-plaintext highlighter-rouge">application/json</code></td> <td><code class="language-plaintext highlighter-rouge">Content-Type: application/json</code></td> </tr> </tbody></table> <h3 id="make-a-tbm-registration-request">TBMの登録リクエスト</h3> <p>以下は、サーバーソフトウェアで<code class="language-plaintext highlighter-rouge">TopicBasedMessaging</code>にセキュリティプロファイルを登録するリクエストを行い、ADMサーバーレスポンスを処理する方法の例です。</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/** * セキュリティプロファイルをTopicBasedMessagingに登録するようADMにリクエストします。 */</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">tbmRegistration</span><span class="o">(</span><span class="nc">String</span> <span class="n">clientSecret</span><span class="o">,</span> <span class="nc">String</span> <span class="n">accessToken</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span> <span class="c1">// メッセージのJSONペイロード表現。</span> <span class="nc">JSONObject</span> <span class="n">payload</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JSONObject</span><span class="o">();</span> <span class="c1">// ヘッダーに指定されたaccessTokenを作成するために使用するclientSecret値を追加します。</span> <span class="n">payload</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"clientSecret"</span><span class="o">,</span> <span class="n">clientSecret</span><span class="o">);</span> <span class="c1">// メッセージをJSONオブジェクトから文字列に変換します。</span> <span class="nc">String</span> <span class="n">payloadString</span> <span class="o">=</span> <span class="n">payload</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span> <span class="c1">// ベースURLを設定します。</span> <span class="nc">String</span> <span class="n">admUrlTemplate</span> <span class="o">=</span> <span class="s">"https://api.amazon.com/v1/messaging/topic/registrations"</span><span class="o">;</span> <span class="no">URL</span> <span class="n">admUrl</span> <span class="o">=</span> <span class="k">new</span> <span class="no">URL</span><span class="o">(</span><span class="n">admUrlTemplate</span><span class="o">);</span> <span class="c1">// POSTリクエスト用のHTTPS接続を生成します。HTTP接続は</span> <span class="c1">// 行えません。</span> <span class="nc">HttpsURLConnection</span> <span class="n">conn</span> <span class="o">=</span> <span class="o">(</span><span class="nc">HttpsURLConnection</span><span class="o">)</span> <span class="n">admUrl</span><span class="o">.</span><span class="na">openConnection</span><span class="o">();</span> <span class="n">conn</span><span class="o">.</span><span class="na">setRequestMethod</span><span class="o">(</span><span class="s">"POST"</span><span class="o">);</span> <span class="n">conn</span><span class="o">.</span><span class="na">setDoOutput</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span> <span class="c1">// コンテンツタイプを設定し、ヘッダーを受け取ります。</span> <span class="n">conn</span><span class="o">.</span><span class="na">setRequestProperty</span><span class="o">(</span><span class="s">"content-type"</span><span class="o">,</span> <span class="s">"application/json"</span><span class="o">);</span> <span class="n">conn</span><span class="o">.</span><span class="na">setRequestProperty</span><span class="o">(</span><span class="s">"accept"</span><span class="o">,</span> <span class="s">"application/json"</span><span class="o">);</span> <span class="c1">// ヘッダーとして認証トークンを追加します。</span> <span class="n">conn</span><span class="o">.</span><span class="na">setRequestProperty</span><span class="o">(</span><span class="s">"Authorization"</span><span class="o">,</span> <span class="s">"Bearer "</span> <span class="o">+</span> <span class="n">accessToken</span><span class="o">);</span> <span class="c1">// 接続の出力ストリームを取得し、メッセージペイロードを書き込みます。</span> <span class="nc">OutputStream</span> <span class="n">os</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="na">getOutputStream</span><span class="o">();</span> <span class="n">os</span><span class="o">.</span><span class="na">write</span><span class="o">(</span><span class="n">payloadString</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(),</span> <span class="mi">0</span><span class="o">,</span> <span class="n">payloadString</span><span class="o">.</span><span class="na">getBytes</span><span class="o">().</span><span class="na">length</span><span class="o">);</span> <span class="n">os</span><span class="o">.</span><span class="na">flush</span><span class="o">();</span> <span class="n">conn</span><span class="o">.</span><span class="na">connect</span><span class="o">();</span> <span class="c1">// 接続からレスポンスコードを取得します。</span> <span class="kt">int</span> <span class="n">responseCode</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="na">getResponseCode</span><span class="o">();</span> <span class="c1">// 失敗のレスポンスを受信したかどうか確認し、受信した場合は失敗の理由を取得します。</span> <span class="k">if</span><span class="o">(</span> <span class="n">responseCode</span> <span class="o">!=</span> <span class="mi">200</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span><span class="o">(</span> <span class="n">responseCode</span> <span class="o">==</span> <span class="mi">401</span> <span class="o">)</span> <span class="o">{</span> <span class="c1">// レスポンスコード401を受信した場合は、アクセストークンの期限が切れていることを意味します。トークンを更新してください。</span> <span class="c1">// このリクエストは再試行できます。</span> <span class="o">}</span> <span class="nc">String</span> <span class="n">errorContent</span> <span class="o">=</span> <span class="n">parseResponse</span><span class="o">(</span><span class="n">conn</span><span class="o">.</span><span class="na">getErrorStream</span><span class="o">());</span> <span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span><span class="nc">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"ERROR: The request to register the security profile with TBM has failed with a "</span> <span class="o">+</span> <span class="s">"%d response code, with the following message: %s"</span><span class="o">,</span> <span class="n">responseCode</span><span class="o">,</span> <span class="n">errorContent</span><span class="o">));</span> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="c1">// リクエストに成功しました。レスポンスには、TopicBasedMessagingに登録されているセキュリティプロファイルが記載されています。</span> <span class="nc">String</span> <span class="n">responseContent</span> <span class="o">=</span> <span class="n">parseResponse</span><span class="o">(</span><span class="n">conn</span><span class="o">.</span><span class="na">getInputStream</span><span class="o">());</span> <span class="nc">JSONObject</span> <span class="n">parsedObject</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JSONObject</span><span class="o">(</span><span class="n">responseContent</span><span class="o">);</span> <span class="nc">String</span> <span class="n">message</span> <span class="o">=</span> <span class="n">parsedObject</span><span class="o">.</span><span class="na">getString</span><span class="o">(</span><span class="s">"message"</span><span class="o">);</span> <span class="c1">// メッセージからセキュリティプロファイルを抽出して、それがリクエストヘッダーで使用されている</span> <span class="c1">// accessTokenの作成に使用したものと同じかどうかを確認できます。</span> <span class="o">}</span> <span class="o">}</span> <span class="kd">private</span> <span class="nc">String</span> <span class="nf">parseResponse</span><span class="o">(</span><span class="nc">InputStream</span> <span class="n">in</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span> <span class="c1">// 入力ストリームから読み取り、文字列に変換します。</span> <span class="nc">InputStreamReader</span> <span class="n">inputStream</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">InputStreamReader</span><span class="o">(</span><span class="n">in</span><span class="o">);</span> <span class="nc">BufferedReader</span> <span class="n">buff</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedReader</span><span class="o">(</span><span class="n">inputStream</span><span class="o">);</span> <span class="nc">StringBuilder</span> <span class="n">sb</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">StringBuilder</span><span class="o">();</span> <span class="nc">String</span> <span class="n">line</span> <span class="o">=</span> <span class="n">buff</span><span class="o">.</span><span class="na">readLine</span><span class="o">();</span> <span class="k">while</span><span class="o">(</span><span class="n">line</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="n">sb</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="n">line</span><span class="o">);</span> <span class="n">line</span> <span class="o">=</span> <span class="n">buff</span><span class="o">.</span><span class="na">readLine</span><span class="o">();</span> <span class="o">}</span> <span class="k">return</span> <span class="n">sb</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span> <span class="o">}</span> </code></pre></div></div> <h2 id="subscribe-the-client-app-instance-to-a-topic-or-unsubscribe-it-from-a-topic">クライアントアプリインスタンスによるトピックのサブスクライブ/サブスクライブ解除</h2> <div class="alert alert-warning" role="alert"><i class="fa fa-warning"></i> <b>重要:</b> TBMを使用するには、クライアントアプリに関連付けられたセキュリティプロファイルを<code class="language-plaintext highlighter-rouge">TopicBasedMessaging</code>に登録する必要があります。詳細については、<a href="#register-a-security-profile-for-topic-based-messaging">トピックベースのメッセージングへのセキュリティプロファイルの登録</a>を参照してください。</div> <p>クライアントアプリは、既存のトピックをサブスクライブするか、新しいトピックを作成できます。クライアントアプリが、関連付けられたセキュリティプロファイルに存在しない新しいトピックをサブスクライブすると、新しいトピックが作成されます。そのセキュリティプロファイルに関連付けられたアプリであれば、そのトピックをサブスクライブできます。</p> <p>アプリでトピックをサブスクライブする場合は、ADMでトピック名を指定して<code class="language-plaintext highlighter-rouge">subscribeToTopic()</code>を呼び出します。アプリは<code class="language-plaintext highlighter-rouge">onSubscribe()</code>または<code class="language-plaintext highlighter-rouge">onSubscribeError()</code>を介して通知を受け取ります。アプリは、<code class="language-plaintext highlighter-rouge">com.amazon.device.messaging.ADMMessageHandlerJobBase</code>クラスと<code class="language-plaintext highlighter-rouge">com.amazon.device.messaging.ADMMessageHandlerBase</code>クラスで定義されているこれらのコールバックメソッドをオーバーライドする必要があります。</p> <h3 id="subscribe-example">サブスクライブの例</h3> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="no">ADM</span> <span class="n">adm</span> <span class="o">=</span> <span class="k">new</span> <span class="no">ADM</span><span class="o">(</span><span class="k">this</span><span class="o">);</span> <span class="c1">// subscribeToTopic()は非同期です。subscribeToTopic()が成功した場合、</span> <span class="c1">// アプリはonSubscribe()コールバックを介して通知を受け取ります。</span> <span class="c1">// subscribeToTopic()が失敗した場合はonSubscribeError()になります。</span> <span class="n">adm</span><span class="o">.</span><span class="na">subscribeToTopic</span><span class="o">(</span><span class="s">"weather"</span><span class="o">);</span> </code></pre></div></div> <p>アプリでトピックのサブスクライブを解除する場合は、トピック名を指定してADMの<code class="language-plaintext highlighter-rouge">unsubscribeFromTopic()</code>を呼び出します。アプリは<code class="language-plaintext highlighter-rouge">onUnsubscribe()</code>または<code class="language-plaintext highlighter-rouge">onUnsubscribeError()</code>を介して通知を受け取ります。アプリは、<code class="language-plaintext highlighter-rouge">com.amazon.device.messaging.ADMMessageHandlerJobBase</code>クラスと<code class="language-plaintext highlighter-rouge">com.amazon.device.messaging.ADMMessageHandlerBase</code>クラスで定義されているこれらのコールバックメソッドをオーバーライドする必要があります。</p> <h3 id="unsubscribe-example">サブスクライブ解除の例</h3> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">final</span> <span class="no">ADM</span> <span class="n">adm</span> <span class="o">=</span> <span class="k">new</span> <span class="no">ADM</span><span class="o">(</span><span class="k">this</span><span class="o">);</span> <span class="c1">// unsubscribeFromTopic()は非同期です。unsubscribeFromTopic()が成功した場合、</span> <span class="c1">// アプリはonUnsubscribe()コールバックを介して通知を受け取ります。</span> <span class="c1">// unsubscribeFromTopic()が失敗した場合はonUnsubscribeError()になります。</span> <span class="n">adm</span><span class="o">.</span><span class="na">unsubscribeFromTopic</span><span class="o">(</span><span class="s">"weather"</span><span class="o">);</span> </code></pre></div></div> <p>これらの新しいAPIは、古いFire OSデバイスでは利用できないことがあります。その場合、デバイス上のアプリがクラッシュするおそれがあります。これを回避するには、以下に示すようにtry/catchブロックを使用してこれらのAPIを呼び出します。</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">try</span> <span class="o">{</span> <span class="nc">Log</span><span class="o">.</span><span class="na">d</span><span class="o">(</span><span class="no">TAG</span><span class="o">,</span> <span class="s">"subscribeToTopic: Trying to subscribe to topic: "</span> <span class="o">+</span> <span class="n">topic</span><span class="o">);</span> <span class="n">adm</span><span class="o">.</span><span class="na">subscribeToTopic</span><span class="o">(</span><span class="n">topic</span><span class="o">);</span> <span class="o">}</span> <span class="k">catch</span> <span class="o">(</span><span class="nc">Error</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span> <span class="nc">Log</span><span class="o">.</span><span class="na">d</span><span class="o">(</span><span class="no">TAG</span><span class="o">,</span> <span class="s">"subscribeToTopic: Error Caught and Error Message is "</span> <span class="o">+</span> <span class="n">e</span><span class="o">.</span><span class="na">getMessage</span><span class="o">());</span> <span class="o">}</span> </code></pre></div></div> <h3 id="callback-method-description">コールバックメソッドの説明</h3> <table> <colgroup> <col width="30%"> <col width="70%"> </colgroup> <tbody><tr> <th>コールバックメソッド</th> <th>説明</th> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">onSubscribe()</code></td> <td>トピックのサブスクリプションが成功すると、パラメーターのトピック(アプリがサブスクライブしたトピック)およびアプリコンテキストと共に呼び出されます。</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">onSubscribeError()</code></td> <td>サブスクリプションリクエストが失敗したときに、パラメーターのトピック(アプリがサブスクライブしようとしていたトピック)、エラーID、アプリコンテキストと共に呼び出されます。</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">onUnsubscribe()</code></td> <td>トピックのサブスクリプション解除が成功すると、パラメーターのトピック(アプリのサブスクリプションが解除されたトピック)およびアプリコンテキストと共に呼び出されます。</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">onUnsubscribeError()</code></td> <td>トピックのサブスクリプション解除が失敗したときに、パラメーターのトピック(アプリがサブスクリプションを解除しようとしていたトピック)、エラーID、アプリコンテキストと共に呼び出されます。</td> </tr> </tbody></table> <h3 id="error-id-and-description">エラーIDと説明</h3> <table> <colgroup> <col width="30%"> <col width="70%"> </colgroup> <tbody><tr> <th>エラーID</th> <th>説明</th> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">INVALID_MANIFEST</code></td> <td>マニフェストに必要な権限/ブロードキャストレシーバーインテントフィルターが定義されていません。統合の手順を確認してマニフェストファイルを更新してください。</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">INTERNAL_ERROR</code></td> <td>HTTP 500ステータスコードに類似した、未処理の内部エラー。必要な対応はありません。</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">INVALID_TOPIC</code></td> <td>指定されたトピックが有効ではありません。トピックはnullにすることはできません。また、トピックの命名パターン(<code class="language-plaintext highlighter-rouge">[a-zA-Z0-9-_.~%]{1,100}</code>)に従う必要があります。</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">NOT_REGISTERED_WITH_TBM</code></td> <td>アプリがTBMに登録されていません。トピックベースのメッセージにアプリを登録してください。</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">UNREGISTERED</code></td> <td>アプリが登録されていないか、登録IDが無効です。再度登録するには、ADMの<code class="language-plaintext highlighter-rouge">startRegister()</code>を呼び出してください。</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">ALREADY_SUBSCRIBED</code></td> <td>アプリは既にそのトピックをサブスクライブしています。再度サブスクライブしないでください。</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">NOT_SUBSCRIBED</code></td> <td>アプリのサブスクリプションが既に解除されているか、指定されたトピックが存在しません。このトピックのサブスクリプションを解除しようとしないでください。</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">MAXIMUM_SUBSCRIPTION_EXCEEDED</code></td> <td>サブスクリプションの上限を超えており、以下のいずれかに該当します。<br>(i) セキュリティプロファイルに100個のトピックが割り当てられている<br>(ii) アプリインスタンスが100個のトピックをサブスクライブしている<br>(iii) トピックが10000個のアプリインスタンス/registrationIdでサブスクライブされている</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">TOO_MANY_REQUESTS</code></td> <td>サブスクライブまたはサブスクライブ解除のリクエストが多すぎます。30秒後に再試行してください。</td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">SERVICE_NOT_AVAILABLE</code></td> <td>ADMサービスと通信できません。非常にまれなエラーです。</td> </tr> </tbody></table> <h3 id="sample-code-for-callback-methods">コールバックメソッドのサンプルコード</h3> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">MyADMMessageHandler</span> <span class="kd">extends</span> <span class="nc">ADMMessageHandlerJobBase</span><span class="o">{</span> <span class="nd">@Override</span> <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onSubscribe</span><span class="o">(</span><span class="kd">final</span> <span class="nc">Context</span> <span class="n">context</span><span class="o">,</span> <span class="kd">final</span> <span class="nc">String</span> <span class="n">topic</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// サブスクリプションが成功した場合のロジックをここに記述します</span> <span class="c1">// 例:ユーザーに通知する、</span> <span class="c1">// サーバーに詳細情報を送信する</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onSubscribeError</span><span class="o">(</span><span class="kd">final</span> <span class="nc">Context</span> <span class="n">context</span><span class="o">,</span> <span class="kd">final</span> <span class="nc">String</span> <span class="n">topic</span><span class="o">,</span> <span class="kd">final</span> <span class="nc">String</span> <span class="n">errorId</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// エラーIDに基づいてサブスクリプションがエラーになった場合のロジックをここに記述します</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onUnsubscribe</span><span class="o">(</span><span class="kd">final</span> <span class="nc">Context</span> <span class="n">context</span><span class="o">,</span> <span class="kd">final</span> <span class="nc">String</span> <span class="n">topic</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// サブスクリプション解除が成功した場合のロジックをここに記述します</span> <span class="c1">// 例:ユーザーに通知する、</span> <span class="c1">// サーバーに詳細情報を送信する</span> <span class="o">}</span> <span class="nd">@Override</span> <span class="kd">protected</span> <span class="kt">void</span> <span class="nf">onUnsubscribeError</span><span class="o">(</span><span class="kd">final</span> <span class="nc">Context</span> <span class="n">context</span><span class="o">,</span> <span class="kd">final</span> <span class="nc">String</span> <span class="n">topic</span><span class="o">,</span> <span class="kd">final</span> <span class="nc">String</span> <span class="n">errorId</span><span class="o">)</span> <span class="o">{</span> <span class="c1">// エラーIDに基づいてサブスクリプション解除がエラーになった場合のロジックをここに記述します</span> <span class="o">}</span> <span class="o">}</span> </code></pre></div></div> <h3 id="receive-and-handle-topic-messages">トピックメッセージの受信と処理</h3> <p>ADMは、単一の登録IDに配信する場合と同じ方法でトピックにメッセージを配信します。詳細については、<a href="message-types.html">ADMメッセージのタイプ</a>を参照してください。</p> <h2 id="send-a-message-to-topic">トピックへのメッセージの送信</h2> <h3 id="prerequisites-1">前提条件</h3> <p>トピックにメッセージを送信するには、以下の前提条件を満たす必要があります。</p> <ul> <li><a href="#register-a-security-profile-for-topic-based-messaging">トピックベースのメッセージングにセキュリティプロファイルを登録</a>している。</li> <li>メッセージの送信先トピックを<a href="#subscribe-the-client-app-instance-to-a-topic-or-unsubscribe-it-from-a-topic">クライアントアプリインスタンスでサブスクライブ</a>している。</li> </ul> <p>これらの前提条件を満たしたら、プログラムでADMを使用してトピックにメッセージを送信できます。</p> <h3 id="request-format-1">リクエスト形式</h3> <p>トピックにメッセージを送信するために、サーバーから以下のようなHTTP POSTリクエストが発行されます。</p> <div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nf">POST</span> <span class="nn">/v1/messaging/topic/messages</span> <span class="k">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="na">Host</span><span class="p">:</span> <span class="s">api.amazon.com</span> <span class="na">Authorization</span><span class="p">:</span> <span class="s">Bearer (アクセストークン)</span> <span class="na">Content-Type</span><span class="p">:</span> <span class="s">application/json</span> <span class="na">X-Amzn-Type-Version</span><span class="p">:</span> <span class="s">com.amazon.device.messaging.ADMMessage@1.0</span> <span class="na">Accept</span><span class="p">:</span> <span class="s">application/json</span> <span class="na">X-Amzn-Accept-Type</span><span class="p">:</span> <span class="s">com.amazon.device.messaging.ADMSendResult@1.0</span> <span class="p">{</span><span class="w"> </span><span class="nl">"data"</span><span class="p">:{</span><span class="nl">"key1"</span><span class="p">:</span><span class="s2">"value1"</span><span class="p">,</span><span class="nl">"key2"</span><span class="p">:</span><span class="s2">"value2"</span><span class="p">},</span><span class="w"> </span><span class="nl">"notification"</span><span class="p">:{</span><span class="nl">"title"</span><span class="p">:</span><span class="s2">"ADM Message Notification"</span><span class="p">,</span><span class="nl">"body"</span><span class="p">:</span><span class="s2">"We have a new offer for you!"</span><span class="p">},</span><span class="w"> </span><span class="nl">"consolidationKey"</span><span class="p">:</span><span class="s2">"Some Key"</span><span class="p">,</span><span class="w"> </span><span class="nl">"expiresAfter"</span><span class="p">:</span><span class="mi">86400</span><span class="p">,</span><span class="w"> </span><span class="nl">"priority"</span><span class="p">:</span><span class="w"> </span><span class="s2">"high"</span><span class="p">,</span><span class="w"> </span><span class="nl">"topic"</span><span class="p">:</span><span class="s2">"SomeTopic"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre></div></div> <p>POST URLは2行目(Host)と1行目(POST)で構成されます。これらを組み合わせると、以下のような完全なURLを取得できます。</p> <div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://api.amazon.com/v1/messaging/topic/messages </code></pre></div></div> <h3 id="request-requirements-1">リクエスト要件</h3> <p>リクエスト自体は、ヘッダーとメッセージ本文で構成されています。</p> <h4 id="header-fields-1">ヘッダーフィールド</h4> <p>ヘッダーには、以下のフィールドを含める必要があります。</p> <table> <colgroup> <col width="20%"> <col width="40%"> <col width="40%"> </colgroup> <tbody><tr> <th>フィールド</th> <th>概要</th> <th>例</th> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">Authorization</code></td> <td>現在のアクセストークンを指定します。有効値: <code class="language-plaintext highlighter-rouge">Bearer (アクセストークン)</code></td> <td><code class="language-plaintext highlighter-rouge">Authorization: <アクセストークン></code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">Content-Type</code></td> <td>有効値:<code class="language-plaintext highlighter-rouge">application/json</code></td> <td><code class="language-plaintext highlighter-rouge">Content-Type: application/json</code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">X-Amzn-Type-Version</code></td> <td>有効値:<code class="language-plaintext highlighter-rouge">com.amazon.device.messaging.ADMMessage@1.0</code></td> <td><code class="language-plaintext highlighter-rouge">X-Amzn-Type-Version: com.amazon.device.messaging.ADMMessage@1.0</code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">Accept</code></td> <td>有効値:<code class="language-plaintext highlighter-rouge">application/json</code></td> <td><code class="language-plaintext highlighter-rouge">Accept: application/json</code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">X-Amzn-Accept-Type</code></td> <td>有効値:<code class="language-plaintext highlighter-rouge">com.amazon.device.messaging.ADMSendResult@1.0</code></td> <td><code class="language-plaintext highlighter-rouge">X-Amzn-Accept-Type: com.amazon.device.messaging.ADMSendResult@1.0</code></td> </tr> </tbody></table> <h4 id="message-body-parameters">メッセージ本文のパラメーター</h4> <p>メッセージ本文のコンテンツとして、<code class="language-plaintext highlighter-rouge">JSONObject</code>に以下のパラメーターを含む文字列を指定します。</p> <table> <colgroup> <col width="22%"> <col width="50%"> <col width="28%"> </colgroup> <tbody><tr> <th>パラメーター</th> <th>説明</th> <th>例</th> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">data</code></td> <td>メッセージと共に送信するペイロードデータ。データはJSON形式のキーと値のペアから成り、いずれも<code class="language-plaintext highlighter-rouge">String</code>値である必要があります。キーと値のほか、これらを囲む引用符、キーと値の間を区切る「:」文字、ペアを区切るコンマ、フィールドを囲む中かっこを含めた合計データサイズが、6KBを超えることはできません(メッセージ本文に<code class="language-plaintext highlighter-rouge">notification</code>フィールドがない場合)。キーと値のペア間の空白は、ペイロードサイズの計算に含まれません。同期メッセージのように、メッセージにペイロードが含まれない場合は、空のオブジェクト(<code class="language-plaintext highlighter-rouge">"data":{}</code>など)を渡すことができます。<br><br> 送信メッセージにデータと通知のペイロード両方が含まれている場合、合計サイズが6KBを超えることはできません。</td> <td><code class="language-plaintext highlighter-rouge">"data":{ "from":"Sam", "message":"Hey, Max.How are you?", "time":"10/26/2012 09:10:00" }</code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">notification</code></td> <td>メッセージと共に送信されるペイロード通知。通知メッセージでは、事前に定義されたキーと値のペアを使用する必要があります。ADM通知でサポートされるキーと値のペアについては、<a href="message-types.html#notification">こちら</a>を参照してください。<br><br> メッセージにデータと通知のペイロード両方が含まれている場合、合計サイズが6KBを超えることはできません。</td> <td><code class="language-plaintext highlighter-rouge">"notification":{"title":"ADM Message Notification","body":"We have a new offer for you!"}</code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">priority</code></td> <td>オプション値。送信メッセージの優先度は、<strong>normal</strong>(通常)と<strong>high</strong>(高)の2つです。メッセージのデフォルトの優先度は<strong>normal</strong>です。優先度がnormalのメッセージは、アプリがフォアグラウンドにある場合はすぐに配信できます。デバイスがDozeモードの場合は、次のメンテナンス時間まで配信が遅れることがあります。優先度が<strong>high</strong>のメッセージの場合、ADMはDozeモードであってもすぐにアプリにメッセージの配信を試みます。アプリが1日に受信できる優先度<strong>high</strong>のメッセージの数は、アプリスタンバイバケットに基づいて制限されます。デフォルト値は<strong>normal</strong>です。</td> <td><code class="language-plaintext highlighter-rouge">"priority": "high"</code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">consolidationKey</code></td> <td>オプション値。これは、複数のメッセージが論理的に同一であり、それまでエンキューされていたメッセージに優先してこの新しいメッセージを使用できることを示すための任意の文字列です。それまでエンキューされていたメッセージが配信されないという保証はありません。連結キーは64文字以下にする必要があります。</td> <td><code class="language-plaintext highlighter-rouge">"consolidationKey":"SyncNow"</code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">expiresAfter</code></td> <td>オプション値。デバイスがオフラインの場合に、ADMがメッセージを保持する秒数を表します。この時間が経過すると、メッセージは破棄される可能性があります。有効値の範囲は1(1秒)~2678400(31日間)で、デフォルト値は604800(1週間)です。</td> <td><code class="language-plaintext highlighter-rouge">"expiresAfter":86400</code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">topic</code></td> <td>必須の値。アプリインスタンスがサブスクライブし、メッセージの送信先となるトピック。文字列値は、正規表現パターン(<code class="language-plaintext highlighter-rouge">[a-zA-Z0-9-_.~%]{1,100}</code>)を満たす必要があります。</td> <td><code class="language-plaintext highlighter-rouge">"topic":"SomeTopic"</code></td> </tr> </tbody></table> <h3 id="response-format-1">レスポンス形式</h3> <p>ADMサーバーは、POSTリクエストメッセージを正常に受信して解釈した後、以下のようなHTTPレスポンスメッセージを送信します。</p> <div class="language-http highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">HTTP</span><span class="o">/</span><span class="m">1.1</span> <span class="m">200</span> <span class="na">X-Amzn-RequestId</span><span class="p">:</span> <span class="s"><Amazon RequestId></span> <span class="na">Content-Type</span><span class="p">:</span> <span class="s">application/json</span> <span class="na">Content-Length</span><span class="p">:</span> <span class="s">308</span> <span class="p">{</span><span class="w"> </span><span class="nl">"messageId"</span><span class="p">:</span><span class="s2">"<メッセージID>"</span><span class="w"> </span><span class="p">}</span><span class="w"> </span></code></pre></div></div> <p>メッセージが受理され、デバイスへの配信用にエンキューされると、ADMからステータスコード200が返されます。その場合、レスポンスメッセージの<code class="language-plaintext highlighter-rouge">JSONObject</code>に以下のパラメーターが含まれます。</p> <ul> <li><code class="language-plaintext highlighter-rouge">messageId</code>: 送信メッセージとメッセージの送信先トピックに関連付けられたID<em>。</em></li> </ul> <p>メッセージが正常に受理されなかった場合は、ADMからエラー(200以外)のステータスコードが返されます。その場合、レスポンスメッセージの<code class="language-plaintext highlighter-rouge">JSONObject</code>の本文に以下のパラメーターが含まれていることがあります。</p> <ul> <li><code class="language-plaintext highlighter-rouge">reason</code>: リクエストが受理されなかった理由。</li> </ul> <h3 id="adm-error-status-codes-1">ADMエラーのステータスコード</h3> <p>ADMエラーのステータスコードとその説明を以下に示します。</p> <table> <colgroup> <col width="10%"> <col width="53%"> <col width="37%"> </colgroup> <tbody><tr> <th>コード</th> <th>説明</th> <th>例</th> </tr> <tr> <td>400</td> <td>以下のような状況では、リクエストがレスポンスコード400で却下されます。<br><br> 1. トピック値が正規表現パターン(<code class="language-plaintext highlighter-rouge">[a-zA-Z0-9-_.~%]{1,100}</code>)を満たしていない。<br><br> 2. トピックにアクティブなサブスクリプションがない。つまり、このトピックをサブスクライブしている<code class="language-plaintext highlighter-rouge">registrationId</code>がない。<br><br> 3. 以下のような、トピック以外の入力パラメーターが無効である。 <br> - <code class="language-plaintext highlighter-rouge">InvalidData</code> - データも通知フィールドも指定されていない。<br> - <code class="language-plaintext highlighter-rouge">InvalidConsolidationKey</code> - キーの長さが64文字を超えている。<br> - <code class="language-plaintext highlighter-rouge">InvalidExpiration</code> - 値が1未満である、または2678400を超えている。<br> - <code class="language-plaintext highlighter-rouge">InvalidType</code> - ヘッダーに指定された<code class="language-plaintext highlighter-rouge">typeVersion</code>と<code class="language-plaintext highlighter-rouge">acceptType</code>の値が<a href="#request-format-1">使用可能な値</a>ではない。<br><br> 4. <code class="language-plaintext highlighter-rouge">accessToken</code>で識別されるセキュリティプロファイルが<code class="language-plaintext highlighter-rouge">TopicBasedMessaging</code>に登録されていない。</td> <td><code class="language-plaintext highlighter-rouge">"reason": "Security profile amzn1.application.<32個の16進文字> is not registered for TopicBasedMessaging."</code></td> </tr> <tr> <td>401</td> <td>提供されたアクセストークンが無効です。送信元は、アクセストークンを更新する必要があります。更新の手順については、<a href="request-access-token.html">アクセストークンのリクエスト方法</a>を参照してください。</td> <td><code class="language-plaintext highlighter-rouge">"reason":"AccessTokenExpired"</code></td> </tr> <tr> <td>413</td> <td>dataパラメーターで渡されたメッセージペイロードが、許容されている最大データサイズ(6KB)を超えています。</td> <td><code class="language-plaintext highlighter-rouge">"reason":"MessageTooLarge"</code></td> </tr> <tr> <td>429</td> <td>リクエスト側が、許容されている最大メッセージレートを超過しました。送信元は、レスポンスに含まれている<code class="language-plaintext highlighter-rouge">Retry-After</code>ヘッダーの指示に従って、後で再試行できます。ADMでは、一定時間内に送信されるメッセージ数を制限することで、高可用性が確保されています。具体的なキャパシティ要件がある場合は、<a href="https://developer.amazon.com/public/support/contact/contact-us">お問い合わせ</a>から以下の情報をお知らせください。<br> - 氏名<br> - 会社名<br> - Eメールアドレス<br> - 必要なTPS(1秒あたりのトランザクション数)制限<br> - 理由</td> <td><code class="language-plaintext highlighter-rouge">"reason":"MaxRateExceeded"</code></td> </tr> <tr> <td>500</td> <td>内部サーバーエラーが発生しました。リクエスト側は、レスポンスに含まれている<code class="language-plaintext highlighter-rouge">Retry-After</code>ヘッダーの指示に従って、後で再試行できます。</td> <td>なし</td> </tr> <tr> <td>503</td> <td>サーバーが一時的に利用できない状態になっています。リクエスト側は、レスポンスに含まれている<code class="language-plaintext highlighter-rouge">Retry-After</code>ヘッダーの指示に従って、後で再試行できます。</td> <td>なし</td> </tr> </tbody></table> <h3 id="response-header-fields-1">レスポンスヘッダーフィールド</h3> <table> <colgroup> <col width="20%"> <col width="40%"> <col width="40%"> </colgroup> <tbody><tr> <th>フィールド</th> <th>概要</th> <th>例</th> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">X-Amzn-RequestId</code></td> <td>リクエストを一意に識別するためにADMによって作成された値。万が一、ADMに問題が発生した場合は、Amazon側でこの値を用いてトラブルシューティングを行います。</td> <td><code class="language-plaintext highlighter-rouge">X-Amzn-RequestId: <Amazon RequestId></code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">Retry-After</code></td> <td>エラーレスポンス429、500、503が発生した場合に、このフィールドが返されます。Retry-Afterメッセージは、サービスが利用できない時間の長さ(予測)を示します。有効値は、レスポンス後の10進法の秒数またはHTTP形式の日付です。この値の有効な形式については、HTTP/1.1仕様の<a href="https://www.rfc-editor.org/rfc/rfc9110.html#name-retry-after">セクション10.2.3</a>を参照してください。</td> <td><code class="language-plaintext highlighter-rouge">Retry-After: 30</code></td> </tr> <tr> <td><code class="language-plaintext highlighter-rouge">Content-Type</code></td> <td>リソースのコンテンツタイプ:<code class="language-plaintext highlighter-rouge">application/json</code></td> <td><code class="language-plaintext highlighter-rouge">Content-Type: application/json</code></td> </tr> </tbody></table> <h3 id="send-a-message-to-a-topic-and-handle-the-response">トピックへのメッセージの送信とレスポンスの処理</h3> <p>以下のコードサンプルは、サーバーソフトウェアでトピックにメッセージを送信し、ADMサーバーのレスポンスを処理する方法を示します。</p> <div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/** * 特定のトピックをサブスクライブしているアプリインスタンスにメッセージを配信するようADMにリクエストします。 */</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">sendMessageToTopic</span><span class="o">(</span><span class="nc">String</span> <span class="n">topic</span><span class="o">,</span> <span class="nc">String</span> <span class="n">accessToken</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span> <span class="c1">// メッセージのJSONペイロード表現。</span> <span class="nc">JSONObject</span> <span class="n">payload</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JSONObject</span><span class="o">();</span> <span class="c1">// データメッセージ内容のキーと値のペアを定義し、メッセージペイロードに</span> <span class="c1">// 追加します。</span> <span class="nc">JSONObject</span> <span class="n">data</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JSONObject</span><span class="o">();</span> <span class="n">data</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"firstKey"</span><span class="o">,</span> <span class="s">"firstValue"</span><span class="o">);</span> <span class="n">data</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"secondKey"</span><span class="o">,</span> <span class="s">"secondValue"</span><span class="o">);</span> <span class="n">payload</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"data"</span><span class="o">,</span> <span class="n">data</span><span class="o">);</span> <span class="c1">// 通知メッセージ内容のキーと値のペアを定義し、メッセージペイロードに</span> <span class="c1">// 追加します。</span> <span class="c1">// 通知メッセージでは、事前に定義されたキーと値のペアのみを使用できます。</span> <span class="c1">// ADM通知でサポートされているキーと値のペアについては、ドキュメント</span> <span class="c1">//(https://developer.amazon.com/ja/docs/adm/message-types.html#notification)を参照してください。</span> <span class="nc">JSONObject</span> <span class="n">notification</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JSONObject</span><span class="o">();</span> <span class="n">notification</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"title"</span><span class="o">,</span> <span class="s">"ADM Message Notification"</span><span class="o">);</span> <span class="n">notification</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"body"</span><span class="o">,</span> <span class="s">"We have a new offer for you!"</span><span class="o">);</span> <span class="n">payload</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"notification"</span><span class="o">,</span> <span class="n">notification</span><span class="o">);</span> <span class="c1">// 連結キーを追加します。アプリインスタンスに対して、同じ連結キーを持つ</span> <span class="c1">// 複数のメッセージの配信が保留になっている場合、ADMでは最後に追加されたメッセージの</span> <span class="c1">// 配信が試行されます。</span> <span class="n">payload</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"consolidationKey"</span><span class="o">,</span> <span class="s">"ADM_Enqueue_Sample"</span><span class="o">);</span> <span class="c1">// メッセージに、expiresAfter値(1日間)を追加します。ターゲットのアプリインスタンスが</span> <span class="c1">// expiresAfter期間内にオンラインにならなかった場合、メッセージは配信されません。</span> <span class="n">payload</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"expiresAfter"</span><span class="o">,</span> <span class="mi">86400</span><span class="o">);</span> <span class="c1">// メッセージにpriorityを追加します。priorityの値によって、デバイスがDoze/アイドルモードの場合に</span> <span class="c1">// メッセージが配信されるかどうかが決まります。</span> <span class="n">payload</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"priority"</span><span class="o">,</span> <span class="s">"high"</span><span class="o">);</span> <span class="c1">// メッセージ本文にトピックを追加します。これを使用してメッセージをアプリインスタンスに配信します。</span> <span class="n">payload</span><span class="o">.</span><span class="na">put</span><span class="o">(</span><span class="s">"topic"</span><span class="o">,</span> <span class="n">topic</span><span class="o">);</span> <span class="c1">// メッセージをJSONオブジェクトから文字列に変換します。</span> <span class="nc">String</span> <span class="n">payloadString</span> <span class="o">=</span> <span class="n">payload</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span> <span class="c1">// ベースURLを設定します</span> <span class="nc">String</span> <span class="n">admUrlTemplate</span> <span class="o">=</span> <span class="s">"https://api.amazon.com/v1/messaging/topic/messages"</span><span class="o">;</span> <span class="no">URL</span> <span class="n">admUrl</span> <span class="o">=</span> <span class="k">new</span> <span class="no">URL</span><span class="o">(</span><span class="n">admUrlTemplate</span><span class="o">);</span> <span class="c1">// POSTリクエスト用のHTTPS接続を生成します。HTTP接続は</span> <span class="c1">// 行えません。</span> <span class="nc">HttpsURLConnection</span> <span class="n">conn</span> <span class="o">=</span> <span class="o">(</span><span class="nc">HttpsURLConnection</span><span class="o">)</span> <span class="n">admUrl</span><span class="o">.</span><span class="na">openConnection</span><span class="o">();</span> <span class="n">conn</span><span class="o">.</span><span class="na">setRequestMethod</span><span class="o">(</span><span class="s">"POST"</span><span class="o">);</span> <span class="n">conn</span><span class="o">.</span><span class="na">setDoOutput</span><span class="o">(</span><span class="kc">true</span><span class="o">);</span> <span class="c1">// コンテンツタイプを設定し、ヘッダーを受け取ります。</span> <span class="n">conn</span><span class="o">.</span><span class="na">setRequestProperty</span><span class="o">(</span><span class="s">"content-type"</span><span class="o">,</span> <span class="s">"application/json"</span><span class="o">);</span> <span class="n">conn</span><span class="o">.</span><span class="na">setRequestProperty</span><span class="o">(</span><span class="s">"accept"</span><span class="o">,</span> <span class="s">"application/json"</span><span class="o">);</span> <span class="n">conn</span><span class="o">.</span><span class="na">setRequestProperty</span><span class="o">(</span><span class="s">"X-Amzn-Type-Version"</span><span class="o">,</span> <span class="s">"com.amazon.device.messaging.ADMMessage@1.0"</span><span class="o">);</span> <span class="n">conn</span><span class="o">.</span><span class="na">setRequestProperty</span><span class="o">(</span><span class="s">"X-Amzn-Accept-Type"</span><span class="o">,</span> <span class="s">"com.amazon.device.messaging.ADMSendResult@1.0"</span><span class="o">);</span> <span class="c1">// ヘッダーとして認証トークンを追加します。</span> <span class="n">conn</span><span class="o">.</span><span class="na">setRequestProperty</span><span class="o">(</span><span class="s">"Authorization"</span><span class="o">,</span> <span class="s">"Bearer "</span> <span class="o">+</span> <span class="n">accessToken</span><span class="o">);</span> <span class="c1">// 接続の出力ストリームを取得し、メッセージペイロードを書き込みます。</span> <span class="nc">OutputStream</span> <span class="n">os</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="na">getOutputStream</span><span class="o">();</span> <span class="n">os</span><span class="o">.</span><span class="na">write</span><span class="o">(</span><span class="n">payloadString</span><span class="o">.</span><span class="na">getBytes</span><span class="o">(),</span> <span class="mi">0</span><span class="o">,</span> <span class="n">payloadString</span><span class="o">.</span><span class="na">getBytes</span><span class="o">().</span><span class="na">length</span><span class="o">);</span> <span class="n">os</span><span class="o">.</span><span class="na">flush</span><span class="o">();</span> <span class="n">conn</span><span class="o">.</span><span class="na">connect</span><span class="o">();</span> <span class="c1">// 接続からレスポンスコードを取得します。</span> <span class="kt">int</span> <span class="n">responseCode</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="na">getResponseCode</span><span class="o">();</span> <span class="c1">// 失敗のレスポンスを受信したかどうか確認し、受信した場合は失敗の理由を取得します。</span> <span class="k">if</span><span class="o">(</span> <span class="n">responseCode</span> <span class="o">!=</span> <span class="mi">200</span><span class="o">)</span> <span class="o">{</span> <span class="k">if</span><span class="o">(</span> <span class="n">responseCode</span> <span class="o">==</span> <span class="mi">401</span> <span class="o">)</span> <span class="o">{</span> <span class="c1">// レスポンスコード401を受信した場合は、アクセストークンの期限が切れていることを意味します。トークンを更新してください。</span> <span class="c1">// このリクエストは再試行できます。</span> <span class="o">}</span> <span class="nc">String</span> <span class="n">errorContent</span> <span class="o">=</span> <span class="n">parseResponse</span><span class="o">(</span><span class="n">conn</span><span class="o">.</span><span class="na">getErrorStream</span><span class="o">());</span> <span class="k">throw</span> <span class="k">new</span> <span class="nf">RuntimeException</span><span class="o">(</span><span class="nc">String</span><span class="o">.</span><span class="na">format</span><span class="o">(</span><span class="s">"ERROR: The send message to the topic %s request failed with a "</span> <span class="o">+</span> <span class="s">"%d response code, with the following message: %s"</span><span class="o">,</span> <span class="n">topic</span><span class="o">,</span> <span class="n">responseCode</span><span class="o">,</span> <span class="n">errorContent</span><span class="o">));</span> <span class="o">}</span> <span class="k">else</span> <span class="o">{</span> <span class="c1">// リクエストに成功しました。レスポンスに、送信メッセージと </span> <span class="c1">// その送信先のトピックに関連付けられたmessageIdが記載されます。</span> <span class="nc">String</span> <span class="n">responseContent</span> <span class="o">=</span> <span class="n">parseResponse</span><span class="o">(</span><span class="n">conn</span><span class="o">.</span><span class="na">getInputStream</span><span class="o">());</span> <span class="nc">JSONObject</span> <span class="n">parsedObject</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JSONObject</span><span class="o">(</span><span class="n">responseContent</span><span class="o">);</span> <span class="nc">String</span> <span class="n">messageId</span> <span class="o">=</span> <span class="n">parsedObject</span><span class="o">.</span><span class="na">getString</span><span class="o">(</span><span class="s">"messageId"</span><span class="o">);</span> <span class="c1">// メッセージがアプリインスタンスに配信されない場合、messageIdをADMに通知して</span> <span class="c1">// 問題のトラブルシューティングを行えます。</span> <span class="o">}</span> <span class="kd">private</span> <span class="nc">String</span> <span class="nf">parseResponse</span><span class="o">(</span><span class="nc">InputStream</span> <span class="n">in</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">Exception</span> <span class="o">{</span> <span class="c1">// 入力ストリームから読み取り、文字列に変換します。</span> <span class="nc">InputStreamReader</span> <span class="n">inputStream</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">InputStreamReader</span><span class="o">(</span><span class="n">in</span><span class="o">);</span> <span class="nc">BufferedReader</span> <span class="n">buff</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">BufferedReader</span><span class="o">(</span><span class="n">inputStream</span><span class="o">);</span> <span class="nc">StringBuilder</span> <span class="n">sb</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">StringBuilder</span><span class="o">();</span> <span class="nc">String</span> <span class="n">line</span> <span class="o">=</span> <span class="n">buff</span><span class="o">.</span><span class="na">readLine</span><span class="o">();</span> <span class="k">while</span><span class="o">(</span><span class="n">line</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span> <span class="n">sb</span><span class="o">.</span><span class="na">append</span><span class="o">(</span><span class="n">line</span><span class="o">);</span> <span class="n">line</span> <span class="o">=</span> <span class="n">buff</span><span class="o">.</span><span class="na">readLine</span><span class="o">();</span> <span class="o">}</span> <span class="k">return</span> <span class="n">sb</span><span class="o">.</span><span class="na">toString</span><span class="o">();</span> <span class="o">}</span> </code></pre></div></div> </div> </div> </div><!--/.container--> </div><!--/.page-container--> <style> .dpFooter .dpfNav { min-height: 220px; } </style> <link rel="stylesheet" href="https://amzndevresources.com/jekyll/css/search-fullpage.css"> <link rel="stylesheet" href="https://amzndevresources.com/jekyll/js/unload.js"> </div> <section class="dp-content-slot dp-content-pixel-tracker-slot"> <div class="dp-content-slot-inner container"> </div> </section> <footer class='dpFooter'> <a class='dpfBackToTopLink' href='#'>トップへ戻る</a> <nav class="dpfNav accordion clearfix"> <div class='dpfWidth'> <div class='dpfnHideRightMargin'> <div class='dpfnColWrap'> <div class="dpfnCol"> <div class="dpfnGroup accrItem"> <div class='dpIconArrow accrHandle'></div> <h3>リソース</h3> <ul> <li><a href="/ja/apps-and-games/blogs">Amazon開発者ブログ</a></li> <li><a href="/ja/apps-and-games/documentation">ドキュメント</a></li> <li><a href="/ja/apps-and-games/devhuddle">Amazon開発者向けハドル</a></li> </ul> </div> </div> <div class="dpfnCol"> <div class="dpfnGroup accrItem"> <div class='dpIconArrow accrHandle'></div> <h3>サポート対象デバイス</h3> <ul> <li><a href="/ja/apps-and-games/fire-tv">Fire TV</a></li> <li><a href="/ja/apps-and-games/fire-tablets">Fireタブレット</a></li> </ul> </div> </div> </div> <div class='dpfnColWrap'> <div class="dpfnCol"> <div class="dpfnGroup accrItem"> <div class='dpIconArrow accrHandle'></div> <h3>その他のサーピスとAPI</h3> <ul> <li><a href="/ja/apps-and-games/small-business-program">小規模ビジネス向けアクセラレータープログラム</a></li> <li><a href="/ja/docs/reports-promo/promo-overview.html ">開発者プロモーションコンソール</a></li> <li><a href="/ja/apps-and-games/alexa-for-video-publishers">Alexa for video publishers</a></li> <li><a href="/ja/apps-and-games/login-with-amazon">Login with Amazon</a></li> <li><a href="/ja/frustration-free-setup">Frustration-Free Setup</a></li> <li><a href="/ja/apps-and-games/incentives-api">AmazonインセンティブAPI</a></li> <li><a href="/ja/apps-and-games/merch">Amazon Merch on Demand</a></li> <li><a href="/ja/docs/music/landing_home.html">Amazon Music</a></li> </ul> </div> </div> <div class="dpfnCol"> <div class="dpfnGroup accrItem"> <div class='dpIconArrow accrHandle'></div> <h3>サポート</h3> <ul> <li><a href="https://community.amazondeveloper.com/">Amazonアプリストア開発者コミュニティ</a></li> <li><a href="/ja/docs/app-submission/faq-landing.html">FAQ</a></li> <li><a href="/ja/support/contact-us">お問い合わせ</a></li> </ul> </div> <div class="dpfnGroup accrItem"> <div class='dpIconArrow accrHandle'></div> <h3>Legal</h3> <ul> <li><a href="/ja/terms-and-agreements">規約・ガイドライン</a></li> <li><a href="https://www.amazon.co.jp/gp/help/customer/display.html?nodeId=GX7NJQ4ZB8MHFRNJ">プライバシー通知</a></li> </ul> </div> </div> </div> </div> </div> </nav> <div class="dpfSocialLocal clearfix"> <div class='dpfWidth'> <div class='dpfLocale'> <nav class="dpLangSwitcher dpsfFlyout"> <span class='dplsTitle'>Language</span> <div class='dplsSwitch'> <span class="dplsCurrent dpsfFlyoutCurrent"> <i class='dpsfIcon dpsfIconGlobe'></i> Japanese (日本語) </span> <div class='dplsOptionsWrap dpsfFlyoutWrap'> <ul class="dplsOptions dpsfFlyoutContent"> <li class="dplsOption dpsfFlyoutItem "> <a data-locale="en_US" href="/docs/adm/topic-based-messaging.html"> English </a> </li> <li class="dplsOption dpsfFlyoutItem "> <a data-locale="zh_CN" href="/zh/docs/adm/topic-based-messaging.html"> Chinese (中文) </a> </li> <li class="dplsOption dpsfFlyoutItem dplsOptionActive"> <a data-locale="ja_JP" href="/ja/docs/adm/topic-based-messaging.html"> Japanese (日本語) </a> </li> </ul> </div> </div> </nav> </div> <div class="dpfSocial"> <span class="dpfSocialTitle"> フォローする </span> <a href="https://www.youtube.com/channel/UCT9ApARFgQJOeqD-ygmxnJQ"> <img src="https://m.media-amazon.com/images/G/01/mobile-apps/dex/logo-youtube.png" alt="youtube_icon"/> </a> <a href="https://www.linkedin.com/showcase/amazon-appstore-developers"> <img src="https://m.media-amazon.com/images/G/01/mobile-apps/dex/logo_linkedin._CB1704305834_.png" alt="linkedin_icon"/> </a> <a href="https://www.twitter.com/AmazonAppDev"> <img src="https://m.media-amazon.com/images/G/01/mobile-apps/dex/logo_X.png" alt="X_icon"/> </a> <a href="https://www.facebook.com/AmazonAppDev"> <img src="https://m.media-amazon.com/images/G/01/mobile-apps/dex/logo_facebook02.png" alt="facebook_icon"/> </a> <a href="/apps-and-games/blog"> <img src="https://images-na.ssl-images-amazon.com/images/G/01/mobile-apps/dex/logo-blog._V290989945_.png" alt="blog_icon"/> </a> </div> </div> </div> <div class="dpfAreaOfInterest dpsfFlyout"> <span class='dpfaCurrent'> <i class='dpsfIcon dpsfIconDots'></i> </span> <div class="dpfWidth dpsfFlyoutWrap"> <div class="dpfaItems dpsfFlyoutContent"> <h3><hza:string id="area_of_interest_title" /></h3> <div class="dpfaItem dpsfFlyoutItem"> <a href="/alexa"> <span class='dpfaiText'>Alexa</span> <img src="https://m.media-amazon.com/images/G/01/mobile-apps/dex/platform-logos/white/Alexalogoheaderwhite._V506548913_.png" alt="Alexa" /> </a> </div> <div class="dpfaItem dpsfFlyoutItem"> <a href="/apps-and-games"> <span class='dpfaiText'>Amazonアプリストア</span> <img src="https://m.media-amazon.com/images/G/01/mobile-apps/dex/platform-logos/white/Appstorelogowhite.png" alt="Amazonアプリストア" /> </a> </div> <div class="dpfaItem dpsfFlyoutItem"> <a href="https://aws.amazon.com"> <span class='dpfaiText'>アマゾンウェブサービス</span> <img src="https://m.media-amazon.com/images/G/01/mobile-apps/dex/platform-logos/white/AWS_logo_RGB_WHT._CB1506540482_.png" alt="アマゾンウェブサービス" /> </a> </div> </div> </div> </div> <div class="dpfCopyright"> © 2010-2024、Amazon.com, Inc. or its affiliates. All Rights Reserved. 無断複写·転載を禁じます。 </div> </footer> </div></body> <!-- Google Tag Manager (noscript) --> <noscript><iframe sandbox src="https://www.googletagmanager.com/ns.html?id=GTM-5LVXJD4" height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript> <!-- End Google Tag Manager (noscript) --> </html>