Refactoring: Add coverage for TwitterSync#process_webhook

Prior to this commit,
the TwitterSync#process_webhook method had only partial test coverage
(in `spec/requests/integration/twitter_webhook_spec.rb`).
This commit replaces the existing, incomplete tests
with a direct spec of the TwitterSync class,
giving individual test cases for all reasonable edge cases
of the #process_webhook method.

Since this method is responsible for a lot of complex behavior,
there are a _lot_ of such test cases.
Putting them all in the same spec file makes it hard to read through,
so a future goal is to break them up into smaller methods
and move some of these methods into other, more appropriate classes.

This could not be achieved with a request spec,
since they enforce testing at a single interface /
level of abstraction (i.e., HTTP requests).

=== Note: This commit will not pass CI.

Some bugs in the existing code were uncovered
in the process of adding comprehensive test coverage
for the #process_webhook method.

In the interest of isolating changes into discrete chunks, fixes for
these bugs have been reserved for the next commit.
This commit is contained in:
Ryan Lue 2019-12-18 14:39:45 +08:00 committed by Thorsten Eckel
parent b990145875
commit 64c882b090
34 changed files with 3872 additions and 844 deletions

View file

@ -1,6 +1,10 @@
require 'rails_helper'
RSpec.describe TwitterSync do
subject(:twitter_sync) { described_class.new(channel.options[:auth], payload) }
let(:channel) { create(:twitter_channel) }
describe '.preferences_cleanup' do
shared_examples 'for normalizing input' do
it 'is converted (from bare hash)' do
@ -65,4 +69,661 @@ RSpec.describe TwitterSync do
include_examples 'for normalizing input'
end
end
describe '#process_webhook' do
before do
# TODO: This is necessary to implicitly set #created_by_id and #updated_by_id on new records.
# It is usually performed by the ApplicationController::HasUser#set_user filter,
# but since we are testing this class in isolation of the controller,
# it has to be done manually here.
#
# Consider putting this in the method itself, rather than in a spec `before` hook.
UserInfo.current_user_id = 1
# Twitter channels must be configured to know whose account they're monitoring.
channel.options[:user][:id] = payload[:for_user_id]
channel.save!
end
let(:payload) { YAML.safe_load(File.read(payload_file), [ActiveSupport::HashWithIndifferentAccess]) }
# TODO: This aspect of #process_webhook's behavior involves deep interaction
# with the User, Avatar, and Authorization classes,
# and thus should really be refactored (moved) elsewhere.
# These specs are being written to support such a refactoring,
# and should be migrated as appropriate when the logic is eventually relocated.
shared_examples 'for user processing' do
let(:sender_attributes) do
{
'login' => sender_profile[:screen_name],
'firstname' => sender_profile[:name].capitalize,
'web' => sender_profile[:url],
'note' => sender_profile[:description],
'address' => sender_profile[:location],
'image_source' => sender_profile[:profile_image_url],
}
end
let(:avatar_attributes) do
{
'object_lookup_id' => ObjectLookup.by_name('User'),
'deletable' => true,
'source' => 'twitter',
'source_url' => sender_profile[:profile_image_url],
}
end
let(:authorization_attributes) do
{
'uid' => sender_profile[:id],
'username' => sender_profile[:screen_name],
'provider' => 'twitter',
}
end
context 'from unknown user' do
it 'creates a User record for the sender' do
expect { twitter_sync.process_webhook(channel) }
.to change(User, :count).by(1)
.and change { User.exists?(sender_attributes) }.to(true)
end
it 'creates an Avatar record for the sender', :use_vcr do
# Why 2, and not 1? Avatar.add auto-generates a default (source: 'init') record
# before actually adding the specified (source: 'twitter') one.
expect { twitter_sync.process_webhook(channel) }
.to change(Avatar, :count).by_at_least(1)
.and change { Avatar.exists?(avatar_attributes) }.to(true)
expect(User.last.image).to eq(Avatar.last.store_hash)
end
it 'creates an Authorization record for the sender' do
expect { twitter_sync.process_webhook(channel) }
.to change(Authorization, :count).by(1)
.and change { Authorization.exists?(authorization_attributes) }.to(true)
end
end
context 'from known user' do
let!(:user) { create(:user) }
let!(:avatar) { create(:avatar, o_id: user.id, object_lookup_id: ObjectLookup.by_name('User'), source: 'twitter') }
let!(:authorization) do
Authorization.create(user_id: user.id, uid: sender_profile[:id], provider: 'twitter')
end
it 'updates the senders existing User record' do
expect { twitter_sync.process_webhook(channel) }
.to not_change(User, :count)
.and not_change { user.reload.attributes.slice('login', 'firstname') }
.and change { User.exists?(sender_attributes.except('login', 'firstname')) }.to(true)
end
it 'updates the senders existing Avatar record', :use_vcr do
expect { twitter_sync.process_webhook(channel) }
.to not_change(Avatar, :count)
.and change { Avatar.exists?(avatar_attributes) }.to(true)
expect(user.reload.image).to eq(avatar.reload.store_hash)
end
it 'updates the senders existing Authorization record' do
expect { twitter_sync.process_webhook(channel) }
.to not_change(Authorization, :count)
.and change { Authorization.exists?(authorization_attributes) }.to(true)
end
end
end
context 'for incoming DM' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'direct_message-incoming.yml') }
include_examples 'for user processing' do
# Payload sent by Twitter is { ..., users: [{ <uid>: <sender> }, { <uid>: <receiver> }] }
let(:sender_profile) { payload[:users].values.first }
end
describe 'ticket creation' do
let(:ticket_attributes) do
# NOTE: missing "customer_id" (because the value is generated as part of the #process_webhook method)
{
'title' => title,
'group_id' => channel.options[:sync][:direct_messages][:group_id],
'state' => Ticket::State.find_by(default_create: true),
'priority' => Ticket::Priority.find_by(default_create: true),
'preferences' => {
'channel_id' => channel.id,
'channel_screen_name' => channel.options[:user][:screen_name],
},
}
end
let(:title) { payload[:direct_message_events].first[:message_create][:message_data][:text] }
it 'creates a new ticket' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket, :count).by(1)
.and change { Ticket.exists?(ticket_attributes) }.to(true)
end
context 'for duplicate messages' do
before do
described_class.new(
channel.options[:auth],
YAML.safe_load(File.read(payload_file), [ActiveSupport::HashWithIndifferentAccess])
).process_webhook(channel)
end
it 'does not create duplicate ticket' do
expect { twitter_sync.process_webhook(channel) }
.to not_change(Ticket, :count)
.and not_change(Ticket::Article, :count)
end
end
context 'for message longer than 80 chars' do
before { payload[:direct_message_events].first[:message_create][:message_data][:text] = 'a' * 81 }
let(:title) { "#{'a' * 80}..." }
it 'creates ticket with truncated title' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket, :count).by(1)
.and change { Ticket.exists?(ticket_attributes) }.to(true)
end
end
context 'in reply to existing thread/ticket' do
# import parent DM
before do
described_class.new(
channel.options[:auth],
YAML.safe_load(
File.read(Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'direct_message-incoming.yml')),
[ActiveSupport::HashWithIndifferentAccess]
)
).process_webhook(channel)
end
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'direct_message-incoming_2.yml') }
it 'uses existing ticket' do
expect { twitter_sync.process_webhook(channel) }
.to not_change(Ticket, :count)
.and not_change { Ticket.last.state }
end
context 'marked "closed" / "merged" / "removed"' do
before { Ticket.last.update(state: Ticket::State.find_by(name: 'closed')) }
it 'creates a new ticket' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket, :count).by(1)
.and change { Ticket.exists?(ticket_attributes) }.to(true)
end
end
context 'marked "pending reminder" / "pending close"' do
before { Ticket.last.update(state: Ticket::State.find_by(name: 'pending reminder')) }
it 'sets existing ticket to "open"' do
expect { twitter_sync.process_webhook(channel) }
.to not_change(Ticket, :count)
.and change { Ticket.last.state.name }.to('open')
end
end
end
end
describe 'article creation' do
let(:article_attributes) do
# NOTE: missing "ticket_id" (because the value is generated as part of the #process_webhook method)
{
'from' => "@#{payload[:users].values.first[:screen_name]}",
'to' => "@#{payload[:users].values.second[:screen_name]}",
'body' => payload[:direct_message_events].first[:message_create][:message_data][:text],
'message_id' => payload[:direct_message_events].first[:id],
'in_reply_to' => nil,
'type_id' => Ticket::Article::Type.find_by(name: 'twitter direct-message').id,
'sender_id' => Ticket::Article::Sender.find_by(name: 'Customer').id,
'internal' => false,
'preferences' => { 'twitter' => twitter_prefs, 'links' => link_array }
}
end
let(:twitter_prefs) do
{
'created_at' => payload[:direct_message_events].first[:created_timestamp],
'recipient_id' => payload[:direct_message_events].first[:message_create][:target][:recipient_id],
'recipient_screen_name' => payload[:users].values.second[:screen_name],
'sender_id' => payload[:direct_message_events].first[:message_create][:sender_id],
'sender_screen_name' => payload[:users].values.first[:screen_name],
'app_id' => payload[:apps]&.values&.first&.dig(:app_id),
'app_name' => payload[:apps]&.values&.first&.dig(:app_name),
'geo' => {},
'place' => {},
}
end
let(:link_array) do
[
{
'url' => "https://twitter.com/messages/#{user_ids.map(&:to_i).sort.join('-')}",
'target' => '_blank',
'name' => 'on Twitter',
},
]
end
let(:user_ids) { payload[:users].values.map { |u| u[:id] } }
it 'creates a new article' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket::Article, :count).by(1)
.and change { Ticket::Article.exists?(article_attributes) }.to(true)
end
context 'for duplicate messages' do
before do
described_class.new(
channel.options[:auth],
YAML.safe_load(File.read(payload_file), [ActiveSupport::HashWithIndifferentAccess])
).process_webhook(channel)
end
it 'does not create duplicate article' do
expect { twitter_sync.process_webhook(channel) }
.to not_change(Ticket::Article, :count)
end
end
context 'when message contains shortened (t.co) url' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'direct_message-incoming_with_url.yml') }
it 'replaces the t.co url for the original' do
expect { twitter_sync.process_webhook(channel) }
.to change { Ticket::Article.exists?(body: <<~BODY.chomp) }.to(true)
Did you know about this? https://en.wikipedia.org/wiki/Frankenstein#Composition
BODY
end
end
end
end
context 'for outgoing DM' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'direct_message-outgoing.yml') }
describe 'ticket creation' do
let(:ticket_attributes) do
# NOTE: missing "customer_id" (because User.last changes before and after the method is called)
{
'title' => payload[:direct_message_events].first[:message_create][:message_data][:text],
'group_id' => channel.options[:sync][:direct_messages][:group_id],
'state' => Ticket::State.find_by(name: 'closed'),
'priority' => Ticket::Priority.find_by(default_create: true),
'preferences' => {
'channel_id' => channel.id,
'channel_screen_name' => channel.options[:user][:screen_name],
},
}
end
it 'creates a closed ticket' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket, :count).by(1)
.and change { Ticket.exists?(ticket_attributes) }.to(true)
end
end
describe 'article creation' do
let(:article_attributes) do
# NOTE: missing "ticket_id" (because the value is generated as part of the #process_webhook method)
{
'from' => "@#{payload[:users].values.first[:screen_name]}",
'to' => "@#{payload[:users].values.second[:screen_name]}",
'body' => payload[:direct_message_events].first[:message_create][:message_data][:text],
'message_id' => payload[:direct_message_events].first[:id],
'in_reply_to' => nil,
'type_id' => Ticket::Article::Type.find_by(name: 'twitter direct-message').id,
'sender_id' => Ticket::Article::Sender.find_by(name: 'Customer').id,
'internal' => false,
'preferences' => { 'twitter' => twitter_prefs, 'links' => link_array }
}
end
let(:twitter_prefs) do
{
'created_at' => payload[:direct_message_events].first[:created_timestamp],
'recipient_id' => payload[:direct_message_events].first[:message_create][:target][:recipient_id],
'recipient_screen_name' => payload[:users].values.second[:screen_name],
'sender_id' => payload[:direct_message_events].first[:message_create][:sender_id],
'sender_screen_name' => payload[:users].values.first[:screen_name],
'app_id' => payload[:apps]&.values&.first&.dig(:app_id),
'app_name' => payload[:apps]&.values&.first&.dig(:app_name),
'geo' => {},
'place' => {},
}
end
let(:link_array) do
[
{
'url' => "https://twitter.com/messages/#{user_ids.map(&:to_i).sort.join('-')}",
'target' => '_blank',
'name' => 'on Twitter',
},
]
end
let(:user_ids) { payload[:users].values.map { |u| u[:id] } }
it 'creates a new article' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket::Article, :count).by(1)
.and change { Ticket::Article.exists?(article_attributes) }.to(true)
end
context 'when message contains shortened (t.co) url' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'direct_message-incoming_with_url.yml') }
it 'replaces the t.co url for the original' do
expect { twitter_sync.process_webhook(channel) }
.to change { Ticket::Article.exists?(body: <<~BODY.chomp) }.to(true)
Did you know about this? https://en.wikipedia.org/wiki/Frankenstein#Composition
BODY
end
end
context 'when message contains a media attachment (e.g., JPG)' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'direct_message-incoming_with_media.yml') }
it 'does not store it as an attachment on the article' do
twitter_sync.process_webhook(channel)
expect(Ticket::Article.last.attachments).to be_empty
end
end
end
end
context 'for incoming tweet' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'tweet_create-user_mention.yml') }
include_examples 'for user processing' do
# Payload sent by Twitter is { ..., tweet_create_events: [{ ..., user: <author> }] }
let(:sender_profile) { payload[:tweet_create_events].first[:user] }
end
describe 'ticket creation' do
let(:ticket_attributes) do
# NOTE: missing "customer_id" (because User.last changes before and after the method is called)
{
'title' => payload[:tweet_create_events].first[:text],
'group_id' => channel.options[:sync][:direct_messages][:group_id],
'state' => Ticket::State.find_by(default_create: true),
'priority' => Ticket::Priority.find_by(default_create: true),
'preferences' => {
'channel_id' => channel.id,
'channel_screen_name' => channel.options[:user][:screen_name],
},
}
end
it 'creates a new ticket' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket, :count).by(1)
end
context 'for duplicate tweets' do
before do
described_class.new(
channel.options[:auth],
YAML.safe_load(File.read(payload_file), [ActiveSupport::HashWithIndifferentAccess])
).process_webhook(channel)
end
it 'does not create duplicate ticket' do
expect { twitter_sync.process_webhook(channel) }
.to not_change(Ticket, :count)
.and not_change(Ticket::Article, :count)
end
end
context 'in response to existing tweet thread' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'tweet_create-response.yml') }
let(:parent_tweet_payload) do
YAML.safe_load(
File.read(Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'tweet_create-user_mention.yml')),
[ActiveSupport::HashWithIndifferentAccess]
)
end
context 'that hasnt been imported yet', :use_vcr do
it 'creates a new ticket' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket, :count).by(1)
end
it 'retrieves the parent tweet via the Twitter API' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket::Article, :count).by(2)
expect(Ticket::Article.second_to_last.body).to eq(parent_tweet_payload[:tweet_create_events].first[:text])
end
context 'after parent tweet has been deleted' do
before do
payload[:tweet_create_events].first[:in_reply_to_status_id] = 1207610954160037890 # rubocop:disable Style/NumericLiterals
payload[:tweet_create_events].first[:in_reply_to_status_id_str] = '1207610954160037890'
end
it 'creates a new ticket' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket, :count).by(1)
end
it 'silently ignores error when retrieving parent tweet' do
expect { twitter_sync.process_webhook(channel) }.to not_raise_error
end
end
end
context 'that was previously imported' do
# import parent tweet
before { described_class.new(channel.options[:auth], parent_tweet_payload).process_webhook(channel) }
it 'uses existing ticket' do
expect { twitter_sync.process_webhook(channel) }
.to not_change(Ticket, :count)
.and not_change { Ticket.last.state }
end
context 'and marked "closed" / "merged" / "removed" / "pending reminder" / "pending close"' do
before { Ticket.last.update(state: Ticket::State.find_by(name: 'closed')) }
it 'sets existing ticket to "open"' do
expect { twitter_sync.process_webhook(channel) }
.to not_change(Ticket, :count)
.and change { Ticket.last.state.name }.to('open')
end
end
end
end
end
describe 'article creation' do
let(:article_attributes) do
# NOTE: missing "ticket_id" (because the value is generated as part of the #process_webhook method)
{
'from' => "@#{payload[:tweet_create_events].first[:user][:screen_name]}",
'to' => "@#{payload[:tweet_create_events].first[:entities][:user_mentions].first[:screen_name]}",
'body' => payload[:tweet_create_events].first[:text],
'message_id' => payload[:tweet_create_events].first[:id_str],
'in_reply_to' => payload[:tweet_create_events].first[:in_reply_to_status_id],
'type_id' => Ticket::Article::Type.find_by(name: 'twitter status').id,
'sender_id' => Ticket::Article::Sender.find_by(name: 'Customer').id,
'internal' => false,
'preferences' => { 'twitter' => twitter_prefs, 'links' => link_array }
}
end
let(:twitter_prefs) do
{
'mention_ids' => payload[:tweet_create_events].first[:entities][:user_mentions].map { |um| um[:id] },
'geo' => payload[:tweet_create_events].first[:geo].to_h,
'retweeted' => payload[:tweet_create_events].first[:retweeted],
'possibly_sensitive' => payload[:tweet_create_events].first[:possibly_sensitive],
'in_reply_to_user_id' => payload[:tweet_create_events].first[:in_reply_to_user_id],
'place' => payload[:tweet_create_events].first[:place].to_h,
'retweet_count' => payload[:tweet_create_events].first[:retweet_count],
'source' => payload[:tweet_create_events].first[:source],
'favorited' => payload[:tweet_create_events].first[:favorited],
'truncated' => payload[:tweet_create_events].first[:truncated],
}
end
let(:link_array) do
[
{
'url' => "https://twitter.com/_/status/#{payload[:tweet_create_events].first[:id]}",
'target' => '_blank',
'name' => 'on Twitter',
},
]
end
it 'creates a new article' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket::Article, :count).by(1)
.and change { Ticket::Article.exists?(article_attributes) }.to(true)
end
context 'when message mentions multiple users' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'tweet_create-user_mention_multiple.yml') }
let(:mentionees) { "@#{payload[:tweet_create_events].first[:entities][:user_mentions].map { |um| um[:screen_name] }.join(', @')}" }
it 'records all mentionees in comma-separated "to" attribute' do
expect { twitter_sync.process_webhook(channel) }
.to change { Ticket::Article.exists?(to: mentionees) }.to(true)
end
end
context 'when message exceeds 140 characters' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'tweet_create-user_mention_extended.yml') }
let(:full_body) { payload[:tweet_create_events].first[:extended_tweet][:full_text] }
it 'records the full (extended) tweet body' do
expect { twitter_sync.process_webhook(channel) }
.to change { Ticket::Article.exists?(body: full_body) }.to(true)
end
end
context 'when message contains shortened (t.co) url' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'tweet_create-user_mention_with_url.yml') }
it 'replaces the t.co url for the original' do
expect { twitter_sync.process_webhook(channel) }
.to change { Ticket::Article.exists?(body: <<~BODY.chomp) }.to(true)
@ScruffyMcG https://zammad.org/
BODY
end
end
context 'when message contains a media attachment (e.g., JPG)' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'tweet_create-user_mention_with_media.yml') }
it 'replaces the t.co url for the original' do
expect { twitter_sync.process_webhook(channel) }
.to change { Ticket::Article.exists?(body: <<~BODY.chomp) }.to(true)
@ScruffyMcG https://twitter.com/pennbrooke1/status/1209101446706122752/photo/1
BODY
end
it 'stores it as an attachment on the article', :use_vcr do
twitter_sync.process_webhook(channel)
expect(Ticket::Article.last.attachments).to be_one
end
end
end
end
context 'for outgoing tweet' do
let(:payload_file) { Rails.root.join('test', 'data', 'twitter', 'webhook_events', 'tweet_create-user_mention_outgoing.yml') }
describe 'ticket creation' do
let(:ticket_attributes) do
# NOTE: missing "customer_id" (because User.last changes before and after the method is called)
{
'title' => payload[:tweet_create_events].first[:text],
'group_id' => channel.options[:sync][:direct_messages][:group_id],
'state' => Ticket::State.find_by(name: 'closed'),
'priority' => Ticket::Priority.find_by(default_create: true),
'preferences' => {
'channel_id' => channel.id,
'channel_screen_name' => channel.options[:user][:screen_name],
},
}
end
it 'creates a closed ticket' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket, :count).by(1)
end
end
describe 'article creation' do
let(:article_attributes) do
# NOTE: missing "ticket_id" (because the value is generated as part of the #process_webhook method)
{
'from' => "@#{payload[:tweet_create_events].first[:user][:screen_name]}",
'to' => "@#{payload[:tweet_create_events].first[:entities][:user_mentions].first[:screen_name]}",
'body' => payload[:tweet_create_events].first[:text],
'message_id' => payload[:tweet_create_events].first[:id_str],
'in_reply_to' => payload[:tweet_create_events].first[:in_reply_to_status_id],
'type_id' => Ticket::Article::Type.find_by(name: 'twitter status').id,
'sender_id' => Ticket::Article::Sender.find_by(name: 'Customer').id,
'internal' => false,
'preferences' => { 'twitter' => twitter_prefs, 'links' => link_array }
}
end
let(:twitter_prefs) do
{
'mention_ids' => payload[:tweet_create_events].first[:entities][:user_mentions].map { |um| um[:id] },
'geo' => payload[:tweet_create_events].first[:geo].to_h,
'retweeted' => payload[:tweet_create_events].first[:retweeted],
'possibly_sensitive' => payload[:tweet_create_events].first[:possibly_sensitive],
'in_reply_to_user_id' => payload[:tweet_create_events].first[:in_reply_to_user_id],
'place' => payload[:tweet_create_events].first[:place].to_h,
'retweet_count' => payload[:tweet_create_events].first[:retweet_count],
'source' => payload[:tweet_create_events].first[:source],
'favorited' => payload[:tweet_create_events].first[:favorited],
'truncated' => payload[:tweet_create_events].first[:truncated],
}
end
let(:link_array) do
[
{
'url' => "https://twitter.com/_/status/#{payload[:tweet_create_events].first[:id]}",
'target' => '_blank',
'name' => 'on Twitter',
},
]
end
it 'creates a new article' do
expect { twitter_sync.process_webhook(channel) }
.to change(Ticket::Article, :count).by(1)
.and change { Ticket::Article.exists?(article_attributes) }.to(true)
end
end
end
end
end

View file

@ -1,312 +0,0 @@
require 'rails_helper'
RSpec.describe 'Twitter Webhook Integration', type: :request do
let!(:external_credential) { create(:twitter_credential, credentials: credentials) }
let(:credentials) { { consumer_key: 'CCC', consumer_secret: 'DDD' } }
describe '#webhook_incoming' do
let!(:channel) do
create(
:twitter_channel,
custom_options: {
auth: {
external_credential_id: external_credential.id,
oauth_token: 'AAA',
oauth_token_secret: 'BBB',
consumer_key: 'CCC',
consumer_secret: 'DDD',
},
user: {
id: 123,
name: 'Zammad HQ',
screen_name: 'zammadhq',
},
sync: {
limit: 20,
track_retweets: false,
search: [
{
term: '#zammad', group_id: Group.first.id.to_s
},
{
term: '#hello1234', group_id: Group.first.id.to_s
}
],
}
}
)
end
describe 'auto-creation of tickets/articles on webhook receipt' do
let(:webhook_payload) do
JSON.parse(File.read(Rails.root.join('test/data/twitter', payload_file))).symbolize_keys
end
context 'for outbound DMs' do
context 'not matching any admin-defined filters' do
let(:payload_file) { 'webhook1_direct_message.json' }
it 'returns 200' do
post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json
expect(response).to have_http_status(:ok)
end
it 'creates closed ticket' do
expect { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
.to change(Ticket, :count).by(1)
expect(Ticket.last.attributes)
.to include(
'title' => 'Hey! Hello!',
'state_id' => Ticket::State.find_by(name: 'closed').id,
'priority_id' => Ticket::Priority.find_by(name: '2 normal').id,
'customer_id' => User.find_by(login: 'zammadhq', firstname: 'Zammad', lastname: 'Hq').id,
'created_by_id' => User.find_by(login: 'zammadhq', firstname: 'Zammad', lastname: 'Hq').id
)
end
it 'creates first article on closed ticket' do
expect { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
.to change { Ticket::Article.count }.by(1)
expect(Ticket::Article.last.attributes)
.to include(
'from' => '@zammadhq',
'to' => '@medenhofer',
'message_id' => '1062015437679050760',
'created_by_id' => User.find_by(login: 'zammadhq', firstname: 'Zammad', lastname: 'Hq').id
)
end
it 'does not add any attachments to newly created ticket' do
post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json
expect(Ticket::Article.last.attachments).to be_empty
end
end
end
context 'for inbound DMs' do
context 'matching admin-defined #hashtag filter, with a link to an image' do
let(:payload_file) { 'webhook2_direct_message.json' }
it 'returns 200' do
post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json
expect(response).to have_http_status(:ok)
end
it 'creates new ticket' do
expect { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
.to change(Ticket, :count).by(1)
expect(Ticket.last.attributes)
.to include(
'title' => 'Hello Zammad #zammad @znuny Yeah! https://t.co/UfaCwi9cUb',
'state_id' => Ticket::State.find_by(name: 'new').id,
'priority_id' => Ticket::Priority.find_by(name: '2 normal').id,
'customer_id' => User.find_by(login: 'medenhofer', firstname: 'Martin', lastname: 'Edenhofer').id,
)
end
it 'creates first article on new ticket' do
expect { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
.to change { Ticket::Article.count }.by(1)
expect(Ticket::Article.last.attributes)
.to include(
'to' => '@zammadhq',
'from' => '@medenhofer',
'body' => "Hello Zammad #zammad @znuny\n\nYeah! https://twitter.com/messages/media/1063077238797725700",
'message_id' => '1063077238797725700',
'created_by_id' => User.find_by(login: 'medenhofer', firstname: 'Martin', lastname: 'Edenhofer').id
)
end
it 'does not add linked image as attachment to newly created ticket' do
post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json
expect(Ticket::Article.last.attachments).to be_empty
end
end
context 'from same sender as previously imported DMs' do
let(:payload_file) { 'webhook3_direct_message.json' }
before { post '/api/v1/channels_twitter_webhook', **previous_webhook_payload, as: :json }
let(:previous_webhook_payload) do
JSON.parse(File.read(Rails.root.join('test/data/twitter/webhook2_direct_message.json'))).symbolize_keys
end
it 'returns 200' do
post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json
expect(response).to have_http_status(:ok)
end
it 'does not create new ticket' do
expect { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
.not_to change(Ticket, :count)
end
it 'adds new article to existing, open ticket' do
expect { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
.to change { Ticket::Article.count }.by(1)
expect(Ticket::Article.last.attributes)
.to include(
'to' => '@zammadhq',
'from' => '@medenhofer',
'body' => 'Hello again!',
'message_id' => '1063077238797725701',
'created_by_id' => User.find_by(login: 'medenhofer', firstname: 'Martin', lastname: 'Edenhofer').id,
'ticket_id' => Ticket.find_by(title: 'Hello Zammad #zammad @znuny Yeah! https://t.co/UfaCwi9cUb').id
)
end
it 'does not add any attachments to newly created ticket' do
post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json
expect(Ticket::Article.last.attachments).to be_empty
end
end
end
context 'when receiving duplicate DMs' do
let(:payload_file) { 'webhook1_direct_message.json' }
it 'still returns 200' do
2.times { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
expect(response).to have_http_status(:ok)
end
it 'does not create duplicate articles' do
expect do
2.times { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
end.to change { Ticket::Article.count }.by(1)
end
end
context 'for tweets' do
context 'matching admin-defined #hashtag filter, with an image link' do
let(:payload_file) { 'webhook1_tweet.json' }
before do
stub_request(:get, 'http://pbs.twimg.com/profile_images/785412960797745152/wxdIvejo_bigger.jpg')
.to_return(status: 200, body: 'some_content')
stub_request(:get, 'https://pbs.twimg.com/media/DsFKfJRWkAAFEbo.jpg')
.to_return(status: 200, body: 'some_content')
end
it 'returns 200' do
post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json
expect(response).to have_http_status(:ok)
end
it 'creates a closed ticket' do
expect { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
.to change(Ticket, :count).by(1)
expect(Ticket.last.attributes)
.to include(
'title' => 'Hey @medenhofer ! #hello1234 https://t.co/f1kffFlwpN',
'state_id' => Ticket::State.find_by(name: 'closed').id,
'priority_id' => Ticket::Priority.find_by(name: '2 normal').id,
'customer_id' => User.find_by(login: 'zammadhq', firstname: 'Zammad', lastname: 'Hq').id,
'created_by_id' => User.find_by(login: 'zammadhq', firstname: 'Zammad', lastname: 'Hq').id,
)
end
it 'creates first article on closed ticket' do
expect { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
.to change { Ticket::Article.count }.by(1)
expect(Ticket::Article.last.attributes)
.to include(
'from' => '@zammadhq',
'to' => '@medenhofer',
'body' => 'Hey @medenhofer ! #hello1234 https://twitter.com/zammadhq/status/1063212927510081536/photo/1',
'message_id' => '1063212927510081536',
'created_by_id' => User.find_by(login: 'zammadhq', firstname: 'Zammad', lastname: 'Hq').id
)
end
it 'add linked image as attachment to newly created article' do
expect(Ticket::Article.last.attachments)
.to match_array(Store.where(filename: 'DsFKfJRWkAAFEbo.jpg'))
end
end
context 'longer than 140 characters (with no media links)' do
let(:payload_file) { 'webhook2_tweet.json' }
before do
stub_request(:get, 'http://pbs.twimg.com/profile_images/794220000450150401/D-eFg44R_bigger.jpg')
.to_return(status: 200, body: 'some_content')
end
it 'returns 200' do
post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json
expect(response).to have_http_status(:ok)
end
it 'creates a new ticket' do
expect { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
.to change(Ticket, :count).by(1)
expect(Ticket.last.attributes)
.to include(
'title' => '@znuny Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy ...',
'state_id' => Ticket::State.find_by(name: 'new').id,
'priority_id' => Ticket::Priority.find_by(name: '2 normal').id,
'customer_id' => User.find_by(login: 'medenhofer', firstname: 'Martin', lastname: 'Edenhofer').id,
'created_by_id' => User.find_by(login: 'medenhofer', firstname: 'Martin', lastname: 'Edenhofer').id,
)
end
it 'creates first article on new ticket' do
expect { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
.to change { Ticket::Article.count }.by(1)
expect(Ticket::Article.last.attributes)
.to include(
'from' => '@medenhofer',
'to' => '@znuny',
'body' => '@znuny Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lore',
'created_by_id' => User.find_by(login: 'medenhofer', firstname: 'Martin', lastname: 'Edenhofer').id,
'message_id' => '1065035365336141825'
)
end
it 'does not add any attachments to newly created ticket' do
post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json
expect(Ticket::Article.last.attachments).to be_empty
end
end
context 'when receiving duplicate messages' do
let(:payload_file) { 'webhook1_tweet.json' }
it 'still returns 200' do
2.times { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
expect(response).to have_http_status(:ok)
end
it 'does not create duplicate articles' do
expect do
2.times { post '/api/v1/channels_twitter_webhook', **webhook_payload, as: :json }
end.to change { Ticket::Article.count }.by(1)
end
end
end
end
end
end

View file

@ -1,3 +1,4 @@
RSpec::Matchers.define_negated_matcher :not_change, :change
RSpec::Matchers.define_negated_matcher :not_include, :include
RSpec::Matchers.define_negated_matcher :not_eq, :eq
RSpec::Matchers.define_negated_matcher :not_raise_error, :raise_error

View file

@ -1,70 +0,0 @@
{
"headers" : {
"x-twitter-webhooks-signature" : "sha256=xXu7qrPhqXfo8Ot14c0si9HrdQdBNru5fkSdoMZi+Ms="
},
"params" : {
"for_user_id": "123",
"direct_message_events": [
{
"type": "message_create",
"id": "1062015437679050760",
"created_timestamp": "1542039186292",
"message_create": {
"target": {
"recipient_id": "456"
},
"sender_id": "123",
"source_app_id": "268278",
"message_data": {
"text": "Hey! Hello!",
"entities": {
"hashtags": [],
"symbols": [],
"user_mentions": [],
"urls": []
}
}
}
}
],
"apps": {
"268278": {
"id": "268278",
"name": "Twitter Web Client",
"url": "http://twitter.com"
}
},
"users": {
"123": {
"id": "123",
"created_timestamp": "1476091912921",
"name": "Zammad HQ",
"screen_name": "zammadhq",
"description": "Helpdesk and Customer Support made easy. Open Source for download or to go with SaaS. #zammad",
"url": "https://t.co/XITyrXmhTP",
"protected": false,
"verified": false,
"followers_count": 426,
"friends_count": 509,
"statuses_count": 436,
"profile_image_url": "http://pbs.twimg.com/profile_images/785412960797745152/wxdIvejo_normal.jpg",
"profile_image_url_https": "https://pbs.twimg.com/profile_images/785412960797745152/wxdIvejo_normal.jpg"
},
"456": {
"id": "456",
"created_timestamp": "1290730789000",
"name": "Martin Edenhofer",
"screen_name": "medenhofer",
"description": "Open Source professional and geek. Also known as #OTRS and #Zammad inventor. ;)\r\nEntrepreneur and Advisor for open source people in need.",
"url": "https://t.co/whm4HTWdMw",
"protected": false,
"verified": false,
"followers_count": 312,
"friends_count": 314,
"statuses_count": 222,
"profile_image_url": "http://pbs.twimg.com/profile_images/794220000450150401/D-eFg44R_normal.jpg",
"profile_image_url_https": "https://pbs.twimg.com/profile_images/794220000450150401/D-eFg44R_normal.jpg"
}
}
}
}

View file

@ -1,167 +0,0 @@
{
"headers": {
"x-twitter-webhooks-signature": "sha256=DmARpz6wdgte6Vj+ePeqC+RHvEDokmwOIIqr4//utkk="
},
"params": {
"for_user_id": "123",
"tweet_create_events": [
{
"created_at": "Thu Nov 15 23:31:30 +0000 2018",
"id": 1063212927510081536,
"id_str": "1063212927510081536",
"text": "Hey @medenhofer ! #hello1234 https://t.co/f1kffFlwpN",
"display_text_range": [0, 29],
"source": "<a href=\"http://twitter.com\" rel=\"nofollow\">Twitter Web Client</a>",
"truncated": false,
"in_reply_to_status_id": null,
"in_reply_to_status_id_str": null,
"in_reply_to_user_id": null,
"in_reply_to_user_id_str": null,
"in_reply_to_screen_name": null,
"user": {
"id": 123,
"id_str": "123",
"name": "Zammad HQ",
"screen_name": "zammadhq",
"location": null,
"url": "http://zammad.com",
"description": "Helpdesk and Customer Support made easy. Open Source for download or to go with SaaS. #zammad",
"translator_type": "none",
"protected": false,
"verified": false,
"followers_count": 427,
"friends_count": 512,
"listed_count": 20,
"favourites_count": 280,
"statuses_count": 438,
"created_at": "Mon Oct 10 09:31:52 +0000 2016",
"utc_offset": null,
"time_zone": null,
"geo_enabled": false,
"lang": "en",
"contributors_enabled": false,
"is_translator": false,
"profile_background_color": "000000",
"profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_tile": false,
"profile_link_color": "31B068",
"profile_sidebar_border_color": "000000",
"profile_sidebar_fill_color": "000000",
"profile_text_color": "000000",
"profile_use_background_image": false,
"profile_image_url": "http://pbs.twimg.com/profile_images/785412960797745152/wxdIvejo_normal.jpg", "profile_image_url_https": "https://pbs.twimg.com/profile_images/785412960797745152/wxdIvejo_normal.jpg",
"profile_banner_url": "https://pbs.twimg.com/profile_banners/123/1476097853",
"default_profile": false,
"default_profile_image": false,
"following": null,
"follow_request_sent": null,
"notifications": null
},
"geo": null,
"coordinates": null,
"place": null,
"contributors": null,
"is_quote_status": false,
"quote_count": 0,
"reply_count": 0,
"retweet_count": 0,
"favorite_count": 0,
"entities": {
"hashtags": [
{"text": "hello1234", "indices": [19, 29]}
],
"urls": [],
"user_mentions": [
{
"screen_name": "medenhofer",
"name": "Martin Edenhofer",
"id": 456,
"id_str": "456",
"indices": [4, 15]
}
],
"symbols": [],
"media": [
{
"id": 1063212885961248768,
"id_str": "1063212885961248768",
"indices": [30, 53],
"media_url": "http://pbs.twimg.com/media/DsFKfJRWkAAFEbo.jpg",
"media_url_https": "https://pbs.twimg.com/media/DsFKfJRWkAAFEbo.jpg",
"url": "https://t.co/f1kffFlwpN",
"display_url": "pic.twitter.com/f1kffFlwpN",
"expanded_url": "https://twitter.com/zammadhq/status/1063212927510081536/photo/1",
"type": "photo",
"sizes": {
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 852,
"h": 462,
"resize": "fit"
},
"medium": {
"w": 852,
"h": 462,
"resize": "fit"
},
"small": {
"w": 680,
"h": 369,
"resize": "fit"
}
}
}
]
},
"extended_entities": {
"media": [
{
"id": 1063212885961248768,
"id_str": "1063212885961248768",
"indices": [30, 53],
"media_url": "http://pbs.twimg.com/media/DsFKfJRWkAAFEbo.jpg",
"media_url_https": "https://pbs.twimg.com/media/DsFKfJRWkAAFEbo.jpg",
"url": "https://t.co/f1kffFlwpN",
"display_url": "pic.twitter.com/f1kffFlwpN",
"expanded_url": "https://twitter.com/zammadhq/status/1063212927510081536/photo/1",
"type": "photo",
"sizes": {
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"large": {
"w": 852,
"h": 462,
"resize": "fit"
},
"medium": {
"w": 852,
"h": 462,
"resize": "fit"
},
"small": {
"w": 680,
"h": 369,
"resize": "fit"
}
}
}
]
},
"favorited": false,
"retweeted": false,
"possibly_sensitive": false,
"filter_level": "low",
"lang": "und",
"timestamp_ms": "1542324690116"
}
]
}
}

View file

@ -1,118 +0,0 @@
{
"headers" : {
"x-twitter-webhooks-signature" : "sha256=wYiCk7gfAgrnerCpj3XD58hozfVDjcQvcYPZCFH+stU="
},
"params": {
"for_user_id": "123",
"direct_message_events": [
{
"type": "message_create",
"id": "1063077238797725700",
"created_timestamp": "1542292339406",
"message_create": {
"target": {
"recipient_id": "123"
},
"sender_id": "456",
"message_data": {
"text": "Hello Zammad #zammad @znuny\n\nYeah! https://t.co/UfaCwi9cUb",
"entities": {
"hashtags": [
{
"text": "zammad",
"indices": [13,20]
}
],
"symbols": [],
"user_mentions": [
{
"screen_name": "znuny",
"name": "Znuny / ES for OTRS",
"id": 789,
"id_str": "789",
"indices": [21, 27]
}
],
"urls": [
{
"url": "https://t.co/UfaCwi9cUb",
"expanded_url": "https://twitter.com/messages/media/1063077238797725700",
"display_url": "pic.twitter.com/UfaCwi9cUb",
"indices": [35, 58]
}
]
},
"attachment": {
"type": "media",
"media": {
"id": 1063077198536556545,
"id_str": "1063077198536556545",
"indices": [35, 58],
"media_url": "https://ton.twitter.com/1.1/ton/data/dm/1063077238797725700/1063077198536556545/9FZgsMdV.jpg",
"media_url_https": "https://ton.twitter.com/1.1/ton/data/dm/1063077238797725700/1063077198536556545/9FZgsMdV.jpg",
"url": "https://t.co/UfaCwi9cUb",
"display_url": "pic.twitter.com/UfaCwi9cUb",
"expanded_url": "https://twitter.com/messages/media/1063077238797725700",
"type": "photo",
"sizes": {
"thumb": {
"w": 150,
"h": 150,
"resize": "crop"
},
"medium": {
"w": 1200,
"h": 313,
"resize": "fit"
},
"small": {
"w": 680,
"h": 177,
"resize": "fit"
},
"large": {
"w": 1472,
"h": 384,
"resize": "fit"
}
}
}
}
}
}
}
],
"users": {
"456": {
"id": "456",
"created_timestamp": "1290730789000",
"name": "Martin Edenhofer",
"screen_name": "medenhofer",
"description": "Open Source professional and geek. Also known as #OTRS and #Zammad inventor. ;)\r\nEntrepreneur and Advisor for open source people in need.",
"url": "https://t.co/whm4HTWdMw",
"protected": false,
"verified": false,
"followers_count": 312,
"friends_count": 314,
"statuses_count": 222,
"profile_image_url": "http://pbs.twimg.com/profile_images/794220000450150401/D-eFg44R_normal.jpg",
"profile_image_url_https": "https://pbs.twimg.com/profile_images/794220000450150401/D-eFg44R_normal.jpg"
},
"123": {
"id": "123",
"created_timestamp": "1476091912921",
"name": "Zammad HQ",
"screen_name": "zammadhq",
"description": "Helpdesk and Customer Support made easy. Open Source for download or to go with SaaS. #zammad",
"url": "https://t.co/XITyrXmhTP",
"protected": false,
"verified": false,
"followers_count": 427,
"friends_count": 512,
"statuses_count": 437,
"profile_image_url": "http://pbs.twimg.com/profile_images/785412960797745152/wxdIvejo_normal.jpg",
"profile_image_url_https": "https://pbs.twimg.com/profile_images/785412960797745152/wxdIvejo_normal.jpg"
}
}
}
}

View file

@ -1,115 +0,0 @@
{
"headers": {
"x-twitter-webhooks-signature": "sha256=U7bglX19JitI2xuvyONAc0d/fowIFEeUzkEgnWdGyUM="
},
"params": {
"for_user_id": "123",
"tweet_create_events": [
{
"created_at": "Wed Nov 21 00:13:13 +0000 2018",
"id": 1065035365336141825,
"id_str": "1065035365336141825",
"text": "@znuny Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et… https://t.co/b9woj0QXNZ",
"source": "<a href=\"http://twitter.com\" rel=\"nofollow\">Twitter Web Client</a>",
"truncated": true,
"in_reply_to_status_id": null,
"in_reply_to_status_id_str": null,
"in_reply_to_user_id": 123,
"in_reply_to_user_id_str": "123",
"in_reply_to_screen_name": "znuny",
"user": {
"id": 219826253,
"id_str": "219826253",
"name": "Martin Edenhofer",
"screen_name": "medenhofer",
"location": null,
"url": "http://edenhofer.de/",
"description": "Open Source professional and geek. Also known as #OTRS and #Zammad inventor. ;)\r\nEntrepreneur and Advisor for open source people in need.",
"translator_type": "regular",
"protected": false,
"verified": false,
"followers_count": 310,
"friends_count": 314,
"listed_count": 16,
"favourites_count": 129,
"statuses_count": 225,
"created_at": "Fri Nov 26 00:19:49 +0000 2010",
"utc_offset": null,
"time_zone": null,
"geo_enabled": false,
"lang": "en",
"contributors_enabled": false,
"is_translator": false,
"profile_background_color": "C0DEED",
"profile_background_image_url": "http://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_image_url_https": "https://abs.twimg.com/images/themes/theme1/bg.png",
"profile_background_tile": true, "profile_link_color": "0084B4", "profile_sidebar_border_color": "FFFFFF",
"profile_sidebar_fill_color": "DDEEF6",
"profile_text_color": "333333",
"profile_use_background_image": true,
"profile_image_url": "http://pbs.twimg.com/profile_images/794220000450150401/D-eFg44R_normal.jpg",
"profile_image_url_https": "https://pbs.twimg.com/profile_images/794220000450150401/D-eFg44R_normal.jpg",
"profile_banner_url": "https://pbs.twimg.com/profile_banners/219826253/1349428277",
"default_profile": false,
"default_profile_image": false,
"following": null,
"follow_request_sent": null,
"notifications": null
},
"geo": null,
"coordinates": null,
"place": null,
"contributors": null,
"is_quote_status": false,
"extended_tweet": {
"full_text": "@znuny Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lore",
"display_text_range": [0, 279],
"entities": {
"hashtags": [],
"urls": [],
"user_mentions": [
{
"screen_name": "znuny",
"name": "Znuny / ES for OTRS",
"id": 123,
"id_str": "123",
"indices": [0, 6]
}
],
"symbols": []
}
},
"quote_count": 0,
"reply_count": 0,
"retweet_count": 0,
"favorite_count": 0,
"entities": {
"hashtags": [],
"urls": [
{
"url": "https://t.co/b9woj0QXNZ",
"expanded_url": "https://twitter.com/i/web/status/1065035365336141825",
"display_url": "twitter.com/i/web/status/1…",
"indices": [117, 140]
}
],
"user_mentions": [
{
"screen_name": "znuny",
"name": "Znuny / ES for OTRS",
"id": 123,
"id_str": "123",
"indices": [0, 6]
}
],
"symbols": []
},
"favorited": false,
"retweeted": false,
"filter_level": "low",
"lang": "ro",
"timestamp_ms": "1542759193153"
}
]
}
}

View file

@ -1,62 +0,0 @@
{
"headers" : {
"x-twitter-webhooks-signature" : "sha256=OTguUdchBdxNal/csZsRkytKL5srrUuezZ3hp/2E404="
},
"params" : {
"for_user_id": "123",
"direct_message_events": [
{
"type": "message_create",
"id": "1063077238797725701",
"created_timestamp": "1542292339406",
"message_create": {
"target": {
"recipient_id": "123"
},
"sender_id": "456",
"message_data": {
"text": "Hello again!",
"entities": {
"hashtags": [],
"symbols": [],
"user_mentions": [],
"urls": []
}
}
}
}
],
"users": {
"456": {
"id": "456",
"created_timestamp": "1290730789000",
"name": "Martin Edenhofer",
"screen_name": "medenhofer",
"description": "Open Source professional and geek. Also known as #OTRS and #Zammad inventor. ;)\r\nEntrepreneur and Advisor for open source people in need.",
"url": "https://t.co/whm4HTWdMw",
"protected": false,
"verified": false,
"followers_count": 312,
"friends_count": 314,
"statuses_count": 222,
"profile_image_url": "http://pbs.twimg.com/profile_images/794220000450150401/D-eFg44R_normal.jpg",
"profile_image_url_https": "https://pbs.twimg.com/profile_images/794220000450150401/D-eFg44R_normal.jpg"
},
"123": {
"id": "123",
"created_timestamp": "1476091912921",
"name": "Zammad HQ",
"screen_name": "zammadhq",
"description": "Helpdesk and Customer Support made easy. Open Source for download or to go with SaaS. #zammad",
"url": "https://t.co/XITyrXmhTP",
"protected": false,
"verified": false,
"followers_count": 427,
"friends_count": 512,
"statuses_count": 437,
"profile_image_url": "http://pbs.twimg.com/profile_images/785412960797745152/wxdIvejo_normal.jpg",
"profile_image_url_https": "https://pbs.twimg.com/profile_images/785412960797745152/wxdIvejo_normal.jpg"
}
}
}
}

View file

@ -0,0 +1,51 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
direct_message_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
type: message_create
id: '1206724334791753732'
created_timestamp: '1576540475925'
message_create: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
target: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
recipient_id: '2975699229'
sender_id: '1205290247124217856'
message_data: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
text: Yes, you are!
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
symbols: []
user_mentions: []
urls: []
users: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
'1205290247124217856': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '1205290247124217856'
created_timestamp: '1576198570797'
name: pennbrooke
screen_name: pennbrooke1
location: London
description: More like penn-broke, amirite?
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 1
friends_count: 1
statuses_count: 2
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
'2975699229': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '2975699229'
created_timestamp: '1421116717416'
name: Ryan Lue
screen_name: ScruffyMcG
location: Taipei
description: I like turtles.
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 31
friends_count: 57
statuses_count: 6
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,51 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
direct_message_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
type: message_create
id: '1207556329834835973'
created_timestamp: '1576738839001'
message_create: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
target: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
recipient_id: '2975699229'
sender_id: '1205290247124217856'
message_data: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
text: and I'm a hungry, hungry hippo!
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
symbols: []
user_mentions: []
urls: []
users: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
'1205290247124217856': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '1205290247124217856'
created_timestamp: '1576198570797'
name: pennbrooke
screen_name: pennbrooke1
location: London
description: More like penn-broke, amirite?
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 0
friends_count: 1
statuses_count: 2
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
'2975699229': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '2975699229'
created_timestamp: '1421116717416'
name: Ryan Lue
screen_name: ScruffyMcG
location: Taipei
description: I like turtles.
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 31
friends_count: 56
statuses_count: 6
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,98 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
direct_message_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
type: message_create
id: '1209117907864571908'
created_timestamp: '1577111148216'
message_create: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
target: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
recipient_id: '2975699229'
sender_id: '1205290247124217856'
message_data: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
text: " https://t.co/amoKo1v19w"
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
symbols: []
user_mentions: []
urls:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
url: https://t.co/amoKo1v19w
expanded_url: https://twitter.com/messages/media/1209117907864571908
display_url: pic.twitter.com/amoKo1v19w
indices:
- 1
- 24
attachment: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
type: media
media: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 1209117874389843969
id_str: '1209117874389843969'
indices:
- 1
- 24
media_url: https://pbs.twimg.com/dm_gif_preview/1209117874389843969/Lgs2ZRqicjZjx6kFdwQcu2T5rmEq7br_m8QKHj-RybsPv0yeq5.jpg
media_url_https: https://pbs.twimg.com/dm_gif_preview/1209117874389843969/Lgs2ZRqicjZjx6kFdwQcu2T5rmEq7br_m8QKHj-RybsPv0yeq5.jpg
url: https://t.co/amoKo1v19w
display_url: pic.twitter.com/amoKo1v19w
expanded_url: https://twitter.com/messages/media/1209117907864571908
type: animated_gif
sizes: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
small: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 270
h: 480
resize: fit
thumb: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 150
h: 150
resize: crop
medium: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 270
h: 480
resize: fit
large: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 270
h: 480
resize: fit
video_info: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
aspect_ratio:
- 9
- 16
variants:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
bitrate: 0
content_type: video/mp4
url: https://video.twimg.com/dm_gif/1209117874389843969/Lgs2ZRqicjZjx6kFdwQcu2T5rmEq7br_m8QKHj-RybsPv0yeq5.mp4
users: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
'1205290247124217856': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '1205290247124217856'
created_timestamp: '1576198570797'
name: pennbrooke
screen_name: pennbrooke1
location: London
description: More like penn-broke, amirite?
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 0
friends_count: 1
statuses_count: 8
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
'2975699229': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '2975699229'
created_timestamp: '1421116717416'
name: Ryan Lue
screen_name: ScruffyMcG
location: Taipei
description: I like turtles.
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 31
friends_count: 56
statuses_count: 7
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,58 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
direct_message_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
type: message_create
id: '1209004344399429636'
created_timestamp: '1577084072576'
message_create: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
target: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
recipient_id: '2975699229'
sender_id: '1205290247124217856'
message_data: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
text: Did you know about this? https://t.co/SJ8nWqjwhz
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
symbols: []
user_mentions: []
urls:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
url: https://t.co/SJ8nWqjwhz
expanded_url: https://en.wikipedia.org/wiki/Frankenstein#Composition
display_url: en.wikipedia.org/wiki/Frankenst…
indices:
- 25
- 48
users: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
'1205290247124217856': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '1205290247124217856'
created_timestamp: '1576198570797'
name: pennbrooke
screen_name: pennbrooke1
location: London
description: More like penn-broke, amirite?
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 0
friends_count: 1
statuses_count: 4
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
'2975699229': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '2975699229'
created_timestamp: '1421116717416'
name: Ryan Lue
screen_name: ScruffyMcG
location: Taipei
description: I like turtles.
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 31
friends_count: 56
statuses_count: 6
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,57 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
direct_message_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
type: message_create
id: '1206724203514228741'
created_timestamp: '1576540444626'
message_create: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
target: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
recipient_id: '1205290247124217856'
sender_id: '2975699229'
source_app_id: '3033300'
message_data: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
text: I'm a banana!
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
symbols: []
user_mentions: []
urls: []
apps: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
'3033300': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '3033300'
name: Twitter Web App
url: https://mobile.twitter.com
users: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
'2975699229': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '2975699229'
created_timestamp: '1421116717416'
name: Ryan Lue
screen_name: ScruffyMcG
location: Taipei
description: I like turtles.
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 31
friends_count: 57
statuses_count: 6
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
'1205290247124217856': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '1205290247124217856'
created_timestamp: '1576198570797'
name: pennbrooke
screen_name: pennbrooke1
location: London
description: More like penn-broke, amirite?
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 1
friends_count: 1
statuses_count: 2
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,41 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
direct_message_indicate_typing_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_timestamp: '1576540471102'
sender_id: '1205290247124217856'
target: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
recipient_id: '2975699229'
users: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
'1205290247124217856': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '1205290247124217856'
created_timestamp: '1576198570797'
name: pennbrooke
screen_name: pennbrooke1
location: London
description: More like penn-broke, amirite?
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 1
friends_count: 1
statuses_count: 2
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
'2975699229': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '2975699229'
created_timestamp: '1421116717416'
name: Ryan Lue
screen_name: ScruffyMcG
location: Taipei
description: I like turtles.
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 31
friends_count: 57
statuses_count: 6
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,42 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
direct_message_mark_read_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_timestamp: '1576540445711'
sender_id: '1205290247124217856'
target: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
recipient_id: '2975699229'
last_read_event_id: '1206724203514228741'
users: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
'1205290247124217856': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '1205290247124217856'
created_timestamp: '1576198570797'
name: pennbrooke
screen_name: pennbrooke1
location: London
description: More like penn-broke, amirite?
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 1
friends_count: 1
statuses_count: 2
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
'2975699229': !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '2975699229'
created_timestamp: '1421116717416'
name: Ryan Lue
screen_name: ScruffyMcG
location: Taipei
description: I like turtles.
url: https://t.co/Y9Umsm0AJJ
protected: false
verified: false
followers_count: 31
friends_count: 57
statuses_count: 6
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,127 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
favorite_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 306365f99a761d92af4753775e89f7a4
created_at: Mon Dec 16 23:49:59 +0000 2019
timestamp_ms: 1576540199643
favorited_status: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_at: Mon Dec 16 12:20:39 +0000 2019
id: 1206549698791657473
id_str: '1206549698791657473'
text: https://t.co/qywSsecZ1I is now running on Falcon.
source: <a href="https://mobile.twitter.com" rel="nofollow">Twitter Web App</a>
truncated: false
in_reply_to_status_id:
in_reply_to_status_id_str:
in_reply_to_user_id:
in_reply_to_user_id_str:
in_reply_to_screen_name:
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 28451785
id_str: '28451785'
name: Samuel Williams
screen_name: ioquatix
location: Christchurch, New Zealand
url: http://www.codeotaku.com
description: '"A candle loses nothing by lighting another"'
translator_type: none
protected: false
verified: false
followers_count: 574
friends_count: 149
listed_count: 22
favourites_count: 1683
statuses_count: 1467
created_at: Thu Apr 02 23:52:51 +0000 2009
utc_offset:
time_zone:
geo_enabled: true
lang:
contributors_enabled: false
is_translator: false
profile_background_color: '000000'
profile_background_image_url: http://abs.twimg.com/images/themes/theme5/bg.gif
profile_background_image_url_https: https://abs.twimg.com/images/themes/theme5/bg.gif
profile_background_tile: true
profile_link_color: '000000'
profile_sidebar_border_color: 4025AD
profile_sidebar_fill_color: DEF0FF
profile_text_color: '000000'
profile_use_background_image: true
profile_image_url: http://pbs.twimg.com/profile_images/1343681082/Chi_Keyboard_normal.png
profile_image_url_https: https://pbs.twimg.com/profile_images/1343681082/Chi_Keyboard_normal.png
profile_banner_url: https://pbs.twimg.com/profile_banners/28451785/1353638161
default_profile: false
default_profile_image: false
following:
follow_request_sent:
notifications:
geo:
coordinates:
place:
contributors:
is_quote_status: false
quote_count: 0
reply_count: 0
retweet_count: 4
favorite_count: 36
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
url: https://t.co/qywSsecZ1I
expanded_url: https://rubyapi.org
display_url: rubyapi.org
indices:
- 0
- 23
user_mentions: []
symbols: []
favorited: false
retweeted: false
possibly_sensitive: false
filter_level: low
lang: en
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 2975699229
id_str: '2975699229'
name: Ryan Lue
screen_name: ScruffyMcG
location: Taipei
url: http://ryanlue.com
description: I like turtles.
translator_type: none
protected: false
verified: false
followers_count: 30
friends_count: 56
listed_count: 0
favourites_count: 20
statuses_count: 6
created_at: Tue Jan 13 02:38:37 +0000 2015
utc_offset:
time_zone:
geo_enabled: false
lang:
contributors_enabled: false
is_translator: false
profile_background_color: C0DEED
profile_background_image_url: http://abs.twimg.com/images/themes/theme1/bg.png
profile_background_image_url_https: https://abs.twimg.com/images/themes/theme1/bg.png
profile_background_tile: false
profile_link_color: 1DA1F2
profile_sidebar_border_color: C0DEED
profile_sidebar_fill_color: DDEEF6
profile_text_color: '333333'
profile_use_background_image: true
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_banner_url: https://pbs.twimg.com/profile_banners/2975699229/1497946434
default_profile: true
default_profile_image: false
following:
follow_request_sent:
notifications:
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,82 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
follow_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
type: unfollow
created_timestamp: '1576540568600'
target: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '1205290247124217856'
default_profile_image: false
profile_background_image_url: ''
friends_count: 1
favourites_count: 0
profile_link_color: -1
profile_background_image_url_https: ''
utc_offset: 0
screen_name: pennbrooke1
is_translator: false
followers_count: 1
name: pennbrooke
lang: ''
profile_use_background_image: false
created_at: Fri Dec 13 00:56:10 +0000 2019
profile_text_color: -1
notifications: false
protected: false
statuses_count: 2
url: https://t.co/Y9Umsm0AJJ
contributors_enabled: false
default_profile: true
profile_sidebar_border_color: -1
time_zone: ''
geo_enabled: false
verified: false
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
following: false
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_background_tile: false
listed_count: 0
profile_sidebar_fill_color: -1
location: London
follow_request_sent: false
description: More like penn-broke, amirite?
profile_background_color: -1
source: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '2975699229'
default_profile_image: false
profile_background_image_url: ''
friends_count: 57
favourites_count: 20
profile_link_color: -1
profile_background_image_url_https: ''
utc_offset: 0
screen_name: ScruffyMcG
is_translator: false
followers_count: 31
name: Ryan Lue
lang: ''
profile_use_background_image: false
created_at: Tue Jan 13 02:38:37 +0000 2015
profile_text_color: -1
notifications: false
protected: false
statuses_count: 6
url: https://t.co/Y9Umsm0AJJ
contributors_enabled: false
default_profile: true
profile_sidebar_border_color: -1
time_zone: ''
geo_enabled: false
verified: false
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
following: false
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_background_tile: false
listed_count: 0
profile_sidebar_fill_color: -1
location: Taipei
follow_request_sent: false
description: I like turtles.
profile_background_color: -1
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,82 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
follow_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
type: follow
created_timestamp: '1576212630171'
target: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '1205290247124217856'
default_profile_image: false
profile_background_image_url: ''
friends_count: 0
favourites_count: 0
profile_link_color: -1
profile_background_image_url_https: ''
utc_offset: 0
screen_name: pennbrooke1
is_translator: false
followers_count: 1
name: pennbrooke
lang: ''
profile_use_background_image: false
created_at: Fri Dec 13 00:56:10 +0000 2019
profile_text_color: -1
notifications: false
protected: false
statuses_count: 2
url: https://t.co/Y9Umsm0AJJ
contributors_enabled: false
default_profile: true
profile_sidebar_border_color: -1
time_zone: ''
geo_enabled: false
verified: false
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
following: false
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_background_tile: false
listed_count: 0
profile_sidebar_fill_color: -1
location: London
follow_request_sent: false
description: More like penn-broke, amirite?
profile_background_color: -1
source: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: '2975699229'
default_profile_image: false
profile_background_image_url: ''
friends_count: 57
favourites_count: 19
profile_link_color: -1
profile_background_image_url_https: ''
utc_offset: 0
screen_name: ScruffyMcG
is_translator: false
followers_count: 30
name: Ryan Lue
lang: ''
profile_use_background_image: false
created_at: Tue Jan 13 02:38:37 +0000 2015
profile_text_color: -1
notifications: false
protected: false
statuses_count: 6
url: https://t.co/Y9Umsm0AJJ
contributors_enabled: false
default_profile: true
profile_sidebar_border_color: -1
time_zone: ''
geo_enabled: false
verified: false
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
following: false
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_background_tile: false
listed_count: 0
profile_sidebar_fill_color: -1
location: Taipei
follow_request_sent: false
description: I like turtles.
profile_background_color: -1
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,76 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
tweet_create_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_at: Thu Dec 19 10:37:42 +0000 2019
id: 1207610954160037890
id_str: '1207610954160037890'
text: Bleep bloop.
source: <a href="https://mobile.twitter.com" rel="nofollow">Twitter Web App</a>
truncated: false
in_reply_to_status_id:
in_reply_to_status_id_str:
in_reply_to_user_id:
in_reply_to_user_id_str:
in_reply_to_screen_name:
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 2975699229
id_str: '2975699229'
name: Ryan Lue
screen_name: ScruffyMcG
location: Taipei
url: http://ryanlue.com
description: I like turtles.
translator_type: none
protected: false
verified: false
followers_count: 31
friends_count: 56
listed_count: 0
favourites_count: 20
statuses_count: 7
created_at: Tue Jan 13 02:38:37 +0000 2015
utc_offset:
time_zone:
geo_enabled: false
lang:
contributors_enabled: false
is_translator: false
profile_background_color: C0DEED
profile_background_image_url: http://abs.twimg.com/images/themes/theme1/bg.png
profile_background_image_url_https: https://abs.twimg.com/images/themes/theme1/bg.png
profile_background_tile: false
profile_link_color: 1DA1F2
profile_sidebar_border_color: C0DEED
profile_sidebar_fill_color: DDEEF6
profile_text_color: '333333'
profile_use_background_image: true
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_banner_url: https://pbs.twimg.com/profile_banners/2975699229/1497946434
default_profile: true
default_profile_image: false
following:
follow_request_sent:
notifications:
geo:
coordinates:
place:
contributors:
is_quote_status: false
quote_count: 0
reply_count: 0
retweet_count: 0
favorite_count: 0
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls: []
user_mentions: []
symbols: []
favorited: false
retweeted: false
filter_level: low
lang: en
timestamp_ms: '1576751862455'
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,87 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
user_has_blocked: false
tweet_create_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_at: Thu Dec 19 11:27:49 +0000 2019
id: 1207623566339919872
id_str: '1207623566339919872'
text: "@ScruffyMcG This is only a test."
display_text_range:
- 12
- 32
source: <a href="https://mobile.twitter.com" rel="nofollow">Twitter Web App</a>
truncated: false
in_reply_to_status_id: 1205348660982083584
in_reply_to_status_id_str: '1205348660982083584'
in_reply_to_user_id: 1205290247124217856
in_reply_to_user_id_str: '1205290247124217856'
in_reply_to_screen_name: pennbrooke1
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 1205290247124217856
id_str: '1205290247124217856'
name: pennbrooke
screen_name: pennbrooke1
location: London
url: https://t.co/Y9Umsm0AJJ
description: More like penn-broke, amirite?
translator_type: none
protected: false
verified: false
followers_count: 0
friends_count: 1
listed_count: 0
favourites_count: 0
statuses_count: 3
created_at: Fri Dec 13 00:56:10 +0000 2019
utc_offset:
time_zone:
geo_enabled: false
lang:
contributors_enabled: false
is_translator: false
profile_background_color: F5F8FA
profile_background_image_url: ''
profile_background_image_url_https: ''
profile_background_tile: false
profile_link_color: 1DA1F2
profile_sidebar_border_color: C0DEED
profile_sidebar_fill_color: DDEEF6
profile_text_color: '333333'
profile_use_background_image: true
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
default_profile: true
default_profile_image: false
following:
follow_request_sent:
notifications:
geo:
coordinates:
place:
contributors:
is_quote_status: false
quote_count: 0
reply_count: 0
retweet_count: 0
favorite_count: 0
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls: []
user_mentions:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
screen_name: ScruffyMcG
name: Ryan Lue
id: 2975699229
id_str: '2975699229'
indices:
- 0
- 11
symbols: []
favorited: false
retweeted: false
filter_level: low
lang: en
timestamp_ms: '1576754869433'
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,171 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
tweet_create_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_at: Fri Dec 13 04:48:35 +0000 2019
id: 1205348768473899008
id_str: '1205348768473899008'
text: 'RT @ScruffyMcG: Verifying myself: I am ryanlue on Keybase.io. 5Ts1MQtWo3WOaJ48lZqiVJ3G-96xWzqvCIx3
/ https://t.co/ukrDDemda2'
source: <a href="https://mobile.twitter.com" rel="nofollow">Twitter Web App</a>
truncated: false
in_reply_to_status_id:
in_reply_to_status_id_str:
in_reply_to_user_id:
in_reply_to_user_id_str:
in_reply_to_screen_name:
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 1205290247124217856
id_str: '1205290247124217856'
name: pennbrooke
screen_name: pennbrooke1
location: London
url: https://t.co/Y9Umsm0AJJ
description: More like penn-broke, amirite?
translator_type: none
protected: false
verified: false
followers_count: 0
friends_count: 0
listed_count: 0
favourites_count: 0
statuses_count: 2
created_at: Fri Dec 13 00:56:10 +0000 2019
utc_offset:
time_zone:
geo_enabled: false
lang:
contributors_enabled: false
is_translator: false
profile_background_color: F5F8FA
profile_background_image_url: ''
profile_background_image_url_https: ''
profile_background_tile: false
profile_link_color: 1DA1F2
profile_sidebar_border_color: C0DEED
profile_sidebar_fill_color: DDEEF6
profile_text_color: '333333'
profile_use_background_image: true
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
default_profile: true
default_profile_image: false
following:
follow_request_sent:
notifications:
geo:
coordinates:
place:
contributors:
retweeted_status: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_at: Fri Jun 17 08:51:11 +0000 2016
id: 743727678734245889
id_str: '743727678734245889'
text: 'Verifying myself: I am ryanlue on Keybase.io. 5Ts1MQtWo3WOaJ48lZqiVJ3G-96xWzqvCIx3
/ https://t.co/ukrDDemda2'
source: <a href="http://twitter.com" rel="nofollow">Twitter Web Client</a>
truncated: false
in_reply_to_status_id:
in_reply_to_status_id_str:
in_reply_to_user_id:
in_reply_to_user_id_str:
in_reply_to_screen_name:
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 2975699229
id_str: '2975699229'
name: Ryan Lue
screen_name: ScruffyMcG
location: Taipei
url: http://ryanlue.com
description: I like turtles.
translator_type: none
protected: false
verified: false
followers_count: 30
friends_count: 56
listed_count: 0
favourites_count: 19
statuses_count: 6
created_at: Tue Jan 13 02:38:37 +0000 2015
utc_offset:
time_zone:
geo_enabled: false
lang:
contributors_enabled: false
is_translator: false
profile_background_color: C0DEED
profile_background_image_url: http://abs.twimg.com/images/themes/theme1/bg.png
profile_background_image_url_https: https://abs.twimg.com/images/themes/theme1/bg.png
profile_background_tile: false
profile_link_color: 1DA1F2
profile_sidebar_border_color: C0DEED
profile_sidebar_fill_color: DDEEF6
profile_text_color: '333333'
profile_use_background_image: true
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_banner_url: https://pbs.twimg.com/profile_banners/2975699229/1497946434
default_profile: true
default_profile_image: false
following:
follow_request_sent:
notifications:
geo:
coordinates:
place:
contributors:
is_quote_status: false
quote_count: 0
reply_count: 0
retweet_count: 1
favorite_count: 4
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
url: https://t.co/ukrDDemda2
expanded_url: https://keybase.io/ryanlue/sigs/5Ts1MQtWo3WOaJ48lZqiVJ3G-96xWzqvCIx3
display_url: keybase.io/ryanlue/sigs/5…
indices:
- 85
- 108
user_mentions: []
symbols: []
favorited: false
retweeted: false
possibly_sensitive: false
filter_level: low
lang: fi
is_quote_status: false
quote_count: 0
reply_count: 0
retweet_count: 0
favorite_count: 0
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
url: https://t.co/ukrDDemda2
expanded_url: https://keybase.io/ryanlue/sigs/5Ts1MQtWo3WOaJ48lZqiVJ3G-96xWzqvCIx3
display_url: keybase.io/ryanlue/sigs/5…
indices:
- 101
- 124
user_mentions:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
screen_name: ScruffyMcG
name: Ryan Lue
id: 2975699229
id_str: '2975699229'
indices:
- 3
- 14
symbols: []
favorited: false
retweeted: false
possibly_sensitive: false
filter_level: low
lang: fi
timestamp_ms: '1576212515358'
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,84 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
user_has_blocked: false
tweet_create_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_at: Fri Dec 13 04:48:09 +0000 2019
id: 1205348660982083584
id_str: '1205348660982083584'
text: "@ScruffyMcG This is a test of Twitter API webhooks."
source: <a href="https://mobile.twitter.com" rel="nofollow">Twitter Web App</a>
truncated: false
in_reply_to_status_id:
in_reply_to_status_id_str:
in_reply_to_user_id: 2975699229
in_reply_to_user_id_str: '2975699229'
in_reply_to_screen_name: ScruffyMcG
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 1205290247124217856
id_str: '1205290247124217856'
name: pennbrooke
screen_name: pennbrooke1
location: London
url: https://t.co/Y9Umsm0AJJ
description: More like penn-broke, amirite?
translator_type: none
protected: false
verified: false
followers_count: 0
friends_count: 0
listed_count: 0
favourites_count: 0
statuses_count: 1
created_at: Fri Dec 13 00:56:10 +0000 2019
utc_offset:
time_zone:
geo_enabled: false
lang:
contributors_enabled: false
is_translator: false
profile_background_color: F5F8FA
profile_background_image_url: ''
profile_background_image_url_https: ''
profile_background_tile: false
profile_link_color: 1DA1F2
profile_sidebar_border_color: C0DEED
profile_sidebar_fill_color: DDEEF6
profile_text_color: '333333'
profile_use_background_image: true
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
default_profile: true
default_profile_image: false
following:
follow_request_sent:
notifications:
geo:
coordinates:
place:
contributors:
is_quote_status: false
quote_count: 0
reply_count: 0
retweet_count: 0
favorite_count: 0
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls: []
user_mentions:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
screen_name: ScruffyMcG
name: Ryan Lue
id: 2975699229
id_str: '2975699229'
indices:
- 0
- 11
symbols: []
favorited: false
retweeted: false
filter_level: low
lang: en
timestamp_ms: '1576212489730'
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,113 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
user_has_blocked: false
tweet_create_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_at: Mon Dec 23 13:03:29 +0000 2019
id: 1209097192914313216
id_str: '1209097192914313216'
text: |-
@ScruffyMcG
This is a test of Zammad's handling of extended tweets. When Twitter sends tweet data (as JSON) to web… https://t.co/cXMQkk9sQb
source: <a href="https://mobile.twitter.com" rel="nofollow">Twitter Web App</a>
truncated: true
in_reply_to_status_id:
in_reply_to_status_id_str:
in_reply_to_user_id: 2975699229
in_reply_to_user_id_str: '2975699229'
in_reply_to_screen_name: ScruffyMcG
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 1205290247124217856
id_str: '1205290247124217856'
name: pennbrooke
screen_name: pennbrooke1
location: London
url: https://t.co/Y9Umsm0AJJ
description: More like penn-broke, amirite?
translator_type: none
protected: false
verified: false
followers_count: 0
friends_count: 1
listed_count: 0
favourites_count: 0
statuses_count: 5
created_at: Fri Dec 13 00:56:10 +0000 2019
utc_offset:
time_zone:
geo_enabled: false
lang:
contributors_enabled: false
is_translator: false
profile_background_color: F5F8FA
profile_background_image_url: ''
profile_background_image_url_https: ''
profile_background_tile: false
profile_link_color: 1DA1F2
profile_sidebar_border_color: C0DEED
profile_sidebar_fill_color: DDEEF6
profile_text_color: '333333'
profile_use_background_image: true
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
default_profile: true
default_profile_image: false
following:
follow_request_sent:
notifications:
geo:
coordinates:
place:
contributors:
is_quote_status: false
extended_tweet: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
full_text: |-
@ScruffyMcG
This is a test of Zammad's handling of extended tweets. When Twitter sends tweet data (as JSON) to webhook endpoints, tweets exceeding 140 characters are truncated (for backwards compatibility). The full tweet body is passed in an "extended_tweet" property.
display_text_range:
- 0
- 270
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls: []
user_mentions:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
screen_name: ScruffyMcG
name: Ryan Lue
id: 2975699229
id_str: '2975699229'
indices:
- 0
- 11
symbols: []
quote_count: 0
reply_count: 0
retweet_count: 0
favorite_count: 0
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
url: https://t.co/cXMQkk9sQb
expanded_url: https://twitter.com/i/web/status/1209097192914313216
display_url: twitter.com/i/web/status/1…
indices:
- 117
- 140
user_mentions:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
screen_name: ScruffyMcG
name: Ryan Lue
id: 2975699229
id_str: '2975699229'
indices:
- 0
- 11
symbols: []
favorited: false
retweeted: false
filter_level: low
lang: en
timestamp_ms: '1577106209387'
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,92 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
user_has_blocked: false
tweet_create_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_at: Mon Dec 23 13:24:07 +0000 2019
id: 1209102385076826113
id_str: '1209102385076826113'
text: "@ScruffyMcG @MrThorstenEckel This is a test of Twitter API webhooks."
source: <a href="https://mobile.twitter.com" rel="nofollow">Twitter Web App</a>
truncated: false
in_reply_to_status_id:
in_reply_to_status_id_str:
in_reply_to_user_id: 2975699229
in_reply_to_user_id_str: '2975699229'
in_reply_to_screen_name: ScruffyMcG
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 1205290247124217856
id_str: '1205290247124217856'
name: pennbrooke
screen_name: pennbrooke1
location:
url:
description:
translator_type: none
protected: false
verified: false
followers_count: 0
friends_count: 1
listed_count: 0
favourites_count: 0
statuses_count: 8
created_at: Fri Dec 13 00:56:10 +0000 2019
utc_offset:
time_zone:
geo_enabled: false
lang:
contributors_enabled: false
is_translator: false
profile_background_color: F5F8FA
profile_background_image_url: ''
profile_background_image_url_https: ''
profile_background_tile: false
profile_link_color: 1DA1F2
profile_sidebar_border_color: C0DEED
profile_sidebar_fill_color: DDEEF6
profile_text_color: '333333'
profile_use_background_image: true
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
default_profile: true
default_profile_image: false
following:
follow_request_sent:
notifications:
geo:
coordinates:
place:
contributors:
is_quote_status: false
quote_count: 0
reply_count: 0
retweet_count: 0
favorite_count: 0
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls: []
user_mentions:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
screen_name: ScruffyMcG
name: Ryan Lue
id: 2975699229
id_str: '2975699229'
indices:
- 0
- 11
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
screen_name: MrThorstenEckel
name: Thorsten Eckel
id: 2474118319
id_str: '2474118319'
indices:
- 12
- 28
symbols: []
favorited: false
retweeted: false
filter_level: low
lang: en
timestamp_ms: '1577107447295'
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,85 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
user_has_blocked: false
tweet_create_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_at: Mon Dec 23 15:06:52 +0000 2019
id: 1209128243955027968
id_str: '1209128243955027968'
text: "@ScruffyMcG Who do you think you are?"
source: <a href="https://mobile.twitter.com" rel="nofollow">Twitter Web App</a>
truncated: false
in_reply_to_status_id:
in_reply_to_status_id_str:
in_reply_to_user_id: 2975699229
in_reply_to_user_id_str: '2975699229'
in_reply_to_screen_name: ScruffyMcG
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 2975699229
id_str: '2975699229'
name: Ryan Lue
screen_name: ScruffyMcG
location: Taipei
url: http://ryanlue.com
description: I like turtles.
translator_type: none
protected: false
verified: false
followers_count: 31
friends_count: 56
listed_count: 0
favourites_count: 20
statuses_count: 8
created_at: Tue Jan 13 02:38:37 +0000 2015
utc_offset:
time_zone:
geo_enabled: false
lang:
contributors_enabled: false
is_translator: false
profile_background_color: C0DEED
profile_background_image_url: http://abs.twimg.com/images/themes/theme1/bg.png
profile_background_image_url_https: https://abs.twimg.com/images/themes/theme1/bg.png
profile_background_tile: false
profile_link_color: 1DA1F2
profile_sidebar_border_color: C0DEED
profile_sidebar_fill_color: DDEEF6
profile_text_color: '333333'
profile_use_background_image: true
profile_image_url: http://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_image_url_https: https://pbs.twimg.com/profile_images/877073703330238464/fnxECj4z_normal.jpg
profile_banner_url: https://pbs.twimg.com/profile_banners/2975699229/1497946434
default_profile: true
default_profile_image: false
following:
follow_request_sent:
notifications:
geo:
coordinates:
place:
contributors:
is_quote_status: false
quote_count: 0
reply_count: 0
retweet_count: 0
favorite_count: 0
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls: []
user_mentions:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
screen_name: ScruffyMcG
name: Ryan Lue
id: 2975699229
id_str: '2975699229'
indices:
- 0
- 11
symbols: []
favorited: false
retweeted: false
filter_level: low
lang: en
timestamp_ms: '1577113612532'
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,158 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
user_has_blocked: false
tweet_create_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_at: Mon Dec 23 13:20:23 +0000 2019
id: 1209101446706122752
id_str: '1209101446706122752'
text: "@ScruffyMcG https://t.co/DHD7xWvvh5"
display_text_range:
- 0
- 11
source: <a href="https://mobile.twitter.com" rel="nofollow">Twitter Web App</a>
truncated: false
in_reply_to_status_id:
in_reply_to_status_id_str:
in_reply_to_user_id: 2975699229
in_reply_to_user_id_str: '2975699229'
in_reply_to_screen_name: ScruffyMcG
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 1205290247124217856
id_str: '1205290247124217856'
name: pennbrooke
screen_name: pennbrooke1
location:
url:
description:
translator_type: none
protected: false
verified: false
followers_count: 0
friends_count: 1
listed_count: 0
favourites_count: 0
statuses_count: 7
created_at: Fri Dec 13 00:56:10 +0000 2019
utc_offset:
time_zone:
geo_enabled: false
lang:
contributors_enabled: false
is_translator: false
profile_background_color: F5F8FA
profile_background_image_url: ''
profile_background_image_url_https: ''
profile_background_tile: false
profile_link_color: 1DA1F2
profile_sidebar_border_color: C0DEED
profile_sidebar_fill_color: DDEEF6
profile_text_color: '333333'
profile_use_background_image: true
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
default_profile: true
default_profile_image: false
following:
follow_request_sent:
notifications:
geo:
coordinates:
place:
contributors:
is_quote_status: false
quote_count: 0
reply_count: 0
retweet_count: 0
favorite_count: 0
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls: []
user_mentions:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
screen_name: ScruffyMcG
name: Ryan Lue
id: 2975699229
id_str: '2975699229'
indices:
- 0
- 11
symbols: []
media:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 1209101411717242881
id_str: '1209101411717242881'
indices:
- 12
- 35
media_url: http://pbs.twimg.com/tweet_video_thumb/EMeXU-7UYAEm71w.jpg
media_url_https: https://pbs.twimg.com/tweet_video_thumb/EMeXU-7UYAEm71w.jpg
url: https://t.co/DHD7xWvvh5
display_url: pic.twitter.com/DHD7xWvvh5
expanded_url: https://twitter.com/pennbrooke1/status/1209101446706122752/photo/1
type: photo
sizes: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
small: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 270
h: 480
resize: fit
thumb: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 150
h: 150
resize: crop
medium: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 270
h: 480
resize: fit
large: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 270
h: 480
resize: fit
extended_entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
media:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 1209101411717242881
id_str: '1209101411717242881'
indices:
- 12
- 35
media_url: http://pbs.twimg.com/tweet_video_thumb/EMeXU-7UYAEm71w.jpg
media_url_https: https://pbs.twimg.com/tweet_video_thumb/EMeXU-7UYAEm71w.jpg
url: https://t.co/DHD7xWvvh5
display_url: pic.twitter.com/DHD7xWvvh5
expanded_url: https://twitter.com/pennbrooke1/status/1209101446706122752/photo/1
type: animated_gif
video_info: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
aspect_ratio:
- 9
- 16
variants:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
bitrate: 0
content_type: video/mp4
url: https://video.twimg.com/tweet_video/EMeXU-7UYAEm71w.mp4
sizes: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
small: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 270
h: 480
resize: fit
thumb: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 150
h: 150
resize: crop
medium: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 270
h: 480
resize: fit
large: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
w: 270
h: 480
resize: fit
favorited: false
retweeted: false
possibly_sensitive: false
filter_level: low
lang: und
timestamp_ms: '1577107223570'
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,92 @@
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
for_user_id: '2975699229'
user_has_blocked: false
tweet_create_events:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
created_at: Mon Dec 23 13:12:50 +0000 2019
id: 1209099545700786176
id_str: '1209099545700786176'
text: "@ScruffyMcG https://t.co/AyVD0yiqOT"
source: <a href="https://mobile.twitter.com" rel="nofollow">Twitter Web App</a>
truncated: false
in_reply_to_status_id:
in_reply_to_status_id_str:
in_reply_to_user_id: 2975699229
in_reply_to_user_id_str: '2975699229'
in_reply_to_screen_name: ScruffyMcG
user: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
id: 1205290247124217856
id_str: '1205290247124217856'
name: pennbrooke
screen_name: pennbrooke1
location:
url:
description:
translator_type: none
protected: false
verified: false
followers_count: 0
friends_count: 1
listed_count: 0
favourites_count: 0
statuses_count: 6
created_at: Fri Dec 13 00:56:10 +0000 2019
utc_offset:
time_zone:
geo_enabled: false
lang:
contributors_enabled: false
is_translator: false
profile_background_color: F5F8FA
profile_background_image_url: ''
profile_background_image_url_https: ''
profile_background_tile: false
profile_link_color: 1DA1F2
profile_sidebar_border_color: C0DEED
profile_sidebar_fill_color: DDEEF6
profile_text_color: '333333'
profile_use_background_image: true
profile_image_url: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
profile_image_url_https: https://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
default_profile: true
default_profile_image: false
following:
follow_request_sent:
notifications:
geo:
coordinates:
place:
contributors:
is_quote_status: false
quote_count: 0
reply_count: 0
retweet_count: 0
favorite_count: 0
entities: !ruby/hash:ActiveSupport::HashWithIndifferentAccess
hashtags: []
urls:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
url: https://t.co/AyVD0yiqOT
expanded_url: https://zammad.org/
display_url: zammad.org
indices:
- 12
- 35
user_mentions:
- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
screen_name: ScruffyMcG
name: Ryan Lue
id: 2975699229
id_str: '2975699229'
indices:
- 0
- 11
symbols: []
favorited: false
retweeted: false
possibly_sensitive: false
filter_level: low
lang: und
timestamp_ms: '1577106770335'
controller: channels_twitter
action: webhook_incoming

View file

@ -0,0 +1,247 @@
---
http_interactions:
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:35 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=2
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:35 GMT
- request:
method: get
uri: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- abs.twimg.com
response:
status:
code: 200
message: OK
headers:
Accept-Ranges:
- bytes
Access-Control-Allow-Origin:
- "*"
Content-Type:
- image/png
Date:
- Fri, 27 Dec 2019 03:45:35 GMT
Etag:
- '"QcuRPIhOAYpzfGh0vMtQAQ=="'
Expires:
- Sat, 26 Dec 2020 03:45:35 GMT
Last-Modified:
- Sat, 22 Dec 2018 15:21:58 GMT
Server:
- ECS (tpe/68A3)
Strict-Transport-Security:
- max-age=631138519
Surrogate-Key:
- twitter-assets
X-Cache:
- HIT
X-Connection-Hash:
- 97b9e7d1341932a1fcad07625c3f5283
X-Content-Type-Options:
- nosniff
X-Response-Time:
- '8'
X-Ton-Expected-Size:
- '504'
Content-Length:
- '504'
body:
encoding: ASCII-8BIT
string: !binary |-
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAwFBMVEXM1t3K1dy5xc2xvca7xs+KmaVrfYtld4agrrhneYhoeoiksbufrbegrbe7xs66xs6Dk5+/ytKdqrWElKCDk6Byg5HG0NjEz9bH0dlqfIprfIuAkJ2ir7nJ09p1hpN0hZO9yNDH0tmbqbTBzNOzv8iqtsCotL6ntL7L1dy3w8yjsLqVpK+Onam8x9CRn6ttf43CzdWMm6dmeIeLmqauusSwvMVxgpCToa29ydFneIeRoKzK1Nttfo2yvseZp7KHl6OOgUPZAAAA80lEQVR4Ae3SA5oDQRgE0Aortm1zNub9T7Xm4O/+uMo7w8O/duNyezxuF3R5fX4+8vu80BII8lUoDA0RfhKFUizIT4JxqCT4RQIKSZokIUvRJAVZmiYZyLI0yUIWpEkQohwtcpDkaZGHpECLAkRFmpQgK9OkDFmFJhXIqjV+Ua9CoZHlJ9kGlJqtLF9lW01oaXe6vX6308aPMRiOxpPJeDQcQMd0Nuer+WwKlcXS4CfG3QKi1Zwm8xUEAYMWRkAZSbvT2qAtYw1bzQ0dbJqws6WjLWzs9nS038HqQMEBFscTBacjzDoUnWF2oegCsytFV7x6ADhgICRy9ELGAAAAAElFTkSuQmCC
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:35 GMT
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:35 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=2
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:35 GMT
- request:
method: get
uri: https://api.twitter.com/1.1/statuses/show/1207610954160037890.json
body:
encoding: UTF-8
string: ''
headers:
User-Agent:
- TwitterRubyGem/6.2.0
Authorization:
- OAuth oauth_consumer_key="<redacted>", oauth_nonce="ccabd7f04882ae0e18d37758ac7c786b",
oauth_signature="<redacted>", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1577418335", oauth_token="<redacted>",
oauth_version="1.0"
Connection:
- close
Host:
- api.twitter.com
response:
status:
code: 404
message: Not Found
headers:
Cache-Control:
- no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Connection:
- close
Content-Disposition:
- attachment; filename=json.json
Content-Length:
- '67'
Content-Type:
- application/json; charset=utf-8
Date:
- Fri, 27 Dec 2019 03:45:36 GMT
Expires:
- Tue, 31 Mar 1981 05:00:00 GMT
Last-Modified:
- Fri, 27 Dec 2019 03:45:36 GMT
Pragma:
- no-cache
Server:
- tsa_m
Set-Cookie:
- guest_id=v1%3A157741833648362103; Max-Age=63072000; Expires=Sun, 26 Dec 2021
03:45:36 GMT; Path=/; Domain=.twitter.com
- lang=en; Path=/
- personalization_id="v1_fsbQON7x7dvQ0evtktqIBw=="; Max-Age=63072000; Expires=Sun,
26 Dec 2021 03:45:36 GMT; Path=/; Domain=.twitter.com
Status:
- 404 Not Found
Strict-Transport-Security:
- max-age=631138519
X-Connection-Hash:
- ccd18097041d5fe32735d89956045f2e
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Rate-Limit-Limit:
- '900'
X-Rate-Limit-Remaining:
- '897'
X-Rate-Limit-Reset:
- '1577419233'
X-Response-Time:
- '110'
X-Transaction:
- 001f68e7002996d0
X-Twitter-Response-Tags:
- BouncerCompliant
X-Xss-Protection:
- '0'
body:
encoding: UTF-8
string: '{"errors":[{"code":144,"message":"No status found with that ID."}]}'
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:36 GMT
recorded_with: VCR 4.0.0

View file

@ -0,0 +1,247 @@
---
http_interactions:
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:36 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=1
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:36 GMT
- request:
method: get
uri: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- abs.twimg.com
response:
status:
code: 200
message: OK
headers:
Accept-Ranges:
- bytes
Access-Control-Allow-Origin:
- "*"
Content-Type:
- image/png
Date:
- Fri, 27 Dec 2019 03:45:36 GMT
Etag:
- '"QcuRPIhOAYpzfGh0vMtQAQ=="'
Expires:
- Sat, 26 Dec 2020 03:45:36 GMT
Last-Modified:
- Sat, 22 Dec 2018 15:21:58 GMT
Server:
- ECS (tpe/68A3)
Strict-Transport-Security:
- max-age=631138519
Surrogate-Key:
- twitter-assets
X-Cache:
- HIT
X-Connection-Hash:
- 97b9e7d1341932a1fcad07625c3f5283
X-Content-Type-Options:
- nosniff
X-Response-Time:
- '8'
X-Ton-Expected-Size:
- '504'
Content-Length:
- '504'
body:
encoding: ASCII-8BIT
string: !binary |-
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAwFBMVEXM1t3K1dy5xc2xvca7xs+KmaVrfYtld4agrrhneYhoeoiksbufrbegrbe7xs66xs6Dk5+/ytKdqrWElKCDk6Byg5HG0NjEz9bH0dlqfIprfIuAkJ2ir7nJ09p1hpN0hZO9yNDH0tmbqbTBzNOzv8iqtsCotL6ntL7L1dy3w8yjsLqVpK+Onam8x9CRn6ttf43CzdWMm6dmeIeLmqauusSwvMVxgpCToa29ydFneIeRoKzK1Nttfo2yvseZp7KHl6OOgUPZAAAA80lEQVR4Ae3SA5oDQRgE0Aortm1zNub9T7Xm4O/+uMo7w8O/duNyezxuF3R5fX4+8vu80BII8lUoDA0RfhKFUizIT4JxqCT4RQIKSZokIUvRJAVZmiYZyLI0yUIWpEkQohwtcpDkaZGHpECLAkRFmpQgK9OkDFmFJhXIqjV+Ua9CoZHlJ9kGlJqtLF9lW01oaXe6vX6308aPMRiOxpPJeDQcQMd0Nuer+WwKlcXS4CfG3QKi1Zwm8xUEAYMWRkAZSbvT2qAtYw1bzQ0dbJqws6WjLWzs9nS038HqQMEBFscTBacjzDoUnWF2oegCsytFV7x6ADhgICRy9ELGAAAAAElFTkSuQmCC
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:36 GMT
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:36 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=1
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:37 GMT
- request:
method: get
uri: https://api.twitter.com/1.1/statuses/show/1207610954160037890.json
body:
encoding: UTF-8
string: ''
headers:
User-Agent:
- TwitterRubyGem/6.2.0
Authorization:
- OAuth oauth_consumer_key="<redacted>", oauth_nonce="ab5fd57ec81489a5a223b56d9af20f0a",
oauth_signature="<redacted>", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1577418337", oauth_token="<redacted>",
oauth_version="1.0"
Connection:
- close
Host:
- api.twitter.com
response:
status:
code: 404
message: Not Found
headers:
Cache-Control:
- no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Connection:
- close
Content-Disposition:
- attachment; filename=json.json
Content-Length:
- '67'
Content-Type:
- application/json; charset=utf-8
Date:
- Fri, 27 Dec 2019 03:45:37 GMT
Expires:
- Tue, 31 Mar 1981 05:00:00 GMT
Last-Modified:
- Fri, 27 Dec 2019 03:45:37 GMT
Pragma:
- no-cache
Server:
- tsa_m
Set-Cookie:
- guest_id=v1%3A157741833757006606; Max-Age=63072000; Expires=Sun, 26 Dec 2021
03:45:37 GMT; Path=/; Domain=.twitter.com
- lang=en; Path=/
- personalization_id="v1_V1rxHe+i86BweSiS2JR1/A=="; Max-Age=63072000; Expires=Sun,
26 Dec 2021 03:45:37 GMT; Path=/; Domain=.twitter.com
Status:
- 404 Not Found
Strict-Transport-Security:
- max-age=631138519
X-Connection-Hash:
- ccc3c9dacffc76705aadbb69ebb5e093
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Rate-Limit-Limit:
- '900'
X-Rate-Limit-Remaining:
- '896'
X-Rate-Limit-Reset:
- '1577419233'
X-Response-Time:
- '110'
X-Transaction:
- 003a85720095790f
X-Twitter-Response-Tags:
- BouncerCompliant
X-Xss-Protection:
- '0'
body:
encoding: UTF-8
string: '{"errors":[{"code":144,"message":"No status found with that ID."}]}'
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:37 GMT
recorded_with: VCR 4.0.0

View file

@ -0,0 +1,169 @@
---
http_interactions:
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:27 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=1
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:27 GMT
- request:
method: get
uri: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- abs.twimg.com
response:
status:
code: 200
message: OK
headers:
Accept-Ranges:
- bytes
Access-Control-Allow-Origin:
- "*"
Content-Type:
- image/png
Date:
- Fri, 27 Dec 2019 03:45:27 GMT
Etag:
- '"QcuRPIhOAYpzfGh0vMtQAQ=="'
Expires:
- Sat, 26 Dec 2020 03:45:27 GMT
Last-Modified:
- Sat, 22 Dec 2018 15:21:58 GMT
Server:
- ECS (tpe/68A3)
Strict-Transport-Security:
- max-age=631138519
Surrogate-Key:
- twitter-assets
X-Cache:
- HIT
X-Connection-Hash:
- 97b9e7d1341932a1fcad07625c3f5283
X-Content-Type-Options:
- nosniff
X-Response-Time:
- '8'
X-Ton-Expected-Size:
- '504'
Content-Length:
- '504'
body:
encoding: ASCII-8BIT
string: !binary |-
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAwFBMVEXM1t3K1dy5xc2xvca7xs+KmaVrfYtld4agrrhneYhoeoiksbufrbegrbe7xs66xs6Dk5+/ytKdqrWElKCDk6Byg5HG0NjEz9bH0dlqfIprfIuAkJ2ir7nJ09p1hpN0hZO9yNDH0tmbqbTBzNOzv8iqtsCotL6ntL7L1dy3w8yjsLqVpK+Onam8x9CRn6ttf43CzdWMm6dmeIeLmqauusSwvMVxgpCToa29ydFneIeRoKzK1Nttfo2yvseZp7KHl6OOgUPZAAAA80lEQVR4Ae3SA5oDQRgE0Aortm1zNub9T7Xm4O/+uMo7w8O/duNyezxuF3R5fX4+8vu80BII8lUoDA0RfhKFUizIT4JxqCT4RQIKSZokIUvRJAVZmiYZyLI0yUIWpEkQohwtcpDkaZGHpECLAkRFmpQgK9OkDFmFJhXIqjV+Ua9CoZHlJ9kGlJqtLF9lW01oaXe6vX6308aPMRiOxpPJeDQcQMd0Nuer+WwKlcXS4CfG3QKi1Zwm8xUEAYMWRkAZSbvT2qAtYw1bzQ0dbJqws6WjLWzs9nS038HqQMEBFscTBacjzDoUnWF2oegCsytFV7x6ADhgICRy9ELGAAAAAElFTkSuQmCC
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:27 GMT
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:27 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=1
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:27 GMT
recorded_with: VCR 4.0.0

View file

@ -0,0 +1,169 @@
---
http_interactions:
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:26 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=1
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:26 GMT
- request:
method: get
uri: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- abs.twimg.com
response:
status:
code: 200
message: OK
headers:
Accept-Ranges:
- bytes
Access-Control-Allow-Origin:
- "*"
Content-Type:
- image/png
Date:
- Fri, 27 Dec 2019 03:45:26 GMT
Etag:
- '"QcuRPIhOAYpzfGh0vMtQAQ=="'
Expires:
- Sat, 26 Dec 2020 03:45:26 GMT
Last-Modified:
- Sat, 22 Dec 2018 15:21:58 GMT
Server:
- ECS (tpe/68A3)
Strict-Transport-Security:
- max-age=631138519
Surrogate-Key:
- twitter-assets
X-Cache:
- HIT
X-Connection-Hash:
- 97b9e7d1341932a1fcad07625c3f5283
X-Content-Type-Options:
- nosniff
X-Response-Time:
- '8'
X-Ton-Expected-Size:
- '504'
Content-Length:
- '504'
body:
encoding: ASCII-8BIT
string: !binary |-
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAwFBMVEXM1t3K1dy5xc2xvca7xs+KmaVrfYtld4agrrhneYhoeoiksbufrbegrbe7xs66xs6Dk5+/ytKdqrWElKCDk6Byg5HG0NjEz9bH0dlqfIprfIuAkJ2ir7nJ09p1hpN0hZO9yNDH0tmbqbTBzNOzv8iqtsCotL6ntL7L1dy3w8yjsLqVpK+Onam8x9CRn6ttf43CzdWMm6dmeIeLmqauusSwvMVxgpCToa29ydFneIeRoKzK1Nttfo2yvseZp7KHl6OOgUPZAAAA80lEQVR4Ae3SA5oDQRgE0Aortm1zNub9T7Xm4O/+uMo7w8O/duNyezxuF3R5fX4+8vu80BII8lUoDA0RfhKFUizIT4JxqCT4RQIKSZokIUvRJAVZmiYZyLI0yUIWpEkQohwtcpDkaZGHpECLAkRFmpQgK9OkDFmFJhXIqjV+Ua9CoZHlJ9kGlJqtLF9lW01oaXe6vX6308aPMRiOxpPJeDQcQMd0Nuer+WwKlcXS4CfG3QKi1Zwm8xUEAYMWRkAZSbvT2qAtYw1bzQ0dbJqws6WjLWzs9nS038HqQMEBFscTBacjzDoUnWF2oegCsytFV7x6ADhgICRy9ELGAAAAAElFTkSuQmCC
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:26 GMT
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:26 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=2
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:26 GMT
recorded_with: VCR 4.0.0

View file

@ -0,0 +1,307 @@
---
http_interactions:
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:33 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=1
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:33 GMT
- request:
method: get
uri: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- abs.twimg.com
response:
status:
code: 200
message: OK
headers:
Accept-Ranges:
- bytes
Access-Control-Allow-Origin:
- "*"
Content-Type:
- image/png
Date:
- Fri, 27 Dec 2019 03:45:33 GMT
Etag:
- '"QcuRPIhOAYpzfGh0vMtQAQ=="'
Expires:
- Sat, 26 Dec 2020 03:45:33 GMT
Last-Modified:
- Sat, 22 Dec 2018 15:21:58 GMT
Server:
- ECS (tpe/68A3)
Strict-Transport-Security:
- max-age=631138519
Surrogate-Key:
- twitter-assets
X-Cache:
- HIT
X-Connection-Hash:
- 97b9e7d1341932a1fcad07625c3f5283
X-Content-Type-Options:
- nosniff
X-Response-Time:
- '8'
X-Ton-Expected-Size:
- '504'
Content-Length:
- '504'
body:
encoding: ASCII-8BIT
string: !binary |-
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAwFBMVEXM1t3K1dy5xc2xvca7xs+KmaVrfYtld4agrrhneYhoeoiksbufrbegrbe7xs66xs6Dk5+/ytKdqrWElKCDk6Byg5HG0NjEz9bH0dlqfIprfIuAkJ2ir7nJ09p1hpN0hZO9yNDH0tmbqbTBzNOzv8iqtsCotL6ntL7L1dy3w8yjsLqVpK+Onam8x9CRn6ttf43CzdWMm6dmeIeLmqauusSwvMVxgpCToa29ydFneIeRoKzK1Nttfo2yvseZp7KHl6OOgUPZAAAA80lEQVR4Ae3SA5oDQRgE0Aortm1zNub9T7Xm4O/+uMo7w8O/duNyezxuF3R5fX4+8vu80BII8lUoDA0RfhKFUizIT4JxqCT4RQIKSZokIUvRJAVZmiYZyLI0yUIWpEkQohwtcpDkaZGHpECLAkRFmpQgK9OkDFmFJhXIqjV+Ua9CoZHlJ9kGlJqtLF9lW01oaXe6vX6308aPMRiOxpPJeDQcQMd0Nuer+WwKlcXS4CfG3QKi1Zwm8xUEAYMWRkAZSbvT2qAtYw1bzQ0dbJqws6WjLWzs9nS038HqQMEBFscTBacjzDoUnWF2oegCsytFV7x6ADhgICRy9ELGAAAAAElFTkSuQmCC
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:33 GMT
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:33 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=1
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:33 GMT
- request:
method: get
uri: https://api.twitter.com/1.1/statuses/show/1205348660982083584.json
body:
encoding: UTF-8
string: ''
headers:
User-Agent:
- TwitterRubyGem/6.2.0
Authorization:
- OAuth oauth_consumer_key="<redacted>", oauth_nonce="fbd8eff18f7b7b63f9cb7a4244a249d9",
oauth_signature="<redacted>", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1577418333", oauth_token="<redacted>",
oauth_version="1.0"
Connection:
- close
Host:
- api.twitter.com
response:
status:
code: 200
message: OK
headers:
Cache-Control:
- no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Connection:
- close
Content-Disposition:
- attachment; filename=json.json
Content-Length:
- '2077'
Content-Type:
- application/json;charset=utf-8
Date:
- Fri, 27 Dec 2019 03:45:34 GMT
Expires:
- Tue, 31 Mar 1981 05:00:00 GMT
Last-Modified:
- Fri, 27 Dec 2019 03:45:33 GMT
Pragma:
- no-cache
Server:
- tsa_m
Set-Cookie:
- guest_id=v1%3A157741833397608077; Max-Age=63072000; Expires=Sun, 26 Dec 2021
03:45:33 GMT; Path=/; Domain=.twitter.com
- lang=en; Path=/
- personalization_id="v1_t/Cj2A8olRHhad2BmhCbcw=="; Max-Age=63072000; Expires=Sun,
26 Dec 2021 03:45:33 GMT; Path=/; Domain=.twitter.com
Status:
- 200 OK
Strict-Transport-Security:
- max-age=631138519
X-Access-Level:
- read-write-directmessages
X-Connection-Hash:
- 66ad116b82e9bcba2664bd96d4057e41
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Rate-Limit-Limit:
- '900'
X-Rate-Limit-Remaining:
- '899'
X-Rate-Limit-Reset:
- '1577419233'
X-Response-Time:
- '127'
X-Transaction:
- '0091b54600e475b9'
X-Twitter-Response-Tags:
- BouncerCompliant
X-Xss-Protection:
- '0'
body:
encoding: UTF-8
string: '{"created_at":"Fri Dec 13 04:48:09 +0000 2019","id":1205348660982083584,"id_str":"1205348660982083584","text":"@ScruffyMcG
This is a test of Twitter API webhooks.","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[{"screen_name":"ScruffyMcG","name":"Ryan
Lue","id":2975699229,"id_str":"2975699229","indices":[0,11]}],"urls":[]},"source":"\u003ca
href=\"https:\/\/mobile.twitter.com\" rel=\"nofollow\"\u003eTwitter Web App\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":2975699229,"in_reply_to_user_id_str":"2975699229","in_reply_to_screen_name":"ScruffyMcG","user":{"id":1205290247124217856,"id_str":"1205290247124217856","name":"pennbrooke","screen_name":"pennbrooke1","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":1,"listed_count":0,"created_at":"Fri
Dec 13 00:56:10 +0000 2019","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":8,"lang":null,"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"F5F8FA","profile_background_image_url":null,"profile_background_image_url_https":null,"profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"can_media_tag":true,"followed_by":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none"},"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"en"}'
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:34 GMT
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:34 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=2
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:34 GMT
recorded_with: VCR 4.0.0

View file

@ -0,0 +1,307 @@
---
http_interactions:
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:34 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=2
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:34 GMT
- request:
method: get
uri: http://abs.twimg.com/sticky/default_profile_images/default_profile_normal.png
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- abs.twimg.com
response:
status:
code: 200
message: OK
headers:
Accept-Ranges:
- bytes
Access-Control-Allow-Origin:
- "*"
Content-Type:
- image/png
Date:
- Fri, 27 Dec 2019 03:45:34 GMT
Etag:
- '"QcuRPIhOAYpzfGh0vMtQAQ=="'
Expires:
- Sat, 26 Dec 2020 03:45:34 GMT
Last-Modified:
- Sat, 22 Dec 2018 15:21:58 GMT
Server:
- ECS (tpe/68A3)
Strict-Transport-Security:
- max-age=631138519
Surrogate-Key:
- twitter-assets
X-Cache:
- HIT
X-Connection-Hash:
- 97b9e7d1341932a1fcad07625c3f5283
X-Content-Type-Options:
- nosniff
X-Response-Time:
- '8'
X-Ton-Expected-Size:
- '504'
Content-Length:
- '504'
body:
encoding: ASCII-8BIT
string: !binary |-
iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAMAAABg3Am1AAAAwFBMVEXM1t3K1dy5xc2xvca7xs+KmaVrfYtld4agrrhneYhoeoiksbufrbegrbe7xs66xs6Dk5+/ytKdqrWElKCDk6Byg5HG0NjEz9bH0dlqfIprfIuAkJ2ir7nJ09p1hpN0hZO9yNDH0tmbqbTBzNOzv8iqtsCotL6ntL7L1dy3w8yjsLqVpK+Onam8x9CRn6ttf43CzdWMm6dmeIeLmqauusSwvMVxgpCToa29ydFneIeRoKzK1Nttfo2yvseZp7KHl6OOgUPZAAAA80lEQVR4Ae3SA5oDQRgE0Aortm1zNub9T7Xm4O/+uMo7w8O/duNyezxuF3R5fX4+8vu80BII8lUoDA0RfhKFUizIT4JxqCT4RQIKSZokIUvRJAVZmiYZyLI0yUIWpEkQohwtcpDkaZGHpECLAkRFmpQgK9OkDFmFJhXIqjV+Ua9CoZHlJ9kGlJqtLF9lW01oaXe6vX6308aPMRiOxpPJeDQcQMd0Nuer+WwKlcXS4CfG3QKi1Zwm8xUEAYMWRkAZSbvT2qAtYw1bzQ0dbJqws6WjLWzs9nS038HqQMEBFscTBacjzDoUnWF2oegCsytFV7x6ADhgICRy9ELGAAAAAElFTkSuQmCC
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:34 GMT
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:34 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=2
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:34 GMT
- request:
method: get
uri: https://api.twitter.com/1.1/statuses/show/1205348660982083584.json
body:
encoding: UTF-8
string: ''
headers:
User-Agent:
- TwitterRubyGem/6.2.0
Authorization:
- OAuth oauth_consumer_key="<redacted>", oauth_nonce="4754f26af6a3a66b618d2b6af10f4c6f",
oauth_signature="<redacted>", oauth_signature_method="HMAC-SHA1",
oauth_timestamp="1577418334", oauth_token="<redacted>",
oauth_version="1.0"
Connection:
- close
Host:
- api.twitter.com
response:
status:
code: 200
message: OK
headers:
Cache-Control:
- no-cache, no-store, must-revalidate, pre-check=0, post-check=0
Connection:
- close
Content-Disposition:
- attachment; filename=json.json
Content-Length:
- '2077'
Content-Type:
- application/json;charset=utf-8
Date:
- Fri, 27 Dec 2019 03:45:35 GMT
Expires:
- Tue, 31 Mar 1981 05:00:00 GMT
Last-Modified:
- Fri, 27 Dec 2019 03:45:35 GMT
Pragma:
- no-cache
Server:
- tsa_m
Set-Cookie:
- guest_id=v1%3A157741833523952118; Max-Age=63072000; Expires=Sun, 26 Dec 2021
03:45:35 GMT; Path=/; Domain=.twitter.com
- lang=en; Path=/
- personalization_id="v1_i22bdfR7BX3UE1wD7pcLEA=="; Max-Age=63072000; Expires=Sun,
26 Dec 2021 03:45:35 GMT; Path=/; Domain=.twitter.com
Status:
- 200 OK
Strict-Transport-Security:
- max-age=631138519
X-Access-Level:
- read-write-directmessages
X-Connection-Hash:
- 61933ead1b9e05a273d158cbcf6e2fcd
X-Content-Type-Options:
- nosniff
X-Frame-Options:
- SAMEORIGIN
X-Rate-Limit-Limit:
- '900'
X-Rate-Limit-Remaining:
- '898'
X-Rate-Limit-Reset:
- '1577419233'
X-Response-Time:
- '126'
X-Transaction:
- 0041e652004e06dc
X-Twitter-Response-Tags:
- BouncerCompliant
X-Xss-Protection:
- '0'
body:
encoding: UTF-8
string: '{"created_at":"Fri Dec 13 04:48:09 +0000 2019","id":1205348660982083584,"id_str":"1205348660982083584","text":"@ScruffyMcG
This is a test of Twitter API webhooks.","truncated":false,"entities":{"hashtags":[],"symbols":[],"user_mentions":[{"screen_name":"ScruffyMcG","name":"Ryan
Lue","id":2975699229,"id_str":"2975699229","indices":[0,11]}],"urls":[]},"source":"\u003ca
href=\"https:\/\/mobile.twitter.com\" rel=\"nofollow\"\u003eTwitter Web App\u003c\/a\u003e","in_reply_to_status_id":null,"in_reply_to_status_id_str":null,"in_reply_to_user_id":2975699229,"in_reply_to_user_id_str":"2975699229","in_reply_to_screen_name":"ScruffyMcG","user":{"id":1205290247124217856,"id_str":"1205290247124217856","name":"pennbrooke","screen_name":"pennbrooke1","location":"","description":"","url":null,"entities":{"description":{"urls":[]}},"protected":false,"followers_count":0,"friends_count":1,"listed_count":0,"created_at":"Fri
Dec 13 00:56:10 +0000 2019","favourites_count":0,"utc_offset":null,"time_zone":null,"geo_enabled":false,"verified":false,"statuses_count":8,"lang":null,"contributors_enabled":false,"is_translator":false,"is_translation_enabled":false,"profile_background_color":"F5F8FA","profile_background_image_url":null,"profile_background_image_url_https":null,"profile_background_tile":false,"profile_image_url":"http:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_image_url_https":"https:\/\/abs.twimg.com\/sticky\/default_profile_images\/default_profile_normal.png","profile_link_color":"1DA1F2","profile_sidebar_border_color":"C0DEED","profile_sidebar_fill_color":"DDEEF6","profile_text_color":"333333","profile_use_background_image":true,"has_extended_profile":false,"default_profile":true,"default_profile_image":true,"can_media_tag":true,"followed_by":true,"following":false,"follow_request_sent":false,"notifications":false,"translator_type":"none"},"geo":null,"coordinates":null,"place":null,"contributors":null,"is_quote_status":false,"retweet_count":0,"favorite_count":0,"favorited":false,"retweeted":false,"lang":"en"}'
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:35 GMT
- request:
method: get
uri: http://maps.googleapis.com/maps/api/geocode/json?address=London&sensor=true
body:
encoding: US-ASCII
string: ''
headers:
User-Agent:
- Zammad User Agent
Accept-Encoding:
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
Accept:
- "*/*"
Host:
- maps.googleapis.com
response:
status:
code: 200
message: OK
headers:
Content-Type:
- application/json; charset=UTF-8
Date:
- Fri, 27 Dec 2019 03:45:35 GMT
Pragma:
- no-cache
Expires:
- Fri, 01 Jan 1990 00:00:00 GMT
Cache-Control:
- no-cache, must-revalidate
Vary:
- Accept-Language
Access-Control-Allow-Origin:
- "*"
Server:
- mafe
Content-Length:
- '202'
X-Xss-Protection:
- '0'
X-Frame-Options:
- SAMEORIGIN
Server-Timing:
- gfet4t7; dur=2
body:
encoding: ASCII-8BIT
string: |
{
"error_message" : "You must use an API key to authenticate each request to Google Maps Platform APIs. For additional information, please refer to http://g.co/dev/maps-no-account",
"results" : [],
"status" : "REQUEST_DENIED"
}
http_version:
recorded_at: Fri, 27 Dec 2019 03:45:35 GMT
recorded_with: VCR 4.0.0