{"id":13879720,"url":"https://github.com/RenoFi/salesforce_streamer","last_synced_at":"2025-07-16T15:32:56.470Z","repository":{"id":45550517,"uuid":"196019594","full_name":"RenoFi/salesforce_streamer","owner":"RenoFi","description":"A wrapper around the Restforce Streaming API with a built-in PushTopic manager.","archived":false,"fork":false,"pushed_at":"2025-07-14T10:36:20.000Z","size":348,"stargazers_count":8,"open_issues_count":1,"forks_count":4,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-07-14T13:52:58.222Z","etag":null,"topics":["backend"],"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/RenoFi.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null}},"created_at":"2019-07-09T13:58:18.000Z","updated_at":"2025-07-14T10:36:23.000Z","dependencies_parsed_at":"2024-01-10T16:41:48.653Z","dependency_job_id":"3137653f-1103-495b-914d-7e799f24e9a4","html_url":"https://github.com/RenoFi/salesforce_streamer","commit_stats":null,"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"purl":"pkg:github/RenoFi/salesforce_streamer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RenoFi%2Fsalesforce_streamer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RenoFi%2Fsalesforce_streamer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RenoFi%2Fsalesforce_streamer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RenoFi%2Fsalesforce_streamer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RenoFi","download_url":"https://codeload.github.com/RenoFi/salesforce_streamer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RenoFi%2Fsalesforce_streamer/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265521500,"owners_count":23781522,"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":["backend"],"created_at":"2024-08-06T08:02:30.224Z","updated_at":"2025-07-16T15:32:56.162Z","avatar_url":"https://github.com/RenoFi.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"[![Gem Version](https://badge.fury.io/rb/salesforce_streamer.svg)](https://rubygems.org/gems/salesforce_streamer)\n[![Build Status](https://github.com/RenoFi/salesforce_streamer/actions/workflows/ci.yml/badge.svg)](https://github.com/RenoFi/salesforce_streamer/actions/workflows/ci.yml?query=branch%3Amain)\n\n# salesforce_streamer\n\nA wrapper around the Restforce Streaming API to receive real time updates from\nyour Salesforce instance with a built-in PushTopic manager.\n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'salesforce_streamer'\n```\n\nAnd then execute:\n\n    $ bundle\n\n## Usage\n\n### Configure Push Topics\n\nCreate a YAML file to configure your PushTopic subscriptions. When streamer\nstarts up it will check for any differences between Salesforce PushTopics and\nthis yaml and update any differences when `config.manage_topics = true`.\n\n```yaml\n# config/streamer.yml\n---\nbase: \u0026DEFAULT\n  accounts:\n    handler: \"AccountChangeHandler\"\n    replay: -1\n    name: \"AllAccounts\"\n    api_version: \"49.0\"\n    description: \"Sync Accounts\"\n    notify_for_fields: \"Referenced\"\n    query: \"Select Id, Name From Account\"\n\ndevelopment:\n  \u003c\u003c: *DEFAULT\n\ntest:\n  \u003c\u003c: *DEFAULT\n\nproduction:\n  \u003c\u003c: *DEFAULT\n```\n\n### Define Message Handlers\n\nDefine your handlers somewhere in your project. They must respond to either\n`.perform_async(str)` or `.call(str)`.\n\n```ruby\n# lib/account_change_handler.rb\n# Handle account changes inline\nclass AccountChangeHandler\n  class \u003c\u003c self\n    def call(message)\n      puts message\n    end\n  end\nend\n\n# Handle account changes asynchronously\nclass AccountChangeHandler\n  include Sidekiq::Worker\n\n  def perform(message)\n    puts message\n  end\nend\n```\n\n### Prepare The Environment\n\nSet your Restforce ENV variables in order to establish a connection. See the\nRestforce API documentation for more details. Then start the server using the\ncommand line interface.\n\nConfigure the `SalesforceStreamer` module.\n\n```ruby\n# config/initializers/salesforce_streamer.rb\n\nSalesforceStreamer.configure do |config|\n  config.logger = Logger.new(STDERR, level: 'INFO')\n  config.exception_adapter = proc { |e| puts e }\n  config.replay_adapter = MyReplayAdapter\n  config.use_middleware AfterMessageReceived\n  config.use_faye_extension ErrorLoggingExtension.new\n  config.manage_topics = true\nend\n```\n\n### Launch The Streamer\n\nLaunch the `streamer` service loads the application code at\n`./config/environment` by default if `config.require_path` is unset. It will\nload your push topic configuration from `./config/streamer.yml` if\n`config.config_file` is unset. During the boot sequence it will connect to\nSalesforce using the Restforce client and your configured ENV variables in order\nto upsert push topic definitions.\n\n```\n$ bundle exec streamer\nI, [2019-07-08T22:16:34.104271 #26973]  INFO -- : Launching Streamer Services\nI, [2019-07-09T15:19:55.862351 #78537]  INFO -- : Running Topic Manager\nI, [2019-07-09T15:19:56.860998 #78537]  INFO -- : New PushTopic AllAccounts\nI, [2019-07-09T15:19:56.861079 #78537]  INFO -- : Upsert PushTopic AllAccounts\nI, [2019-07-09T15:19:56.861109 #78537]  INFO -- : Skipping upsert because manage topics is off\nI, [2019-07-08T22:16:34.794933 #26973]  INFO -- : Starting Server\n```\n\nBy default, the server will start up without syncing the push topic configuration.\nSet the configuration option `config.manage_topics = true` will tell the server\nlauncher to update the configuration of the push topic in Salesforce.\n\n```\n$ bundle exec streamer\nI, [2019-07-09T15:19:55.862296 #78537]  INFO -- : Launching Streamer Services\nI, [2019-07-09T15:19:55.862351 #78537]  INFO -- : Running Topic Manager\nI, [2019-07-09T15:19:56.860998 #78537]  INFO -- : New PushTopic AllAccounts\nI, [2019-07-09T15:19:56.861079 #78537]  INFO -- : Upsert PushTopic AllAccounts\nI, [2019-07-09T15:19:57.591241 #78537]  INFO -- : Starting Server\n```\n\nBy default, the executable will load the YAML based on the `RACK_ENV` environment\nvariable, or default to `:development` if not set. You can override this by\nsetting the `config.environment = :integration`\n\n### Message Handling Middleware\n\nYou can initialize the streamer server with any number of middleware classes.\nWhen a message is received by a PushTopic subscription, the chain of middleware\nclasses are executed before the message handler is called.\n\n```ruby\n# config/initializers/streamer.rb\nclass MySimpleMiddleware\n  def initialize(handler)\n    @handler = handler\n  end\n\n  def call(message)\n    @handler.call(message)\n  end\nend\n\nSalesforceStreamer.config.use_middleware MySimpleMiddleware\n```\n\n### ReplayAdapter\n\nThe `config.replay_adapter` should be an object that has an interface like Hash.\nIt must respond to `[]` and `[]=`. By default the adapter is an empty hash.  If\nyou want your push topic replayId to persist between restarts, then you should\nimplement a class with an appropriate interface.\n\n```ruby\nclass MyReplayAdapter\n  def [](channel)\n    Persistence.get(channel)\n  end\n\n  def []=(channel, replay_id)\n    Persistence.set(channel, replay_id)\n  end\nend\n```\n\nThis adapter will be used directly by `Restforce::ReplayExtension`.\n\n### Use Faye Extension\n\nThe `config.use_faye_extension` should be given an object that responds to\n`.incoming(message, callback)` or `.outgoing(message, callback)` or both. Find\nout more about extensions from\n[Faye](https://github.com/faye/faye/blob/master/spec/ruby/server/extensions_spec.rb)\nspecs.\n\nAny configured extensions are added to the Faye client used by the Restforce\nclient when starting up the server. If the extension responds to `.server=` then\nthe instance of `SalesforceStreamer::Server` is assigned. This may be convenient\nto restart the server subscriptions if an error requires a reset.\n\n```ruby\nclass MyRestartFayeExtension\n  attr_accessor :server\n\n  def incoming(message, callback)\n    callback.call(message).tap |message|\n      server.restart if message['error'] == 'tragic'\n    end\n  end\nend\n\nSalesforceStreamer.config.use_faye_extension MyRestartFayeExtension.new\n```\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake rspec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.\n\nTo 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 tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).\n\n## Contributing\n\nBug reports and pull requests are welcome on GitHub at https://github.com/renofi/salesforce_streamer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.\n\n## License\n\nThe gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRenoFi%2Fsalesforce_streamer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FRenoFi%2Fsalesforce_streamer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FRenoFi%2Fsalesforce_streamer/lists"}