Home

Awesome

Feedx

Build Status Coverage Status

Generic feed adding social features to current applications.



Details

RabbitMQ as event producer. This app consumes, stores, and serves. The goal is to create a plug-n-play social feed for existing applications. May be easy to consume events from other sources.

Design

This is an OTP umbrella application, containing other 3 OTP applications within the apps folder.

/apps/bus
/apps/store
/apps/web

bus

store

web

Usage

An app should post events to RabbitMQ with a given format, in order for this app to consume and process events to build the feed. We can always shutdown AMQP, and feed the Store.FeedBuilder using distributed erlang, the API, or building some other mecanism.

We support 3 kind of events. create, update, delete. In order for us to handle an update or delete correctly, we should have already processed the create. udpate wont work once the event is deleted.

Our generic event looks like this.

{
	"event": {
		"type": "create",
		"tenant": 0,
		"user_id": 0,
		"content": "Main data content",
		"extra": {},
		"date": "ISOz date"
	}
}

This app exposes an API endpoint.

GET @ /api/v1/feed

{
	data: [{
		"id": 1,
		"user": {
			"id": 1,
			"full_name": "Nombre",
			"profile_pic": "profile"
		},
		"type": "post",
		"content": "some content",
		"comments": {
			"total": 10,
			"preview": [{
				"user":...,
				"comment": "hello world!"
			}]
		}
	}]
}

GET @ /api/v1/feed/:tenant_id

{
	data: [{
		"id": 1,
		"user": {
			"id": 1,
			"full_name": "Nombre",
			"profile_pic": "profile"
		},
		"type": "post",
		"content": "some content",
		"comments": {
			"total": 10,
			"preview": [{
				"user":...,
				"comment": "hello world!",
				"id": 1
			}]
		}
	}]
}

GET @ /api/v1/feed/:tenant_id/event/:event_id/comments

{
	data: [{
		"user": ...,
		"comment": "Content",
		"id": 1
	}]
}

POST @ /api/v1/feed/:tenant_id/event/:event_id/comments

{
	content: "Hello world!"
}

DELETE @ /api/v1/feed/:tenant_id/event/:event_id/comments/:comment_id

GET @ /api/v1/feed/:tenant_id/event/:event_id/like

GET @ /api/v1/feed/:tenant_id/event/:event_id/unlike

Websockets

We can also subscibe for updates using phoenix channels.

Websocket @ /ws/v1/feed

Channel Subscriptions

Subscribe for company events @ company:<id>

// new event
{
	"type": "create",
	"data": {},
	"id": 0
}

// update event
{
	"type": "create",
	"data": {},
	"id": 0
}

// delete event
{
	"id": 0
}

Subscribe for event changes @ event:<id>

// new comment
{
	"type": "create_comment",
	"data": {},
	"id": 0
}

// update comment
{
	"type": "update_comment",
	"data": {},
	"id": 0
}

// delete comment
{
	"type": "delete_comment",
	"id": 0
}

// new like state
{
	"type": "update_likes",
	"data": {}
}

// someone is typing
{
	"type": "typing",
	"data": {}
}

setup

Change RabbitMQ config on apps/bus/config/{dev, test, prod}.exs.

config :bus, :rabbitmq, "amqp://guest:guest@127.0.0.1"

Change feed data store settings on apps/store/config/{dev, test, prod}.exs

config :store, Store.FeedRepo,
  adapter: Ecto.Adapters.Postgres,
  username: "postgres",
  password: "postgres",
  database: "store_db_dev",
  hostname: "localhost",
  pool_size: 10

Setup your app's database connection, and the name of the table and columns to pull the users parameters.

config :store, Store.SourceRepo,
  adapter: Ecto.Adapters.Postgres,
  username: "postgres",
  password: "postgres",
  database: "store_db_dev",
  hostname: "localhost",
  pool_size: 10

config :store, :external_db_table_name, "tabla"
config :store, :external_db_full_name, :full_name
config :store, :external_db_user_id, :id
config :store, :external_db_profile_pic, :image_url

Cache mecanism for users and other feed interactions can be customized. TTL is not active by default.

config :store, :user_cache,
  ttl: true,
  touch_on_read: true,
  global_ttl: 20,
  check_interval: 2

config :store, :interactions_cache,
  ttl: false

TODO


Easy deploy using edeliver