- フリー版でもGWSでも良いですが、Google Apps ScriptをWebアプリとして公開するので、Googleアカウントを作っておく。
- Developer ConsoleでBotの登録ができること
- 管理者コンソールでBotの追加ができること
- API Keyが発行できること
※Callback URLはGASを作成後に設定します。
以上
以上
/** | |
* OpenGPT 設定 | |
*/ | |
// const GPT_MODEL = 'gpt-3.5-turbo'; | |
const GPT_MODEL = 'gpt-4-turbo-preview'; | |
const GPT_URL = "https://api.openai.com/v1/chat/completions"; | |
const GPT_API_KEY = 'xxx' | |
// const GPT_MAX_TOKENS = 1024; | |
const GPT_MAX_TOKENS = 2000; | |
const GPT_TEMPERATURE = 0.1; // 大きくするほど、想像力豊かになる | |
/** | |
* LINEWORKS 設定 | |
*/ | |
const LW_CLIENT_ID = "xxx"; | |
const LW_CLIENT_SECRET = "xxx"; | |
const LW_SERVICE_ACCOUNT = "xxx@xxx"; | |
const LW_PRIVATE_KEY = `-----BEGIN PRIVATE KEY----- | |
-----END PRIVATE KEY-----`; | |
const LW_BOT_ID = 0; | |
const LW_NORTIFY_USER = 'xxx@xxx'; | |
function openAIAPI(prompt) { | |
var uri = 'https://api.openai.com/v1/chat/completions'; | |
var headers = { | |
'Authorization': `Bearer ${GPT_API_KEY}`, | |
'Content-type': 'application/json', | |
}; | |
var options = { | |
'muteHttpExceptions': true, | |
'headers': headers, | |
'method': 'POST', | |
'payload': JSON.stringify({ | |
model: `${GPT_MODEL}`, | |
temperature: GPT_TEMPERATURE, | |
max_tokens: GPT_MAX_TOKENS, | |
messages: [ | |
{ role: "user", content: prompt } | |
] | |
}) | |
}; | |
const response = UrlFetchApp.fetch(uri, options); | |
var json = JSON.parse(response.getContentText()); | |
let generatedText = json["choices"][0]['message']['content']; | |
return generatedText.trim(); | |
} | |
function testOpenAIAPI() { | |
console.log(openAIAPI(` | |
名古屋の良いところを教えてください。`)); | |
} | |
function overWriteCell() { | |
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); | |
const lastRow = sheet.getLastRow(); | |
var range = sheet.getRange("C3:C" + lastRow); | |
range.setValues(range.getValues()) | |
sheet.getSheetValues(3, 3, lastRow, 3); | |
} | |
/** | |
* Lineworksからのコールバック受付 | |
*/ | |
function doPost(e) { | |
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('log'); | |
const nextRow = sheet.getLastRow() + 1; | |
sheet.getRange(nextRow, 1).setValue(Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss')); | |
try { | |
const contents = JSON.parse(e.postData.contents); // json to dic | |
const userId = contents.source.userId; | |
sheet.getRange(nextRow, 2).setValue(userId); | |
const talkMessage = contents.content['text']; | |
sheet.getRange(nextRow, 3).setValue(talkMessage); | |
// sheet.getRange(nextRow, 5).setValue(e); | |
if (talkMessage == '利用開始') { | |
// sendText(userId, 'こんにちは、私はOpenAIのチャットボットです。私は自然言語処理技術を使って、人工知能による自動応答を行うことができます。私は、様々な分野での情報収集や問題解決に役立つことができます。よろしくお願いします。' + '\n※文脈を読む機能には対応していません。'); | |
sendText(userId,`私はOpenAI社が開発したAIを利用したチャットボットです。以下のようなことに活用いただけます。 | |
※文脈を読む機能には対応していません。 | |
1. カスタマーサポート: | |
- チャットボットとして顧客からの問い合わせにリアルタイムで対応。 | |
- サイズガイド、在庫状況、配送情報などの基本的な質問に答える。 | |
- 返品・交換ポリシーの説明や手続きの支援。 | |
2. パーソナライズされたショッピングアシスタント: | |
- 顧客の好みや購買履歴に基づいて、パーソナライズされた商品推薦を提供。 | |
- スタイリングのアドバイスやコーディネートの提案。 | |
3. マーケティングとコミュニケーション: | |
- ソーシャルメディアやメールマーケティングでのキャンペーンの作成支援。 | |
- プロモーションや新商品の発表時に、顧客とのエンゲージメントを高めるためのコンテンツ作成。 | |
4. トレンド分析と市場調査: | |
- ソーシャルメディアやレビューサイトからのデータを分析して、トレンドを把握。 | |
- 顧客のフィードバックやレビューを分析して、商品開発や品質改善に活かす。 | |
5. 在庫管理と需要予測: | |
- 過去の販売データを分析して、需要予測を行い、在庫管理を最適化。 | |
- セールスパターンを分析して、過剰在庫や品切れを防ぐ。 | |
6. 製品説明とコンテンツ生成: | |
- 商品の特徴や素材、お手入れ方法などの詳細な説明文の作成。 | |
- SEOに最適化された製品説明でウェブサイトのトラフィックを増やす。 | |
7. 言語翻訳と多言語サポート: | |
- 多言語での顧客サポートを提供し、国際的な顧客基盤を拡大。 | |
- ウェブサイトや商品説明の翻訳を行い、異なる市場に対応。 | |
8. 教育とトレーニング: | |
- 社内の新入社員やスタッフ向けの製品知識や販売技術のトレーニング資料の作成。 | |
- よくある質問やケーススタディを使って、顧客対応スキルを向上させる。 | |
9. フィードバックとレビューの収集: | |
- 顧客からのフィードバックやレビューを収集し、製品やサービスの改善点を特定。 | |
- ポジティブなレビューをマーケティング資料として活用。 | |
10. クリエイティブなコンテンツ生成: | |
- ブランドストーリーやブログ記事、ソーシャルメディア投稿のためのクリエイティブなコンテンツの生成。`); | |
return; | |
} | |
const openAIAPIMessage = openAIAPI(talkMessage); | |
sheet.getRange(nextRow, 4).setValue(openAIAPIMessage); | |
sendText(userId, openAIAPIMessage); | |
} | |
catch (error) { | |
sendText(userId, '生成に失敗しました。'); | |
errorMessage = getErrorMessage(error); | |
sheet.getRange(nextRow, 4).setValue(errorMessage); | |
sendText(LW_NORTIFY_USER, errorMessage); // 管理者にエラーを送信 | |
} | |
} | |
function getErrorMessage(error) { | |
return "[名前] " + error.name + "\n" + | |
"[場所] " + error.fileName + "(" + error.lineNumber + "行目)\n" + | |
"[メッセージ]" + error.message + "\n" + | |
"[StackTrace]\n" + error.stack; | |
} | |
/** | |
* テキスト送信 | |
*/ | |
function sendText(userId, talkMessage) { | |
if (talkMessage == '') { | |
return; | |
} | |
const content = { | |
"type": "text", | |
"text": talkMessage | |
}; | |
const options = { | |
'method': 'POST', | |
'headers': { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + getToken(), | |
}, | |
'payload': JSON.stringify({ | |
"accountId": userId, | |
"content": content | |
}), | |
'muteHttpExceptions': true, | |
}; | |
UrlFetchApp.fetch(`https://www.worksapis.com/v1.0/bots/${LW_BOT_ID}/users/${userId}/messages`, options); | |
} | |
// function testSendText() { | |
// sendText(nortifyUser, 'ほげ') | |
// } | |
function getJwt() { | |
const header = Utilities.base64Encode(JSON.stringify({ "alg": "RS256", "typ": "JWT" }), Utilities.Charset.UTF_8) | |
const claimSet = JSON.stringify({ | |
"iss": LW_CLIENT_ID, | |
"sub": LW_SERVICE_ACCOUNT, | |
"iat": Math.floor(Date.now() / 1000), | |
"exp": Math.floor(Date.now() / 1000 + 2000) | |
}) | |
const encodeText = header + "." + Utilities.base64Encode(claimSet, Utilities.Charset.UTF_8) | |
const signature = Utilities.computeRsaSha256Signature(encodeText, LW_PRIVATE_KEY) | |
return encodeText + "." + Utilities.base64Encode(signature) | |
} | |
// function testGetJwt() { | |
// console.log(getJwt()); | |
// } | |
function getToken() { | |
const uri = "https://auth.worksmobile.com/oauth2/v2.0/token" | |
const payload = { | |
"assertion": getJwt(), | |
"grant_type": encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer"), | |
"client_id": LW_CLIENT_ID, | |
"client_secret": LW_CLIENT_SECRET, | |
"scope": 'bot' | |
} | |
const options = { | |
"method": "post", | |
"headers": { "Content-Type": "application/x-www-form-urlencoded" }, | |
"payload": payload | |
} | |
return JSON.parse(UrlFetchApp.fetch(uri, options)).access_token; | |
} | |
// function testGetToken() { | |
// console.log(getToken()); | |
// } |
/** | |
* OpenGPT 設定 | |
*/ | |
const DALLE_MODEL = 'dall-e-3'; | |
const DALLE_MODEL_URL = "https://api.openai.com/v1/images/generations"; | |
const DALLE_MODEL_API_KEY = 'xxx' | |
const DALLE_MODEL_SIZE = '1024x1024'; | |
const DALLE_MODEL_NUMBER = 1; // 1しか指定できない | |
/** | |
* LINEWORKS 設定 | |
*/ | |
const LW_CLIENT_ID = "xxx"; | |
const LW_CLIENT_SECRET = "xxx"; | |
const LW_SERVICE_ACCOUNT = "xxx@xxx"; | |
const LW_PRIVATE_KEY = `-----BEGIN PRIVATE KEY----- | |
-----END PRIVATE KEY-----`; | |
const LW_BOT_ID = 0; | |
const LW_NORTIFY_USER = 'xxx@xxx'; | |
function callImagesGeneration(prompt) { | |
var options = { | |
"method": 'POST', | |
"headers": { | |
'Authorization': `Bearer ${DALLE_MODEL_API_KEY}`, | |
'Content-type': 'application/json', | |
}, | |
"payload": JSON.stringify({ | |
"model": DALLE_MODEL, | |
"prompt": prompt, | |
"n": DALLE_MODEL_NUMBER, | |
"size": DALLE_MODEL_SIZE, | |
"response_format": "url" | |
}), | |
muteHttpExceptions: true | |
} | |
var response = UrlFetchApp.fetch(DALLE_MODEL_URL, options); | |
var responseJson = response.getContentText(); | |
var responseData = JSON.parse(responseJson); | |
// Logger.log(responseData); | |
return responseData['data'] | |
} | |
// function testCallImagesGeneration() { | |
// var result = callImagesGeneration('NAIKIと文字の入ったロゴを作って。斧持ったモヒカンの侍のイラストをつけて') | |
// Logger.log(result); | |
// } | |
function overWriteCell() { | |
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); | |
const lastRow = sheet.getLastRow(); | |
var range = sheet.getRange("C3:C" + lastRow); | |
range.setValues(range.getValues()) | |
sheet.getSheetValues(3, 3, lastRow, 3); | |
} | |
/** | |
* Lineworksからのコールバック受付 | |
*/ | |
function doPost(e) { | |
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('log'); | |
const nextRow = sheet.getLastRow() + 1; | |
sheet.getRange(nextRow, 1).setValue(Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss')); | |
try { | |
const contents = JSON.parse(e.postData.contents); // json to dic | |
const userId = contents.source.userId; | |
sheet.getRange(nextRow, 2).setValue(userId); | |
const talkMessage = contents.content['text']; | |
sheet.getRange(nextRow, 3).setValue(talkMessage); | |
// sheet.getRange(nextRow, 5).setValue(e); | |
if (talkMessage == '利用開始') { | |
sendText(userId, `こんにちは、私は画像生成AIのDALL·Eを利用してイメージを生成するBotです。 | |
※1枚$0.04かかりますので、あまり呼び出し過ぎないようにしてください。 | |
※DALL·E3で生成された画像につきましては公式サイトにて商用利用可と記載がございますが、業務で利用する場合、上長や関連部署に確認の上、ご利用ください。 | |
※オリジナルサイズの画像は2時間だけしかダウンロードできないので、保存しておきたい画像は早めにダウンロードしてください。`); | |
return; | |
} | |
for (let i = 0; i < 4; i++) { | |
const openAIAPIMessage = callImagesGeneration(talkMessage); | |
sheet.getRange(nextRow, 4).setValue(openAIAPIMessage); | |
sendImages(userId, openAIAPIMessage); | |
} | |
} | |
catch (error) { | |
sendText(userId, '生成に失敗しました。'); | |
errorMessage = getErrorMessage(error); | |
sheet.getRange(nextRow, 4).setValue(errorMessage); | |
sendText(LW_NORTIFY_USER, errorMessage); // 管理者にエラーを送信 | |
} | |
} | |
function getErrorMessage(error) { | |
return "[名前] " + error.name + "\n" + | |
"[場所] " + error.fileName + "(" + error.lineNumber + "行目)\n" + | |
"[メッセージ]" + error.message + "\n" + | |
"[StackTrace]\n" + error.stack; | |
} | |
/** | |
* テキスト送信 | |
*/ | |
function sendImages(userId, dataArray) { | |
for (let data in dataArray) { | |
//取得したオブジェクトのキーをログ出力 | |
sendText(userId, dataArray[data]['url']) | |
sendImage(userId, dataArray[data]['url']) | |
} | |
} | |
// function testSendImages() { | |
// var results = callImagesGeneration('NAIKIと文字の入ったロゴを作って。斧持ったモヒカンの侍のイラストをつけて'); | |
// sendImages(LW_NORTIFY_USER, results); | |
// } | |
function sendImage(userId, url) { | |
const content = { | |
"type": "image", | |
"previewImageUrl": url, | |
"originalContentUrl": url | |
}; | |
const options = { | |
'method': 'POST', | |
'headers': { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + getToken(), | |
}, | |
'payload': JSON.stringify({ | |
"accountId": userId, | |
"content": content | |
}), | |
'muteHttpExceptions': true, | |
}; | |
UrlFetchApp.fetch(`https://www.worksapis.com/v1.0/bots/${LW_BOT_ID}/users/${userId}/messages`, options); | |
} | |
/** | |
* テキスト送信 | |
*/ | |
function sendText(userId, talkMessage) { | |
if (talkMessage == '') { | |
return; | |
} | |
const content = { | |
"type": "text", | |
"text": talkMessage | |
}; | |
const options = { | |
'method': 'POST', | |
'headers': { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + getToken(), | |
}, | |
'payload': JSON.stringify({ | |
"accountId": userId, | |
"content": content | |
}), | |
'muteHttpExceptions': true, | |
}; | |
UrlFetchApp.fetch(`https://www.worksapis.com/v1.0/bots/${LW_BOT_ID}/users/${userId}/messages`, options); | |
} | |
function getJwt() { | |
const header = Utilities.base64Encode(JSON.stringify({ "alg": "RS256", "typ": "JWT" }), Utilities.Charset.UTF_8) | |
const claimSet = JSON.stringify({ | |
"iss": LW_CLIENT_ID, | |
"sub": LW_SERVICE_ACCOUNT, | |
"iat": Math.floor(Date.now() / 1000), | |
"exp": Math.floor(Date.now() / 1000 + 2000) | |
}) | |
const encodeText = header + "." + Utilities.base64Encode(claimSet, Utilities.Charset.UTF_8) | |
const signature = Utilities.computeRsaSha256Signature(encodeText, LW_PRIVATE_KEY) | |
return encodeText + "." + Utilities.base64Encode(signature) | |
} | |
// function testGetJwt() { | |
// console.log(getJwt()); | |
// } | |
function getToken() { | |
const uri = "https://auth.worksmobile.com/oauth2/v2.0/token" | |
const payload = { | |
"assertion": getJwt(), | |
"grant_type": encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer"), | |
"client_id": LW_CLIENT_ID, | |
"client_secret": LW_CLIENT_SECRET, | |
"scope": 'bot' | |
} | |
const options = { | |
"method": "post", | |
"headers": { "Content-Type": "application/x-www-form-urlencoded" }, | |
"payload": payload | |
} | |
return JSON.parse(UrlFetchApp.fetch(uri, options)).access_token; | |
} | |
// function testGetToken() { | |
// console.log(getToken()); | |
// } |
/** | |
* OpenGPT 設定 | |
*/ | |
const GPT4V_MODEL = 'gpt-4-vision-preview'; | |
const GPT4V_MODEL_URL = "https://api.openai.com/v1/chat/completions"; | |
const GPT4V_MODEL_API_KEY = 'xxx' | |
const GPT4V_PROMPT = 'この画像になにが書いてあるか教えて'; | |
/** | |
* LINEWORKS 設定 | |
*/ | |
const LW_CLIENT_ID = "xxx"; | |
const LW_CLIENT_SECRET = "xxx"; | |
const LW_SERVICE_ACCOUNT = "xxx@xxx"; | |
const LW_PRIVATE_KEY = `-----BEGIN PRIVATE KEY----- | |
-----END PRIVATE KEY-----`; | |
const LW_BOT_ID = 0; | |
const LW_NORTIFY_USER = 'xxx@xxx'; | |
function overWriteCell() { | |
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); | |
const lastRow = sheet.getLastRow(); | |
var range = sheet.getRange("C3:C" + lastRow); | |
range.setValues(range.getValues()) | |
sheet.getSheetValues(3, 3, lastRow, 3); | |
} | |
/** | |
* Lineworksからのコールバック受付 | |
*/ | |
function doPost(e) { | |
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('log'); | |
const nextRow = sheet.getLastRow() + 1; | |
sheet.getRange(nextRow, 1).setValue(Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy/MM/dd HH:mm:ss')); | |
try { | |
const contents = JSON.parse(e.postData.contents); // json to dic | |
const userId = contents.source.userId; | |
sheet.getRange(nextRow, 2).setValue(userId); | |
sheet.getRange(nextRow, 3).setValue(contents); | |
if ('text' == contents.content.type) { | |
// テキストの場合 | |
const talkMessage = contents.content['text']; | |
if (talkMessage == '利用開始') { | |
sendText(userId, `こんにちは、私はGPT-4Visionを使って画像を解析するBotです。 | |
メッセージを打ち込むとプロンプトが置き換わります。 | |
最初は「${GPT4V_PROMPT}」が設定されています。`); | |
setVisionPrompt(userId, GPT4V_PROMPT); | |
return; | |
} | |
setVisionPrompt(userId, talkMessage); | |
const prompt = getVisionPrompt(userId); | |
sendText(userId, `「${prompt}」をプロンプトに設定しました`); | |
sheet.getRange(nextRow, 3).setValue(talkMessage); | |
return; | |
} | |
if ('image' == contents.content.type) { | |
const imageVision = getImageVison(contents.content.fileId, getVisionPrompt(userId)); | |
sendText(userId, imageVision); | |
sheet.getRange(nextRow, 4).setValue(imageVision); | |
} | |
} | |
catch (error) { | |
sendText(userId, '生成に失敗しました。'); | |
errorMessage = getErrorMessage(error); | |
sheet.getRange(nextRow, 4).setValue(errorMessage); | |
sendText(LW_NORTIFY_USER, errorMessage); // 管理者にエラーを送信 | |
} | |
} | |
/** | |
* ユーザごとのプロンプトを設定する | |
*/ | |
function setVisionPrompt(userId, visionPrompt) { | |
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('vpromt'); | |
var userColumn = sheet.getRange("A:A").getValues(); | |
var rowIndex = userColumn.findIndex(row => row[0] == userId) + 1; | |
if (rowIndex != 0) { | |
// ユーザIDが見つかった場合はその行のB列を上書き | |
sheet.getRange(rowIndex, 2).setValue(visionPrompt); | |
return; | |
} | |
sheet.appendRow([userId, visionPrompt]); | |
} | |
/** | |
* ユーザごとのプロンプトを取得する | |
*/ | |
function getVisionPrompt(userId) { | |
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('vpromt'); | |
var userColumn = sheet.getRange("A:A").getValues(); | |
var rowIndex = userColumn.findIndex(row => row[0] == userId) + 1; | |
if (rowIndex == 0) { | |
return GPT4V_PROMPT; | |
} | |
// 行インデックスのB列の値を取得 | |
var visionPrompt = sheet.getRange(rowIndex, 2).getValue(); | |
return visionPrompt; | |
} | |
function getImageVison(fileId, prompt) { | |
let image = UrlFetchApp.fetch(`https://www.worksapis.com/v1.0/bots/${LW_BOT_ID}/attachments/${fileId}`, { | |
"headers": { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + getToken(), | |
}, | |
"method": "get" | |
}); | |
let imageData = image.getContent(); | |
let base64Image = Utilities.base64Encode(imageData); | |
return callOpenAiApi(base64Image, prompt); | |
} | |
function callOpenAiApi(base64Image, prompt) { | |
let options = { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + GPT4V_MODEL_API_KEY, | |
}, | |
payload: JSON.stringify({ | |
'model': GPT4V_MODEL, | |
'messages': [ | |
{ | |
'role': 'user', | |
'content': [ | |
{ | |
'type': 'text', | |
'text': prompt | |
}, | |
{ | |
'type': 'image_url', | |
'image_url': { | |
'url': "data:image/jpeg;base64," + base64Image | |
} | |
} | |
] | |
} | |
], | |
'max_tokens': 2000 // 返信の最大トークン数 | |
}) | |
}; | |
let response = UrlFetchApp.fetch(GPT4V_MODEL_URL, options); | |
let responseMessage = JSON.parse(response).choices[0].message.content | |
return responseMessage; | |
} | |
function getErrorMessage(error) { | |
return "[名前] " + error.name + "\n" + | |
"[場所] " + error.fileName + "(" + error.lineNumber + "行目)\n" + | |
"[メッセージ]" + error.message + "\n" + | |
"[StackTrace]\n" + error.stack; | |
} | |
/** | |
* テキスト送信 | |
*/ | |
function sendText(userId, talkMessage) { | |
if (talkMessage == '') { | |
return; | |
} | |
const content = { | |
"type": "text", | |
"text": talkMessage | |
}; | |
const options = { | |
'method': 'POST', | |
'headers': { | |
'Content-Type': 'application/json', | |
'Authorization': 'Bearer ' + getToken(), | |
}, | |
'payload': JSON.stringify({ | |
"accountId": userId, | |
"content": content | |
}), | |
'muteHttpExceptions': true, | |
}; | |
UrlFetchApp.fetch(`https://www.worksapis.com/v1.0/bots/${LW_BOT_ID}/users/${userId}/messages`, options); | |
} | |
function getJwt() { | |
const header = Utilities.base64Encode(JSON.stringify({ "alg": "RS256", "typ": "JWT" }), Utilities.Charset.UTF_8) | |
const claimSet = JSON.stringify({ | |
"iss": LW_CLIENT_ID, | |
"sub": LW_SERVICE_ACCOUNT, | |
"iat": Math.floor(Date.now() / 1000), | |
"exp": Math.floor(Date.now() / 1000 + 2000) | |
}) | |
const encodeText = header + "." + Utilities.base64Encode(claimSet, Utilities.Charset.UTF_8) | |
const signature = Utilities.computeRsaSha256Signature(encodeText, LW_PRIVATE_KEY) | |
return encodeText + "." + Utilities.base64Encode(signature) | |
} | |
// function testGetJwt() { | |
// console.log(getJwt()); | |
// } | |
function getToken() { | |
const uri = "https://auth.worksmobile.com/oauth2/v2.0/token" | |
const payload = { | |
"assertion": getJwt(), | |
"grant_type": encodeURIComponent("urn:ietf:params:oauth:grant-type:jwt-bearer"), | |
"client_id": LW_CLIENT_ID, | |
"client_secret": LW_CLIENT_SECRET, | |
"scope": 'bot' | |
} | |
const options = { | |
"method": "post", | |
"headers": { "Content-Type": "application/x-www-form-urlencoded" }, | |
"payload": payload | |
} | |
return JSON.parse(UrlFetchApp.fetch(uri, options)).access_token; | |
} | |
// function testGetToken() { | |
// console.log(getToken()); | |
// } |