2

以下は古いです。下部の更新されたテキストを見てください。

そこで、友達と私は学校でGoogleドキュメントを使ってコミュニケーションを取り、より良い結果を得るために、機能する「効率的な」チャットバーを作成するという課題を設定しました. 私はかなり長い間 JavaScript を使用してきましたが、Google Apps Scriptをいじったことは一度もありません。チャットにはドキュメント アプリを使用しています。私が思いついたコードは次のとおりですが、いくつか問題があります。

  1. ユーザーがチャットを閉じてから、ツールバーの[チャット] -> [チャットを開く] に移動して再度開くと、"エラーが発生しました: 予期しないエラーが発生しました" と表示されるエラー。行または理由を指定しない
  2. ユーザーが他のユーザーが入力した内容を確認できるが、チャット ボックスを使用しないと編集できない非表示の要素がドキュメントのどこかに必要です (テキストが修正されたときにチャット ボックスを更新するイベント リスナーを追加します)。

//Main function, ran when the document first opens.
function onOpen() {
    var app = UiApp.createApplication(); //Create a Ui App to use for the chat bar

    if(getCurrentUser()=="dev1"||getCurrentUser()=="dev2"){ //user-Id's hidden for privacy
        DocumentApp.getUi().createMenu('Chat')
          .addItem('AutoColor', 'autoColor')
          .addItem('Open Chat', 'createChatBox')
          .addItem('Elements', 'displayElements') //Hidden as it is not important for regular use
          .addItem('MyID', 'showUser')
          .addToUi();
    }else{
        DocumentApp.getUi().createMenu('Chat')
          .addItem('AutoColor', 'autoColor')
          .addItem('Open Chat', 'createChatBox')
          .addToUi();
   }
}

//Creates and returns the chats GUI
function createChatBox(){
    var app = UiApp.getActiveApplication()
    app.setTitle("Chat Bar (not yet working)");
    var vPanel = app.createVerticalPanel().setId('chatPanel').setWidth('100%');
    var textArea = app.createTextArea().setId('chatBox').setName('chatBox').setReadOnly(true).setText('').setSize('250px', '450px'); //Read only so they can not edit the text, even if it won't affect overall chat
    var textBox = app.createTextBox().setId('messageBox').setName('messageBox').setText('Words');
    var chatHandler = app.createServerHandler("sayChat").addCallbackElement(textArea).addCallbackElement(textBox);
    var chatButton = app.createButton().setId("sayButton").setText("Say!").addMouseUpHandler(chatHandler);

    vPanel.add(textArea);
    vPanel.add(textBox);
    vPanel.add(chatButton);

    app.add(vPanel);
    DocumentApp.getUi().showSidebar(app);
    return app;
}

//The event handler for when the "Say!" (post) button is pressed. Is probably where the conflict stems from.
function sayChat(eventInfo){
    var app = UiApp.getActiveApplication();
    var parameter = eventInfo.parameter;

    app.getElementById("chatBox").setText(parameter.chatBox+"["+getCurrentUser()+"]: "+parameter.messageBox);
    app.getElementById("messageBox").setText("");

    return app;
}

//A debug function and a function to tell you the unique part of your email (useless, really)
function showUser(){
    DocumentApp.getUi().alert("Your userId is: "+getCurrentUser());
}

//Returns the unique part of a person's email; if their email is "magicuser@gmail.com", it returns "magicuser"
function getCurrentUser(){
    var email = Session.getActiveUser().getEmail();
    return email.substring(0,email.indexOf("@"));
}
//The Auto-color and displayElements methods are hidden as they contain other user-info. They both work as intended and are not part of the issue.

誰かがコードを書き直す必要はありませんが (それは大歓迎です!)、代わりに、私が間違っていることを指摘したり、変更/追加する何かを提案したりします。

最後に、提案する前に、Google ドキュメントのチャットは私たちのコンピューターでは機能しません。ドキュメントのせいではありませんが、おそらくブラウザとの互換性エラーです。この問題が原因で、独自のチャット メソッドを作成するという楽しくも急いでいるプロセスを経ています。

アップデート

純粋な Google Apps Script を使用したバージョンのチャットをあきらめ、GAS と HTML の両方を使用して友人のバージョンを改善することにしました。コマンド /img または /image を使用して画像のサムネイル/リンクのサポートを追加し、時間とカウンターを改善し、その他の舞台裏の更新を行いました。これがその簡単なスクリーンショットです。

Google Apps Script チャット

ゼロからプログラムされた素晴らしいチャット、バグのある更新方法はありません。メッセージをチェックして HTML テキスト領域のテキストを設定するためのカジュアルな更新データベースだけです。バグのある getText メソッドはもう必要ありません。データベース内の新しいメッセージごとに、対象がユーザーであるかチャット内の全員であるかに関係なく、すべてのデータベース メッセージを上限 (一度に 50 メッセージ) まで読み込み、表示します。メッセージでの HTML の使用は、その外観と画像などの機能にとって重要です。

function getChat() {
  var chat = "";
  var time = getTime();

  var username = getCurrentUsername();

  var db = ScriptDb.getMyDb();
  var query = db.query({time : db.greaterThan(getJoinTime())}).sortBy('time', db.DESCENDING).limit(50);

  var flag = query.getSize() % 2 != 0;

  while(query.hasNext()) {
    var record = query.next();
    if(record.showTo == "all" || record.showTo == getCurrentUsername()) {
      var text = record.text;
      for(var i = 0; i < text.split(" ").length; i++) {
        var substr = text.split(" ")[i];
        if(substr.indexOf("http://") == 0 || substr.indexOf("https://") == 0) {
          text = text.replace(substr, "<a href='" + substr + "'>" + substr + "</a>");
        }
      }
      var message = "<pre style='display:inline;'><span class='" + (flag? "even" : "odd") + "'><b>[" + record.realTime + "]</b>" + text;
      message += "</span></pre>";
      chat += message;
      flag = !flag;
    }
  }
  //DocumentApp.getUi().alert(getTime() - time);

  return chat;
}

彼のgetChat()方法をやり直して、新しいメッセージのみをチェックし、更新のたびにすべてのメッセージをロードしないようにします。

4

1 に答える 1

2

エラーメッセージを取り除くために最初にすることは、createChat関数ではなく UiApp を作成することですonOpen

また、クライアント ハンドラーを使用して textBox をクリアしました。より効率的だからです。変更されたコードは次のとおりです。

コードが削除されました 以下の更新を参照してください

あなたの 2 番目のリクエストについては、あなたが何をしたいのか正確に理解しているかどうかわかりません...あなたが期待する動作をより正確に説明できますか? (これは回答というよりコメントですが、読みやすくするために「回答フィールド」を使用しました)


編集:私はこのコードで少し遊んで、-ほぼ-動作するものに来ました...まだ改善する必要がありますが、それがどのように機能するかを示す価値があります。

会話の共通部分を保存するために scriptProperties を使用しました。これは良いアプローチだと思いますが、内容を更新するタイミングを知ることが問題です。ここに私がこれまでに持っているコードがあります。もちろん、私はどんな提案/改善にもオープンです。

コードは削除されました。新しいバージョンは以下のとおりです


EDIT 2 : これは、非常にうまく機能する自動更新を備えたバージョンです。スクリプトは、一定時間、チャット エリアを自動的に更新します...アクティビティがない場合は停止し、ユーザーの操作を待ちます。(2 つのアカウントを使用して) テストして、ご意見をお聞かせください。

私はチェックボックスを使用して autoUpdate をハンドリングしたことに注意してください。テスト目的で表示したままにしていますが、もちろん、最終バージョンでは非表示にすることもできます。

EDIT 3 :オフラインになったときにユーザーに警告するメッセージを追加 + textBox を色付きの textArea に変更して、より長いメッセージを許可する + 警告メッセージが会話に入らないように messageBox をクリアする条件。(テスト目的でタイムアウトを非常に短い値に設定し、カウンター値を変更して必要に応じて復元します)

function onOpen() {

    if(getCurrentUser()=="dev1"||getCurrentUser()=="dev2"){ //user-Id's hidden for privacy
        DocumentApp.getUi().createMenu('Chat')
          .addItem('AutoColor', 'autoColor')
          .addItem('Open Chat', 'createChatBox')
          .addItem('Elements', 'displayElements') //Hidden as it is not important for regular use
          .addItem('MyID', 'showUser')
          .addToUi();
    }else{
        DocumentApp.getUi().createMenu('Chat')
          .addItem('AutoColor', 'autoColor')
          .addItem('Open Chat', 'createChatBox')
          .addToUi();
   }
}

function createChatBox(){
  ScriptProperties.setProperty('chatContent','');
  var app = UiApp.createApplication().setWidth(252);
  app.setTitle("Chat Bar");
  var vPanel = app.createVerticalPanel().setId('chatPanel').setWidth('100%');
  var chatHandler = app.createServerHandler("sayChat").addCallbackElement(vPanel);
  var textArea = app.createTextArea().setId('chatBox').setName('chatBox').setReadOnly(true).setText('').setSize('250px', '450px');
  var textBox = app.createTextArea().setId('messageBox').setName('messageBox').setText('Start chat...').setPixelSize(250,100).setStyleAttributes({'padding':'5px','background':'#ffffcc'}).addKeyPressHandler(chatHandler);
  var clearTextBoxClientHandler = app.createClientHandler().forTargets(textBox).setText('');
  textBox.addClickHandler(clearTextBoxClientHandler);
  var chatButton = app.createButton().setId("sayButton").setText("Say!").addMouseUpHandler(chatHandler);
  var chkHandler = app.createServerHandler('autoUpdate').addCallbackElement(vPanel);
  var chk = app.createCheckBox().setId('chk').addValueChangeHandler(chkHandler);
  vPanel.add(textArea);
  vPanel.add(textBox);
  vPanel.add(chatButton);
  vPanel.add(chk);
  app.add(vPanel);
  DocumentApp.getUi().showSidebar(app);
  return app;
}

function sayChat(e){
  var app = UiApp.getActiveApplication();  
  var user = '['+getCurrentUser()+'] : ';
  if(e.parameter.messageBox=="You have been put offline because you didn't type anything for more than 5 minutes..., please click here to refresh the conversation"){
    app.getElementById('messageBox').setText('');// clear messageBox
    ScriptProperties.setProperty('chatTimer',0);// reset counter
    return app;
  }
  if(e.parameter.source=='messageBox'&&e.parameter.keyCode!=13){return app};
  var content = ScriptProperties.getProperty('chatContent');
  ScriptProperties.setProperty('chatContent',content+"\n"+user+e.parameter.messageBox)
  app.getElementById("chatBox").setText(content+"\n"+user+e.parameter.messageBox+'\n');
  app.getElementById('messageBox').setText('');
  app.getElementById('chk').setValue(true,true);
  ScriptProperties.setProperty('chatTimer',0);
  return app;
}

function autoUpdate(){
  var app = UiApp.getActiveApplication();
  var content = ScriptProperties.getProperty('chatContent');
  var counter = Number(ScriptProperties.getProperty('chatTimer'));
  ++counter;
  if(counter>20){
    app.getElementById('chk').setValue(false);
    app.getElementById('messageBox').setText("You have been put offline because you didn't type anything for more than 5 minutes..., please click here to refresh the conversation");
    return app;
  }
  ScriptProperties.setProperty('chatTimer',counter);
  var content = ScriptProperties.getProperty('chatContent');
  app.getElementById("chatBox").setText(content+'*'); // the * is there only for test purpose
  app.getElementById('chk').setValue(false);
  Utilities.sleep(750);
  app.getElementById('chk').setValue(true,true).setText('timer = '+counter);
  return app;
}

function showUser(){
  DocumentApp.getUi().alert("Your userId is: "+getCurrentUser());
}

function getCurrentUser(){
  var email = Session.getEffectiveUser().getEmail();
  return email.substring(0,email.indexOf("@"));
}
于 2013-10-29T08:54:44.587 に答える