はじめに
- 読みやすさ重視のため、本文におじさん構文は登場しません。期待された方には深くお詫び申し上げます。
- また、デモサイトやバックエンドに関することは後日別記事にしようと思います。
- 前提知識 => JavaScriptのみ(!)
- 記事中に登場するコードは、axiosとfsが動くnode環境ならコピペで実行可能です。COTOHAの気軽さをお試しください。
- 筆者は趣味でコードを書く大学生です。動けばいいやの精神が強いのですが、ITの世界に進むならこれじゃあかんやろと思っているので、コードにとどまらずいろいろご指摘くだされば幸いです。
- ソースコード
おじさんと一緒に考えよう
普通の文章を入れたらその内容がおじさん構文になったらおもしろくね?
ということでCOTOHA APIのみを使ってデモページを作ってみました。
注意したこと・開発動機
COTOHA APIの記事はキャンペーンの影響で数多作成されており、この記事もその例外ではありません。しかし、「COTOHA API だけで言語を処理する」記事はあまり見当たりませんでした。僕自身が自然言語処理に全く知識がなく、また、pythonを使うことができない(jsで書いています)ため、他のライブラリを使うことができませんでした。なにより僕の頭の中では
そもそもCOTOHA APIって、僕みたいになにも知らなくても簡単気楽に実装できるところがいいんじゃないの?
という気持ちが強くありました。そういうわけで、この記事ではJavaScriptさえ読めれば誰でもわかることを目指し、自然言語処理に関わることはCOTOHA API以外のライブラリ、APIなどは使わずに実装しました。読者対象は「なんとなく興味を持っているけれど」の層です。難しい話はなしです。他のライブラリと合わせることでより真価を引き出し素晴らしいプロダクトを開発されている方は他にたくさんいらっしゃいますので、この記事で興味を持たれた方はぜひそちらもご覧ください。
開発動機は純粋にプレゼントほしいぃという気持ちもありつつ、最近僕の中で話題だった、おじさん構文を作れるかもしれない!とリファレンスを読みながら思ったからです。プロダクトは未完成ですが、雰囲気を楽しんでいただけたらなと思います。
3/15 22時追記 ほぼ完成しました。
デモサイト
使い方
- COTOHA APIの利用登録を済ませ、Client ID とClient secretを取得する
- デモページにてIDとsecretを入力し、「Access Tokenを取得」を押下
- 「アクセストークンの取得に成功しました!」が表示されたら、おじさん構文にしたい文書を入力して「おじさん構文化」を押下
- おじさん
構成
最初はウェブページ上にすべての機能を実装してやろうと考えていたのですが、Cross-Origin Resource Sharing (CORS)に引っかかるじゃん!ということで、いったんGoogle Cloud Platformのfunctionに情報を渡して結果をフロントに表示する構成にしています。 このせいでClient IDやsecretをHTTP通信してますやべー
おじさん構文化の仕組み
本記事のメインです。
そもそもおじさん構文って?
実際に存在しているおじさん構文を見たことがないため、Twitterなどで見かける「私たちがおじさん構文と認識するもの」をおじさん構文として定義し、これを再現することを目標とします。
高校の友達に、いま某外国語学科に所属している変態言語オタクがいたので、「おじさん構文を自動作成しようと思うんだけど、定式化できないかな」と相談したところ、以下のレポートを頂戴しました。言語系に進んでいらっしゃる方は、筆者デアショコがフィードバックが欲しいということでしたので、コメント欄にてよろしくお願いします。
「おじさん構文解析」全文展開
そうそう❗️❗️昨日も話したけど、Aちゃんと今度ゴルフ行きたいな❗️❗️⛳😝クルマはおじさんのアウディ🚐✨で行こうね😍💕
あとあと❗️❗️今月のハワイ旅行✈✨だけど、25日(月)に出て、30日(土)に戻ってくるで大丈夫かな❓❓😝
海にも入るから水着も忘れないでね😍💕オジサン、ウルフギャングも予約しちゃいまーす❗️😘Aちゃんは来てくれるだけでOK牧場だよ❗️❗️🐮💕
(笑)よろしくね❗️❗️😝✨
具体例2
ベイビーちゃんおはよう☀
昨日マック🍔食べたいけど、ダイエット中だから我慢😅して、おにぎり🍙にしたよ~❗️❗️褒めて~😊✨
でも、その後おにぎり🍙食べたこと忘れて、ビッグマック🍔のLセット食べちゃった💧
アンビリーバブルだよ~~😔ベイビーちゃんに会えないから。ボケちゃったのかも❗️❓
来週一緒にマック🍔行こうね💕クーポン券🎫あるから、ポテトL奢ってあげるよ✌
聖母マリアのような優しい笑み😊が恋しくて、毎日恋ダンス踊ってるよ👐
世界で一番愛してる。
ギュッ💕
その1:最初の挨拶
呼びかけから入るが、その際、相手を「ちゃん付け」する傾向が認められる。名前にちゃん付けするか、そのままあだ名的に呼ぶなどの揺れは認められる。テンプレ化を目指すのならば、「ベイビーちゃん」に統一するのも一つの手と思われる。
その2:文末
文末に付く「!」は、基本的に二つ付く傾向が認められる。これは具体例1に特に顕著である。具体例2においても、語尾の「!」が二つ付いているのが散見される。また、文章の内容や発話者の感情に応じて、顔文字が使い分けられているのが確認できる。これは「おじさん構文」に限らず普通の発話においても見られる特徴だが、その顔文字がほぼ全文にあり、多用されているという点が「おじさん構文」の特徴と考えられる。具体例2に見られる面白い特徴として挙げられるのが、文末では無く、名詞の後に顔文字が使用されている点である。具体例2の「~ダイエット中だから我慢😅して、~」がその例である。これまで、普通名詞の後にその名詞を表す絵文字が使用されるのは指摘されてきた。今回の例は、普通名詞というよりは、発話者の感情を表すものであると言える。我慢をすることに対する発話者のネガティブな感情が顔文字😅に現れている。単なる名詞の具現化だけでなく、聞いてもいない感情を自ら表しにきているところが、「おじさん構文」らしさの1つと、ここから言える。無論、感情を顔文字の使用により表すのはごく自然なことだが、
・その多用
・名詞の直後に持ってくることによるその感情の強調
が、普通の文章と「おじさん構文」の違いだと考えることができる。
その3:✨と💕の使用の区別の仕方
相手に対して誘いや依頼をする際は、💕が使用されることが多いと考えられる。これは、お願いする相手(おそらく女性)に対する好意を明確に示すものだと思われる。
・具体例1:クルマはおじさんのアウディ🚐✨で行こうね😍💕(勧誘)
・具体例2:来週一緒にマック🍔行こうね💕(勧誘)
・具体例1:海にも入るから水着も忘れないでね😍💕(依頼)
対して、✨は、単純な感情の高まりとそれによる事柄の強調、もしくは、自分自身のことを強調する際に使用されると思われる。
・具体例1:今月のハワイ旅行✈✨だけど、(強調)
・具体例1:よろしくね❗️❗️😝✨(強調的)
・具体例2:褒めて~😊✨(自身の強調)
3. 以上のルールを踏まえた上での、「おじさん構文」化
例1
「コーディングが楽しくてやめられないけど、ひたすら眠くて仕方ないジレンマ」
→「コーディング(?)が楽しくて😁やめられない😂けど、ひたすら眠くて😪仕方ないジレンマ😅💧」
解説
本来はコーディングの後に何かしらコーディングを表す絵文字が欲しかったが見つけることができなかったため割愛。今回は「楽しくて」「やめられない」「眠くて」「ジレンマ」等、発話者の感情を表す単語が多い。ポイントは「やめられない」と「ジレンマ」の箇所である。今回の「やめられない」は、直前の「楽しくて」から推測されるようにネガティブな意味では無いと思われるため、泣き笑いの表情を選択した。「ジレンマ」の箇所については、ジレンマは、『眠ることができず、困っている』という意味で使用されていることが明白なため、その『困っている』発話者の感情を表現するため、汗をかいている顔文字と、汗の絵文字を使用した。
例2
「図書館でいろんな本を借りてたけど、これだけはどうしても欲しくなって買ってしまいました。これ一冊は必ず仕上げようと思います!」
→「図書館📚でいろんな本📙を借りてた✨けど、これだけはどうしても😎欲しくなって😁買ってしまいました📖✨。これ一冊📙は必ず仕上げようと思います❗️ ❗️」
解説
今回は「本」というわかりやすい普通名詞の登場で、絵文字を置きやすくなった。「借りてた」の箇所に関しては、『いろんな本を借りる』という文言を『自分の行為の強調』と捉えたため、✨を置いた。「どうしても」の箇所は賛否あるとは思うが、『他は買わないがこれだけは買う』という意思を表すため含みのある😎を採用した。
4. まとめ
今回、様々な文章に対応しうる「おじさん構文」のルールをある程度見つけ出すことを目的に、「おじさん構文」の分析を行い、通常の文章を違和感のないおじさん構文に変換することを試みた。選択する顔文字や付け加えた絵文字に関してはまだまだ賛否や議論の余地があると思うので、その洗練は今後の課題としたい。
5.出典、資料
https://neetola.com/ojisan/
具体例として扱わせていただいた
https://twitter.com/gyozaisgood/status/1236355783090008064?s=21
https://twitter.com/gyozaisgood/status/1232326974636359680?s=21
「おじさん構文」化の例に使用させていただいた。
資料:今回使用した顔文字一覧
😊😢😂😅😍😌😝😘😁😪😎
普通名詞の絵文字に関しては省略した。
展開した文章はここまで、以下本文
要点は
- 名前をチャン呼びする
- 全文に顔文字
- 自身の感情を絵文字で表現
この三つになりそうです。ここから、文章への加工内容を考えると以下のようになりました。
- 文末にその文に対応した顔文字の付与
- 各名詞や特徴的な表現の後ろに、対応するEmojiの付与
- 人名が出た際、「チャン」付けする
この加工を以下で行っていきます。
1,渡された文章を文にする
ユーザーは文だけでなく、長い文章などを入力することが考えられます。この場合、文の文末に付与する絵文字が名詞の後ろに付与するものを除けば一つだけになってしまい、おじさん感がありません。そのため、与えられた文章を文に区切る必要があります。
文の区切りを判定するために、今回は「終助詞」を選びました。他にも適切なものがあればコメント欄で教えていただきたいです。この開発ではCOTOHA APIに依存することをテーマにしているので、終助詞判定も当然COTOHA APIにしてもらいます。この判定には「構文解析」APIを利用します。
/*コピペ前にすること
npm install fs axios
*/
const axios = require('axios')
const fs = require('fs')
class Cotoha{
constructor(sentence,cotoha_token){
this.sentence = sentence
this.cotoha_token = cotoha_token
}
client(){
const axiosConfig = axios.create({
headers:{
"Authorization": `Bearer ${this.cotoha_token}`,
"Content-Type": "application/json"
},
baseURL:"https://api.ce-cotoha.com/api/dev/nlp/v1",
});
return axiosConfig;
}
async parse(){
const axiosBase = await this.client();
try{
const res = await axiosBase.post("/parse",{"sentence":this.sentence})//parseが構文解析のリクエスト
const result = res.data.result;
return result
}catch(e){
console.log(e)
}
}
}
//cotoha_token(Access token)はデモサイトにて取得できます。Client IDとClient Secretを入力して
//ボタン押下してから、サイト下部のLogをご覧ください
const main = async () => {
const inputMsg = "今日のランチはハンバーガーだった、優美ちゃんはなんだった?"
const cotoha_token = "hogehogehogehoge"
const cotoha = new Cotoha(inputMsg, cotoha_token)
const outputMsg = await cotoha.parse()
fs.writeFile("./parse.json",JSON.stringify(outputMsg,null,"\t"),()=>{console.log("fs end")})
}
main()
/*実行コマンド
node .
*/
レスポンスは以下のようになっています。
parse.json※長い!!
[
{
"chunk_info": {
"id": 0,
"head": 1,
"dep": "D",
"chunk_head": 0,
"chunk_func": 1,
"links": []
},
"tokens": [
{
"id": 0,
"form": "今日",
"kana": "キョウ",
"lemma": "今日",
"pos": "名詞",
"features": [
"日時"
],
"dependency_labels": [
{
"token_id": 1,
"label": "case"
}
],
"attributes": {}
},
{
"id": 1,
"form": "の",
"kana": "ノ",
"lemma": "の",
"pos": "格助詞",
"features": [
"連体"
],
"attributes": {}
}
]
},
{
"chunk_info": {
"id": 1,
"head": 2,
"dep": "D",
"chunk_head": 0,
"chunk_func": 1,
"links": [
{
"link": 0,
"label": "adjectivals"
}
]
},
"tokens": [
{
"id": 2,
"form": "ランチ",
"kana": "ランチ",
"lemma": "ランチ",
"pos": "名詞",
"features": [],
"dependency_labels": [
{
"token_id": 0,
"label": "nmod"
},
{
"token_id": 3,
"label": "case"
}
],
"attributes": {}
},
{
"id": 3,
"form": "は",
"kana": "ハ",
"lemma": "は",
"pos": "連用助詞",
"features": [],
"attributes": {}
}
]
},
{
"chunk_info": {
"id": 2,
"head": 3,
"dep": "D",
"chunk_head": 0,
"chunk_func": 1,
"links": [
{
"link": 1,
"label": "agent"
}
],
"predicate": [
"past"
]
},
"tokens": [
{
"id": 4,
"form": "ハンバーガー",
"kana": "ハンバーガー",
"lemma": "ハンバーガー",
"pos": "名詞",
"features": [],
"dependency_labels": [
{
"token_id": 2,
"label": "nsubj"
},
{
"token_id": 5,
"label": "cop"
},
{
"token_id": 6,
"label": "punct"
}
],
"attributes": {}
},
{
"id": 5,
"form": "だった",
"kana": "ダッタ",
"lemma": "だった",
"pos": "判定詞",
"features": [
"連体"
],
"attributes": {}
},
{
"id": 6,
"form": "、",
"kana": "",
"lemma": "、",
"pos": "読点",
"features": [],
"attributes": {}
}
]
},
{
"chunk_info": {
"id": 3,
"head": 4,
"dep": "D",
"chunk_head": 1,
"chunk_func": 2,
"links": [
{
"link": 2,
"label": "adjectivals"
}
]
},
"tokens": [
{
"id": 7,
"form": "優美",
"kana": "ユミ",
"lemma": "優美",
"pos": "名詞",
"features": [
"名",
"固有"
],
"attributes": {}
},
{
"id": 8,
"form": "ちゃん",
"kana": "チャン",
"lemma": "ちゃん",
"pos": "名詞接尾辞",
"features": [
"名詞"
],
"dependency_labels": [
{
"token_id": 4,
"label": "acl"
},
{
"token_id": 7,
"label": "name"
},
{
"token_id": 9,
"label": "case"
}
],
"attributes": {}
},
{
"id": 9,
"form": "は",
"kana": "ハ",
"lemma": "は",
"pos": "連用助詞",
"features": [],
"attributes": {}
}
]
},
{
"chunk_info": {
"id": 4,
"head": -1,
"dep": "O",
"chunk_head": 0,
"chunk_func": 1,
"links": [
{
"link": 3,
"label": "aobject"
}
],
"predicate": [
"past"
]
},
"tokens": [
{
"id": 10,
"form": "なん",
"kana": "ナン",
"lemma": "何",
"pos": "名詞",
"features": [],
"dependency_labels": [
{
"token_id": 8,
"label": "nmod"
},
{
"token_id": 11,
"label": "cop"
},
{
"token_id": 12,
"label": "punct"
}
],
"attributes": {}
},
{
"id": 11,
"form": "だった",
"kana": "ダッタ",
"lemma": "だった",
"pos": "判定詞",
"features": [
"終止"
],
"attributes": {}
},
{
"id": 12,
"form": "?",
"kana": "",
"lemma": "?",
"pos": "句点",
"features": [
"疑問符"
],
"attributes": {}
}
]
}
]
( API一覧より)、その文がどんな文なのか調べるAPIがあるので、この結果をもとに顔文字を付け替えていきます。
/*コピペ前にすること
npm install fs axios
*/
const axios = require('axios')
const fs = require('fs')
class Cotoha{
constructor(sentence,cotoha_token){
this.sentence = sentence
this.cotoha_token = cotoha_token
}
client(){
const axiosConfig = axios.create({
headers:{
"Authorization": `Bearer ${this.cotoha_token}`,
"Content-Type": "application/json"
},
baseURL:"https://api.ce-cotoha.com/api/dev/nlp/v1",
});
return axiosConfig;
}
async sentenceType(){
const axiosBase = await this.client();
try{
const res = await axiosBase.post("/sentence_type",{
"sentence":this.sentence,
});
const result = res.data.result
return result
}catch(e){
console.log(e)
}
}
}
//cotoha_tokne(Access token)はデモサイトにて取得できます。Client IDとClient Secretを入力して
//ボタン押下してから、サイト下部のLogをご覧ください
const main = async () => {
const inputMsg = "今日のランチはハンバーガーだった、優美ちゃんはなんだった?"
const cotoha_token = "0oTUaaBrA5zALXOGyxxnkcgxAhVH"
const cotoha = new Cotoha(inputMsg, cotoha_token)
const outputMsg = await cotoha.sentenceType()
fs.writeFile("./sentenceType.json",JSON.stringify(outputMsg,null,"\t"),()=>{console.log("fs end")})
}
main()
/*実行コマンド
node .
*/
{
"modality": "interrogative",
"dialog_act": [
"information-seeking"
]
}
modalityは投げた文が「叙述」「質問」「命令」の3つのどれかかを判別した結果を返してくれます。dialog_actは投げた文のタイプをより詳細に判別した結果を返してくれます。今回はdialog_actの結果を利用します。
返り値 | 日本語説明 | Emoji |
---|---|---|
greeting | 挨拶 | 😘 |
information-providing | 情報提供 | ❗❗ |
feedback | フィードバック/相槌 | 😓 |
information-seeking | 情報獲得 | 🤔 |
agreement | 同意 | 🥰 |
feedbackElicitation | 理解確認 | 😏 |
commissive | 約束 | 😘 |
acceptOffer | 受領 | 🤩 |
selfCorrection | 言い直し | 😁 |
thanking | 感謝 | 😘 💕 |
apology | 謝罪 | 🥺 |
stalling | 時間埋め | 😧 |
directive | 指示 | 😤 |
goodbye | 挨拶(別れ) | 😚 |
declineOffer | 否認 | 😦 |
turnAssign | ターン譲渡 | 😄 |
pausing | 中断 | ✋ |
acceptApology | 謝罪受領 | 😍 |
acceptThanking | 感謝受領 | 🥰 |
このどれかが返ってくるので、対応するEmoji(上記Emoji列)を文末に付与します。 |
##3,名詞の後ろにいい感じのEmojiを付与
文末に絵文字を付与しただけでは、おじさん感がありません。文中いたるところに絵文字を付与して、よりおじさんに近づきましょう。構文解析の結果は品詞分解されているため、適当な名詞の後ろに適当な絵文字を付与すればいいおじさんになれそうですが、この「適当な絵文字」をそれぞれの名詞につけるのは自然言語処理の力がないとできそうにありません。
COTOHA APIには「固有表現抽出」というAPIがあり、これを使って文中の名詞の判定とどんな名詞なのかを調べようと思います。
/*コピペ前にすること
npm install fs axios
*/
const axios = require('axios')
const fs = require('fs')
class Cotoha{
constructor(sentence,cotoha_token){
this.sentence = sentence
this.cotoha_token = cotoha_token
}
client(){
const axiosConfig = axios.create({
headers:{
"Authorization": `Bearer ${this.cotoha_token}`,
"Content-Type": "application/json"
},
baseURL:"https://api.ce-cotoha.com/api/dev/nlp/v1",
});
return axiosConfig;
}
async unique(){
const axiosBase = await this.client();
try{
const res = await axiosBase.post("/ne",{
"sentence":this.sentence
})
await fs.writeFile("./output/unique.json",JSON.stringify(res.data,null,"\t"));
const result = res.data.result;
return result
}catch(e){
return e
}
}
}
//cotoha_tokne(Access token)はデモサイトにて取得できます。Client IDとClient Secretを入力して
//ボタン押下してから、サイト下部のLogをご覧ください
const main = async () => {
const inputMsg = "今日のランチはハンバーガーだった、優美ちゃんはなんだった?"
const cotoha_token = "hogehoge"
const cotoha = new Cotoha(inputMsg, cotoha_token)
const outputMsg = await cotoha.unique()
fs.writeFile("./unique.json",JSON.stringify(outputMsg,null,"\t"),()=>{console.log("fs end")})
}
main()
/*実行コマンド
node .
*/
[
{
"begin_pos": 0,
"end_pos": 2,
"form": "今日",
"std_form": "今日",
"class": "DAT",
"extended_class": "",
"source": "basic"
},
{
"begin_pos": 17,
"end_pos": 19,
"form": "優美",
"std_form": "優美",
"class": "PSN",
"extended_class": "",
"source": "basic"
},
{
"begin_pos": 3,
"end_pos": 6,
"form": "ランチ",
"std_form": "ランチ",
"class": "ART",
"extended_class": "Dish",
"source": "basic"
},
{
"begin_pos": 7,
"end_pos": 13,
"form": "ハンバーガー",
"std_form": "ハンバーガー",
"class": "ART",
"extended_class": "Dish",
"source": "basic"
},
{
"begin_pos": 19,
"end_pos": 22,
"form": "ちゃん",
"std_form": "ちゃん",
"class": "ART",
"extended_class": "Title_Other",
"source": "basic"
}
]
返り値の"extended_class"は、対象の語が「人」「食べ物」「神」「島名」などを数多くの選択肢(100以上)からどれに類するかを返してくれます。(割り当てがないものもあります。上記例だと「今日」は"extended_class"がありません)
あとは返ってきた値に対してあらかじめ決めておいたEmojiを付与します。
・
・
・
100以上の項目に対応する絵文字を決めるのが途方もなさすぎるので、一旦リリースすることにいたしました...絶賛絵文字付与中です。
4,実行結果
入力文
今日のランチはハンバーガーだったよ、優美ちゃんはなんだった?
出力文(2020年3月15日、名詞後置修飾未実装)
今日のランチはハンバーガーだったよ🤔優美ちゃんはなんだった?🤔
理想の出力文(名詞後置修飾完全実装後)
今日のランチはハンバーガーだったよ🤔優美チャンはなんだった?🤔
(ランチもハンバーガーもdishのため、同じ絵文字の予定
終わりに
感想
名詞に対して自分でEmojiを選ぶのが非常にめんどうでした。これは人工知能やAIだとかいうのを使えばいいのか、はたまた今回僕が作ったものも人工知能の一角なのか...難しい世界です。
難しい世界ですが、今回のプロダクトを作るのは非常に簡単でした。リファレンスも日本語で簡潔だし、リクエスト文も簡単、レスポンスも明確、いいことずくめでした。 むしろasync/awaitの非同期に手こずりました IDやsecretをユーザーに依存しないサービスにしようとすると月10万円のCOTOHAの利用料が飛ぶのでできそうにありませんが、エンジニア専用だったり利用数の少ないサービスならいろいろ面白いことができそうなので、挑戦してみようと思いました。
実装方法については後日記事にする予定ですので、もしよろしければご覧ください。
Special Thanks
高校の同級生、デアショコ君には定式化、もとい、僕のやりたいことをコードに落とすプロセスを手伝ってもらっただけでなく、絵文字選定のお手伝いまでしてくれて...本当に助かりました。ありがとう。賞がもらえて退院したら焼き肉行こう。
コード
index.js全文
/*コピペ前にすること
npm install fs axios
*/
const axios = require('axios')
const fs = require('fs')
class Cotoha{
constructor(sentence,cotoha_token){
this.sentence = sentence
this.cotoha_token = cotoha_token
}
client(){
const axiosConfig = axios.create({
headers:{
"Authorization": `Bearer ${this.cotoha_token}`,
"Content-Type": "application/json"
},
baseURL:"https://api.ce-cotoha.com/api/dev/nlp/v1",
});
return axiosConfig;
}
async parse(){
const axiosBase = await this.client();
try{
const res = await axiosBase.post("/parse",{"sentence":this.sentence})//parseが構文解析のリクエスト
const result = res.data.result;
return result
}catch(e){
console.log(e)
}
}
async sentenceType(){
const axiosBase = await this.client();
try{
const res = await axiosBase.post("/sentence_type",{
"sentence":this.sentence,
});
const result = res.data.result
return result
}catch(e){
console.log(e)
}
}
async unique(){
const axiosBase = await this.client();
try{
const res = await axiosBase.post("/ne",{
"sentence":this.sentence
})
const result = res.data.result;
//console.log(result)
return result
}catch(e){
return e
}
}
}
/*
cotoha_tokne(Access token)はデモサイトにて取得できます。Client IDとClient Secretを入力して
ボタン押下してから、サイト下部のLogをご覧ください
*/
const main = async () => {
const inputMsg = "今日のランチはハンバーガーだった、優美ちゃんはなんだった?"
const cotoha_token = "hogehoge"
const cotoha = new Cotoha(inputMsg, cotoha_token)
const outputMsg = await cotoha.unique()//すきなメソッドを選らんで実行してください。
fs.writeFile("./output.json",JSON.stringify(outputMsg,null,"\t"),()=>{console.log("fs end")})
}
main()
/*実行コマンド
node .
*/