{"id":19723500,"url":"https://github.com/remind101/beso","last_synced_at":"2025-07-06T13:39:32.604Z","repository":{"id":2983350,"uuid":"3999292","full_name":"remind101/beso","owner":"remind101","description":null,"archived":false,"fork":false,"pushed_at":"2012-05-15T00:43:31.000Z","size":204,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-10T17:54:17.081Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/remind101.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-04-11T22:57:01.000Z","updated_at":"2013-10-03T09:16:16.000Z","dependencies_parsed_at":"2022-08-06T13:00:41.031Z","dependency_job_id":null,"html_url":"https://github.com/remind101/beso","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remind101%2Fbeso","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remind101%2Fbeso/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remind101%2Fbeso/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/remind101%2Fbeso/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/remind101","download_url":"https://codeload.github.com/remind101/beso/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241045473,"owners_count":19899654,"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":[],"created_at":"2024-11-11T23:22:24.412Z","updated_at":"2025-02-27T18:43:23.665Z","avatar_url":"https://github.com/remind101.png","language":"Ruby","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Beso\n\nSync your historical events to KISSmetrics via CSV.\n\nhttp://support.kissmetrics.com/integrations/csv-import/recurring-import\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n    gem 'beso'\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install beso\n\nNext, create an initializer for **beso**. There, you can set up your S3 bucket information and define your\nserialization jobs:\n\n``` rb\n# config/initializers/beso.rb\nBeso.configure do |config|\n\n  # First, set up your S3 credentials:\n\n  config.access_key  = '[your AWS access key]'\n  config.secret_key  = '[your AWS secret key]'\n  config.bucket_name = 'beso' # recommended, but you can really call this anything\n\n  # Then, define some jobs:\n\n  config.job :message_delivered, :table =\u003e :messages do\n    identity { |message| message.user.id }\n    timestamp :created_at\n    prop( :message_id ) { |message| message.id }\n  end\n\n  config.job :signed_up, :table =\u003e :users do\n    identity { |user| user.id }\n    timestamp :created_at\n    prop( :age ){ |user| user.age }\n  end\nend\n```\n\n## Usage\n\n### Defining Jobs\n\nKISSmetrics events have three properties that *must* be defined:\n\n- Identity\n- Timestamp\n- Event\n\nThe **Identity** field is some sort of identifier for your user. Even if your job\nis working on another table, you should probably have a way to tie the event back\nto the user who caused it. Here, you can provide one of three things:\n\n- A proc that should receive the record and return the identity value\n- A symbol that will get passed to `record.send`\n- A literal (You'll probably want to do one of the other two options)\n\nThe **Timestamp** field is slightly different in that it should always be part of\nthe table you are querying, not the user. This symbol will get sent to each record,\nbut will also be used in determining the query for the job.\n\nThe **Event** name is inferred by the name of your job. It will be provided and\nformatted for you.\n\nOn top of this, you can specify up to **ten** custom properties. Like `identity`,\nyou can pass either a proc, a symbol, or a literal:\n\n``` rb\nconfig.job :signed_up, :table =\u003e :users do\n  identity :id\n  timestamp :created_at\n  prop( :age ){ |user| user.age }\n  prop( :new_user, true )\nend\n```\n\n### Using the rake task\n\nBy requiring `beso`, you get the `beso:run` rake task. This task will do the following:\n\n- Connect to your S3 bucket\n- Pull down 'beso.yml' if it exists\n\n\u003e `beso.yml` contains the timestamp of the last record queried for each job.\n\u003e If it doesn't exist, it will be created after the first run.\n\n- Iterate over the jobs defined in the initializer you set up\n- Create a CSV representation of all records newer than the timestamp found in `beso.yml`\n- Upload each CSV to your S3 bucket with the event name and timestamp\n- Update `beso.yml` with the latest timestamp for each job\n\nThe rake task is designed to be used via cron. For the moment, KISSmetrics will only process\none CSV file per hour, so it makes sense that this task should be run at an interval of hours\nequal to the number of jobs you have defined. For example, if you have defined 4 jobs, this\ntask should run once every 4 hours.\n\nThe rake task also accepts two options that you can set via environment variables.\n\n`BESO_PREFIX` will change the prefix of the CSV filenames that get uploaded to S3. The default\nis 'beso', so it is recommended you use that when telling KISSmetrics what your filename\npattern is. You can then adjust the prefix if you would like to upload CSV's that you don't\nwant KISSmetrics to recognize.\n\n`BESO_ORIGIN` will change the behavior of the task when there is no previous timestamp\ndefined for a job in `beso.yml`.\n\n\u003e By default, the task will use the last timestamp in your table (which effectively\n\u003e means the first run of this task will do nothing). This is because KISSmetrics\n\u003e charges you for every event you log through their system, so you probably don't\n\u003e want to upload 8 months worth of events straight away.\n\nThis option will accept two values to alter the behavior:\n\n- `now` will set the first run timestamp to now, which will obviously not create any events.\n- `first` will set the first run timestamp to the first timestamp in each table. Use this with\n  `BESO_PREFIX` if you want to dump an entire table's worth of events to S3 without having\n  KISSmetrics process them.\n\n## Contributing\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Added some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremind101%2Fbeso","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fremind101%2Fbeso","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fremind101%2Fbeso/lists"}