Google apps script 创建一个基本的聊天吧? 下面是旧的;查看底部的更新文本。
因此,我和我的朋友们在学校时使用谷歌文档进行交流,我们设置了一个挑战,创建一个工作且“高效”的聊天栏,以获得更好的交流效果。我研究JavaScript已经有相当一段时间了,但以前从未玩弄过Google Apps脚本。我们正在使用文档应用程序进行聊天;我提出的代码如下,但我有一些问题:Google apps script 创建一个基本的聊天吧? 下面是旧的;查看底部的更新文本。,google-apps-script,chat,google-docs,Google Apps Script,Chat,Google Docs,因此,我和我的朋友们在学校时使用谷歌文档进行交流,我们设置了一个挑战,创建一个工作且“高效”的聊天栏,以获得更好的交流效果。我研究JavaScript已经有相当一段时间了,但以前从未玩弄过Google Apps脚本。我们正在使用文档应用程序进行聊天;我提出的代码如下,但我有一些问题: 当用户关闭聊天室时出错,然后转到工具栏中的Chat->Open Chat重新打开,显示“遇到错误:发生意外错误”;不指定行或原因 文档中的某个地方需要一个隐藏元素,该元素允许用户查看其他人键入的内容,但如果不使用聊
我不需要有人重写代码(尽管我非常感激!),而是指出我做错了什么,或者提出一些修改/添加的建议 最后,在你提出建议之前,谷歌文档聊天不适用于我们的电脑。这不是文档的错误,但可能是与浏览器的兼容性错误。正是因为这个问题,我们正在经历一个有趣而又仓促的过程来创建我们自己的聊天方法 更新 我决定放弃使用纯谷歌应用程序脚本的聊天版本,并使用G-A-S和HTML帮助改进我的朋友版本。我使用命令/img或/image添加了图像缩略图/链接支持,同时改进了时间和计数器,以及一些其他幕后更新。以下是它的快速屏幕截图: 华丽的聊天程序从头开始,并没有错误的更新方法,只是一个偶然刷新数据库检查消息和设置HTML文本区文本。不再使用有bug的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(){
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;
对于(变量i=0;i我将重新执行他的
getChat()
方法,只检查新消息,而不是在每次刷新时加载每条消息。要消除错误消息,首先要在createChat
函数中创建UiApp,而不是在onOpen
中创建
我还使用了客户端处理程序来清除文本框,因为这样更有效。以下是修改后的代码:
代码删除请参见下面的更新
至于你的第二个要求,我不确定我是否完全理解你想要做什么。。。你能更准确地解释一下你期望的行为吗?(这与其说是一个答案,不如说是一个评论,但我使用了“答案字段”以便更具可读性)
编辑:我对这段代码做了一些修改,找到了一个几乎可以工作的东西。。。它仍然需要改进,但值得展示它是如何工作的 我使用scriptProperties来存储对话的公共部分,我认为这是一个很好的方法,但问题在于它需要知道何时更新内容。这是我到目前为止所掌握的代码,当然,我对任何建议/改进都持开放态度 代码已删除,新版本如下
编辑2:这是一个自动更新的版本,效果非常好,脚本会自动更新聊天区域一段时间。。。如果没有活动,则停止并等待用户操作。请测试(使用2个帐户)并让我们知道您的想法 注意:我使用了一个复选框来处理自动更新,为了测试的目的,我将其保持可见,但当然它可以隐藏在最终版本中 编辑3:添加了一条消息,当用户脱机时警告用户+将文本框更改为彩色文本区,以允许发送更长的消息+清除消息框的条件,以便警告消息不会出现在对话中。(出于测试目的,将超时设置为非常短的值,更改计数器值以恢复到您的需要)
自从第一篇文章发表以来,我修复了不少错误,并更新了它以匹配我的新代码,但我仍然对其他问题感到困惑。请注意,当两个用户运行此应用程序时,我们有两个相同脚本的UI实例,因此我们不能使用textArea来存储对话的公共值…请参阅下面回答中的我的建议。第二部分基本上是询问如何自动更新。我的朋友创建了一个自动更新,但是他的版本使用了HTML,在标题中有一个脚本。我更喜欢使用纯脚本实现而不是组合。我刚刚在文档上同时测试了3个用户,效果很好。。。注意:不要单击该复选框,因为它可能会导致“在短时间内多次调用服务”错误,但在正常使用中似乎不会发生这种情况。我开始使用ScriptDB而不是ScriptProperties,与SP一样,当新用户加入时,聊天似乎会消失。我会将不活动时间增加到10分钟,并提醒用户它们已处于非活动状态。我还是
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;
}
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("@"));
}