diff --git a/bot.ts b/bot.ts index d9e0bbb..ee85628 100644 --- a/bot.ts +++ b/bot.ts @@ -3,18 +3,23 @@ import { Bot, GrammyError, HttpError, -} from 'https://deno.land/x/grammy@v1.20.3/mod.ts' +} from 'https://deno.land/x/grammy@v1.21.1/mod.ts' import { createConversation } from 'https://deno.land/x/grammy_conversations@v1.2.0/conversation.ts' import { conversations } from 'https://deno.land/x/grammy_conversations@v1.2.0/mod.ts' import { askApiKey, saveBunchUrls, + setDefaultLabel, updateToken, } from './src/conversations.ts' import { cancelMenu } from './src/menus.ts' import { OmnivoreApi } from './src/omnivore/api.ts' import { MyContext, sessionHandler } from './src/sessionsHandler.ts' import { inlineQuery } from "./src/inlineQuery.ts"; +import { slashCommandsListener } from './src/slashCommands.ts' +import { cancelMenuAndResetLabel } from "./src/menus.ts"; +import { getUrlAndLabels } from "./src/utils/getUrlAndLabels.ts"; +import { includeSourceChoiceMenu } from "./src/menus.ts"; await load({ export: true }) @@ -30,26 +35,34 @@ bot.use(conversations()) bot.use(createConversation(askApiKey)) bot.use(createConversation(saveBunchUrls)) bot.use(createConversation(updateToken)) +bot.use(createConversation(setDefaultLabel)) // Menu bot.use(cancelMenu) +bot.use(cancelMenuAndResetLabel) +bot.use(includeSourceChoiceMenu) // inline query bot.use(inlineQuery) +// slash commands handler +bot.use(slashCommandsListener) + // handlers bot.on('message:entities:url', async ctx => { + // retrieve stuff from session const token = ctx.session.apiToken - const api = new OmnivoreApi(token) - await api.saveUrl(ctx.message.text || '') + const {url, labels} = getUrlAndLabels(ctx) - if (api.addedEntriesCount === 1) { - await ctx.reply('Successfully added link to Omnivore! πŸ˜ΈπŸ‘') - } else { - await ctx.reply('Failed to add the link. 😿') - } + await api.saveUrl(url, labels) + + const feedback = api.addedEntriesCount === 1 + ? 'Successfully added link to Omnivore! πŸ˜ΈπŸ‘' + : 'Failed to add the link. 😿' + + await ctx.reply(feedback) }) bot.command('start', async ctx => { diff --git a/deno.lock b/deno.lock index 4fc7c21..9077963 100644 --- a/deno.lock +++ b/deno.lock @@ -1,10 +1,10 @@ { "version": "3", "redirects": { - "https://lib.deno.dev/x/grammy@1.x/mod.ts": "https://deno.land/x/grammy@v1.20.3/mod.ts", - "https://lib.deno.dev/x/grammy@1.x/types.ts": "https://deno.land/x/grammy@v1.20.3/types.ts", - "https://lib.deno.dev/x/grammy@v1/mod.ts": "https://deno.land/x/grammy@v1.20.3/mod.ts", - "https://lib.deno.dev/x/grammy@v1/types.ts": "https://deno.land/x/grammy@v1.20.3/types.ts" + "https://lib.deno.dev/x/grammy@1.x/mod.ts": "https://deno.land/x/grammy@v1.21.1/mod.ts", + "https://lib.deno.dev/x/grammy@1.x/types.ts": "https://deno.land/x/grammy@v1.21.1/types.ts", + "https://lib.deno.dev/x/grammy@v1/mod.ts": "https://deno.land/x/grammy@v1.21.1/mod.ts", + "https://lib.deno.dev/x/grammy@v1/types.ts": "https://deno.land/x/grammy@v1.21.1/types.ts" }, "remote": { "https://cdn.skypack.dev/-/debug@v4.3.4-o4liVvMlOnQWbLSYZMXw/dist=es2019,mode=imports/optimized/debug.js": "671100993996e39b501301a87000607916d4d2d9f8fc8e9c5200ae5ba64a1389", @@ -29,57 +29,25 @@ "https://deno.land/std@0.211.0/path/windows/basename.ts": "e2dbf31d1d6385bfab1ce38c333aa290b6d7ae9e0ecb8234a654e583cf22f8fe", "https://deno.land/std@0.211.0/streams/_common.ts": "4f9f2958d853b9a456be033631dabb7519daa68ee4d02caf53e2ecbffaf5805f", "https://deno.land/std@0.211.0/streams/iterate_reader.ts": "353e516908ce637e8b2a2e1301fa60316825667d0d880d47ea4c427a9a7758cf", - "https://deno.land/std@0.218.0/assert/_constants.ts": "a271e8ef5a573f1df8e822a6eb9d09df064ad66a4390f21b3e31f820a38e0975", - "https://deno.land/std@0.218.0/assert/_diff.ts": "dcc63d94ca289aec80644030cf88ccbf7acaa6fbd7b0f22add93616b36593840", - "https://deno.land/std@0.218.0/assert/_format.ts": "0ba808961bf678437fb486b56405b6fefad2cf87b5809667c781ddee8c32aff4", - "https://deno.land/std@0.218.0/assert/assert.ts": "bec068b2fccdd434c138a555b19a2c2393b71dfaada02b7d568a01541e67cdc5", - "https://deno.land/std@0.218.0/assert/assert_almost_equals.ts": "8b96b7385cc117668b0720115eb6ee73d04c9bcb2f5d2344d674918c9113688f", - "https://deno.land/std@0.218.0/assert/assert_array_includes.ts": "1688d76317fd45b7e93ef9e2765f112fdf2b7c9821016cdfb380b9445374aed1", - "https://deno.land/std@0.218.0/assert/assert_equals.ts": "4497c56fe7d2993b0d447926702802fc0becb44e319079e8eca39b482ee01b4e", - "https://deno.land/std@0.218.0/assert/assert_exists.ts": "24a7bf965e634f909242cd09fbaf38bde6b791128ece08e33ab08586a7cc55c9", - "https://deno.land/std@0.218.0/assert/assert_false.ts": "6f382568e5128c0f855e5f7dbda8624c1ed9af4fcc33ef4a9afeeedcdce99769", - "https://deno.land/std@0.218.0/assert/assert_greater.ts": "4945cf5729f1a38874d7e589e0fe5cc5cd5abe5573ca2ddca9d3791aa891856c", - "https://deno.land/std@0.218.0/assert/assert_greater_or_equal.ts": "573ed8823283b8d94b7443eb69a849a3c369a8eb9666b2d1db50c33763a5d219", - "https://deno.land/std@0.218.0/assert/assert_instance_of.ts": "72dc1faff1e248692d873c89382fa1579dd7b53b56d52f37f9874a75b11ba444", - "https://deno.land/std@0.218.0/assert/assert_is_error.ts": "6596f2b5ba89ba2fe9b074f75e9318cda97a2381e59d476812e30077fbdb6ed2", - "https://deno.land/std@0.218.0/assert/assert_less.ts": "2b4b3fe7910f65f7be52212f19c3977ecb8ba5b2d6d0a296c83cde42920bb005", - "https://deno.land/std@0.218.0/assert/assert_less_or_equal.ts": "b93d212fe669fbde959e35b3437ac9a4468f2e6b77377e7b6ea2cfdd825d38a0", - "https://deno.land/std@0.218.0/assert/assert_match.ts": "ec2d9680ed3e7b9746ec57ec923a17eef6d476202f339ad91d22277d7f1d16e1", - "https://deno.land/std@0.218.0/assert/assert_not_equals.ts": "ac86413ab70ffb14fdfc41740ba579a983fe355ba0ce4a9ab685e6b8e7f6a250", - "https://deno.land/std@0.218.0/assert/assert_not_instance_of.ts": "8f720d92d83775c40b2542a8d76c60c2d4aeddaf8713c8d11df8984af2604931", - "https://deno.land/std@0.218.0/assert/assert_not_match.ts": "b4b7c77f146963e2b673c1ce4846473703409eb93f5ab0eb60f6e6f8aeffe39f", - "https://deno.land/std@0.218.0/assert/assert_not_strict_equals.ts": "da0b8ab60a45d5a9371088378e5313f624799470c3b54c76e8b8abeec40a77be", - "https://deno.land/std@0.218.0/assert/assert_object_match.ts": "e85e5eef62a56ce364c3afdd27978ccab979288a3e772e6855c270a7b118fa49", - "https://deno.land/std@0.218.0/assert/assert_rejects.ts": "5206ac37d883797d9504e3915a0c7b692df6efcdefff3889cc14bb5a325641dd", - "https://deno.land/std@0.218.0/assert/assert_strict_equals.ts": "0425a98f70badccb151644c902384c12771a93e65f8ff610244b8147b03a2366", - "https://deno.land/std@0.218.0/assert/assert_string_includes.ts": "dfb072a890167146f8e5bdd6fde887ce4657098e9f71f12716ef37f35fb6f4a7", - "https://deno.land/std@0.218.0/assert/assert_throws.ts": "31f3c061338aec2c2c33731973d58ccd4f14e42f355501541409ee958d2eb8e5", - "https://deno.land/std@0.218.0/assert/assertion_error.ts": "9f689a101ee586c4ce92f52fa7ddd362e86434ffdf1f848e45987dc7689976b8", - "https://deno.land/std@0.218.0/assert/equal.ts": "fae5e8a52a11d3ac694bbe1a53e13a7969e3f60791262312e91a3e741ae519e2", - "https://deno.land/std@0.218.0/assert/fail.ts": "f310e51992bac8e54f5fd8e44d098638434b2edb802383690e0d7a9be1979f1c", - "https://deno.land/std@0.218.0/assert/mod.ts": "325df8c0683ad83a873b9691aa66b812d6275fc9fec0b2d180ac68a2c5efed3b", - "https://deno.land/std@0.218.0/assert/unimplemented.ts": "47ca67d1c6dc53abd0bd729b71a31e0825fc452dbcd4fde4ca06789d5644e7fd", - "https://deno.land/std@0.218.0/assert/unreachable.ts": "3670816a4ab3214349acb6730e3e6f5299021234657eefe05b48092f3848c270", - "https://deno.land/std@0.218.0/fmt/colors.ts": "d239d84620b921ea520125d778947881f62c50e78deef2657073840b8af9559a", - "https://deno.land/x/grammy@v1.20.3/bot.ts": "bbfc31f976a27a48992ebb21bcdc137f216eb28e32cc5de0041dcc8fca53d5b8", - "https://deno.land/x/grammy@v1.20.3/composer.ts": "a86dcd6c83e91f720ceb85dab2b1c7b966fc18fc6440848b87b4897fcaa63fc8", - "https://deno.land/x/grammy@v1.20.3/context.ts": "3e9b8e277f8b75bed20b46047ad93b027a182e9d3504f1f2d2bba0852d0bb77f", - "https://deno.land/x/grammy@v1.20.3/convenience/constants.ts": "8d7e2fb9b0f5bd4c10585d8a7528dee573dea5096041b35bebadbb943318d1fc", - "https://deno.land/x/grammy@v1.20.3/convenience/frameworks.ts": "77e2f9fc841ab92d4310b556126447a42f131ad976a6adfff454c016f339b28e", - "https://deno.land/x/grammy@v1.20.3/convenience/inline_query.ts": "409d1940c7670708064efa495003bcbfdf6763a756b2e6303c464489fd3394ff", - "https://deno.land/x/grammy@v1.20.3/convenience/input_media.ts": "7af72a5fdb1af0417e31b1327003f536ddfdf64e06ab8bc7f5da6b574de38658", - "https://deno.land/x/grammy@v1.20.3/convenience/keyboard.ts": "88aeab16f2aaf0b4098135b5f7a678f7d2ce288f28c7eba93eaa5553a7395152", - "https://deno.land/x/grammy@v1.20.3/convenience/session.ts": "f92d57b6b2b61920912cf5c44d4db2f6ca999fe4f9adef170c321889d49667c2", - "https://deno.land/x/grammy@v1.20.3/convenience/webhook.ts": "f1da7d6426171fb7b5d5f6b59633f91d3bab9a474eea821f714932650965eb9e", - "https://deno.land/x/grammy@v1.20.3/core/api.ts": "840c5d39ca953d5bdbf89e61836a8212b22110d142b1606127b9c1a5f7d0b96a", - "https://deno.land/x/grammy@v1.20.3/core/client.ts": "df622a135e71229ffe722406850c9c08b90dcdd4d049b46926128599c73f9dc5", - "https://deno.land/x/grammy@v1.20.3/core/error.ts": "4638b2127ebe60249c78b83011d468f5e1e1a87748d32fe11a8200d9f824ad13", - "https://deno.land/x/grammy@v1.20.3/core/payload.ts": "420e17c3c2830b5576ea187cfce77578fe09f1204b25c25ea2f220ca7c86e73b", - "https://deno.land/x/grammy@v1.20.3/filter.ts": "8bfd76005929c22c42c6fd70064467dd4e8cf6e83de3c8d9d0522930d433e45d", - "https://deno.land/x/grammy@v1.20.3/mod.ts": "7723e08709ff7fd01df3e463503e14e4fd1a581669380eed70351e1121e8a833", - "https://deno.land/x/grammy@v1.20.3/platform.deno.ts": "68272a7e1d9a2d74d8a45342526485dbc0531dee812f675d7f8a4e7fc8393028", - "https://deno.land/x/grammy@v1.20.3/types.deno.ts": "d43290407cdd90eaa67393f8ab53139bfb9f692335a92cb6f1c607ddac706b26", - "https://deno.land/x/grammy@v1.20.3/types.ts": "729415590dfa188dbe924dea614dff4e976babdbabb28a307b869fc25777cdf0", + "https://deno.land/x/grammy@v1.21.1/bot.ts": "bbfc31f976a27a48992ebb21bcdc137f216eb28e32cc5de0041dcc8fca53d5b8", + "https://deno.land/x/grammy@v1.21.1/composer.ts": "a86dcd6c83e91f720ceb85dab2b1c7b966fc18fc6440848b87b4897fcaa63fc8", + "https://deno.land/x/grammy@v1.21.1/context.ts": "3e9b8e277f8b75bed20b46047ad93b027a182e9d3504f1f2d2bba0852d0bb77f", + "https://deno.land/x/grammy@v1.21.1/convenience/constants.ts": "8d7e2fb9b0f5bd4c10585d8a7528dee573dea5096041b35bebadbb943318d1fc", + "https://deno.land/x/grammy@v1.21.1/convenience/frameworks.ts": "ef57a31722a7f1b393f04db83cd123e6455a7b17028d3388e7d5d12970ec8978", + "https://deno.land/x/grammy@v1.21.1/convenience/inline_query.ts": "409d1940c7670708064efa495003bcbfdf6763a756b2e6303c464489fd3394ff", + "https://deno.land/x/grammy@v1.21.1/convenience/input_media.ts": "7af72a5fdb1af0417e31b1327003f536ddfdf64e06ab8bc7f5da6b574de38658", + "https://deno.land/x/grammy@v1.21.1/convenience/keyboard.ts": "88aeab16f2aaf0b4098135b5f7a678f7d2ce288f28c7eba93eaa5553a7395152", + "https://deno.land/x/grammy@v1.21.1/convenience/session.ts": "f92d57b6b2b61920912cf5c44d4db2f6ca999fe4f9adef170c321889d49667c2", + "https://deno.land/x/grammy@v1.21.1/convenience/webhook.ts": "f1da7d6426171fb7b5d5f6b59633f91d3bab9a474eea821f714932650965eb9e", + "https://deno.land/x/grammy@v1.21.1/core/api.ts": "840c5d39ca953d5bdbf89e61836a8212b22110d142b1606127b9c1a5f7d0b96a", + "https://deno.land/x/grammy@v1.21.1/core/client.ts": "df622a135e71229ffe722406850c9c08b90dcdd4d049b46926128599c73f9dc5", + "https://deno.land/x/grammy@v1.21.1/core/error.ts": "4638b2127ebe60249c78b83011d468f5e1e1a87748d32fe11a8200d9f824ad13", + "https://deno.land/x/grammy@v1.21.1/core/payload.ts": "420e17c3c2830b5576ea187cfce77578fe09f1204b25c25ea2f220ca7c86e73b", + "https://deno.land/x/grammy@v1.21.1/filter.ts": "31b9048d543f4e280a573d2e0b47f4ebbbaead753e4c836525026af5f6af9307", + "https://deno.land/x/grammy@v1.21.1/mod.ts": "7723e08709ff7fd01df3e463503e14e4fd1a581669380eed70351e1121e8a833", + "https://deno.land/x/grammy@v1.21.1/platform.deno.ts": "68272a7e1d9a2d74d8a45342526485dbc0531dee812f675d7f8a4e7fc8393028", + "https://deno.land/x/grammy@v1.21.1/types.deno.ts": "9ef5b8524e5779b1cc6df72736b0663a103b0be549dc4d4c93df2528b27e1534", + "https://deno.land/x/grammy@v1.21.1/types.ts": "729415590dfa188dbe924dea614dff4e976babdbabb28a307b869fc25777cdf0", "https://deno.land/x/grammy_conversations@v1.2.0/conversation.ts": "4bcad06e2ac562969a7a6661bb1cf1477a3fe9e537c18419de65c456feb69499", "https://deno.land/x/grammy_conversations@v1.2.0/deps.deno.ts": "c982798d7ca4cd3ebcd5a24319d03c5980dc47827b5a172a77022859abdb404e", "https://deno.land/x/grammy_conversations@v1.2.0/form.ts": "d2d527fdcb26eb489b4aa1a183ae3aa14bf185a375ebf7d5c6ab8360e8b0e170", @@ -90,17 +58,17 @@ "https://deno.land/x/grammy_menu@v1.2.1/mod.ts": "ec3d890cabdb7ee1ea72f5fcd1b0b05a84c208975c34251e8a0e9a595e40713b", "https://deno.land/x/grammy_storages@v2.4.1/supabase/src/deps.deno.ts": "74b945bf5c1ade714a1e8de482d752bc952db909f8cffdcceb290d2d74aada3a", "https://deno.land/x/grammy_storages@v2.4.1/supabase/src/mod.ts": "dd28166e9cb8f93dcd67e0732df91753f60ce18da35b13299c3d7467a7d7aad3", - "https://deno.land/x/grammy_types@v3.4.6/api.ts": "ae04d6628e3d25ae805bc07a19475065044fc44cde0a40877405bc3544d03a5f", - "https://deno.land/x/grammy_types@v3.4.6/inline.ts": "594e1e487c94bde6f1d17f457b7b002786eb40b7b3b77ed32b830571e6285b7e", - "https://deno.land/x/grammy_types@v3.4.6/manage.ts": "1d2b76d8735cdb56a2afe89097169ff4403b14016adb73e682fce61bc4c2efad", - "https://deno.land/x/grammy_types@v3.4.6/markup.ts": "bef977ea4c2f17791d6f8a0a8f37f6f7f622967030da4f6b42e41c3a9d797113", - "https://deno.land/x/grammy_types@v3.4.6/message.ts": "24de17e147a992eedebc8b28a553eeb1d62b0aecb93649fbde5f642bd5ad2b47", - "https://deno.land/x/grammy_types@v3.4.6/methods.ts": "9c4d413f1a240e356b58c41a2c9417ccbd42b287d7cab9375c568d5d80ffcb2b", - "https://deno.land/x/grammy_types@v3.4.6/mod.ts": "7b5f421b4fbb1761f7f0d68328eaddd515f3222ce3f3cdfbedd8d5a4781e91a7", - "https://deno.land/x/grammy_types@v3.4.6/passport.ts": "e3fb63aec96510bcc317ef48fd25b435444b8f407502d7568c00fce15f2958fd", - "https://deno.land/x/grammy_types@v3.4.6/payment.ts": "d23e9038c5b479b606e620dd84e3e67b6642ada110a962f2d5b5286e99ec7de5", - "https://deno.land/x/grammy_types@v3.4.6/settings.ts": "5e989f5bd6c587d55673bd8052293869aa2f372e9223dd7f6e28632bfe021b6e", - "https://deno.land/x/grammy_types@v3.4.6/update.ts": "597465794cbf6a6ab8a6e69c24645ed928e79af3d384dce63ae83716ba78ba3e", + "https://deno.land/x/grammy_types@v3.5.2/api.ts": "ae04d6628e3d25ae805bc07a19475065044fc44cde0a40877405bc3544d03a5f", + "https://deno.land/x/grammy_types@v3.5.2/inline.ts": "12b33002c4d7880b2e80aaee68ac344110360886efe48ab20d40e93b90849f04", + "https://deno.land/x/grammy_types@v3.5.2/manage.ts": "3bc9717ba157d3b0e076ff256322f9bf7ea2da28eaf25ea1dbcdc84c9f780804", + "https://deno.land/x/grammy_types@v3.5.2/markup.ts": "38f2de2c01531486d98ad17f7622af15d720ffaf5cf721af77ece49e403a09bb", + "https://deno.land/x/grammy_types@v3.5.2/message.ts": "90b9a23fc90f056ad34f71ed194f2cba30a91f3fa7b3e699a577172a2eceeb2d", + "https://deno.land/x/grammy_types@v3.5.2/methods.ts": "3429cc7f124337bb2cd2d16015272125f8e44d440d3480a87241905113fab701", + "https://deno.land/x/grammy_types@v3.5.2/mod.ts": "7b5f421b4fbb1761f7f0d68328eaddd515f3222ce3f3cdfbedd8d5a4781e91a7", + "https://deno.land/x/grammy_types@v3.5.2/passport.ts": "e3fb63aec96510bcc317ef48fd25b435444b8f407502d7568c00fce15f2958fd", + "https://deno.land/x/grammy_types@v3.5.2/payment.ts": "d23e9038c5b479b606e620dd84e3e67b6642ada110a962f2d5b5286e99ec7de5", + "https://deno.land/x/grammy_types@v3.5.2/settings.ts": "5e989f5bd6c587d55673bd8052293869aa2f372e9223dd7f6e28632bfe021b6e", + "https://deno.land/x/grammy_types@v3.5.2/update.ts": "a9fe07b677235a0d29e371f7fdc57ebf46b248ce956a2d918ed844a3c0fbe5de", "https://deno.land/x/oson@1.0.1/constructors.ts": "2b77dcdc8d8db5ece2860d1657f4dcef37dd761684f1d4b9535c7e56a0fbfcf6", "https://deno.land/x/oson@1.0.1/mod.ts": "54e494dc517ce0de6c727c25d9731ccc748e8646c883e922dc5d656f523a4e5b", "https://deno.land/x/oson@1.0.1/oson.ts": "ec3908ae5c9ceff7bfd869d95a2183b929b9d96fbff44b57d28d3b742d06a4a1", diff --git a/src/conversations.ts b/src/conversations.ts index 26ebb28..8dfcbca 100644 --- a/src/conversations.ts +++ b/src/conversations.ts @@ -53,7 +53,7 @@ export async function saveBunchUrls( const api = new OmnivoreApi(token) - await api.processUrls(urlsArray) + await api.processUrls({urls: urlsArray}) await ctx.reply( `Successfully added ${api.addedEntriesCount} of ${urlsArray.length} links!\nFailed to add ${api.failedEntriesCount} links.`, { @@ -75,3 +75,19 @@ export async function updateToken( reply_markup: mainKeyboardLayout, }) } + +export async function setDefaultLabel( + conversation: MyConversation, + ctx: MyContext +) { + const newCtx = await conversation.waitFor('msg:text') + const label = newCtx.message?.text + + conversation.session.defaultLabel = label || ctx.session.defaultLabel + + await ctx.reply(`You've Successfully set the label ${label} πŸŽ‰`, { + reply_markup: mainKeyboardLayout, + }) +} + + diff --git a/src/inlineQuery.ts b/src/inlineQuery.ts index 261dbbc..1433c0b 100644 --- a/src/inlineQuery.ts +++ b/src/inlineQuery.ts @@ -1,4 +1,4 @@ -import { Composer } from 'https://deno.land/x/grammy@v1.20.3/mod.ts' +import { Composer } from 'https://deno.land/x/grammy@v1.21.1/mod.ts' import { OmnivoreApi } from './omnivore/api.ts' import { MyContext } from './sessionsHandler.ts' diff --git a/src/keyboards.ts b/src/keyboards.ts index 6d0a82d..6f1fa7f 100644 --- a/src/keyboards.ts +++ b/src/keyboards.ts @@ -1,4 +1,4 @@ -import { Keyboard } from 'https://deno.land/x/grammy@v1.20.3/mod.ts' +import { Keyboard } from 'https://deno.land/x/grammy@v1.21.1/mod.ts' export const mainKeyboardLayout = new Keyboard() .text('πŸ‘Ύ Save a bunch of urls') diff --git a/src/menus.ts b/src/menus.ts index 18efc28..840d9df 100644 --- a/src/menus.ts +++ b/src/menus.ts @@ -3,10 +3,39 @@ import { mainKeyboardLayout } from './keyboards.ts' import { MyContext } from './sessionsHandler.ts' // Cancel menu button -export const cancelMenu = new Menu('Cancel') - .text('Cancel', ctx => { +export const cancelMenu = new Menu('Cancel').text( + 'Cancel', + ctx => { ctx.reply('canceled πŸ‘Œ', { reply_markup: mainKeyboardLayout }) ctx.conversation.exit() } - ) - .row() +) + +// cancel + reset button for set_default_label command +export const cancelMenuAndResetLabel = new Menu( + 'CancelAndReset' +) + .addRange(cancelMenu) + .text('Reset label', ctx => { + ctx.session.defaultLabel = '' + + ctx.reply('πŸƒ from now on there is no default label for links') + }) + +export const includeSourceChoiceMenu = new Menu( + 'includeSourceChoiceMenu' +) + .text('yes', ctx => { + ctx.session.includeSource = true + + ctx.reply(`Now your links sended to me, will include the source where they came from πŸ˜ΈπŸ‘`, { + reply_markup: mainKeyboardLayout, + }) + }) + .text('no', ctx => { + ctx.session.includeSource = false + + ctx.reply(`Your links won't include the source, and that's absolutely normal πŸ˜ΈπŸ‘`, { + reply_markup: mainKeyboardLayout, + }) + }) diff --git a/src/omnivore/api.ts b/src/omnivore/api.ts index 2fc38a9..d4cbb8d 100644 --- a/src/omnivore/api.ts +++ b/src/omnivore/api.ts @@ -8,7 +8,8 @@ import { graphqlEndpoint, searchQuery, } from './graphql.ts' -import { InlineQueryResultBuilder } from 'https://deno.land/x/grammy@v1.20.3/mod.ts' +import { InlineQueryResultBuilder } from 'https://deno.land/x/grammy@v1.21.1/mod.ts' +import { Label, ProcessUrlsParams } from "../types.ts"; interface OmnivoreApiInterface { apiToken: string @@ -28,12 +29,13 @@ export class OmnivoreApi implements OmnivoreApiInterface { this.apiToken = apiToken } - async saveUrl(url: string) { + async saveUrl(url: string, labels: Label[]) { const variables = { input: { clientRequestId: globalThis.crypto.randomUUID(), source: 'api', url, + labels }, } @@ -69,13 +71,18 @@ export class OmnivoreApi implements OmnivoreApiInterface { } } - async processUrls(urls: string[], startIndex = 0) { + async processUrls({ urls, additionalLabels, startIndex = 0 }: ProcessUrlsParams) { const batchSize = 50 const remainingUrls = urls.slice(startIndex) for (let i = 0; i <= batchSize && i < remainingUrls.length; i++) { - const url = remainingUrls[i] - await this.saveUrl(url) + const url = remainingUrls[i].url + const urlLabels = remainingUrls[i].labels + + // add additional labels to each url + additionalLabels?.map((label) => urlLabels.push(label)) + + await this.saveUrl(url, urlLabels) } const nextIndex = startIndex + batchSize + 1 @@ -84,7 +91,7 @@ export class OmnivoreApi implements OmnivoreApiInterface { await new Promise(resolve => setTimeout(resolve, OmnivoreApi.delayBetweenRequests) ) - await this.processUrls(urls, nextIndex) + await this.processUrls({urls, startIndex: nextIndex}) } } diff --git a/src/sessionsHandler.ts b/src/sessionsHandler.ts index d4e0779..795584c 100644 --- a/src/sessionsHandler.ts +++ b/src/sessionsHandler.ts @@ -2,7 +2,7 @@ import { Context, session, SessionFlavor, -} from 'https://deno.land/x/grammy@v1.20.3/mod.ts' +} from 'https://deno.land/x/grammy@v1.21.1/mod.ts' import { createClient } from 'https://esm.sh/@supabase/supabase-js@2.33.1' import { supabaseAdapter } from 'https://deno.land/x/grammy_storages@v2.4.1/supabase/src/mod.ts' import { load } from 'https://deno.land/std@0.211.0/dotenv/mod.ts' @@ -22,6 +22,8 @@ const storage = supabaseAdapter({ interface SessionData { apiToken: string + defaultLabel: string + includeSource: boolean } export type MyContext = Context & @@ -31,6 +33,8 @@ export type MyContext = Context & function initial(): SessionData { return { apiToken: '', + defaultLabel: '', + includeSource: false } } diff --git a/src/slashCommands.ts b/src/slashCommands.ts new file mode 100644 index 0000000..a7e5dae --- /dev/null +++ b/src/slashCommands.ts @@ -0,0 +1,23 @@ +import { Composer } from 'https://deno.land/x/grammy@v1.21.1/mod.ts' +import { MyContext } from './sessionsHandler.ts' +import { cancelMenuAndResetLabel, includeSourceChoiceMenu } from "./menus.ts"; + +export const slashCommandsListener = new Composer() + +slashCommandsListener.hears('/set_default_label', async ctx => { + ctx.reply( + 'Send the label you want to be added for all of the links you send me', + { + reply_markup: cancelMenuAndResetLabel, + } + ) + + await ctx.conversation.enter('setDefaultLabel') +}) + +slashCommandsListener.hears('/set_include_source', ctx => { + ctx.reply( + 'Do you want to include label from what channel or contact you\'ve saved the article?', { + reply_markup: includeSourceChoiceMenu + }) +}) diff --git a/src/types.ts b/src/types.ts new file mode 100644 index 0000000..7fcc9e2 --- /dev/null +++ b/src/types.ts @@ -0,0 +1,15 @@ +export type Label = { + name: string +} + +export type UrlInfo = { + url: string + labels: Label[] +} + + +export type ProcessUrlsParams = { + urls: UrlInfo[]; + additionalLabels?: Label[]; + startIndex?: number; +}; diff --git a/src/utils/getDefaultLabel.ts b/src/utils/getDefaultLabel.ts new file mode 100644 index 0000000..94a7ec9 --- /dev/null +++ b/src/utils/getDefaultLabel.ts @@ -0,0 +1,3 @@ +export function getDefaultLabel(sessionDefaultLabel: string) { + return sessionDefaultLabel ? { name: sessionDefaultLabel } : {} +} diff --git a/src/utils/getSourceLabel.ts b/src/utils/getSourceLabel.ts new file mode 100644 index 0000000..45cd35d --- /dev/null +++ b/src/utils/getSourceLabel.ts @@ -0,0 +1,24 @@ +import { MessageOrigin } from "https://deno.land/x/grammy_types@v3.5.2/message.ts"; + +export function getSourceLabel(source: MessageOrigin) { + let sourceLabel = { name: '' } + + if (source) { + switch (source.type) { + case 'user': + sourceLabel = { name: `${source.sender_user.first_name} ${source.sender_user.last_name}` } + break; + case 'hidden_user': + sourceLabel = { name: source.sender_user_name } + break + case 'channel': + sourceLabel = { name: source.chat.title } + break + case 'chat': + sourceLabel = { name: source.author_signature || '' } + break + } + + return sourceLabel + } +} diff --git a/src/utils/getUrlAndLabels.ts b/src/utils/getUrlAndLabels.ts new file mode 100644 index 0000000..6a360ed --- /dev/null +++ b/src/utils/getUrlAndLabels.ts @@ -0,0 +1,46 @@ +import { getSourceLabel } from "./getSourceLabel.ts"; +import { getDefaultLabel } from "./getDefaultLabel.ts"; +import { parseUrls } from "./parseUrls.ts"; +import { startsWithUrl } from "./startsWithUrl.ts"; +import { Label } from '../types.ts' +import { type Filter } from "https://deno.land/x/grammy@v1.21.1/mod.ts" +import { MyContext } from '../sessionsHandler.ts' + +export function getUrlAndLabels(ctx: Filter) { + let url, labels: Label[] + + // retrieving information from ctx + const message = ctx.message.text + const source = ctx.msg?.forward_origin + + // retrieving information from session + const sessionIncludeSource = ctx.session.includeSource + const sessionDefaultLabel = ctx.session.defaultLabel + + // parse url from the message + if (startsWithUrl(message)) { + ({ url, labels } = parseUrls(message)[0]); + } else { + // retrieve the first url from the message + const urlMatch = message.match(/(?:https?:\/\/|www\.)\S+?(?=\s|$)/); + url = urlMatch ? urlMatch[0] : ''; + labels = []; + } + + // add default label + const defaultLabel = getDefaultLabel(sessionDefaultLabel); + if (defaultLabel.name) { + labels.push(defaultLabel); + } + + // add source label if includeSource is true + if (source && sessionIncludeSource) { + const sourceLabel = getSourceLabel(source); + + if (sourceLabel) { + labels.push(sourceLabel); + } + } + + return { url, labels }; +} diff --git a/src/utils/parseUrls.ts b/src/utils/parseUrls.ts index e693b05..1e70a59 100644 --- a/src/utils/parseUrls.ts +++ b/src/utils/parseUrls.ts @@ -1,7 +1,17 @@ -export function parseUrls(urls: string): string[] { - const regex = /(?:https?:\/\/|www\.)\S+?(?=\s|$)/g +import { UrlInfo } from '../types.ts' - const urlsArray = urls.match(regex) +export function parseUrls(urls: string): UrlInfo[] { + const regex = /((?:https?:\/\/|www\.)[^ \n\r]+)(.*)/g + + let match + const urlsArray = [] + + while ((match = regex.exec(urls)) !== null) { + const url = match[1].trim() + const labels = match[2] ? match[2].trim().split(/\s+/).map(label => ({ name: label })) : [] + + urlsArray.push({ url, labels }) + } return urlsArray || [] } diff --git a/src/utils/startsWithUrl.ts b/src/utils/startsWithUrl.ts new file mode 100644 index 0000000..f8f4c04 --- /dev/null +++ b/src/utils/startsWithUrl.ts @@ -0,0 +1,5 @@ +export function startsWithUrl(text: string) { + const urlPattern = /^\s*(http[s]?:\/\/|www\.)\S/; + + return urlPattern.test(text); +} diff --git a/test/parseUrls.test.ts b/test/parseUrls.test.ts index 237963f..5705cf2 100644 --- a/test/parseUrls.test.ts +++ b/test/parseUrls.test.ts @@ -2,15 +2,15 @@ import { assertEquals } from 'https://deno.land/std@0.218.0/assert/mod.ts' import { parseUrls } from '../src/utils/parseUrls.ts' Deno.test('parse urls from string to array', () => { - const text = `www.sample.com/ - https://omnivore.app/ + const text = `www.sample.com/ fruits science + https://omnivore.app/ productivity https://www.youtube.com/` const arrayOfUrls = parseUrls(text) assertEquals(arrayOfUrls, [ - 'www.sample.com/', - 'https://omnivore.app/', - 'https://www.youtube.com/', + { url: 'www.sample.com/', labels: [ { name: 'fruits' }, { name: 'science' } ] }, + { url: 'https://omnivore.app/', labels: [ { name: 'productivity' } ] }, + { url: 'https://www.youtube.com/', labels: [] } ]) })