Satan:如何做一个嘟嘟中转站

缪尚咖啡馆快闪活动:撒旦老人关心您!帮您传递悄悄话并接收您的愿望!

Summary

不好意思直说的心意,撒旦老人帮您转达。
无法自己言说的心愿,撒旦老人帮您一键广播。
撒旦老人为圣诞节、新年快闪活动,活动时间为 22.12.15 - 23.02.05。活动结束后将清空账号内容,请自行保存您发送或收到的内容。

使用

由于撒旦老人背后灵懒得写容错性健壮性强的代码,请大家联系撒旦老人时严格遵循以下格式:
如果您想讲悄悄话:

1
2
3
4
5
6
@Satan # 向撒旦老人发送私信
悄悄话 # 表达心意关键词
向谁说: # 对方账号,包括实例部分但不需要第一个'@'符号
内容: # 一行,即这一部分不要换行,写完再敲回车
匿名:是或否,默认匿名
可见度:[private, public, unlisted, direct] 四选一

示例

1
2
3
4
5
6
@Satan
悄悄话
向谁说:Satan@musain.cafe
内容:Do you hear the Santa sing?
匿名:是
可见度:direct

如果您想许愿:

1
2
3
4
5
@Satan # 向撒旦老人发送私信
许愿 # 表达心愿关键词
愿望:# 一行内,写完再敲回车
匿名:是或否,默认匿名
可见度:[private, public, unlisted] 三选一

示例

1
2
3
4
5
@Satan
许愿
愿望:Beyond the barricade, there is a world we long to see.
匿名:否
可见度:unlisted

创造一个撒旦老人需要什么准备

注册账号

在缪尚新注册一个账号:@Satan@musain.cafe,修改基本资料,注意选中 “这是一个 bot 账号 / This is a bot account”。
在管理面板找到 开发/Development-创建新应用/New Application,创建新应用并给予读写权限,复制访问令牌。

安装 Mastodon.py

安装 miniconda3:

1
2
3
4
5
6
mkdir miniconda
cd miniconda

# 下载 python 最新版本并用 bash 安装
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh
sh Miniconda3-latest-Linux-x86_64.sh //用bash安装

通过 pip 安装 Mastodon.py:

1
2
3
4
5
pip3 install requests beautifulsoup4 Mastodon.py # 安装mastodon.py
mkdir satan
cd satan
nano mybot_usercred.secret # 写入刚才复制的访问令牌,保存退出
nano satan.py # 发嘟脚本

最新 mastodon.py 已经更新至1.8.0 (最新版本查询:mastodon.py release),代码结构有较大变动。但由于之前写 DOGchan 和 CATsama 已经安装过 mastodon.py,satan 仍使用之前下载的版本 1.5.1 ( 代码下载 )。

撒旦本体

因为不想仔细写代码,所以对用户发嘟的要求较高,每一步代码也都是默认用户会按照要求向撒旦老人发私信来写的,每一步处理都简单粗暴。如果明年还会有这个快闪活动,或许会修改代码,提高容错和健壮性。

提取嘟文主体

代码基本与 DOGchan 时参考的代码一致,但删减了部分不需要的修改,最终使用版本如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def extract_toot(toot):
toot = toot.replace("'", "'") #convert HTML stuff to normal stuff
toot = toot.replace(""", '"') #ditto
soup = BeautifulSoup(toot, "html.parser")
for lb in soup.select("br"): #replace <br> with linebreak
lb.insert_after("\n")
lb.decompose()
for p in soup.select("p"): #ditto for <p>
p.insert_after("\n")
p.unwrap()
for ht in soup.select("a.hashtag"): #make hashtags no longer links, just text
ht.unwrap()
text = soup.get_text()
text = text.rstrip("\n") #remove trailing newline
return text

利用 extract_toot 提取嘟文内容将只剩下需要处理判断的部分,后续只需要根据关键词送入不同的 if 处理文本。
上述两个例子处理后的文本如下:

1
2
@Satan\n悄悄话\n向谁说:Satan@musain.cafe\n内容:Do you hear the Santa sing?\n匿名:是\n可见度:direct
@Satan\n许愿\n愿望:Beyond the barricade, there is a world we long to see.\n匿名:否\n可见度:unlisted

许愿

许愿主要实现投稿愿望,Satan 账号根据投稿时标注的相关要求,将心愿发布。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if pattern2.search(mention_text):
print("Wish!")
mention_text_temp = mention_text.split('\n')
mention_text_len = len(mention_text_temp)
mention_text = mention_text_temp[(mention_text_len-3):]
wish_text = mention_text[0].split(':')[1]
anonymous_if = mention_text[1].split(':')[1].lower() == ('否' or 'no')
to_visibility = mention_text[2].split(':')[1]
if anonymous_if:
content = wish_text + '\n 来自 ' + acct + ' '
else:
content = wish_text
mastodon.status_post(
status = content,
visibility=to_visibility
)

悄悄话

悄悄话主要实现根据投稿人提供的悄悄话内容和其它范围要求,将悄悄话转发给投稿人希望的用户。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
if pattern1.search(mention_text):
print("Whisper!")
mention_text_temp = mention_text.split('\n')
mention_text_len = len(mention_text_temp)
mention_text = mention_text_temp[(mention_text_len-4):]
to_account_id = '@' + mention_text[0].split(':')[1]
whisper_text = mention_text[1].split(':')[1]
anonymous_if = mention_text[2].split(':')[1].lower() == ('否' or 'no')
to_visibility = mention_text[3].split(':')[1]
if anonymous_if:
content = to_account_id + ' \n' + whisper_text + '\n 来自' + acct + ' '
else:
content = to_account_id + ' \n' + whisper_text
mastodon.status_post(
status = content,
visibility = to_visibility
)

Reference

Satan 的代码部分来源于 mastodon-bot-template,并参考了 mstdn-ebooks 和 Mastodon.py。
Mastodon.py: Docs , GitHub
mastodon-bot-template: reply.py
mstdn-ebooks: reply.py

功能与自动回复的汪汪相差不大,所以参考仍然是上次写汪汪时的参考。