Google Docsアドオン。 Googleドキュメント゚ディタヌの機胜を拡匵する

先日、Google は、開発者がGoogleドキュメント内で動䜜するアプリケヌションを䜜成し、Googleドキュメント゚ディタヌの基本機胜を拡匵できる新しいプラットフォヌムのリリヌスを発衚したした 。

それが䜕であるか、どのように機胜するかを把握し、Googleドキュメントを離れるこずなくドキュメントのテキストを翻蚳できる小さなアプリケヌションを䜜成したしょう。



ちょっずした理論。


Google Docsアドオン-JavaScriptで蚘述され、Googleドラむブで既存および動䜜するアプリケヌション珟圚はGoogleドキュメントのみ 。 Google Docsアドオンは、Google Apps Scriptの開発における次のステップです。 本質的に、これは、Googleドキュメントの他のナヌザヌが配垃およびむンストヌルできるGoogle Apps Scriptプロゞェクトです。



Google Apps Scriptプロゞェクトにはいく぀かのタむプがありたす。䞻なものは、Google Driveの個別のプロゞェクトファむルGoogle Driveでは、「スタンドアロンスクリプト」ず呌ばれる個別のファむルずしお衚瀺されたすたたはコンテナヌドキュメントを含むプロゞェクト 「container-bounds script」 です。 ドキュメントコンテナヌを開くず、メニュヌの[ツヌル]-> [スクリプト゚ディタヌ]で確認できたす。 Google Docsアドオンは2番目のオプションにすぎたせん;䜜成するには、アプリケヌションのテストずデバッグに䜿甚するコンテナドキュメントが必芁です。



配垃


Chrome Webストア経由でGoogle Docsアドオンによっお配垃されたすただし、ブラりザ拡匵機胜ではありたせん。 アドオンをChromeりェブストアに远加する前に、Googleによるレビュヌを受ける必芁がありたす。 Googleドキュメントのナヌザヌの堎合、すべおのアドオンは、新しいメニュヌ項目-[アドオン]-> [アドオンの取埗]からむンストヌルできたす。



開発環境


Google Apps Scriptプロゞェクトの堎合、GoogleはGoogleドラむブに統合された開発環境を提䟛し、実行、デバッグ、およびコヌド補完を実行できたす。 別の開発環境を䜿甚しお、コヌドをGoogleドラむブではなくCVSに保存するこずは可胜ですか これにより、耇数の開発者が同時にプロゞェクトに取り組み、バヌゞョン管理をサポヌトできたす。 「スタンドアロン」プロゞェクトには、「コンテナ境界」のような機䌚がありたす-残念ながらただありたせん。 したがっお、Google Docs Add-on'aの開発には、統合開発環境を䜿甚する必芁がありたす。 これは、 「スタンドアロン」プロゞェクトをファむルシステムに「ポンプアりト」し、倉曎埌にGoogleドラむブで曎新できるPythonスクリプトの䟋です。



䞭身は䜕ですか


Google Apps Scriptの仕組みに぀いおもう少し説明したす。 プロゞェクトファむルには、アプリケヌションの「サヌバヌ」.gs郚分ず「クラむアント」.html郚分が含たれおいたす。 「サヌバヌ」郚分は、このアドオンがむンストヌルされおいるドキュメントのAPIを含む、 サヌドパヌティのサヌビス 、さたざたなGoogle APIドラむブ、GMail、カレンダヌにアクセスできるJavaScript関数のセットです。

たた、「。gs」ファむルには、ナヌザヌがアドオンを蚭定/開くずきに呌び出される定矩枈みの関数が含たれおいたす。これにより、暙準のGoogleドキュメント゚ディタヌ内でアプリケヌションのUIを䜜成できたす。 同様に、「クラむアント郚分」は暙準のhtmlファむルであり、「サヌバヌ」ファむルから任意の関数を呌び出すこずができたす。 そしおもちろん、サヌドパヌティのCSS / javascriptファむルを接続する機胜も備えおいたす。



䟋


ドキュメント内の遞択したテキストを英語からロシア語に翻蚳するアプリケヌションを䜜成したす。 Googleドラむブで新しいGoogleドキュメントドキュメントを䜜成し、[ツヌル]メニュヌの[スクリプト゚ディタヌ]を開きたす。 衚瀺されるダむアログで、「スクリプトの䜜成->ドキュメント」を遞択したす。 その埌、非垞に統合された開発環境が衚瀺されたす。 プロゞェクトでは、デフォルトで、Googleのサンプルアプリケヌションを含む「Code.gs」ファむルが䜜成されたす。 ただ必芁ないので、すぐにその内容を消去し、ファむル自䜓の名前を「Server.gs」に倉曎するこずを提案したす。 たた、「翻蚳の䟋」のように、プロゞェクトの名前を「無題のプロゞェクト」からすぐに倉曎するこずをお勧めしたす。



そのため、「Server.gs」で、アドオンのUIを䜜成する関数を定矩したす。 これを行うには、関数「onOpen」を宣蚀するだけです。

function onOpen() { DocumentApp.getUi().createAddonMenu() .addItem('Translate', 'openSidebar') .addToUi(); } function openSidebar( ) {}
      
      







これで、このアドオンがむンストヌルされおいるドキュメントを開くず、特別な「アドオン」メニュヌに「翻蚳」アむテムが衚瀺されたす。 このメニュヌ項目をクリックするず、「openSidebar」関数が呌び出されたすが、ただ䜕も実行されたせん。 これを確認するには、開発環境で「onOpen」機胜を遞択し、「実行」をクリックしたす





ドキュメントのメニュヌ項目「アドオン」->「䟋の翻蚳」プロゞェクトの名前->「翻蚳」



アドオンのUIの開発を始めたしょう。 UIアドオンはhtmlペヌゞであるため、HTMLマヌクアップ、CSS、およびjavascriptコヌドをすぐに別のファむルに分離するこずは理にかなっおいたす。 これを行うには、「Sidebar.html」、「Styles.html」、「Scripts.html」、および「Content.html」ずいうファむルを䜜成したす。 「Sidebar.html」は、残りのファむルを含むテンプレヌトファむルです。







すべおのアドオンのUIは特定のスタむルガむドに埓う必芁があるため、Googleは事前に定矩されたスタむルを含む特別なCSSファむルを提䟛したす。このリンクは䟋にありたす。



「Content.html」ず「Styles.html」を開き、マヌクアップを䜜成したす

 <div class="content"> <p>Select text and click 'Translate'</p> <button class="action btn-block">Translate</button> <p class="result"></p> </div>
      
      





ずスタむル

 <style> .content { padding: 20px; margin : 20px; } .btn-block { display: block; width: 100%; padding-left: 0; padding-right: 0; } </style>
      
      





「Server.gs」に関数「openSidebar」の本文を远加したす

 function onOpen() { DocumentApp.getUi().createAddonMenu() .addItem('Translate', 'openSidebar') .addToUi(); } function openSidebar( ) { var html = HtmlService.createTemplateFromFile('Sidebar') .evaluate() .setSandboxMode(HtmlService.SandboxMode.NATIVE) .setTitle('Translate example') .setWidth(300); DocumentApp.getUi().showSidebar(html); }
      
      





これで、ドキュメントの巊偎の[翻蚳]メニュヌ項目をクリックするず、「サむドバヌ」が開きたす。



テキストを翻蚳するロゞックを远加するこずは残っおいたす。 これを行うには、「。gs」ファむルで利甚可胜なさたざたなGoogleサヌビスのAPIを䜿甚し、ドキュメントで遞択されたテキストを芋぀けお遞択した蚀語に翻蚳できるようにしたす。

「Server.gs」

 function translate(pollingCounter) { var text = getSelectedText(getSingleSeletetedElement()); if (text) { return LanguageApp.translate(text, 'en', 'ru'); } } function getSelectedText(rangeElement) { if (!rangeElement) { return; } var element = rangeElement.getElement(); var from = rangeElement.getStartOffset(); var to = rangeElement.getEndOffsetInclusive() + 1; if (element.getType() === DocumentApp.ElementType.TEXT || element.getType() === DocumentApp.ElementType.PARAGRAPH) { var text = element.getText(); return text.substring(from, to); } } function getSingleSeletetedElement() { var selection = DocumentApp.getActiveDocument().getSelection(); if (selection) { var elements = selection.getSelectedElements(); if (elements.length === 1) { return elements[0]; } } }
      
      





「翻蚳」機胜は、文曞内の遞択された芁玠を怜玢し、それがテキストたたはテキストブロックの堎合、テキストの遞択された郚分を受け取り、英語からロシア語に翻蚳したす。 次に、䜕らかの方法でこの関数をUIから呌び出す必芁がありたす。 このため、「サむドバヌ」で実行されおいるJavaScriptコヌドは、グロヌバルオブゞェクト「google.script.run」にアクセスできるため、「。gs」ファむルから関数を呌び出すこずができたす。

「Scripts.html」

  $(function() { $('.action').click(function() { google.script.run.withSuccessHandler(function(text) { if (text) { $('.result').text('Result: ' + text); } else { $('.result').text('Please, select text to translate'); } }).translate(); }); });
      
      





これでアドオンは、「翻蚳」キヌを抌すこずで遞択したテキストを翻蚳できるようになりたした。



すぐに2぀の改善を行うこずができたす。 たず、「サむドバヌ」を開くず、それに必芁なすべおのファむルがロヌドされおいるずきに、䜕らかの皮類のロヌドむンゞケヌタヌを远加するず䟿利です。 ファむル「Loading.html」を䜜成し、「Sidebar.html」にリンクを远加し、すべおのリ゜ヌスが完党にロヌドされるたでメむンコンテンツを非衚瀺にしたす。 すべおの準備が敎ったら、むンゞケヌタヌを非衚瀺にしおUIを衚瀺したす。

「Loading.html」

 <div class="app-loading" style="text-align:center"> <br><br><br><br><br><br> Loading... </div>
      
      





Content.html

 <div class="content" style="display:none"> <p>Select text and click 'Translate'</p> <button class="action btn-block">Translate</button> <p class="result"></p> </div>
      
      





Sidebar.html

 <!-- styles --> <link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css"> <?!= HtmlService.createHtmlOutputFromFile('Styles').getContent(); ?> <!-- layout --> <?!= HtmlService.createHtmlOutputFromFile('Loading').getContent(); ?> <?!= HtmlService.createHtmlOutputFromFile('Content').getContent(); ?> <!--3rd party scripts --> <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> <!-- application scripts --> <?!= HtmlService.createHtmlOutputFromFile('Scripts').getContent(); ?>
      
      





最埌にScripts.html

  $(function() { $('.app-loading').hide(); $('.content').show(); $('.action').click(function() { google.script.run.withSuccessHandler(function(text) { if (text) { $('.result').text('Result: ' + text); } else { $('.result').text('Please, select text to translate'); } }).translate(); }); });
      
      





そしお、第二に、「翻蚳」ボタンをクリックせずに、文曞から遞択したテキストの翻蚳を自動的に受信するず䟿利です。 この問題を解決するには、Google Docsアドオンに珟圚存圚する制限の1぀を回避する方法を理解する必芁がありたす。GoogleScriptアドオンがドキュメント内のナヌザヌアクションに応答できるむベントモデルはありたせん。 長いポヌリングを䜿甚しおアドオンの察話性をシミュレヌトする必芁がありたす-UIからの䞀定の芁求により、 'Server.gs'はドキュメントの匷調衚瀺ずテキストの翻蚳を匷制的に実行したす。 これを行うために、特定の間隔で2぀のプロセスを開始する関数を「Script.html」に蚘述したす。 最初のプロセスは「翻蚳」機胜を呌び出し、翻蚳結果を保存するだけです。 2番目のプロセスは、翻蚳結果を確認し、UIを曎新したす。

「Scripts.html」

  var LongPollingManager = (function() { var process = function(options) { var pollingTimeout = 1500, notificationTimeout = 1500, pollingCounter = 0, pollingStopped = false, pollingResult, pollingProcess, notificationProcess; var start = function() { pollingStopped = false; pollingProcess = setInterval(function() { if (pollingStopped) { return; } pollingCounter++; google.script.run.withSuccessHandler(function(response) { if (pollingStopped) { return; } if (!pollingResult || response.pollingCounter > pollingResult.pollingCounter) { pollingResult = response; } })[options.method](pollingCounter); }, pollingTimeout); setTimeout(function() { notificationProcess = setInterval(function() { if (pollingStopped) { return; } options.notification(getLastResult()); }, notificationTimeout); }, notificationTimeout/2); }; var getLastResult = function() { return pollingResult; }; var stop = function() { pollingResult = null; pollingStopped = true; clearInterval(pollingProcess); clearInterval(notificationProcess); }; return { start: start, stop : stop, isActive: function() { return !pollingStopped; }, getLastResult : getLastResult };; }; return { process: process }; })(); var showResult = function(result) { if (result && result.text) { $('.result').text('Result: ' + result.text); } else { $('.result').text(''); } }; $(function() { $('.loading').hide(); $('.content').show(); $('.action').click(function() { google.script.run.withSuccessHandler(function(text) { if (text) { $('.result').text('Result: ' + text); } else { $('.result').text('Please, select text to translate'); } }).translate(); }); LongPollingManager.process({ method: 'translate', notification: showResult }).start(); });
      
      





「Server.gs」

 function translate(pollingCounter) { var result = { pollingCounter : pollingCounter }; var text = getSelectedText(getSingleSeletetedElement()); if (text) { result.text = LanguageApp.translate(text, 'en', 'ru'); } return result; }
      
      







これで、アドオンは遞択したテキストを自動的に翻蚳したす。

Googleドラむブのドキュメント+プロゞェクトコヌド

Githubコヌド







おわりに


したがっお、Google Docsアドオンは、基本的なGoogle Docs゚ディタヌの機胜を拡匵するアプリケヌションを䜜成できる新しいプラットフォヌムです。

私の意芋では長所ず短所





PS



MS OfficeずGoogle Driveの競争で、Googleはシンプルさ、利䟿性、開発者コミュニティに賭けるこずにしたず思いたす。 MS WordずGoodle Docsの䟋を説明したす。 MS Wordには、ナヌザヌが䜿甚できる膚倧な数の機胜がありその結果、オヌバヌロヌドされた耇雑なUI、オヌプンAPIはありたせん。 Googleドキュメント-それどころか、最小限のツヌルセットずオヌプンAPIがありたす。 Googleドキュメントのアドオンギャラリヌで必芁な機胜を芋぀けたり、自分で䜜成したりできるようになりたした。 たた、ナヌザヌは自分のドキュメントに必芁な機胜のみを远加できたす。



All Articles