{"id":17933588,"url":"https://github.com/matrix86/driplane","last_synced_at":"2025-07-10T07:36:35.773Z","repository":{"id":43163490,"uuid":"221052181","full_name":"Matrix86/driplane","owner":"Matrix86","description":"Create automated tasks and keep an eye on interesting things!","archived":false,"fork":false,"pushed_at":"2025-02-18T11:50:29.000Z","size":3246,"stargazers_count":81,"open_issues_count":0,"forks_count":4,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-19T23:05:02.141Z","etag":null,"topics":["automation","bot","filtering","keywords","pipeline","rss-feed","slack","task","tweets","twitter"],"latest_commit_sha":null,"homepage":"https://matrix86.github.io/driplane","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Matrix86.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-11-11T19:15:48.000Z","updated_at":"2025-03-22T10:42:45.000Z","dependencies_parsed_at":"2023-12-22T17:28:44.695Z","dependency_job_id":"6187163e-79e6-4026-a5a9-75de2d819892","html_url":"https://github.com/Matrix86/driplane","commit_stats":{"total_commits":368,"total_committers":3,"mean_commits":"122.66666666666667","dds":0.09239130434782605,"last_synced_commit":"25974fe2ac8d342c6ba422caaad2164786c21c39"},"previous_names":[],"tags_count":22,"template":false,"template_full_name":null,"purl":"pkg:github/Matrix86/driplane","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Matrix86%2Fdriplane","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Matrix86%2Fdriplane/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Matrix86%2Fdriplane/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Matrix86%2Fdriplane/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Matrix86","download_url":"https://codeload.github.com/Matrix86/driplane/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Matrix86%2Fdriplane/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264545256,"owners_count":23625408,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","bot","filtering","keywords","pipeline","rss-feed","slack","task","tweets","twitter"],"created_at":"2024-10-28T21:40:51.156Z","updated_at":"2025-07-10T07:36:35.723Z","avatar_url":"https://github.com/Matrix86.png","language":"Go","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://github.com/Matrix86/driplane/blob/gh-pages/logo.png\"/\u003e\n\u003c/p\u003e\n\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.buymeacoffee.com/mtx86\"\u003e\n    \u003cimg src=\"https://img.shields.io/badge/Buy me a-%F0%9F%8D%BA%20beer-blue?logo=beer\u0026style=for-the-badge\u0026color=grey\u0026logoColor=white\u0026labelColor=blue\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n# Driplane ![License](https://img.shields.io/github/license/Matrix86/driplane) ![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/Matrix86/driplane) ![GitHub Workflow Status (branch)](https://img.shields.io/github/workflow/status/Matrix86/driplane/Build%20and%20Test/master) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/Matrix86/driplane?color=red) ![Codecov](https://img.shields.io/codecov/c/github/Matrix86/driplane) \n\n`Driplane` allows you to create an automatic alerting system or start automated tasks triggered by events.\nYou can keep under control a stream source as Twitter, a file, a RSS feed or a website.\nIt includes a mini language that allows you to define the filtering pipelines (the rules), and it is extensible thanks to an integrated JS plugin system. \n\nWith `driplane` you can create several rules starting from one or more streams, filter the content in the pipeline and launch tasks or send alerts if some event occurred.\n\nThe complete documentation can be found [HERE](https://matrix86.github.io/driplane/doc/)\n\n## Examples\n\n### Twitter\n\nKeep under control the Twitter account of some users or keywords used in Tweets, search for hashes and send a message on Slack using the webhook. \nThe cache will avoid sending messages with hashes already seen in the last 24h. \n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eShow example\u003c/b\u003e\u003c/summary\u003e\n\n**`twitter.rule`**\n```bash\n# Twitter feed\n# Define a rule with a Twitter feeder and define keywords and users\nTwitter =\u003e \u003ctwitter: users=\"goofy, mickeymouse\", keywords=\"malware, virus, PE\"\u003e;\n\n# Define a rule to send a slack message using a defined api hook\nslack =\u003e http(url=\"https://hooks.slack.com/services/XXXXXXXXXX/XXXXXXXXXX/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\",method=\"POST\",headers=\"{\\\"Content-type\\\": \\\"application/json\\\"}\",rawData=\"{{.main}}\");\n\n# Define a rule that filter the received tweets\ntweet_rule =\u003e @Twitter |\n              # ignore spanish tweets\n              !text(target=\"language\", pattern=\"es\") |\n              # extract hashes from them\n              hash(extract=\"true\") |\n              # add a new field to the stream with the hash\n              override(name=\"hash\", value=\"{{ .main }}\") |\n              # drop it if we saw that hash before\n              cache(ttl=\"24h\", global=\"true\") |\n              # fill the template with extracted data\n              format(file=\"slack_twitter.txt\") |\n              # use the rule defined above to send the filled template to slack endpoint\n              @slack_alert;\n```\n\n**`slack_twitter.txt`**\n```json\n{\n\t\"blocks\": [{\n\t\t\"type\": \"context\",\n\t\t\"elements\": [{\n\t\t\t\"text\": \"*Rule* : {{.rule_name}} | *Feeder* : {{.source_feeder}} \",\n\t\t\t\"type\": \"mrkdwn\"\n\t\t}]\n\t}, {\n\t\t\"type\": \"divider\"\n\t}, {\n\t\t\"type\": \"section\",\n\t\t\"text\": {\n\t\t\t\"type\": \"mrkdwn\",\n\t\t\t\"text\": \"Found a new hash : _{{.hash}}_\\nLink to the Twitter post: {{ .link }}\"\n\t\t}\n\t}]\n}\n```\n\n\u003c/details\u003e\n\n### RSS Feed\n\nCheck a RSS feed with a defined frequency to be alerted every time a news containing one or more interesting keywords are published, and send a telegram message.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eShow example\u003c/b\u003e\u003c/summary\u003e\n\n**`rss.rule`**\n```bash\n# Feed example\n# Define a rule called 'RSS' that read a RSS feed every minutes\nRSS =\u003e \u003crss: url=\"http://rss.cnn.com/rss/cnn_topstories.rss\", freq=\"1m\", ignore_pubdate=\"true\"\u003e;\n\n# Define a rule to send a telegram message using a defined api hook\ntelegram =\u003e  http(url=\"https://api.telegram.org/XXX:XXXX/sendMessage\", method=\"POST\", headers=\"{\\\"Content-type\\\": \\\"application/json\\\"}\", rawData=\"{{.main}}\");\n\nnews =\u003e @RSS |\n        # skip links if we saw that before\n        cache(ttl=\"100h\", target=\"link\") |\n        # Search in the description field using a regular expression\n        text(pattern=\"(?i)tech|discovery|bitcoin|trump\", regexp=\"true\", target=\"description\") |\n        # format the output text to send on telegram\n        format(template=\"Found new interesting article: {{ .link }}\") |\n        @telegram;\n```\n\n\u003c/details\u003e\n\n### Slack\n\nCreates a simple bot or keep under control one or more channel. Using the event APIs of Slack every time the bot receives \na message with hashes, it will try to get information from this hash and it replies to the original channel \n(in a private chat if the user contacted the bot privately or in a channel if it has been added to a channel and the event comes from there) with all the gathered info.\nAlso, using another rule, if a file is uploaded, the bot will analyze it and return a report in the reply message. \n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eShow example\u003c/b\u003e\u003c/summary\u003e\n\n**`slack.rule`**\n```bash\n# Simple Slack Bot\n# define the slack feeder: token and verification token are defined in the configuration file\nSlackEvent =\u003e \u003cslack\u003e;\n\n# Get status from zMD\nstatus =\u003e @SlackEvent |\n          # consider only message events\n          text(target=\"type\", pattern=\"message\") |\n          # extract all the hashes found in the message\n          hash(extract=\"true\") |\n          # logic to get the info in the report\n          js(path=\"bot.js\", function=\"GetHashReport\") |\n          # format of the response using the Slack template system\n          format(file=\"slack_report.txt\") |\n          # reply to the channel where the event has been generated \n          slack(action=\"send_message\", to=\"{{.channel}}\", target=\"main\", blocks=\"true\");\n\n# Upload file and get status\nupload =\u003e @SlackEvent |\n          # consider only file_share events\n          text(target=\"type\", pattern=\"file_share\") |\n          # download the file and store it in /tmp/nameofthefile\n          slack(action=\"download_file\", filename=\"/tmp/{{ .name }}\") |\n          # call the method UploadFile() in bot.js: it extract info from the file and return them\n          js(path=\"bot.js\", function=\"UploadFile\") |\n          # format of the response using the Slack template system\n          format(file=\"slack_report.txt\") |\n          # reply to the channel where the event has been generated \n          slack(action=\"send_message\", to=\"{{.channel}}\", target=\"main\");\n\n```\n\n\u003c/details\u003e\n\n## How it works\n\nThe user can define one or more rules. Usually a rule contains a source (`feeder`), who cares of getting the information and sending updates (`Message`) through the pipeline, and one or more `filters`.\nThe filters' job is to choose whether to propagate or not the `Message` to the next filter in the pipeline relying on a _condition_, or change the `Message` received before to propagate it. The `Message` will be propagated only if it verifies the condition.\n\n## Use cases\n\nUsing `driplane` is it possible to:\n\n * keep track of keywords or users on Twitter, receive the new tweets or quoted tweets from them, search for URLs or particular strings in them and send a Telegram or a Slack message through their webhooks.\n * keep track of a RSS feed or a website, and download and store on file all the new changes to them.\n * keep track of changes on a file, and launch alert if a particular condition is verified.\n \nThe rules and the JS plugins allows you to create very complex custom logics.\n  \n## Usage\n\n```\nUsage of ./bin/driplane:\n  -config string\n    \tSet configuration file.\n  -debug\n    \tEnable debug logs.\n  -dry-run\n    \tOnly test the rules syntax.\n  -help\n    \tThis help.\n  -js string\n    \tPath of the js plugins.\n  -rules string\n    \tPath of the rules' directory.\n```\n\n","funding_links":["https://www.buymeacoffee.com/mtx86"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatrix86%2Fdriplane","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmatrix86%2Fdriplane","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmatrix86%2Fdriplane/lists"}