Added first user also to all groups (master agent).
This commit is contained in:
parent
f1c934caa4
commit
2c325454a1
22 changed files with 793 additions and 320 deletions
|
@ -1,5 +1,10 @@
|
|||
$ = jQuery.sub()
|
||||
|
||||
$.fn.item = (genericObject) ->
|
||||
elementID = $(@).data('id')
|
||||
elementID or= $(@).parents('[data-id]').data('id')
|
||||
genericObject.find(elementID)
|
||||
|
||||
class App.ChannelEmail extends App.ControllerTabs
|
||||
constructor: ->
|
||||
super
|
||||
|
@ -8,10 +13,12 @@ class App.ChannelEmail extends App.ControllerTabs
|
|||
{
|
||||
name: 'Inbound',
|
||||
target: 'c-inbound',
|
||||
controller: App.ChannelEmailInbound,
|
||||
},
|
||||
{
|
||||
name: 'Outbound',
|
||||
target: 'c-outbound',
|
||||
controller: App.ChannelEmailOutbound,
|
||||
},
|
||||
{
|
||||
name: 'Adresses',
|
||||
|
@ -28,84 +35,197 @@ class App.ChannelEmail extends App.ControllerTabs
|
|||
},
|
||||
]
|
||||
|
||||
# App.Channel.bind 'refresh change', @render
|
||||
# App.Channel.fetch()
|
||||
@render()
|
||||
|
||||
render2: =>
|
||||
settings = App.Setting.all()
|
||||
class App.ChannelEmailInboundEdit extends App.ControllerModal
|
||||
constructor: ->
|
||||
super
|
||||
@render(@object)
|
||||
|
||||
html = $('<div></div>')
|
||||
for setting in settings
|
||||
if setting.area is @area
|
||||
item = new App.SettingsAreaItem( setting: setting )
|
||||
html.append( item.el )
|
||||
render: (data = {}) ->
|
||||
|
||||
@html html
|
||||
configure_attributes = [
|
||||
{ name: 'adapter', display: 'Type', tag: 'select', multiple: false, null: false, options: { IMAP: 'IMAP', POP3: 'POP3' } , class: 'span4', default: data['adapter'] },
|
||||
{ name: 'host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, class: 'span4', autocapitalize: false, default: (data['options']&&data['options']['host']) },
|
||||
{ name: 'user', display: 'User', tag: 'input', type: 'text', limit: 120, null: false, class: 'span4', autocapitalize: false, default: (data['options']&&data['options']['user']) },
|
||||
{ name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: false, class: 'span4', autocapitalize: false, default: (data['options']&&data['options']['password']) },
|
||||
{ name: 'ssl', display: 'SSL', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' } , class: 'span4', default: (data['options']&&data['options']['ssl']) },
|
||||
{ name: 'group_id', display: 'Group', tag: 'select', multiple: false, null: false, filter: @edit_form, nulloption: false, relation: 'Group', class: 'span4', default: data['group_id'] },
|
||||
{ name: 'active', display: 'Active', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' } , class: 'span4', default: data['active'] },
|
||||
]
|
||||
form = @formGen( model: { configure_attributes: configure_attributes, className: '' } )
|
||||
|
||||
@html App.view('generic/admin/new')(
|
||||
form: form,
|
||||
head: 'New Channel'
|
||||
)
|
||||
@modalShow()
|
||||
|
||||
submit: (e) =>
|
||||
e.preventDefault()
|
||||
|
||||
# get params
|
||||
params = @formParam(e.target)
|
||||
|
||||
object = @object || new App.Channel
|
||||
object.load(
|
||||
area: 'Email::Inbound',
|
||||
adapter: params['adapter'],
|
||||
group_id: params['group_id'],
|
||||
options: {
|
||||
host: params['host'],
|
||||
user: params['user'],
|
||||
password: params['password'],
|
||||
ssl: params['ssl'],
|
||||
},
|
||||
host: params['host'],
|
||||
user: params['user'],
|
||||
password: params['password'],
|
||||
active: params['active'],
|
||||
)
|
||||
|
||||
# validate form
|
||||
errors = object.validate()
|
||||
|
||||
# show errors in form
|
||||
if errors
|
||||
@log 'error new', errors
|
||||
@validateForm( form: e.target, errors: errors )
|
||||
return false
|
||||
|
||||
# save object
|
||||
object.save(
|
||||
success: =>
|
||||
@modalHide()
|
||||
error: =>
|
||||
@log 'errors'
|
||||
@modalHide()
|
||||
)
|
||||
|
||||
|
||||
|
||||
class App.SettingsAreaItem2 extends App.Controller
|
||||
class App.ChannelEmailInbound extends App.Controller
|
||||
events:
|
||||
'submit form': 'update',
|
||||
'click [data-type=new]': 'new'
|
||||
'click [data-type=edit]': 'edit'
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
@render()
|
||||
|
||||
App.Channel.bind 'refresh change', @render
|
||||
App.Channel.fetch()
|
||||
|
||||
render: =>
|
||||
# defaults
|
||||
for item in @setting.options['form']
|
||||
if typeof @setting.state.value is 'object'
|
||||
item['default'] = @setting.state.value[item.name]
|
||||
else
|
||||
item['default'] = @setting.state.value
|
||||
channels = App.Channel.all()
|
||||
|
||||
# form
|
||||
@configure_attributes = @setting.options['form']
|
||||
form = @formGen( model: { configure_attributes: @configure_attributes, className: '' }, autofocus: false )
|
||||
html = $('<div></div>')
|
||||
data = []
|
||||
for channel in channels
|
||||
if channel.area is 'Email::Inbound'
|
||||
channel.host = channel.options['host']
|
||||
channel.user = channel.options['user']
|
||||
data.push channel
|
||||
|
||||
# item
|
||||
@html App.view('settings/item')(
|
||||
setting: @setting,
|
||||
form: form,
|
||||
table = @table(
|
||||
overview: ['host', 'user', 'adapter', 'active'],
|
||||
model: App.Channel,
|
||||
objects: data,
|
||||
)
|
||||
|
||||
html.append( table )
|
||||
html.append( '<a data-type="new" class="btn">new account</a>' )
|
||||
@html html
|
||||
|
||||
new: (e) =>
|
||||
e.preventDefault()
|
||||
new App.ChannelEmailInboundEdit()
|
||||
|
||||
edit: (e) =>
|
||||
e.preventDefault()
|
||||
item = $(e.target).item( App.Channel )
|
||||
new App.ChannelEmailInboundEdit( object: item )
|
||||
|
||||
|
||||
class App.ChannelEmailOutbound extends App.Controller
|
||||
events:
|
||||
'change #_adapter': 'toggle'
|
||||
'submit #mail_adapter': 'update'
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
App.Channel.bind 'refresh change', @render
|
||||
App.Channel.fetch()
|
||||
|
||||
render: =>
|
||||
channels = App.Channel.all()
|
||||
data = []
|
||||
adapters = {}
|
||||
adapter_used = undefined
|
||||
channel_used = undefined
|
||||
for channel in channels
|
||||
if channel.area is 'Email::Outbound'
|
||||
|
||||
data.push channel
|
||||
adapters[channel.adapter] = channel.adapter
|
||||
if @adapter_used
|
||||
if @adapter_used is channel.adapter
|
||||
adapter_used = channel.adapter
|
||||
channel_used = channel
|
||||
else if channel.active is true
|
||||
adapter_used = channel.adapter
|
||||
channel_used = channel
|
||||
|
||||
configure_attributes = [
|
||||
{ name: 'adapter', display: 'Send Mails via', tag: 'select', multiple: false, null: false, options: adapters , class: 'span4', default: adapter_used },
|
||||
]
|
||||
form_adapter = @formGen( model: { configure_attributes: configure_attributes, className: '' } )
|
||||
|
||||
if adapter_used is 'SMTP'
|
||||
configure_attributes = [
|
||||
{ name: 'host', display: 'Host', tag: 'input', type: 'text', limit: 120, null: false, class: 'span4', autocapitalize: false, default: (channel_used['options']&&channel_used['options']['host']) },
|
||||
{ name: 'user', display: 'User', tag: 'input', type: 'text', limit: 120, null: true, class: 'span4', autocapitalize: false, default: (channel_used['options']&&channel_used['options']['user']) },
|
||||
{ name: 'password', display: 'Password', tag: 'input', type: 'password', limit: 120, null: true, class: 'span4', autocapitalize: false, default: (channel_used['options']&&channel_used['options']['password']) },
|
||||
{ name: 'ssl', display: 'SSL', tag: 'select', multiple: false, null: false, options: { true: 'yes', false: 'no' } , class: 'span4', default: (channel_used['options']&&channel_used['options']['ssl']) },
|
||||
]
|
||||
form_adapter_settings = @formGen( model: { configure_attributes: configure_attributes, className: '' } )
|
||||
|
||||
html = App.view('channel/email_outbound')(
|
||||
form_adapter: form_adapter,
|
||||
form_adapter_settings: form_adapter_settings,
|
||||
)
|
||||
html = $(html)
|
||||
@html html
|
||||
|
||||
toggle: (e) =>
|
||||
|
||||
# get params
|
||||
params = @formParam(e.target)
|
||||
|
||||
@adapter_used = params['adapter']
|
||||
|
||||
@render()
|
||||
|
||||
update: (e) =>
|
||||
e.preventDefault()
|
||||
params = @formParam(e.target)
|
||||
@log 'submit', @setting, params, e.target
|
||||
if typeof @setting.state.value is 'object'
|
||||
state = {
|
||||
value: params
|
||||
}
|
||||
else
|
||||
state = {
|
||||
value: params[@setting.name]
|
||||
}
|
||||
|
||||
@setting['state'] = state
|
||||
@setting.save(
|
||||
success: =>
|
||||
|
||||
# login check
|
||||
auth = new App.Auth
|
||||
auth.loginCheck()
|
||||
channels = App.Channel.all()
|
||||
for channel in channels
|
||||
if channel.area is 'Email::Outbound' && channel.adapter is params['adapter']
|
||||
channel.updateAttributes(
|
||||
options: {
|
||||
host: params['host'],
|
||||
user: params['user'],
|
||||
password: params['password'],
|
||||
ssl: params['ssl'],
|
||||
},
|
||||
active: true,
|
||||
)
|
||||
|
||||
class App.ChannelEmail2 extends App.Controller
|
||||
events:
|
||||
'click [data-toggle="tabnav"]': 'toggle',
|
||||
# set all other to inactive
|
||||
channels = App.Channel.all()
|
||||
for channel in channels
|
||||
if channel.area is 'Email::Outbound' && channel.adapter isnt params['adapter']
|
||||
channel.updateAttributes( active: false )
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
# render page
|
||||
# rerender
|
||||
@render()
|
||||
|
||||
render: ->
|
||||
|
||||
@html App.view('channel/email')(
|
||||
head: 'some header'
|
||||
)
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
$ = jQuery.sub()
|
||||
|
||||
class Index extends App.ControllerLevel2
|
||||
toggleable: true
|
||||
# toggleable: true
|
||||
toggleable: false
|
||||
|
||||
menu: [
|
||||
{ name: 'Web', 'target': 'web', controller: App.ChannelWeb },
|
||||
{ name: 'Mail', 'target': 'email', controller: App.ChannelEmail },
|
||||
{ name: 'Chat', 'target': 'chat', controller: App.ChannelChat },
|
||||
{ name: 'Twitter', 'target': 'twitter', controller: App.ChannelTwitter },
|
||||
{ name: 'Facebook', 'target': 'facebook', controller: App.ChannelFacebook },
|
||||
{ name: 'Web', target: 'web', controller: App.ChannelWeb },
|
||||
{ name: 'Mail', target: 'email', controller: App.ChannelEmail },
|
||||
{ name: 'Chat', target: 'chat', controller: App.ChannelChat },
|
||||
{ name: 'Twitter', target: 'twitter', controller: App.ChannelTwitter },
|
||||
{ name: 'Facebook', target: 'facebook', controller: App.ChannelFacebook },
|
||||
]
|
||||
page: {
|
||||
title: 'Channels',
|
||||
|
@ -24,5 +25,6 @@ class Index extends App.ControllerLevel2
|
|||
# render page
|
||||
@render()
|
||||
|
||||
Config.Routes['channels/:target'] = Index
|
||||
Config.Routes['channels'] = Index
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ $ = jQuery.sub()
|
|||
|
||||
class Index extends App.ControllerLevel2
|
||||
toggleable: false
|
||||
toggleable: true
|
||||
# toggleable: true
|
||||
|
||||
constructor: ->
|
||||
super
|
||||
|
|
14
app/assets/javascripts/app/models/channel.js.coffee
Normal file
14
app/assets/javascripts/app/models/channel.js.coffee
Normal file
|
@ -0,0 +1,14 @@
|
|||
class App.Channel extends App.Model
|
||||
@configure 'Channel', 'adapter', 'area', 'options', 'group_id', 'active'
|
||||
@extend Spine.Model.Ajax
|
||||
|
||||
@configure_attributes = [
|
||||
{ name: 'adapter', display: 'Adapter', tag: 'input', type: 'text', limit: 100, null: false, 'class': 'xlarge' },
|
||||
{ name: 'area', display: 'Area', tag: 'input', type: 'text', limit: 100, null: false, 'class': 'xlarge' },
|
||||
# { name: 'host', display: 'Host', tag: 'input', type: 'text', limit: 100, null: false, 'class': 'xlarge' },
|
||||
# { name: 'user', display: 'User', tag: 'input', type: 'text', limit: 100, null: false, 'class': 'xlarge' },
|
||||
# { name: 'password', display: 'Password', tag: 'input', type: 'text', limit: 100, null: fa, 'class': 'xlarge' },
|
||||
{ name: 'options', display: 'Area', tag: 'input', type: 'text', limit: 100, null: false, 'class': 'xlarge' },
|
||||
{ name: 'group_id', display: 'Group', tag: 'option', type: 'text', limit: 100, null: true, 'class': 'xlarge' },
|
||||
{ name: 'active', display: 'Active', tag: 'boolean', type: 'boolean', 'default': true, null: true, 'class': 'xlarge' },
|
||||
]
|
|
@ -1,72 +0,0 @@
|
|||
<div class="tab-pane active" id="channel-inbound">
|
||||
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Host</th>
|
||||
<th>User</th>
|
||||
<th>Type</th>
|
||||
<th>Active</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lalal.example.com</td>
|
||||
<td>wpt234rwr</td>
|
||||
<td>IMAP</td>
|
||||
<td>true</td>
|
||||
<td>x</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>l31alal.example.com</td>
|
||||
<td>wpt23dd4rwr</td>
|
||||
<td>POP3</td>
|
||||
<td>true</td>
|
||||
<td>x</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
<div class="tab-pane" id="channel-outbound">
|
||||
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Host</th>
|
||||
<th>User</th>
|
||||
<th>Type</th>
|
||||
<th>Active</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lalal.example.com</td>
|
||||
<td>wpt234rwr</td>
|
||||
<td>SMTP</td>
|
||||
<td>true</td>
|
||||
<td>x</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>l31alal.example.com</td>
|
||||
<td>wpt23dd4rwr</td>
|
||||
<td>Sendmail</td>
|
||||
<td>true</td>
|
||||
<td>x</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="tab-pane" id="channel-filter">
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>Active</th>
|
||||
<th>Delete</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>lalal.example.com</td>
|
||||
<td>true</td>
|
||||
<td>x</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>wpt23dd4rwr</td>
|
||||
<td>true</td>
|
||||
<td>x</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
|
@ -0,0 +1,5 @@
|
|||
<form id="mail_adapter">
|
||||
<%- @form_adapter %>
|
||||
<%- @form_adapter_settings %>
|
||||
<button data-type="" type="submit" class="btn">submit</botton>
|
||||
</form>
|
|
@ -3,6 +3,7 @@
|
|||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="">
|
||||
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
|
@ -20,5 +21,6 @@
|
|||
<td>x</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
|
@ -130,8 +130,8 @@ class ApplicationController < ActionController::Base
|
|||
|
||||
# config
|
||||
config = {}
|
||||
Setting.where( :frontend => true ).each { |setting|
|
||||
config[setting.name] = setting.state[:value]
|
||||
Setting.select('name').where( :frontend => true ).each { |setting|
|
||||
config[setting.name] = Setting.get(setting.name)
|
||||
}
|
||||
return config
|
||||
end
|
||||
|
|
49
app/controllers/channels_controller.rb
Normal file
49
app/controllers/channels_controller.rb
Normal file
|
@ -0,0 +1,49 @@
|
|||
class ChannelsController < ApplicationController
|
||||
before_filter :authentication_check
|
||||
|
||||
# GET /channels
|
||||
def index
|
||||
@channels = Channel.all
|
||||
|
||||
render :json => @channels
|
||||
end
|
||||
|
||||
# GET /channels/1
|
||||
def show
|
||||
@channel = Channel.find(params[:id])
|
||||
|
||||
render :json => @channel
|
||||
end
|
||||
|
||||
# POST /channels
|
||||
def create
|
||||
|
||||
@channel = Channel.new(params[:channel])
|
||||
@channel.created_by_id = current_user.id
|
||||
|
||||
if @channel.save
|
||||
render :json => @channel, :status => :created
|
||||
else
|
||||
render :json => @channel.errors, :status => :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
# PUT /channels/1
|
||||
def update
|
||||
@channel = Channel.find(params[:id])
|
||||
|
||||
if @channel.update_attributes(params[:channel])
|
||||
render :json => @channel, :status => :ok
|
||||
else
|
||||
render :json => @channel.errors, :status => :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
# DELETE /channels/1
|
||||
def destroy
|
||||
@channel = Channel.find(params[:id])
|
||||
@channel.destroy
|
||||
|
||||
head :ok
|
||||
end
|
||||
end
|
|
@ -38,14 +38,24 @@ class UsersController < ApplicationController
|
|||
|
||||
# check if it's first user
|
||||
count = User.all.count()
|
||||
group_ids = []
|
||||
role_ids = []
|
||||
|
||||
# add first user as admin/agent and to all groups
|
||||
if count <= 2
|
||||
role_ids.push Role.where( :name => 'Admin' ).first.id
|
||||
role_ids.push Role.where( :name => 'Agent' ).first.id
|
||||
Role.where( :name => [ 'Admin', 'Agent'] ).each { |role|
|
||||
role_ids.push role.id
|
||||
}
|
||||
Group.all().each { |group|
|
||||
group_ids.push group.id
|
||||
}
|
||||
|
||||
# everybody else will go as customer per default
|
||||
else
|
||||
role_ids.push Role.where( :name => 'Customer' ).first.id
|
||||
end
|
||||
@user.role_ids = role_ids
|
||||
@user.group_ids = group_ids
|
||||
|
||||
# else do assignment as defined
|
||||
else
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
class Channel < ActiveRecord::Base
|
||||
store :options
|
||||
|
||||
def self.send2
|
||||
# find outbound
|
||||
|
||||
end
|
||||
|
||||
def self.fetch
|
||||
Rails.application.config.channel.each { |channel|
|
||||
channels = Channel.where( 'active = ? AND area LIKE ?', true, '%::Inbound' )
|
||||
channels.each { |channel|
|
||||
begin
|
||||
c = eval channel[:module] + '.new'
|
||||
c = eval 'Channel::' + channel[:adapter] + '.new'
|
||||
c.fetch(channel)
|
||||
rescue Exception => e
|
||||
puts "can't use " + channel[:module]
|
||||
puts "can't use " + 'Channel::' + channel[:adapter]
|
||||
puts e.inspect
|
||||
end
|
||||
}
|
||||
|
|
|
@ -4,12 +4,11 @@ require 'net/imap'
|
|||
class Channel::IMAP
|
||||
include UserInfo
|
||||
|
||||
# def fetch(:oauth_token, :oauth_token_secret)
|
||||
def fetch (account)
|
||||
puts 'fetching imap'
|
||||
|
||||
imap = Net::IMAP.new(account[:host], 993, true )
|
||||
imap.authenticate('LOGIN', account[:user], account[:pw])
|
||||
imap = Net::IMAP.new(account[:options][:host], 993, true )
|
||||
imap.authenticate('LOGIN', account[:options][:user], account[:options][:password])
|
||||
imap.select('INBOX')
|
||||
imap.search(['ALL']).each do |message_id|
|
||||
msg = imap.fetch(message_id,'RFC822')[0].attr['RFC822']
|
||||
|
@ -50,7 +49,7 @@ class Channel::IMAP
|
|||
end
|
||||
|
||||
# get ticket# from subject
|
||||
ticket = Ticket.number_check(mail[:subject].value)
|
||||
ticket = Ticket.number_check( mail[:subject].value )
|
||||
|
||||
# set ticket state to open if not new
|
||||
if ticket
|
||||
|
@ -65,7 +64,7 @@ class Channel::IMAP
|
|||
# create new ticket
|
||||
if !ticket then
|
||||
ticket = Ticket.create(
|
||||
:group_id => Group.where( :name => account[:group] ).first.id,
|
||||
:group_id => account[:group_id],
|
||||
:customer_id => user.id,
|
||||
:title => conv(mail['subject'].charset || 'LATIN1', mail['subject'].to_s),
|
||||
:ticket_state_id => Ticket::State.where(:name => 'new').first.id,
|
||||
|
@ -143,59 +142,16 @@ class Channel::IMAP
|
|||
end
|
||||
imap.expunge()
|
||||
imap.disconnect()
|
||||
puts 'done'
|
||||
end
|
||||
def send(attr, account, notification = false)
|
||||
mail = Mail.new
|
||||
|
||||
# set organization
|
||||
organization = Setting.get('organization')
|
||||
if organization then;
|
||||
mail['organization'] = organization.to_s
|
||||
def send(attr, notification = false)
|
||||
channel = Channel.where( :area => 'Email::Outbound', :active => true ).first
|
||||
begin
|
||||
c = eval 'Channel::' + channel[:adapter] + '.new'
|
||||
c.send(attr, channel, notification)
|
||||
rescue Exception => e
|
||||
puts "can't use " + 'Channel::' + channel[:adapter]
|
||||
puts e.inspect
|
||||
end
|
||||
|
||||
# notification
|
||||
if notification
|
||||
attr['X-Loop'] = 'yes'
|
||||
attr['Precedence'] = 'bulk'
|
||||
attr['Auto-Submitted'] = 'auto-generated'
|
||||
end
|
||||
|
||||
# set headers
|
||||
attr.each do |key, v|
|
||||
if key.to_s != 'attachments' && key.to_s != 'body'
|
||||
mail[key.to_s] = v.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# add body
|
||||
mail.text_part = Mail::Part.new do
|
||||
body attr[:body]
|
||||
end
|
||||
|
||||
# add attachments
|
||||
if attr[:attachments]
|
||||
attr[:attachments].each do |attachment|
|
||||
mail.attachments[attachment.filename] = {
|
||||
:content_type => attachment.preferences['Content-Type'],
|
||||
:mime_type => attachment.preferences['Mime-Type'],
|
||||
:content => attachment.store_file.data
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
#mail.delivery_method :sendmail
|
||||
mail.delivery_method :smtp, {
|
||||
:openssl_verify_mode => 'none',
|
||||
:address => account[:host],
|
||||
# :port => 587,
|
||||
:port => 25,
|
||||
:domain => account[:host],
|
||||
:user_name => account[:user],
|
||||
:password => account[:pw],
|
||||
# :authentication => 'plain',
|
||||
:enable_starttls_auto => true
|
||||
}
|
||||
mail.deliver
|
||||
|
||||
end
|
||||
end
|
48
app/models/channel/sendmail.rb
Normal file
48
app/models/channel/sendmail.rb
Normal file
|
@ -0,0 +1,48 @@
|
|||
require 'mail'
|
||||
|
||||
class Channel::Sendmail
|
||||
include UserInfo
|
||||
def send(attr, channel, notification = false)
|
||||
mail = Mail.new
|
||||
|
||||
# set organization
|
||||
organization = Setting.get('organization')
|
||||
if organization then;
|
||||
mail['organization'] = organization.to_s
|
||||
end
|
||||
|
||||
# notification
|
||||
if notification
|
||||
attr['X-Loop'] = 'yes'
|
||||
attr['Precedence'] = 'bulk'
|
||||
attr['Auto-Submitted'] = 'auto-generated'
|
||||
end
|
||||
|
||||
# set headers
|
||||
attr.each do |key, v|
|
||||
if key.to_s != 'attachments' && key.to_s != 'body'
|
||||
mail[key.to_s] = v.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# add body
|
||||
mail.text_part = Mail::Part.new do
|
||||
body attr[:body]
|
||||
end
|
||||
|
||||
# add attachments
|
||||
if attr[:attachments]
|
||||
attr[:attachments].each do |attachment|
|
||||
mail.attachments[attachment.filename] = {
|
||||
:content_type => attachment.preferences['Content-Type'],
|
||||
:mime_type => attachment.preferences['Mime-Type'],
|
||||
:content => attachment.store_file.data
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
mail.delivery_method :sendmail
|
||||
mail.deliver
|
||||
|
||||
end
|
||||
end
|
58
app/models/channel/smtp.rb
Normal file
58
app/models/channel/smtp.rb
Normal file
|
@ -0,0 +1,58 @@
|
|||
require 'mail'
|
||||
|
||||
class Channel::SMTP
|
||||
include UserInfo
|
||||
def send(attr, channel, notification = false)
|
||||
mail = Mail.new
|
||||
|
||||
# set organization
|
||||
organization = Setting.get('organization')
|
||||
if organization then;
|
||||
mail['organization'] = organization.to_s
|
||||
end
|
||||
|
||||
# notification
|
||||
if notification
|
||||
attr['X-Loop'] = 'yes'
|
||||
attr['Precedence'] = 'bulk'
|
||||
attr['Auto-Submitted'] = 'auto-generated'
|
||||
end
|
||||
|
||||
# set headers
|
||||
attr.each do |key, v|
|
||||
if key.to_s != 'attachments' && key.to_s != 'body'
|
||||
mail[key.to_s] = v.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# add body
|
||||
mail.text_part = Mail::Part.new do
|
||||
body attr[:body]
|
||||
end
|
||||
|
||||
# add attachments
|
||||
if attr[:attachments]
|
||||
attr[:attachments].each do |attachment|
|
||||
mail.attachments[attachment.filename] = {
|
||||
:content_type => attachment.preferences['Content-Type'],
|
||||
:mime_type => attachment.preferences['Mime-Type'],
|
||||
:content => attachment.store_file.data
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
mail.delivery_method :smtp, {
|
||||
:openssl_verify_mode => 'none',
|
||||
:address => channel[:options][:host],
|
||||
# :port => 587,
|
||||
:port => 25,
|
||||
:domain => channel[:options][:host],
|
||||
:user_name => channel[:options][:user],
|
||||
:password => channel[:options][:password],
|
||||
# :authentication => 'plain',
|
||||
:enable_starttls_auto => true
|
||||
}
|
||||
mail.deliver
|
||||
|
||||
end
|
||||
end
|
|
@ -1,4 +1,3 @@
|
|||
#require 'rubygems'
|
||||
require 'twitter'
|
||||
|
||||
class Channel::Twitter2
|
||||
|
@ -37,6 +36,7 @@ class Channel::Twitter2
|
|||
@article_type = 'twitter direct-message'
|
||||
fetch_loop(tweets, account, account[:direct_messages][:group])
|
||||
end
|
||||
puts 'done'
|
||||
end
|
||||
|
||||
def fetch_loop(tweets, account, group)
|
||||
|
@ -103,7 +103,6 @@ class Channel::Twitter2
|
|||
# puts tweet.inspect
|
||||
# user = User.where( :login => tweet.sender.screen_name ).first
|
||||
auth = Authorization.where( :uid => sender.id, :provider => 'twitter' ).first
|
||||
# user = undef
|
||||
user = nil
|
||||
if auth
|
||||
puts 'user_id', auth.user_id
|
||||
|
|
|
@ -7,11 +7,25 @@ class Setting < ActiveRecord::Base
|
|||
@@config = nil
|
||||
|
||||
def self.load
|
||||
|
||||
# check if config is already generated
|
||||
return @@config if @@config
|
||||
|
||||
# read all config settings
|
||||
config = {}
|
||||
Setting.select('name, state').order(:id).each { |setting|
|
||||
config[setting.name] = setting.state[:value]
|
||||
}
|
||||
|
||||
# config lookups
|
||||
config.each { |key, value|
|
||||
next if value.class.to_s != 'String'
|
||||
config[key].gsub!( /\#\{config\.(.+?)\}/ ) { |s|
|
||||
s = config[$1].to_s
|
||||
}
|
||||
}
|
||||
|
||||
# store for class requests
|
||||
@@config = config
|
||||
return config
|
||||
end
|
||||
|
|
|
@ -158,7 +158,7 @@ class Ticket < ActiveRecord::Base
|
|||
self.message_id = '<' + DateTime.current.to_s(:number) + '.' + self.ticket_id.to_s + '.' + rand(999999).to_s() + '@' + fqdn + '>'
|
||||
|
||||
# set sender
|
||||
self.from = Rails.application.config.email_sender
|
||||
self.from = Setting.get('system_sender')
|
||||
end
|
||||
end
|
||||
def attachment_check
|
||||
|
@ -235,8 +235,7 @@ class Ticket < ActiveRecord::Base
|
|||
:subject => subject,
|
||||
:body => self.body,
|
||||
:attachments => self.attachments
|
||||
},
|
||||
Rails.application.config.channel_email
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -214,7 +214,6 @@ From: #{ticket.articles[-1].from}
|
|||
:subject => subject,
|
||||
:body => body,
|
||||
},
|
||||
Rails.application.config.channel_email,
|
||||
true
|
||||
)
|
||||
end
|
||||
|
|
|
@ -24,6 +24,12 @@ module Zammad
|
|||
|
||||
# Activate observers that should always be running.
|
||||
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
||||
config.active_record.observers =
|
||||
:history_observer,
|
||||
'ticket::_observer::_first_response',
|
||||
'ticket::_observer::_last_contact',
|
||||
'ticket::_observer::_close_time',
|
||||
'ticket::_observer::_notification'
|
||||
|
||||
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
||||
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
||||
|
|
|
@ -21,6 +21,7 @@ Zammad::Application.routes.draw do
|
|||
resources :notes
|
||||
|
||||
# tickets
|
||||
resources :channels, :only => [:create, :show, :index, :update, :destroy]
|
||||
resources :ticket_articles, :only => [:create, :show, :index, :update]
|
||||
resources :ticket_priorities, :only => [:create, :show, :index, :update]
|
||||
resources :ticket_states, :only => [:create, :show, :index, :update]
|
||||
|
|
21
db/migrate/20120101000070_create_channel.rb
Normal file
21
db/migrate/20120101000070_create_channel.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
class CreateChannel < ActiveRecord::Migration
|
||||
def up
|
||||
|
||||
create_table :channels do |t|
|
||||
t.references :group, :null => true
|
||||
t.column :adapter, :string, :limit => 100, :null => false
|
||||
t.column :area, :string, :limit => 100, :null => false
|
||||
t.column :options, :string, :limit => 2000, :null => true
|
||||
t.column :active, :boolean, :null => false, :default => true
|
||||
t.column :created_by_id, :integer, :null => false
|
||||
t.timestamps
|
||||
end
|
||||
add_index :channels, [:area]
|
||||
add_index :channels, [:adapter]
|
||||
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :channels
|
||||
end
|
||||
end
|
332
db/seeds.rb
332
db/seeds.rb
|
@ -627,7 +627,7 @@ Setting.create(
|
|||
:value => {
|
||||
:checksum => false,
|
||||
:file => '/tmp/counter.log',
|
||||
:min_size => 4,
|
||||
:min_size => 5,
|
||||
},
|
||||
},
|
||||
:frontend => false
|
||||
|
@ -712,10 +712,130 @@ Setting.create(
|
|||
:frontend => false
|
||||
)
|
||||
|
||||
Setting.create(
|
||||
:title => 'Enable Ticket creation',
|
||||
:name => 'customer_ticket_create',
|
||||
:area => 'CustomerWeb::Base',
|
||||
:description => 'Defines if a customer can create tickets via the web interface.',
|
||||
:options => {
|
||||
:form => [
|
||||
{
|
||||
:display => '',
|
||||
:null => true,
|
||||
:name => 'customer_ticket_create',
|
||||
:tag => 'select',
|
||||
:options => {
|
||||
true => 'yes',
|
||||
false => 'no',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
:state => {
|
||||
:value => true,
|
||||
},
|
||||
:frontend => true
|
||||
)
|
||||
|
||||
Setting.create(
|
||||
:title => 'Enable Ticket View/Update',
|
||||
:name => 'customer_ticket_view',
|
||||
:area => 'CustomerWeb::Base',
|
||||
:description => 'Defines if a customer view and update his own tickets.',
|
||||
:options => {
|
||||
:form => [
|
||||
{
|
||||
:display => '',
|
||||
:null => true,
|
||||
:name => 'customer_ticket_view',
|
||||
:tag => 'select',
|
||||
:options => {
|
||||
true => 'yes',
|
||||
false => 'no',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
:state => {
|
||||
:value => true,
|
||||
},
|
||||
:frontend => true
|
||||
)
|
||||
|
||||
Setting.create(
|
||||
:title => 'Max. Email Size',
|
||||
:name => 'postmaster_max_size',
|
||||
:area => 'Email::Base',
|
||||
:description => 'Maximal size in MB of emails.',
|
||||
:options => {
|
||||
:form => [
|
||||
{
|
||||
:display => '',
|
||||
:null => true,
|
||||
:name => 'postmaster_max_size',
|
||||
:tag => 'select',
|
||||
:options => {
|
||||
1 => 1,
|
||||
2 => 2,
|
||||
3 => 3,
|
||||
4 => 4,
|
||||
5 => 5,
|
||||
6 => 6,
|
||||
7 => 7,
|
||||
8 => 8,
|
||||
9 => 9,
|
||||
10 => 10,
|
||||
11 => 11,
|
||||
12 => 12,
|
||||
13 => 13,
|
||||
14 => 14,
|
||||
15 => 15,
|
||||
16 => 16,
|
||||
17 => 17,
|
||||
18 => 18,
|
||||
19 => 19,
|
||||
20 => 20,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
:state => {
|
||||
:value => 10,
|
||||
},
|
||||
:frontend => false
|
||||
)
|
||||
|
||||
Setting.create(
|
||||
:title => 'Additional follow up detection',
|
||||
:name => 'postmaster_follow_up_search_in',
|
||||
:area => 'Email::Base',
|
||||
:description => '"References" - Executes follow up checks on In-Reply-To or References headers for mails that don\'t have a ticket number in the subject. "Body" - Executes follow up mail body checks in mails that don\'t have a ticket number in the subject. "Attachment" - Executes follow up mail attachments checks in mails that don\'t have a ticket number in the subject. "Raw" - Executes follow up plain/raw mail checks in mails that don\'t have a ticket number in the subject.',
|
||||
:options => {
|
||||
:form => [
|
||||
{
|
||||
:display => '',
|
||||
:null => true,
|
||||
:name => 'postmaster_follow_up_search_in',
|
||||
:tag => 'checkbox',
|
||||
:options => {
|
||||
'references' => 'References',
|
||||
'body' => 'Body',
|
||||
'attachment' => 'Attachment',
|
||||
'raw' => 'Raw',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
:state => {
|
||||
:value => ['subject'],
|
||||
},
|
||||
:frontend => false
|
||||
)
|
||||
|
||||
Setting.create(
|
||||
:title => 'Notification Sender',
|
||||
:name => 'notification_sender',
|
||||
:area => 'Ticket::Notification',
|
||||
:area => 'Email::Base',
|
||||
:description => 'Defines the sender of email notifications.',
|
||||
:options => {
|
||||
:form => [
|
||||
|
@ -728,11 +848,78 @@ Setting.create(
|
|||
],
|
||||
},
|
||||
:state => {
|
||||
:value => 'Notify <noreply@znuny.com>',
|
||||
:value => 'Notification Master <noreply@#{config.fqdn}>',
|
||||
},
|
||||
:frontend => false
|
||||
)
|
||||
|
||||
Setting.create(
|
||||
:title => 'System Sender',
|
||||
:name => 'system_sender',
|
||||
:area => 'Email::Base',
|
||||
:description => 'ONLY TEMP!',
|
||||
:options => {
|
||||
:form => [
|
||||
{
|
||||
:display => '',
|
||||
:null => false,
|
||||
:name => 'system_sender',
|
||||
:tag => 'input',
|
||||
},
|
||||
],
|
||||
},
|
||||
:state => {
|
||||
:value => 'Zammad Team <zammad@#{config.fqdn}>',
|
||||
},
|
||||
:frontend => false
|
||||
)
|
||||
Setting.create(
|
||||
:title => 'Block Notifications',
|
||||
:name => 'send_no_auto_response_reg_exp',
|
||||
:area => 'Email::Base',
|
||||
:description => 'If this regex matches, no notification will be send by the sender.',
|
||||
:options => {
|
||||
:form => [
|
||||
{
|
||||
:display => '',
|
||||
:null => false,
|
||||
:name => 'send_no_auto_response_reg_exp',
|
||||
:tag => 'input',
|
||||
},
|
||||
],
|
||||
},
|
||||
:state => {
|
||||
:value => '(MAILER-DAEMON|postmaster|abuse)@.+?\..+?',
|
||||
},
|
||||
:frontend => false
|
||||
)
|
||||
|
||||
Setting.create(
|
||||
:title => 'Enable Chat',
|
||||
:name => 'chat',
|
||||
:area => 'Chat::Base',
|
||||
:description => 'Enable/Disable online chat.',
|
||||
:options => {
|
||||
:form => [
|
||||
{
|
||||
:display => '',
|
||||
:null => true,
|
||||
:name => 'chat',
|
||||
:tag => 'select',
|
||||
:options => {
|
||||
true => 'yes',
|
||||
false => 'no',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
:state => {
|
||||
:value => false,
|
||||
},
|
||||
:frontend => true
|
||||
)
|
||||
|
||||
|
||||
Role.create(
|
||||
:id => 1,
|
||||
:name => 'Admin',
|
||||
|
@ -818,56 +1005,35 @@ Ticket::Article::Sender.create( :name => 'Agent' )
|
|||
Ticket::Article::Sender.create( :name => 'Customer' )
|
||||
Ticket::Article::Sender.create( :name => 'System' )
|
||||
|
||||
for i in (1..10)
|
||||
next
|
||||
ticket = Ticket.create(
|
||||
# :number => '1314' + i.to_s,
|
||||
:group_id => Group.where(:name => 'Users' ).first.id,
|
||||
:customer_id => User.where(:login => '-').first.id,
|
||||
:title => 'printer isn\'t working...',
|
||||
:ticket_state_id => Ticket::State.where(:name => 'new').first.id,
|
||||
:ticket_priority_id => Ticket::Priority.where(:name => '2 normal').first.id,
|
||||
:created_by_id => User.where(:login => '-').first.id
|
||||
)
|
||||
Ticket::Article.create(
|
||||
ticket = Ticket.create(
|
||||
:group_id => Group.where( :name => 'Users' ).first.id,
|
||||
:customer_id => User.where( :login => '-' ).first.id,
|
||||
:owner_id => User.where( :login => '-' ).first.id,
|
||||
:title => 'Welcome to Zammad!',
|
||||
:ticket_state_id => Ticket::State.where( :name => 'new' ).first.id,
|
||||
:ticket_priority_id => Ticket::Priority.where( :name => '2 normal' ).first.id,
|
||||
:created_by_id => User.where( :login => '-' ).first.id
|
||||
)
|
||||
Ticket::Article.create(
|
||||
:created_by_id => User.where(:login => '-').first.id,
|
||||
:ticket_id => ticket.id,
|
||||
:ticket_article_type_id => Ticket::Article::Type.where(:name => 'email').first.id,
|
||||
:ticket_article_sender_id => Ticket::Article::Sender.where(:name => 'Agent').first.id,
|
||||
:body => 'Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat. Quis aute iure reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint obcaecat cupiditat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.',
|
||||
:from => 'Some Agent <agent@localhost>',
|
||||
:internal => false
|
||||
)
|
||||
Ticket::Article.create(
|
||||
:created_by_id => User.where(:login => '-').first.id,
|
||||
:ticket_id => ticket.id,
|
||||
:ticket_article_type_id => Ticket::Article::Type.where(:name => 'email').first.id,
|
||||
:ticket_article_sender_id => Ticket::Article::Sender.where(:name => 'Customer').first.id,
|
||||
:body => 'Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.',
|
||||
:from => 'Some Customer <customer@localhost>',
|
||||
:internal => false
|
||||
)
|
||||
end
|
||||
:ticket_article_type_id => Ticket::Article::Type.where(:name => 'email' ).first.id,
|
||||
:ticket_article_sender_id => Ticket::Article::Sender.where(:name => 'Customer' ).first.id,
|
||||
:from => 'Zammad Feedback <feedback@zammad.org>',
|
||||
:body => 'Welcome!
|
||||
|
||||
#Ticket.create(
|
||||
# :number => '1315',
|
||||
# :group_id => Group.where(:name => 'Users' ).first.id,
|
||||
# :customer_id => User.where(:login => '-').first.id,
|
||||
# :title => 'iphone isn\'t working...',
|
||||
# :ticket_state_id => Ticket::State.where(:name => 'new').first.id,
|
||||
# :ticket_priority_id => Ticket::Priority.where(:name => '2 normal').first.id,
|
||||
# :created_by_id => User.where(:login => '-').first.id
|
||||
#)
|
||||
Thank you for installing Zammad.
|
||||
|
||||
#Ticket.create(
|
||||
# :number => '1316',
|
||||
# :group_id => Group.where(:name => 'Users' ).first.id,
|
||||
# :customer_id => User.where(:login => '-').first.id,
|
||||
# :title => 'android isn\'t working...',
|
||||
# :ticket_state_id => Ticket::State.where(:name => 'new').first.id,
|
||||
# :ticket_priority_id => Ticket::Priority.where(:name => '2 normal').first.id,
|
||||
# :created_by_id => User.where(:login => '-').first.id
|
||||
#)
|
||||
You will find updates and patches at http://zammad.org/. Online
|
||||
documentation is available at http://guides.zammad.org/. You can also
|
||||
use our forums at http://forums.zammad.org/
|
||||
|
||||
Regards,
|
||||
|
||||
The Zammad.org Project
|
||||
',
|
||||
:internal => false
|
||||
)
|
||||
|
||||
Overview.create(
|
||||
:name => 'my_assigned',
|
||||
|
@ -1058,6 +1224,74 @@ Overview.create(
|
|||
}
|
||||
)
|
||||
|
||||
Channel.create(
|
||||
:adapter => 'IMAP',
|
||||
:area => 'Email::Inbound',
|
||||
:options => {
|
||||
:host => 'edenhofer.de',
|
||||
:user => 'mebox',
|
||||
:password => '123',
|
||||
:ssl => true,
|
||||
},
|
||||
:active => true,
|
||||
:created_by_id => User.where( :login => '-' ).first.id
|
||||
)
|
||||
|
||||
|
||||
Channel.create(
|
||||
:adapter => 'SMTP',
|
||||
:area => 'Email::Outbound',
|
||||
:options => {
|
||||
:host => 'edenhofer.de',
|
||||
:user => 'me-box',
|
||||
:password => 'BidZ&2#.z',
|
||||
:ssl => true,
|
||||
},
|
||||
:group_id => 1,
|
||||
:active => false,
|
||||
:created_by_id => User.where( :login => '-' ).first.id
|
||||
)
|
||||
Channel.create(
|
||||
:adapter => 'Sendmail',
|
||||
:area => 'Email::Outbound',
|
||||
:options => {},
|
||||
:active => false,
|
||||
:created_by_id => User.where( :login => '-' ).first.id
|
||||
)
|
||||
|
||||
Channel.create(
|
||||
:adapter => 'Twitter2',
|
||||
:area => 'Twitter',
|
||||
:options => {
|
||||
:consumer_key => 'PJ4c3dYYRtSZZZdOKo8ow',
|
||||
:consumer_secret => 'ggAdnJE2Al1Vv0cwwvX5bdvKOieFs0vjCIh5M8Dxk',
|
||||
:oauth_token => '293437546-xxRa9g74CercnU5AvY1uQwLLGIYrV1ezYtpX8oKW',
|
||||
:oauth_token_secret => 'ju0E4l9OdY2Lh1iTKMymAu6XVfOaU2oGxmcbIMRZQK4',
|
||||
:search => [
|
||||
{
|
||||
:item => '#otrs',
|
||||
:group => 'Twitter',
|
||||
},
|
||||
{
|
||||
:item => '#zombie42',
|
||||
:group => 'Twitter',
|
||||
},
|
||||
{
|
||||
:item => '#otterhub',
|
||||
:group => 'Twitter',
|
||||
},
|
||||
],
|
||||
:mentions => {
|
||||
:group => 'Twitter',
|
||||
},
|
||||
:direct_messages => {
|
||||
:group => 'Twitter',
|
||||
}
|
||||
},
|
||||
:active => true,
|
||||
:created_by_id => User.where( :login => '-' ).first.id
|
||||
)
|
||||
|
||||
network = Network.create(
|
||||
:name => 'base'
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue