From e34081d076c9ee39820cf7018c453db8903f5230 Mon Sep 17 00:00:00 2001 From: FelipeGuzmanSierra <97761783+FelipeGuzmanSierra@users.noreply.github.com> Date: Mon, 25 Mar 2024 17:35:03 -0500 Subject: [PATCH] Add deprecatios warning and update readme --- README.md | 318 +--------------------------------------------------- bns.gemspec | 6 + lib/bns.rb | 2 + 3 files changed, 10 insertions(+), 316 deletions(-) diff --git a/README.md b/README.md index 80b0c52..93d3004 100644 --- a/README.md +++ b/README.md @@ -1,320 +1,6 @@ -# BNS - Business Notification System +# BNS -Many organizations and individuals rely on automatic notifications across various contexts in their daily operations. With BNS, we aim to provide an open-source platform that empowers users to create customized notification systems tailored to their unique requirements. BNS consists of a series of abstract components designed to facilitate the creation of diverse use cases, regardless of context. - -The underlying idea is to develop generic components that can serve a wide range of needs, this approach ensures that all members of the community can leverage the platform's evolving suite of components and use cases to their advantage. - -![Gem Version](https://img.shields.io/gem/v/bns?style=for-the-badge) -![Gem Total Downloads](https://img.shields.io/gem/dt/bns?style=for-the-badge) -![Build Badge](https://img.shields.io/github/actions/workflow/status/kommitters/bns/ci.yml?branch=project-opensource-config&style=for-the-badge) -[![Coverage Status](https://img.shields.io/coveralls/github/kommitters/bns?style=for-the-badge)](https://coveralls.io/github/kommitters/bns?branch=main) -![GitHub License](https://img.shields.io/github/license/kommitters/bns?style=for-the-badge) -[![OpenSSF Scorecard](https://img.shields.io/ossf-scorecard/github.com/kommitters/bns?label=openssf%20scorecard&style=for-the-badge)](https://api.securityscorecards.dev/projects/github.com/kommitters/bns) -[![OpenSSF Best Practices](https://img.shields.io/cii/summary/8383?label=openssf%20best%20practices&style=for-the-badge)](https://bestpractices.coreinfrastructure.org/projects/8383) - -## Installation - -Install the gem and add to the application's Gemfile by executing: - - $ bundle add bns - -If bundler is not being used to manage dependencies, install the gem by executing: - - $ gem install bns - -## Requirements - -* Ruby 3.2.2 or higher - -## Building my own use case - -The gem provides with basic interfaces, types, and methods to shape your own use cases in an easy way. - -There are 2 currently implemented use cases: -* Birthday notifications - from Notion to Discord -* PTO notifications - from Notion to Discord - -For this example we'll analize the birthday notification use case, bringing data from a notion database, and dispatching the -notifications to a Discord channel. - -A *Use Case* object, consists on 4 main componenets, having it's own responsability: - -### 1. Fetcher - Obtaining the data - -Specifically, a fetcher is an object in charged of bringing data from a data source. The gem already provides the base interface -for building your own fetcher for your specific data source, or rely on already built classes if they match your purpose. - -The base interface for a fetcher can be found under the `bns/fetcher/base.rb` class. Since this is a implementation of the `Fetcher::Base` -for bringing data from a Notion database, it was created on a new namespace for that data source, it can be found under -`/bns/fetcher/notion/birthday.rb`. It implements specific logic for fetching the data and validating the response. - -### 2. Mapper - Shaping it - -The **Mapper** responsability, is to shape the data using custom types from the app domain, bringing it into a -common structure understandable for other components, specifically the **Formatter**. - -Because of the use case, the Mapper implementation for it, relyes on specific types for representing a Birthday it self. It can be found -under `/bns/mapper/notion/birthday.rb` - -### 3. Formatter - Preparing the message - -The **Formatter**, is in charge of preparing the message to be sent in our notification, and give it the right format with the right data. -The template or 'format' to be used should be included in the use case configurations, which we'll review in a further step. It's -implementation can be found under `/bns/formatter/discord/birthday.rb`. - -### 4. Dispatcher - Sending your notification - -Finally, the **Dispatcher** basically, sends or dispatches the formatted message into a destination, since the use case was implemented for -Discord, it implements specific logic to communicate with a Discord channel using a webhook. The webhook configuration and name for the 'Sender' -in the channel should be provided with the initial use case configurations. It can be found under `/bns/dispatcher/discord/implementation.rb` - -## Examples - -In this example, we demonstrate how to instantiate a birthday notification use case and execute it in a basic Ruby project. We'll also cover its deployment in a serverless configuration, specifically using a simple Lambda deployment. - -### Preparing the configurations - -We'll need some configurations for this specific use case: -* A **Notion database ID**, from a database with the following structure: - -| Complete Name (text) | BD_this_year (formula) | BD (date) | -| -------------------- | --------------------------- | ------------------------ | -| John Doe | January 24, 2024 | January 24, 2000 | -| Jane Doe | June 20, 2024 | June 20, 2000 | - -With the following formula for the **BD_this_year** column: `dateAdd(prop("BD"), year(now()) - year(prop("BD")), "years")` - -* A Notion secret, which can be obtained, by creating an integration here: `https://developers.notion.com/`, browsing on the **View my integations** option, and selecting the **New Integration** or **Create new integration** buttons. - -* A webhook key, which can be generated directly on discord on the desired channel, following this instructions: `https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks` - -* A filter, to determine which data to bring from the database, for this specific case, the filter we used is: - -``` -#### file.rb #### -today = Date.now -{ - "filter": { - "or": [ - { - "property": "BD_this_year", - "date": { - "equals": today - } - } - ] - }, - "sorts": [] -} -``` - -* A template for the formatter to be used for formatting the payload to dispatch to Discord. For this specific case, the format of the messages should be: - -`"NAME, Wishing you a very happy birthday! Enjoy your special day! :birthday: :gift:"` - -### Instantiating the Use Case - -To instantiate the use case, the `UseCases` module should provide a method for this purpose, for this specific case, the `notify_birthday_from_notion_to_discord` -is the desired one. - -**Normal ruby code** -``` -filter = { - "filter": { - "or": [ - { - "property": "BD_this_year", - "date": { - "equals": today - } - } - ] - }, - "sorts": [] -} - -options = { - fetch_options: { - base_url: "https://api.notion.com", - database_id: NOTION_DATABASE_ID, - secret: NOTION_API_INTEGRATION_SECRET, - filter: filter - }, - dispatch_options: { - webhook: "https://discord.com/api/webhooks/1199213527672565760/KmpoIzBet9xYG16oFh8W1RWHbpIqT7UtTBRrhfLcvWZdNiVZCTM-gpil2Qoy4eYEgpdf", - name: "Birthday Bot" - } -} - -use_case = UseCases.notify_birthday_from_notion_to_discord(options) - -use_case.perform - -``` - -### Serverless -We'll explain how to configure and deploy a use case with serverless, this example will cover the PTO's notifications use case. - -#### Configuring environment variables -Create the environment variables configuration file. - -```bash -cp env.yml.example env.yml -``` - -And put the following env variables -``` -dev: - NOTION_DATABASE_ID: NOTION_DATABASE_ID - NOTION_SECRET: NOTION_SECRET - DISCORD_WEBHOOK: DISCORD_WEBHOOK - DISCORD_BOT_NAME: DISCORD_BOT_NAME -prod: - NOTION_DATABASE_ID: NOTION_DATABASE_ID - NOTION_SECRET: NOTION_SECRET - DISCORD_WEBHOOK: DISCORD_WEBHOOK - DISCORD_BOT_NAME: DISCORD_BOT_NAME - -``` - -The variables should be defined either in the custom settings section within the `serverless.yml` file to ensure accessibility by all lambdas, or in the environment configuration option for each lambda respectively. For example: - -```bash -# Accessible by all the lambdas -custom: - settings: - api: - NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.NOTION_DATABASE_ID} - NOTION_SECRET: ${file(./env.yml):${env:STAGE}.NOTION_SECRET}} - -# Accessible by the lambda -functions: - lambdaName: - environment: - NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.NOTION_DATABASE_ID} - NOTION_SECRET: ${file(./env.yml):${env:STAGE}.NOTION_SECRET}} -``` - -#### Schedule -the schedule is configured using an environment variable containing the cron configuration. For example: -```bash -# env.yml file -SCHEDULER: cron(0 13 ? * MON-FRI *) - -# serverless.yml -functions: - lambdaName: - events: - - schedule: - rate: ${file(./env.yml):${env:STAGE}.SCHEDULER} -``` - -To learn how to modify the cron configuration follow this guide: [Schedule expressions using rate or cron](https://docs.aws.amazon.com/lambda/latest/dg/services-cloudwatchevents-expressions.html) - -#### Building your lambda -On your serverless configuration, create your lambda function, on your serverless `/src` folder. - -```ruby -# frozen_string_literal: true - -require 'bns' - -# Initialize the environment variables -NOTION_BASE_URL = 'https://api.notion.com' -NOTION_DATABASE_ID = ENV.fetch('PTO_NOTION_DATABASE_ID') -NOTION_SECRET = ENV.fetch('PTO_NOTION_SECRET') -DISCORD_WEBHOOK = ENV.fetch('PTO_DISCORD_WEBHOOK') -DISCORD_BOT_NAME = ENV.fetch('PTO_DISCORD_BOT_NAME') - -module Notifier - # Service description - class UseCaseName - def self.notify(*) - options = { fetch_options:, dispatch_options: } - - begin - use_case = UseCases.use_case_build_function(options) - - use_case.perform - rescue StandardError => e - { body: { message: e.message } } - end - end - - def self.fetch_options - { - base_url: NOTION_BASE_URL, - database_id: NOTION_DATABASE_ID, - secret: NOTION_SECRET, - filter: { - filter: { "and": fetch_filter } - } - } - end - - def self.fetch_filter - today = Common::TimeZone.set_colombia_time_zone.strftime('%F').to_s - - [ - { property: 'Desde?', date: { on_or_before: today } }, - { property: 'Hasta?', date: { on_or_after: today } } - ] - end - - def self.dispatch_options - { - webhook: DISCORD_WEBHOOK, - name: DISCORD_BOT_NAME - } - end - - def self.format_options - { - template: ':beach: individual_name is on PTO' - } - end - end -end -``` - -#### Configure the lambda -In the `serverless.yml` file, add a new instance in the `functions` block with this structure: - -```bash -functions: - ptoNotification: - handler: src/lambdas/pto_notification.Notifier::PTO.notify - environment: - PTO_NOTION_DATABASE_ID: ${file(./env.yml):${env:STAGE}.PTO_NOTION_DATABASE_ID} - PTO_NOTION_SECRET: ${file(./env.yml):${env:STAGE}.PTO_NOTION_SECRET} - PTO_DISCORD_WEBHOOK: ${file(./env.yml):${env:STAGE}.PTO_DISCORD_WEBHOOK} - PTO_DISCORD_BOT_NAME: ${file(./env.yml):${env:STAGE}.DISCORD_BOT_NAME} - events: - - schedule: - name: pto-daily-notification - description: "Notify every 24 hours at 8:30 a.m (UTC-5) from monday to friday" - rate: cron(${file(./env.yml):${env:STAGE}.PTO_SCHEDULER}) - enabled: true -``` - -#### Deploying - -Configure the AWS keys: - -```bash -serverless config credentials --provider aws --key YOUR_KEY --secret YOUR_SECRET -``` - -Deploy the project: -```bash -STAGE=prod sls deploy --verbose -``` - -## Development - -After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. - -To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org). +Moved to [bas](https://github.com/kommitters/bas). ## Changelog diff --git a/bns.gemspec b/bns.gemspec index c6fdcfa..7e3d815 100644 --- a/bns.gemspec +++ b/bns.gemspec @@ -34,4 +34,10 @@ Gem::Specification.new do |spec| # For more information and examples about making a new gem, check out our # guide at: https://bundler.io/guides/creating_gem.html + + spec.post_install_message = <<-MESSAGE + ! The 'BNS' gem has been deprecated and has been replaced by 'BAS'. + ! See: https://rubygems.org/gems/bas + ! And: https://github.com/kommitters/bas + MESSAGE end diff --git a/lib/bns.rb b/lib/bns.rb index 2af1f6f..5592f8f 100644 --- a/lib/bns.rb +++ b/lib/bns.rb @@ -6,4 +6,6 @@ module Bns # rubocop:disable Style/Documentation include UseCases class Error < StandardError; end + + warn "[DEPRECATION] This gem has been renamed to bas and will no longer be supported. Please switch to bas as soon as possible." end