diff --git a/.gitignore b/.gitignore
index 25974ac..bcb7247 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,2 @@
-config.own
\ No newline at end of file
+config.own
+redditimages.db
\ No newline at end of file
diff --git a/config.example.own b/config.example.own
new file mode 100644
index 0000000..fb6b054
--- /dev/null
+++ b/config.example.own
@@ -0,0 +1,8 @@
+config = {
+ "token": "1234567890:AABBCCDDEE",
+ "peer": 1234, // chat_id
+ "items-in-top": 3,
+ "subreddits": [
+ "wholesomememes", "aww"
+ ]
+}
diff --git a/redditimages2telegram.own b/redditimages2telegram.own
new file mode 100644
index 0000000..6c55152
--- /dev/null
+++ b/redditimages2telegram.own
@@ -0,0 +1,157 @@
+// At the start of a main script, include config
+// include "config.own"
+
+use ["std", "math", "http", "json", "functional", "files", "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
+ }, ::debug)
+}
+def sendMediaGroup(chatId, media) {
+ invoke("sendMediaGroup", {
+ "chat_id": chatId,
+ "media": jsonencode(media)
+ }, ::debug)
+}
+
+// Reddit
+def fetchSubreddit(subreddit) {
+ url = "https://www.reddit.com/r/" + subreddit + ".json"
+ data = sync(def(ret) = http(url, combine(::jsondecode, ret))).data ?? []
+ if (data.isEmpty()) return []
+ return stream(data.children)
+ .map(def(child) = child.data)
+ .limit(min(config["items-in-top"], data.dist ?? 0))
+ .map(def(post) = {
+ "id": post.id,
+ "sub": subreddit,
+ "url": post.url,
+ "time": post.created_utc,
+ "title": post.title,
+ "permalink": post.permalink,
+ "flair_text": arrayKeyExists("link_flair_text", post) ? post.link_flair_text : ""
+ })
+ .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 url_idx ON posts (url)")
+st.close()
+
+stIsPostExists = conn.prepareStatement(
+ "SELECT COUNT(*) FROM posts
+ WHERE url = ?")
+stAddPost = conn.prepareStatement(
+ "INSERT INTO posts(post_id, subreddit, url, created_at, sent_at)
+ VALUES(?, ?, ?, ?, ?)")
+
+def isPostUnique(post) {
+ stIsPostExists.setString(1, post.url)
+ 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()
+}
+
+// Helpers
+def strToHashtag(str) =
+ str.toLowerCase()
+ .replaceAll("[^a-z_0-9\s]", "")
+ .replaceAll("\s+", "_")
+
+def multireplace(str, replacements) {
+ for re : replacements {
+ str = str.replace(re[0], re[1])
+ }
+ return str
+}
+
+r10s = [
+ [">", ">"], ["<", "<"], ["!", "%21"], ["#", "%23"],
+ ["$", "%24"], ["&", "%26"], ["'", "%27"], ["(", "%28"],
+ [")", "%29"], ["*", "%2A"], ["+", "%2B"], [",", "%2C"],
+ ["/", "%2F"], [":", "%3A"], [";", "%3B"], ["=", "%3D"],
+ ["?", "%3F"], ["@", "%40"], ["[", "%5B"], ["]", "%5D"]
+]
+def safeText(str) = multireplace(str, r10s)
+def safeLink(str) = multireplace(str, r10s + ["\"", """])
+
+def getCaption(post) {
+ tag = ""
+ if (length(post.flair_text) > 0) {
+ tag = " %23" + strToHashtag(post.sub + "_" + post.flair_text)
+ }
+ return sprintf(
+ "%s\n" +
+ "🗨 Comments%s",
+ safeLink(post.url),
+ safeText(post.title),
+ safeLink(post.permalink),
+ tag
+ )
+}
+
+
+media = 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)
+ .map(def(p) = {
+ "type": "photo",
+ "media": p.url,
+ "caption": getCaption(p),
+ "parse_mode": "html"
+ })
+ .limit(10)
+ .toArray()
+
+debug(jsonencode(media))
+
+if (length(media) > 0) {
+ sendMediaGroup(config.peer, media)
+}
+
+stIsPostExists.close()
+stAddPost.close()
+conn.close()
+
+def debug(r) {
+// echo(r)
+}
+
+sleep(10)
+use "java"
+System = newClass("java.lang.System")
+System.exit(0)