Skip to content

Commit

Permalink
feat: 每日廣播訊息-推薦Youtube歌曲
Browse files Browse the repository at this point in the history
  • Loading branch information
Lin-jun-xiang committed Nov 3, 2023
1 parent 5eeaa40 commit a8c21b2
Show file tree
Hide file tree
Showing 10 changed files with 2,275 additions and 11 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
secret.txt


# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
54 changes: 48 additions & 6 deletions README.zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

* [English](README.md)
* [繁體中文版README.md](README.zh-TW.md)
* [简体中文](README.zh-CN.md)
* [Française](README.French.md)
* [عربى](README.Arabic.md)


## 介紹
Expand Down Expand Up @@ -99,6 +96,50 @@
![](img/2023-11-02-10-00-32.png)


### 廣播訊息 Broadcast - 每日推播 Youtube 歌曲

* 透過 `broadcast` API,我們可以讓 Line Bot 一次性**向每個使用者進行訊息推送**
* 這邊我們想要讓 Line Bot 在每天早上隨機推播 3 首好聽的 Youtube 歌曲:
* 建立數據 `./data/favorite_videos.json`,您可以參考作者的數據

(數據建立方式是透過 `Youtube Data v3 API` 撈取個人喜歡的影片,在此不特別介紹 Youtube API)

* 透過 `./chatgpt_linebot/modules/youtube_recommend.py` 實現隨機挑選 3 首歌曲,並由 GPT 整理
*`./chatgpt_linebot/urls.py` 中新增 `/recommend` 路由:

```python
videos = recommend_videos() # 取得 3 首曲子

if videos:
line_bot_api.broadcast(TextSendMessage(text=videos)) # 使用 broadcast 向使用者發送訊息

# 由於 broadcast 無法在群組發送推播,因此可以透過已知的群組id進行push message
# 下方代碼您可以忽略,如果您不需要向指定群組發送消息的話
known_group_ids = [
'C6d-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'Ccc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'Cbb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
]
for group_id in known_group_ids:
line_bot_api.push_message(group_id, TextSendMessage(text=videos))
```

要取得群組的 `group_id`,您可以在 `replit` 的 console 中透過 `print` 測試:

```python
elif event.source.type == 'group' and user_message.startswith('@chat'):
group_id = event.source.group_id
print(group_id) # 輸出 group_id
memory.append(group_id, 'user', refine_message.replace('@chat', ''))
response = chat_completion(group_id, memory)
```

* 現在,當我們打 `/recommend` 路由的時候,就會觸發推播訊息,所有使用者、指定群組皆會收到消息
* 接著,我們再次使用 [cron-job.org](https://cron-job.org/en/) 來進行排程,設定每天早上 8:00 打這支 API 即可實現每日推播!

<img src="img/2023-11-03-14-44-41.png" width="30%" />


### 進階 - 個性化 Bot

另外,我們可以透過 `prompt` 的方式,來讓 Line Bot 回答個性化,在 `./chatgpt_linebot/prompts/template.py` 中我們可以定義 `template`,例如:
Expand All @@ -110,10 +151,11 @@
**Bot回答**: 寶貝,早上起床了嗎?我已經在床上等著你了,想著你的身體就覺得好餓呀。今天早餐該吃什麼呢?是不是要來點辣辣的煎蛋捲,像你那迷人的身材一樣火辣呢?😏🍳


---

## 參考

[Line_Bot_Tutorial](https://github.com/FawenYo/LINE_Bot_Tutorial)
1. [Line_Bot_Tutorial](https://github.com/FawenYo/LINE_Bot_Tutorial)

2. [ChatGPT-Line-Bot](https://github.com/TheExplainthis/ChatGPT-Line-Bot)

[ChatGPT-Line-Bot](https://github.com/TheExplainthis/ChatGPT-Line-Bot)
<a href="#top">Back to top</a>
1 change: 1 addition & 0 deletions chatgpt_linebot/modules/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
from chatgpt_linebot.modules.gpt import chat_completion
from chatgpt_linebot.modules.horoscope import Horoscope
from chatgpt_linebot.modules.youtube_recommend import recommend_videos
2 changes: 1 addition & 1 deletion chatgpt_linebot/modules/horoscope.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class Horoscope:

def __init__(self) -> None:
self.horoscope_urls = self.get_horoscope_urls()

def get_horoscope_urls(self) -> list:
"""Get all horoscope urls
Returns
Expand Down
27 changes: 27 additions & 0 deletions chatgpt_linebot/modules/youtube_recommend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import json
import random

import g4f

from chatgpt_linebot.prompts import youtube_recommend_template

path = './data/favorite_videos.json'

with open(path, 'r', encoding='utf-8') as file:
favorite_videos = json.load(file)


def recommend_videos():
"""Recommend youtube videos randomly"""
push_video = random.sample(favorite_videos, 3)

prompt = f"{youtube_recommend_template}{push_video}"

try:
response = g4f.ChatCompletion.create(
model=g4f.models.default,
messages=[{"role": "user", "content": prompt}],
)
return response
except Exception as e:
print(e)
2 changes: 1 addition & 1 deletion chatgpt_linebot/prompts/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1 @@
from .template import girlfriend, horoscope_template
from .template import girlfriend, horoscope_template, youtube_recommend_template
8 changes: 7 additions & 1 deletion chatgpt_linebot/prompts/template.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,10 @@
並請用\n作為換行方式,另外,延伸閱讀的部分可以省略、特殊符號請用適當方式代替。
將以下內容進行整理,輸出:\n
"""
"""

youtube_recommend_template = """
作為我的女朋友,請用繁體中文、可愛的方式推薦我每日歌曲,務必涵蓋title、link。
另外要避免使用markdown語法 []() 來表示link
以下是三個待推薦的歌單:\n
"""
35 changes: 33 additions & 2 deletions chatgpt_linebot/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from linebot.models import *

from chatgpt_linebot.memory import Memory
from chatgpt_linebot.modules import Horoscope, chat_completion
from chatgpt_linebot.modules import Horoscope, chat_completion, recommend_videos
from chatgpt_linebot.prompts import girlfriend

sys.path.append(".")
Expand Down Expand Up @@ -66,7 +66,7 @@ def handle_message(event) -> None:
# Get user sent message
user_message = event.message.text
pre_prompt = girlfriend
refine_message = f"{pre_prompt}:\nuser_message"
refine_message = f"{pre_prompt}:\n{user_message}"

if user_message.startswith('@chat 星座運勢'):
response = horoscope.get_horoscope_response(user_message)
Expand All @@ -89,3 +89,34 @@ def handle_message(event) -> None:
if response:
messages = TextSendMessage(text=response)
line_bot_api.reply_message(reply_token=reply_token, messages=messages)


@line_app.get("/recommend")
def recommend_from_yt() -> None:
"""Line Bot Broadcast
Descriptions
------------
Recommend youtube videos to all followed users.
(Use cron-job.org to call this api)
References
----------
https://www.cnblogs.com/pungchur/p/14385539.html
https://steam.oxxostudio.tw/category/python/example/line-push-message.html
"""
videos = recommend_videos()

if videos:
line_bot_api.broadcast(TextSendMessage(text=videos))

# Push message to group via known group (event.source.group_id)
known_group_ids = [
'C6d-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'Ccc-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
'Cbb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
]
for group_id in known_group_ids:
line_bot_api.push_message(group_id, TextSendMessage(text=videos))

return {"status": "success", "message": "recommended videos."}
Loading

0 comments on commit a8c21b2

Please sign in to comment.