Pixivのアートワークを取得して貼り付けるDiscordBotを作る
はじめに
DiscordでpixivのURLを貼った際にアートワークが半分程度しか表示されないことにモヤモヤしていたのでアートワークを取得して貼り付けるbotを作成しました。
概要
技術構成
使用言語
Python - Discord.pyライブラリとPixivpyライブラリを使用したいために選定
使用ライブラリ
Discord.py
Pixivpy
使用ツール
Retrieving Auth Token (with Selenium)
できました
config.json
のpixiv_refresh_token
とdiscord_token
をご自身の情報に上書きしてください。
チャート
- Pixivログイン情報の取得
- アートワークの取得
- DiscordBotの有効化
Pixivログイン情報の取得
ツールを使用してご利用のpixivアカウントのrefresh token
を取得します。
取得の方法は下記ページを参考にしてください。
また、このツールを使用する用のアカウントを別に取得することをお勧めいたします。
アートワークの取得
まずpixivpyをインストールします。
pip install pixivpy
これでライブラリを使用する準備はできました。
引数として受け取ったPixivのアートワークIDをもとにアートワークを取得します。
ライブラリが充実しているので難しいことはありませんでした。
import json
from pixivpy3 import *
class PixivData():
def __init__(self):
with open('config.json', 'r') as f:
config = json.load(f)
self.__pixivToken = config['pixiv_refresh_token']
self.__downloadPath = config['download_path']
self.__pixiv = AppPixivAPI()
@property
def pixivToken(self):
return self.__pixivToken
@property
def downloadPath(self):
return self.__downloadPath
@property
def pixiv(self):
return self.__pixiv
class PixivWork():
def __init__(self, artworkId):
self.__artworkId = artworkId
@property
def artworkId(self):
return self.__artworkId
@artworkId.setter
def artworkId(self, val):
self.__artworkId = val
def getArtwork(self):
p = PixivData()
p.pixiv.auth(refresh_token = p.pixivToken)
data = p.pixiv.illust_detail(self.artworkId)
artwork = data.illust.image_urls.large
exteniton = artwork[artwork.find('master1200.'):]
fileName = f'{self.artworkId}{exteniton}'
p.pixiv.download(artwork, path = p.downloadPath, name = fileName)
result = {
'title': data.illust.title,
'user': data.illust.user.name,
'fileName': fileName
}
return result
def getArtworks(self):
p = PixivData()
p.pixiv.auth(refresh_token = p.pixivToken)
data = p.pixiv.illust_detail(self.artworkId)
artworks = data.illust.meta_pages
i = 0
for artwork in artworks:
imageUrl = artwork.image_urls.large
exteniton = imageUrl[imageUrl.find('master1200.'):]
artworkName = f'{self.artworkId}{exteniton}'
fileName = f'{str(i)}_{artworkName}'
p.pixiv.download(imageUrl, path = p.downloadPath, name = fileName)
i = i + 1
result = {
'title': data.illust.title,
'user': data.illust.user.name,
'fileName': artworkName,
'pageCount': data.illust.page_count,
}
return result
DiscordBotの有効化
Botアカウント作成に従いDiscordBotを有効化します。
bot作成後、config.json
のdiscord_token
を変更してください。
続いてライブラリdiscord.pyをインストールします。
pip install discord.py
bot部分はクイックスタートを基に作成します。
メッセージで受け取ったURLを分解してアートワークIDを取得しpixivwork
に渡します。
URLの前に!all
メッセージが入っている場合は全てのイメージを出力するようにしました。
メッセージはembedの形式で多少見栄えがよく出力されるようにしました。
特に難しいことはしていないのですが、embedにイメージを挿入する際にローカルで保存したファイルを送信する場合はattachment//
をつけることを忘れないようにしましょう。詳しくはこちらをご覧ください。
import re
import json
import discord
from libs.pixivwork import PixivWork
from libs.calendar import Calendar
with open('config.json', 'r') as f:
config = json.load(f)
discordToken = config['discord_token']
artworkUrl = config['artwork_url']
client = discord.Client(ws = int(os.environ.get('PORT', 5000)))
@client.event
async def on_ready():
print('READY')
@client.event
async def on_message(message):
content = message.content
if re.search(artworkUrl, content):
if re.search('#manga', content):
content = content.replace('#manga', '')
if re.search('!all ', content):
content = content.replace('!all ', '')
artworkId = content[len(artworkUrl):]
work = PixivWork(artworkId)
result = work.getArtworks()
embed=discord.Embed(title=result["user"], description=result["title"])
for i in range(result["pageCount"]):
artworkPath = f'{i}_{result["fileName"]}'
file = discord.File(artworkPath)
embed.set_image(url=f'attachment://{artworkPath}')
if i == 0 :
await message.channel.send(file=file, embed=embed)
else:
await message.channel.send(file=file)
os.remove(artworkPath)
else:
artworkId = content[len(artworkUrl):]
work = PixivWork(artworkId)
result = work.getArtwork()
file = discord.File(fp=result["fileName"],filename=result["fileName"])
embed=discord.Embed(title=result["user"], description=result["title"])
embed.set_image(url=f'attachment://{result["fileName"]}')
await message.channel.send(file=file, embed=embed)
os.remove(result["fileName"])
client.run(discordToken)
以上です。
おわりに
pythonを書いたのは初めてだったのですがライブラリのヘルプが充実していたのでそこまで苦労せずに作成できました。
Botから画像の送信の場合embedの表示で画像の埋め込みが一枚までしか送れないようなので、いずれはDiscordWebhookを使用する方法も実装したいと思います。
以上、ご覧いただきありがとうございました。
Discussion