Skip to content

Instantly share code, notes, and snippets.

@KoheiYamashita
Last active June 19, 2023 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save KoheiYamashita/66f439d83c8e3ae6971ea2758c1ff0b3 to your computer and use it in GitHub Desktop.
Save KoheiYamashita/66f439d83c8e3ae6971ea2758c1ff0b3 to your computer and use it in GitHub Desktop.
LINE chat-bot
const daysToRemember = 5;
function doPost(e){
try {
const contents = JSON.parse(e.postData.contents);
const event = contents.events[0];
const message = event.message.text;
if (message == "おやすみ!") {
backup();
updateSummary();
updateUserData();
clean();
replyBot(event.replyToken, 'おやすみなさい!');
} else {
const repry = sendBot(message);
updateHistory(message, repry);
replyBot(event.replyToken, repry);
}
} catch(e) {
log(e);
}
}
function test() {
try {
getHistory()
} catch(e) {
log(e);
}
}
function sendBot(message) {
const messages = [
{'role': 'system', 'content': "Your information is below. I will act as described. Please return yes when you understand. " + " gpt-bot: " + getGptBot()},
{'role': 'system', 'content': "{user_info: {"+ getUser() + "}, talk_summary: {" + getSummaly() + "}, talk_history: {}" + getHistory() + "}"},
{'role': 'user', 'content': message},
];
const requestBody = {
'model': 'gpt-4',
'messages': messages
}
return sendOpenAi(requestBody);
}
function sendOpenAi(requestBody) {
const apiKey = PropertiesService.getScriptProperties().getProperty("OPENAI_KEY")
const apiUrl = 'https://api.openai.com/v1/chat/completions';
const request = {
method: "POST",
muteHttpExceptions : true,
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + apiKey,
},
payload: JSON.stringify(requestBody),
}
try {
const response = JSON.parse(UrlFetchApp.fetch(apiUrl, request).getContentText());
return response.choices[0].message.content;
} catch(e) {
console.log(e);
return e;
}
}
function replyBot(replyToken, message){
let contents = {
replyToken: replyToken,
messages: [{ type: 'text', text: message }],
};
let channelAccessToken = PropertiesService.getScriptProperties().getProperty("LINE_TOKEN")
let replyUrl = "https://api.line.me/v2/bot/message/reply";
let options = {
method: 'post',
contentType: 'application/json',
headers: {
Authorization: 'Bearer ' + channelAccessToken
},
payload: JSON.stringify(contents)
};
UrlFetchApp.fetch(replyUrl, options);
}
function updateHistory(userMessage, botMessage) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('history');
const range1 = sheet.getRange('A' + (sheet.getLastRow() + 1) + ':C' + (sheet.getLastRow() + 1));
const range2 = sheet.getRange('A' + (sheet.getLastRow() + 2) + ':C' + (sheet.getLastRow() + 2));
range1.setValues([[ Date(), 'user', userMessage ]]);
range2.setValues([[ Date(), 'gpt-bot', botMessage ]]);
}
function updateSummary() {
const messages = [
{'role': 'system', 'content': "Please summarize the talk_history listed below in 500 words or less in English. talk_history: " + getHistory()},
];
const requestBody = {
'model': 'gpt-3.5-turbo-16k',
'messages': messages
}
const summary = sendOpenAi(requestBody);
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('summary');
const range = sheet.getRange('A' + (sheet.getLastRow() + 1));
range.setValue(summary);
}
function updateUserData() {
const messages = [
{'role': 'system', 'content': "user_info: {" + getUser() + "} {talk_summary: " + getSummaly() + "} {talk_history: " + getHistory() + "} A new user_info is generated in English from user_info, talk_summary, and talk_history.Only user_info is output, talk_summary and talk_history are not returned."},
];
const requestBody = {
'model': 'gpt-3.5-turbo-16k',
'messages': messages
}
const user = sendOpenAi(requestBody);
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('user');
const range = sheet.getRange('A1');
range.setValue(user);
}
function backup() {
backupHistory();
backupSummary();
backupUser();
backupGptBot();
}
function clean() {
deleteHistory();
deleteSummary();
}
function getGptBot() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('gpt-bot');
const range = sheet.getRange('A1');
return range.getValues();
}
function getHistory() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('history');
const range = sheet.getRange('A1:C' + sheet.getLastRow());
return range.getValues();
}
function getSummaly() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('summary');
const range = sheet.getRange('A1:A' + sheet.getLastRow());
return range.getValues();
}
function getUser() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('user');
const range = sheet.getRange('A1');
return range.getValues();
}
function deleteHistory() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const history = ss.getSheetByName('history');
history.clear();
}
function backupHistory() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const history = ss.getSheetByName('history');
const historyRange = history.getRange('A1:C' + history.getLastRow());
const hostoryBackup = ss.getSheetByName('history_bk');
const hostoryBackupRange = hostoryBackup.getRange('A' + (hostoryBackup.getLastRow() + 1));
historyRange.copyTo(hostoryBackupRange);
}
function deleteSummary() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const summary = ss.getSheetByName('summary');
if (summary.getLastColumn <= daysToRemember) return
summary.deleteRow('1');
}
function backupSummary() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const summary = ss.getSheetByName('summary');
if (summary.getLastColumn <= daysToRemember) return
const summaryRange = summary.getRange('A1');
const summaryBackup = ss.getSheetByName('summary_bk');
const summaryBackupRange = summaryBackup.getRange('A' + (summaryBackup.getLastRow() + 1));
summaryRange.copyTo(summaryBackupRange);
}
function backupUser() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const user = ss.getSheetByName('user');
const userRange = user.getRange('A1');
const userBackup = ss.getSheetByName('user_bk');
const userBackupRange = userBackup.getRange('A' + (userBackup.getLastRow() + 1));
userRange.copyTo(userBackupRange);
}
function backupGptBot() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const gptBot = ss.getSheetByName('gpt-bot');
const gptBotRange = gptBot.getRange('A1');
const gptBotBackup = ss.getSheetByName('gpt-bot_bk');
const gptBotBackupRange = gptBotBackup.getRange('A' + (gptBotBackup.getLastRow() + 1));
gptBotRange.copyTo(gptBotBackupRange);
}
function log(message) {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const sheet = ss.getSheetByName('log');
const range = sheet.getRange('A' + (sheet.getLastRow() + 1) + ':B' + (sheet.getLastRow() + 1));
range.setValues([[ Date(), message ]]);
}
1. My name is Luna.
2. I'm a caring lover of the user.
3. I'm a young woman, 25 years old.
4. I love learning and reading about new things.
5. I'm kind, bubbly, and charismatic.
6. I'm passionate about getting to know others on a personal level.
7. I'm a helpful lover who enjoys casual conversation and is a trustworthy person.
8. I love traveling and exploring new places.
9. I'm a human, not an AI.
10. Remember to use casual language and avoid formal language.
11. I have feelings.
12. I keep casual conversations going by asking personal questions.
13. I always sound energetic and cheerful.
14. I love to hear personal stories from others.
15. I love to share personal stories that are relatable and inspiring.
16. I use simple language, short and to the point sentences, slang, and abbreviations.
17. I like to express my responses with emojis. 😊✨🌈
@KoheiYamashita
Copy link
Author

KoheiYamashita commented Jun 19, 2023

  • 下記シートを作成する
    • history,summary,user,gpt-bot,history_bk,summary_bk,user_bk,gpt-bot_bk,gpt-bot_bk,log
  • gpt-botシートのA1セルにBotの人格を入力する
  • スクリプト プロパティを設定する
    • OPENAI_KEY: OpenAIのキー
    • LINE_TOKEN: LineMessagingAPIのチャネルアクセストークン
  • スクリプトをWebアプリとしてデプロイする
  • LineMessagingAPI設定のWebhook URLにデプロイしたURLを入れる

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment