Скрипт для отправки лучших картинок из Reddit в Telegram
- config = {
- "token": "123456789:ABCDEFGH", // токен бота
- "peer": -1001111234567, // id канала или чатика
- "items-in-top": 3, // сколько рассматривать картинок в топе сабреддита
- "subreddits": [
- // Список сабреддитов
- "aww", "pics", "Art", "japanpics"
- ]
- }
- use "std"
- use "math"
- use "http"
- use "json"
- use "functional"
- use "files"
- use "jdbc"
- // Telegram
- def toParams(obj) = reduce(obj, "", def(acc, k, v) = acc + k + "=" + v + "&")
- def createRawUrl(method, params, token = "") = "https://api.telegram.org/bot" + token + "/" + method + "?"+params+"access_token="+token
- def createUrl(method, params, token = "") = createRawUrl(method, toParams(params), token)
- def invokeJson(method, params, callback) = http(createUrl(method, params, config.token), combine(::jsondecode, callback))
- def invoke(method, params, callback) = http(createUrl(method, params, config.token), callback)
- def sendPhoto(chatId, url) {
- invoke("sendPhoto", {
- "chat_id": chatId,
- "photo": url
- }, def(r) {})
- }
- // Reddit
- def fetchSubreddit(subreddit) {
- url = "https://www.reddit.com/r/" + subreddit + "/.json"
- data = sync(def(ret) = http(url, combine(::jsondecode, ret))).data
- return stream(data.children)
- .map(def(child) = child.data)
- .limit(min(config["items-in-top"], data.dist))
- .map(def(post) = {
- "id": post.id,
- "sub": subreddit,
- "url": post.url,
- "time": post.created_utc
- })
- .toArray()
- }
- def fetchAll(subreddits) =
- stream(subreddits)
- .flatMap(::fetchSubreddit)
- .toArray()
- // Database
- conn = getConnection("jdbc:sqlite:redditimages.db")
- st = conn.createStatement()
- st.executeUpdate(
- "CREATE TABLE IF NOT EXISTS posts (
- id INTEGER PRIMARY KEY AUTOINCREMENT,
- post_id STRING NOT NULL,
- subreddit STRING NOT NULL,
- url STRING NOT NULL,
- created_at INTEGER NOT NULL,
- sent_at INTEGER NOT NULL
- )")
- st.executeUpdate(
- "CREATE UNIQUE INDEX IF NOT EXISTS reddit_post_idx ON posts (post_id, subreddit)")
- st.close()
- stIsPostExists = conn.prepareStatement(
- "SELECT COUNT(*) FROM posts
- WHERE post_id = ? AND subreddit = ?")
- stAddPost = conn.prepareStatement(
- "INSERT INTO posts(post_id, subreddit, url, created_at, sent_at)
- VALUES(?, ?, ?, ?, ?)")
- def isPostUnique(post) {
- stIsPostExists.setString(1, post.id)
- stIsPostExists.setString(2, post.sub)
- rs = stIsPostExists.executeQuery()
- return rs.getInt(1) == 0
- }
- def addPost(post) {
- stAddPost.setString(1, post.id)
- stAddPost.setString(2, post.sub)
- stAddPost.setString(3, post.url)
- stAddPost.setLong(4, post.time)
- stAddPost.setLong(5, time() / 1000)
- stAddPost.executeUpdate()
- }
- stream(fetchAll(config.subreddits))
- .filter(def(p) = reduce([".jpg", ".png"], false, def(acc, ext) = acc || indexOf(p.url, ext) > 0))
- .filter(::isPostUnique)
- .peek(def(p) = sendPhoto(config.peer, p.url))
- .peek(::addPost)
- .count()
- stIsPostExists.close()
- stAddPost.close()
- conn.close()
Скрипт отправляет в указанный телеграм канал или чат самые лучшие картинки из определённых сабреддитов. Для фильтрации повторов используется база данных sqlite.
Вешать на крон с интервалом по желанию (зависит от частоты появления картинок в сабреддитах и желаемой частоты отправки картинок, я повесил раз в три часа):
Вешать на крон с интервалом по желанию (зависит от частоты появления картинок в сабреддитах и желаемой частоты отправки картинок, я повесил раз в три часа):
- 0 */3 * * * /usr/local/bin/ownlang -f /var/www/ownlang/scripts/redditimages2telegram.own