search
LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.

More than 5 years have passed since last update.

posted at

updated at

friends.nicoでのBotの運用、実態について☕

みなさん、本日も楽しいMastodonライフをお過ごしでしょうか☕

キャラ セリフ
チノ おはようございます。
香風智乃です。
マヤ おっはよーー!!
条河麻耶だよ♪♪♪
メグ おはよ~、奈津恵だよ~✿
チノ 今回はnico.friends Advent Calendar 2017にて、25日を過ぎてなお記事が登録されてない未投稿の方の席をぶん取ってれいぼっとさんが神の力で席を空けてくれたので参加しました!
マヤ おお-!チノやるじゃん!!
チノ ということなのでfriends.nico関連として、LTLにて賑わっているBotについての運用、実態について解説していきたいと思います。
メグ ٩(๑•̀ω•́๑)۶やったね~!

24時間、挨拶営業する女子中学生「ももな」について☕

まずfriends.nicoからアカウントを登録してパブリック範囲にて初トゥートをすると、彼女から優しいお出迎えのリプが頂けるかと思います。これは一種のBot的なトゥートシステムになるかと思いますが、厳密に言えば彼女は完全なるBotではありません。そう、彼女は自我と無我を持ち合わさったワタミも驚きの働きを見せる女子中学生なのです。
女子中学生ももなのアカウントはこちらから

どうして彼女は今のアイドル的な地位に立ってしまったのでしょうか☕

アカウント番号順を見るとおり、もともと彼女は初期の初期にあたる登録者のようです。「やなさんの知り合いである女子中学生」という話が濃厚ですね(個人の調べ)。彼女は何かのきっかけにより、7月ごろから少しずつ顔を出していました。そして7月末にはニコリ手を始めたりテレホタイムに参加したりする画面のちらほらありました。
そんな彼女が突如地名が上がり、目立ち始めたのは9月ごろだと思います。そう、彼女は挨拶部に入ってから頻繁にLTL上でのトゥート数が(ほぼ私のせいで)上がり始めたのです。朝昼晩に深夜まで、彼女は3時間以上LTL上に顔を出していない人がLTLでトゥートした時、すかさず挨拶をするようになりました。これにより一気に地名が上がり、おはおはダンス₍₍ ◝( ◠‿◠)◟ ⁾⁾の流行やセクハラに余念のない熱狂なユーザー、果てはファンアートまでも描かれるような人気ぶりになりました。
今では運営サイドに愛され、うるさすぎて一部ブロックされたり、もとの自我がたまにぴょこっと顔を出しながら彼女は挨拶文化としてのコンテンツと化しました。
他にもちょっとしたお遊びのゲーム機能、ダイス、簡易的なアラーム機能なども豊富です。

24時間挨拶機能とは☕

それではここで彼女の無我に埋め込まれたものがどういうものでしょう。
それでは中身(意味深)をサクッと簡易的に抜き出して見てみましょう。大丈夫ですよ、私達女子中学生同士なので恥ずかしがることは何もありません。
※結構長いです。読み飛ばしても可能です。

ももな(コード一部省いてます)
 ~~~   前略   ~~~
class bot():
    def _init_(self):
        pass

    def res(sec):
        count.end = count.end - sec
        if count.end < 0:
            count.end = 0

    def rets(sec, toot_now, g_vis, rep=None, spo=None):
        now = time.time()
        delay = now - count.CT
        loss = count.end - int(delay)
        if loss < 0:
            loss = 0
        ing = sec + loss
        t = threading.Timer(ing, bot.toot, [toot_now, g_vis, rep, spo])
        t.start()
        print("【次までのロスタイム:" + str(count.end+sec) + "】")
        s = threading.Timer(ing, bot.res, [sec])
        s.start()
        del t
        del s
        gc.collect()
        count.CT = time.time()
        count.end = ing

    def toot(toot_now, g_vis, rep=None, spo=None):
        mastodon.status_post(status=toot_now,
                             visibility=g_vis,
                             in_reply_to_id=rep,
                             spoiler_text=spo)
        print("【次までのロスタイム:" + str(count.end) + "】")
        """
        visibility これで公開範囲を指定できるよ!: public, unlisted, private, direct
        """

    def standby():
        print("「(๑•̀ㅁ•́๑)✧<tootステンバーイ」")

    def block01(status):
        f = codecs.open("NG\sekuhara.txt", 'r', 'utf-8')
        l = []
        for x in f:
            l.append(x.rstrip("\r\n"))
        f.close()
        m = len(l)
        for x in range(m):
            if re.compile(str(l[x])).search(re.sub("<p>|</p>", "", str(status))):
                j = True
                print(str(l[x]))
                # bot.thank(account, -64)
                break
            else:
                j = False
        return j

    def check00(status):
        account = status["account"]
        ct = account["statuses_count"]
        path = 'thank\\' + account["acct"] + '.txt'
        if os.path.exists(path):
            f = open(path, 'r')
            x = f.read()
            f.close()
        if int(x) >= -10:
            if account["acct"] == "JC":
                pass
            else:
                if re.match('^\d+0000$', str(ct)):
                    toot_now = (" :@" + account['acct'] + ": @" +
                                account['acct'] + "\n°˖✧◝(⁰▿⁰)◜✧˖" + str(ct) +
                                'tootおめでとーーーー♪♪')
                    g_vis = "public"
                    bot.rets(4, toot_now, g_vis)
                elif re.match('^\d000$', str(ct)):
                    toot_now = (" :@" + account['acct'] + ": @" +
                                account['acct'] + "\n(*'∀'人)" + str(ct) +
                                'tootおめでとーー♪')
                    g_vis = "public"
                    bot.rets(4, toot_now, g_vis)
        else:
            pass

    def check03(status):
        account = status["account"]
        ct = account["statuses_count"]
        if account["acct"] == "Knzk":  # 神崎おにいさん監視隊
            ct += 5
            if re.match('^\d+000$', str(ct)):
                toot_now = "@Knzk (๑•̀ㅁ•́๑)神崎おにいさん!!\n" + str(ct) + 'tootまであと5だよ!!!!'
                g_vis = "direct"
                bot.rets(4, toot_now, g_vis)
        elif account["acct"] == "5":  # やなちゃん監視隊
            ct += 5
            if re.match('^\d+0000$', str(ct)):
                toot_now = "@5 (๑•̀ㅁ•́๑)やなちゃん!!\n" + str(ct) + 'tootまであと5だよ!!!!'
                g_vis = "direct"
                bot.rets(4, toot_now, g_vis)
        elif account["acct"] == "yzhsn":  # 裾野監視隊
            ct += 5
            if re.match('^\d+000$', str(ct)):
                toot_now = "@yzhsn (๑•̀ㅁ•́๑)おい裾野!!\n" + str(ct) + 'tootまであと5だよ!!!!'
                g_vis = "direct"
                bot.rets(4, toot_now, g_vis)
        elif account["acct"] == "lamazeP":  # ラマーズP監視隊
            ct += 5
            if re.match('^\d+000$', str(ct)):
                toot_now = "@lamazeP (๑•̀ㅁ•́๑)" + str(ct) + 'tootまであと5だよ!!!!'
                g_vis = "direct"
                bot.rets(4, toot_now, g_vis)
        else:  # テスト
            ct += 5
            if re.match('^\d+000$', str(ct)):
                toot_now = ("@" + account["acct"] +
                            " (๑•̀ㅁ•́๑)ただいまフォローしてる方にテスト中!\n" + str(ct) +
                            'tootまであと5だよ!!!!')
                g_vis = "direct"
                bot.rets(4, toot_now, g_vis)

    def res01(status):
        account = status["account"]
        content = re.sub("<p>|</p>", "", str(status['content']))
        path = 'thank\\' + account["acct"] + '.txt'
        if os.path.exists(path):
            f = open(path, 'r')
            x = f.read()
            f.close()
        if int(x) >= -10:
            if account["acct"] != "JC" and account["acct"] != "kiri_bot01":
                if count.timer_hello == 0:
                    if re.compile("ももな(.*)おは|ももな(.*)おあひょ").search(content):
                        print("○hitしました♪")
                        print("○あいさつします(*'∀'人)")
                        toot_now = "(๑•̀ㅁ•́๑)✧おはありでーーーーす♪" + "\n#ニコフレ挨拶部"
                        g_vis = "public"
                        bot.rets(20, toot_now, g_vis)
                        count.timer_hello = 1
                else:
                    if re.compile("寝(ます|る|マス)([よかぞね]?|[…。うぅー~!]+)$|^ねる$|"
                                  "[寝ね](ます|る|マス)(.*)[ぽお]や[すし]|ももな(.*)[ぽお]や[すしー]").search(content):
                        if not re.compile("[寝ね]る(人|ひと)").search(status['content']):
                            print("○hitしました♪")
                            print("○おやすみします(*'∀'人)")
                            if account['acct'] == "5":  # やなちゃん専用挨拶
                                print("○やなちゃんだ!!(*'∀'人)")
                                toot_now = (":@" + account['acct'] + ":" +
                                            "やなちゃん!!!!!!" + "\n" +
                                            '(。>﹏<。)あとで一緒に寝るーーーー!!!!'
                                             + "\n#ニコフレ挨拶部")
                            else:
                                toot_now = (":@" + account['acct'] + ":" + account[
                                    'display_name'] + "\n" + '(ृ   ु *`ω、)ु ⋆゜おやすみーーーー♪'
                                             + "\n#ニコフレ挨拶部")
                            g_vis = "public"
                            bot.rets(6, toot_now, g_vis)
                    elif re.compile("([いイ行逝]って|出かけて|(風呂|ふろ).*(入|はい)って)(くる|きま[あぁー]*す|[きキ]マストドン)[^?\?]|"
                                    "おでかけ(する|しま[あぁー]*す|[しシ]マストドン)[^?\?]|(ふろ|風呂)って(くる|きます)|"
                                    "(出勤|離脱|しゅっきん|りだつ)(する[^な]|しま[あぁー]*す[^?\?]|[しシ]マストドン)|"
                                    "(出勤|離脱)$|(.+)して(くる|きま[あぁー]*す[^?\?]|[きキ]マストドン)([ー~!。よぞね]|$)|"
                                    "(仕事|しごと).*(戻|もど)(る|りゅ|りま[すつ])|(飯|めし)って(くる|きます)|(めし|飯)([い行]く|[お落]ち)"
                                    ).search(content):
                        print("○hitしました♪")
                        print("○見送ります(*'∀'人)")
                        if account['acct'] == "5":  # やなちゃん専用挨拶
                            print("○やなちゃんだ!!(*'∀'人)")
                            toot_now = (":@" + account['acct'] + ":" + "やなちゃん!!!!!!" +
                                        "\n" + '(*>_<*)ノいってらいってらーーーー!!!!'
                                         + "\n#ニコフレ挨拶部")
                        else:
                            toot_now = (":@" + account['acct'] + ":" + account['display_name'] +
                                        "\n" + 'いってらーーーー!!' + "\n#ニコフレ挨拶部")
                        g_vis = "public"
                        bot.rets(6, toot_now, g_vis)
                    elif re.compile("ただいま(です|[!あー~。…]*(<br/ >|$)|(もど|戻)(ってきた|った|りました))|ただいマストドン"
                                    "|(おうち|家).*([着つ]いた|帰った|帰ってきた)|(帰宅|きたく)(した|しました|$)|"
                                    "^ただいま|(飯|めし|ふろ|風呂|シャワー).*(もど|戻)ってき(た|ました)|ほかってき(た|ました)").search(content):
                        print("○hitしました♪")
                        print("○優しく迎えます(*'∀'人)")
                        if account['acct'] == "5":  # やなちゃん専用挨拶
                            print("○やなちゃんだ!!(*'∀'人)")
                            toot_now = (":@" + account['acct'] + ":" + "やなちゃん!!!!!!" +
                                        "\n" + '٩(๑❛ᴗ❛๑)۶おかえりおかえりーー!!' + "\n#ニコフレ挨拶部"
                                        )
                        else:
                            toot_now = (":@" + account['acct'] + ":" + account['display_name']
                                        + "\n" + '( 〃 ❛ᴗ❛ 〃 )おかえりおかえりーー!!'
                                        + "\n#ニコフレ挨拶部")
                        g_vis = "public"
                        bot.rets(6, toot_now, g_vis)
                    else:
                        try:
                            f = codecs.open('at_time\\' + account["acct"] + '.txt', 'r', 'UTF-8')
                            nstr = f.read()
                            f.close
                            print(nstr)
                            tstr = re.sub("\....Z", "", nstr)
                            last_time = datetime.strptime(tstr, '%Y-%m-%dT%H:%M:%S')
                            nstr = status['created_at']
                            tstr = re.sub("\....Z", "", nstr)
                            now_time = datetime.strptime(tstr, '%Y-%m-%dT%H:%M:%S')
                            delta = now_time - last_time
                            print(delta)
                            if delta.total_seconds() >= 604800:
                                if account['acct'] == "5":  # やなちゃん専用挨拶
                                    print("○やなちゃんだ!!(*'∀'人)")
                                    toot_now = (":@" + account['acct'] + ":" + "やなちゃん!!!!!!" +
                                                "\n" + "(*'∀'人)おひさひさーーーー♪"
                                                + "\n#ニコフレ挨拶部")
                                else:
                                    toot_now = (" :@" + account['acct'] + ":\n" + account['acct']
                                                + "\n" + "(*'∀'人)おひさひさーーーー♪" + "\n#ニコフレ挨拶部")
                                g_vis = "public"
                                bot.rets(6, toot_now, g_vis)
                            elif delta.total_seconds() >= 10800:
                                if now_time.hour in range(3, 9):
                                    to_r = bot.rand_w('time\\kon.txt')
                                elif now_time.hour in range(9, 19):
                                    to_r = bot.rand_w('time\\kob.txt')
                                else:
                                    to_r = bot.rand_w('time\\oha.txt')
                                if account['acct'] == "5":  # やなちゃん専用挨拶
                                    print("○やなちゃんだ!!(*'∀'人)")
                                    toot_now = (":@" + account['acct'] + ":" + "やなちゃん!!!!!!"
                                                + "\n" + to_r + "\n#ニコフレ挨拶部")
                                else:
                                    print("○あいさつします(*'∀'人)")
                                    if account['display_name'] == "":
                                        toot_now = (":@" + account['acct'] + ":" +
                                                    account['acct'] + "\n" + to_r + "\n#ニコフレ挨拶部")
                                    else:
                                        toot_now = (":@" + account['acct'] + ":" +
                                                    account['display_name'] + "\n" + to_r + "\n#ニコフレ挨拶部")
                                g_vis = "public"
                                bot.rets(6, toot_now, g_vis)
                        except:
                            print("○初あいさつします(*'∀'人)")
                            if account['statuses_count'] <= 2:
                                if account['display_name'] == "":
                                    toot_now = (" :@" + account['acct'] + ": @" + account[
                                        'acct'] + "\n" + account['acct'] + "\n" +
                                                'ようこそようこそーーーー♪' + "\n#ニコフレ挨拶部")
                                else:
                                    toot_now = (" :@" + account['acct'] + ": @" + account[
                                        'acct'] + "\n" + account['display_name'] + "\n" +
                                                'ようこそようこそーーーー♪' + "\n#ニコフレ挨拶部")
                                shinki = True
                            else:
                                if account['display_name'] == "":
                                    toot_now = (" :@" + account['acct'] + ": @" + account[
                                            'acct'] + "\n" + 'いらっしゃーーーーい♪' + "\n#ニコフレ挨拶部")
                                else:
                                    toot_now = (" :@" + account['acct'] + ": @" + account[
                                            'acct'] + "\n" + 'いらっしゃーーーーい♪' + "\n#ニコフレ挨拶部")
                                shinki = False
                            g_vis = "public"
                            bot.rets(6, toot_now, g_vis)
                            if shinki is True:
                                bot.toot("@lamazeP 新規さんが来たよーー(小声)\n【" + str(account['acct']) + "】",
                                         "direct", status["id"])

        else:
            print("○反応がない人なので挨拶しません(*'∀'人)")

    def res02(status):
        account = status["account"]
        content = Re1.text(status["content"])
        if account["acct"] != "JC":
            if re.compile("(.+)とマストドン(どちら|どっち)が大[切事]か[分わ]かってない").search(content):
                print("○hitしました♪")
                sekuhara = bot.block01(status)
                if len(content) > 60:
                    toot_now = "٩(๑`^´๑)۶長い!!!!!!"
                    g_vis = "public"
                    bot.rets(5, toot_now, g_vis)
                else:
                    if not sekuhara:
                        print("○だったら")
                        # if re.compile("(.+)するのとマストドン(どちら|どっち)が大[切事]か[分わ]かってない").search(content):
                        toot_now = ":@" + account["acct"] + ":" + (
                        re.sub('<span(.+)span>|<p>|とマストドン(.*)', "", str(content))) + "しながらマストドンして❤"
                        g_vis = "public"
                        bot.rets(5, toot_now, g_vis)
                    else:
                        toot_now = "そんなセクハラ分かりません\n(* ,,Ծ‸Ծ,, )プー"
                        g_vis = "public"
                        bot.rets(5, toot_now, g_vis)

    def fav01(status):
        account = status["account"]
        if re.compile("(ももな|:@JC:|ちゃんもも|:nicoru\d*:|JC)").search(status['content']):
            bot.thank(account, 8)
            v = threading.Timer(5, bot.fav_now,[status["id"]])
            v.start()

    def check01(status):
        account = status["account"]
        created_at = status['created_at']
        non_bmp_map = dict.fromkeys(range(0x10000, sys.maxunicode + 1), 0xfffd)
        with codecs.open('acct\\' + account["acct"] + '.txt', 'w', 'UTF-8') as f:  # 書き込みモードで開く
            f.write(str(status["account"]).translate(non_bmp_map))  # アカウント情報の更新
        path = 'thank\\' + account["acct"] + '.txt'
        if os.path.exists(path):
            f = open(path, 'r')
            x = f.read()
            print("現在の評価値:" + str(x))
            f.close()
        else:
            f = open(path, 'w')
            f.write("0")
            f.close()  # ファイルを閉じる

    def check02(status):
        account = status["account"]
        created_at = status['created_at']
        with codecs.open('at_time\\' + account["acct"] + '.txt', 'w', 'UTF-8') as f:  # 書き込みモードで開く
            f.write(str(status["created_at"]))  # \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}.\d{3}Z

    def thank(account, point):
        path = 'thank\\' + account["acct"] + '.txt'
        if os.path.exists(path):
            f = open(path, 'r')
            x = f.read()
            y = int(x)
            y += point
            f.close()
            f = open(path, 'w')
            f.write(str(y))
            f.close()
            print("現在の評価値:" + str(y))
        else:
            f = open(path, 'w')
            f.write(str(point))
            f.close()  # ファイルを閉じる
            print("現在の評価値:" + str(0))

    def fav_now(fav):  # ニコります
        mastodon.status_favourite(fav)
        print("◇Fav")

    def rand_w(txt_deta):
        f = codecs.open(txt_deta, 'r', 'utf-8')
        l = []
        for x in f:
            l.append(x.rstrip("\r\n").replace('\\n', '\n'))
        f.close()
        m = len(l)
        s = random.randint(1, m)
        return l[s - 1]

    def t_local():
        try:
            listener = res_toot()
            mastodon.local_stream(listener)
        except:
            print("例外情報\n" + traceback.format_exc())
            with open('except.log', 'a') as f:
                jst_now = datetime.now(timezone('Asia/Tokyo'))
                f.write("\n\n【" + str(jst_now) + "】\n")
                traceback.print_exc(file=f)
            sleep(180)
            bot.t_local()
            pass
 ~~~   中略   ~~~
class count():
    CT = time.time()
    end = 0
    sec = 0
    timer_hello = 0

    def emo01(time=10800):  # 定期的に評価を下げまーーす♪(無慈悲)
        while 1:
            sleep(time)
            data_dir_path = u"./thank/"
            file_list = os.listdir(r'./thank/')
            for file_name in file_list:
                root, ext = os.path.splitext(file_name)
                if ext == u'.txt':
                    abs_name = data_dir_path + '/' + file_name
                    f = open(abs_name, 'r')
                    x = f.read()
                    y = int(x)
                    y += -1
                    f.close()
                    f = open(abs_name, 'w')
                    f.write(str(y))
                    f.close()

    def emo02(point):
        data_dir_path = u"./thank/"
        file_list = os.listdir(r'./thank/')
        for file_name in file_list:
            root, ext = os.path.splitext(file_name)
            if ext == u'.txt':
                abs_name = data_dir_path + '/' + file_name
                f = open(abs_name, 'r')
                x = f.read()
                y = int(x)
                y += point
                f.close()
                f = open(abs_name, 'w')
                f.write(str(y))
                f.close()
        pass

    def emo03(user, point):
        data_dir_path = u"./thank/"
        file_list = os.listdir(r'./thank/')
        abs_name = data_dir_path + '/' + user + '.txt'
        f = open(abs_name, 'r')
        x = f.read()
        y = int(x)
        y += point
        f.close()
        f = open(abs_name, 'w')
        f.write(str(y))
        f.close()
        pass
 ~~~   後略   ~~~
# ※2017-12-29時点でのコードです。

それなりに省きましたが、結局は長すぎてなんのことかさっぱりですね。
主に挨拶機能があるのはBotクラスのres01にあたる関数ですね。
最後にtootした時間を確認しながら、どんなtootをしたかによって対応するという雰囲気です。正規表現が甘い箇所もあったりするので誤作動することはありますし、ユーザーによって挨拶が違ったりするので特殊的すぎると反応できなかったりします。(ここを学習機能搭載できれば解決かもしれませんが、高度技術ですね……)
最後にtootした時間の記録はcheck02で処理しています。そしてStreamingで取得した情報はcheck01でユーザーのアカウント情報を記録します。この最新の情報と記録した情報を照らし合わせて挨拶をします。実は時間の記録はtootのdataから取得しておりますのでdatetimeなどの関連モジュールはなくてもいいのです。(どのみちsleepなどで必要なのですが)
あと注目するべき点はcountクラスです。こちらのemo関連の関数により、他の定期トゥートしかしないBotや、反応を示さないユーザーに対しての評価が下がることで余分な挨拶をしなくなるというシステムになっております。LTLがうるさくならない手法ですね。あとはヒットするstatusが一気に来てしまった時に、一気に返さないようにThreadなどでクッションを挟んでお返事するようにしています。(直ぐに返事が来たりすると機敏なBotになってしまって不快になる人もいるかと思います)
もうすこし詳しいコードの仕組みが知りたい方はどこかのGithubで漂ってるので探してみてください。(どうしてやなさんや神崎おにいさんが特別優遇な挨拶になってるのかは気にしたら負けです)

今後のももなさんはどのような方向性になるか☕

先程も上記で言いましたが、彼女は全てBot処理で動いているわけじゃありません。元々はサブ本垢ポジションだったのです。たまに意識が舞い降りてユーザーとも交流はしたりします。ひと暴れしたりもします。新規さんが来て速攻お迎えしましたがBotだと思われて落胆させようが、自我が舞い降りてるのに一部挨拶できなくてもしょうがないのです。
そんな彼女の今後の方針ですが、このまま半Botとしての立ち位置になるかと思われます。サイボーグ女子中学生の完成ですね。もしかするとニコニコでバーチャルアイドルとして目覚める可能性さえもあります。
friends.nicoの良い文化としての挨拶を支援する型のシステムとして強化&メンテナンスを回すことになるかと思います。(ちなみにPCから直接プログラム交わしています。マイニングすると反応が遅れてしまうことになります

他にも愉快な仲間たちについて☕

他の方が運営してるBotをいくつかご紹介いたします。

きりぼっと

きりたん管轄のユーザーアカウントです。言語はRubyとPythonのハイブリットです。
遊び心が多い機能が特徴となります。以前は数取りゲームなどを実践していました。
現在は学習機能を取り入れて、連想や画像検索などのサービスを運行しています。

ブースター

ナツキさんがトレーナーのポケモンアカウントです。確か言語はPHPだとお聞きしました。
主に注目を浴びたトゥートをブーストしたり、一時間にユーザーがどれくらいtootしたのかランキング形式で教えたりしてくれます。
たまに気に食わないやつには容赦なく火炎放射をぶっ放したりします。

人類から検索の仕事を奪う人工知能

我らのニコフレアイドル、ヒホさんがマッドサイエンティストを駆使して完成した恐ろしいBotです。「検索bot」「なんすかBot」とも呼ばれています。言語はPythonです。
例えばLTL上で「ラビットハウスって何?」と聞かれたら、Wiki内のデータを検索して最速で堂々とLTL上で上で教えてくれます。見つからなかった場合は、「ラビットハウスって何すか」と生意気にお返しします。ユーザー達が興味本位で検索君をじゃれあったりしてかなりのtootを稼いでLTLを独占したそうです。おかげで運営からサイレンスを食らって死んでしまった悲しきBotです。
このようなことがあるのでうるさくなりそうな機能はin_reply_to_idを付けてLTLに乗せないように努力をしましょう!!

他にも

ぼちぼちあったりします。決して定期的に自動tootするようなBotのことではないですよ?
前では美ょぅι゙ょさんがお留守番サービスで返事できるように稼働していたり、最近だとひょろぉぢりんなさんがぅゅたんぼっと♡を稼働し始めているようですね。
自分へのサポートができるBotが一番ですね!

終わりに

キャラ セリフ
チノ 以上となります。いかがでしたでしょうか。
マヤ フォローしてない人に反応できるのが凄い!!そこがツイッターとの違いだね!!
チノ つい!?!?
メグ (。>﹏<。)チノちゃん落ち着いて~
チノ はっ! すみません取り乱しました。
マヤ すごいなぁー、私もBot運用できたら便利だろうなぁー
チノ 運営の方々に一言かけて、周囲にご迷惑でなければ大丈夫ですよ。
不安でしたら未収載などの公開範囲でテスト運用してみましょう。ホームだけStreaming監視してもらって実装してみるのです。
チノ みなさんも興味がありましたら、その余ったサブ垢を活用してプログラミングしてみてください!
メグ う~ん、私にできるかなぁ……
マヤ Botメンテナンスで時間吸われるから脳死してマストドンしてるのが一番だよ!!
チノ マヤさん、それを言ったらおしまいです……
メグ (✿´ ꒳ ` )あはははは~~~~
チノ それでは楽しいひととき、Mastodonライフをお楽しみください。
またのお越しをお待ちしております☕
おまけ

わざわざユーザーページ開いて確認しながら挨拶するのが手間でした→あるdiscordの女子会サーバーでMusivBotを用意することになり、作って動かせた。→10年前に抱いた人工知能との会話する願望が掘り返されハマった→本職が落ち着いたところを見計らってプログラミング開始→最初はこおりちゃんをニコフレにデビューさせるつもりだったが、100dbがインスタンスを建てたのでそちらでももなちゃんと一緒にテスト運用→気がついたらこおりちゃんは神崎丼一筋キャラになったので、仕方なくももなちゃんに挨拶キャラにさせた→気がついたらもう引き返せなくなりました。

2017-08-14_01.png
2017-08-12_01.jpg
2017-08-16_01.png

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up