tipoff / seo Goto Github PK
View Code? Open in Web Editor NEWLaravel Package for tracking SEO keywords
License: MIT License
Laravel Package for tracking SEO keywords
License: MIT License
Create Permissions (TIPOFF/authorization#22) & assign to default Roles (TIPOFF/authorization#21) using the new PermissionMigration
and Helper in tipoff/authorization package:
When I attempt to make a Keyword #17 in the demo app through Nova, I am redirected to a 404 page once I attempt to create a resource. If I navigate back to the Keywords page in Nova, it does not appear that I have any Keywords created. Although if I view the database, it appears that a entry was added to some extent.
Screen where I provide input for the new keyword:
It appears that the record was created, but I receive a 404 error:
The result of running a query on the database showing the inserted record:
Additional note: not quite sure if it's related, but I'm having difficulties accessing the Keyword after this process in other resources as well. Even though the database entry is there, I'm not seeing it show up in other resources.
Keywords are stored lowercase and need to have the ability for slight variations to be grouped together with a parent keyword relationship.
Keywords will also belong to a Keyword Type (#16).
Keywords are created in each project by the Admin, Owners or Staff roles (TIPOFF/authorization#21) in the admin section (Laravel Nova).
Datetime for tracking requested and for when a keyword should no longer be tracked in the Rankings.
Later there will be options to approve ones that can be pulled from the Google Search Console API.
Create Nova Resources for all models in SEO package
This package currently pulls Google Rankings (#18) through the SerpAPI provider in the tipoff/laravel-serpapi package but I want to make sure everything is implemented so that we can switch out providers or make other providers optional in the future. I want to implement it in a similar approach to Flysystem:
Rankings (#18) should be broken out from one large table with nullable fields of each position to have a set of Results in a table for each Ranking. The Results will have a Type for each of the SERP sections (Organic Listing, Local Listing, Featured Snippet, Inline Video Listings, etc). This will also allow the results to be much more flexible in the future.
Waiting to do this until locations, market and blog are done
SEO rankings will be fetched for Local Keywords (#17) with SerpApi and stored in the database. These will be pulled on the first of the month and once weekly (I prefer Wednesdays).
Rankings will just look at the first page of search results. They will have the 10 spots created as a relationship to Webpages and any Local Maps SERP that appears in the results will also have the 3 Map Pack listings saved as Places (#15).
Keyword Types include:
Keywords will have a one-to-many relationship with Keyword Types.
When attempting to create a Company User(#36) in the demo app, I receive the following message:
We need to create an accessor on the domain model for formatted_title which concatenates the 'https://' .{domain->name}. '.' .{domain->tld}
Then we need to do the same thing for the formatted Webpage output
Expanding on the Places (#15) model, I want to save the details about places from the Google Places API.
This should be done in such a way that the Places associated with Competitors (TIPOFF/reviews#19) are checked regularly (perhaps weekly or monthly) to find out when details are updated. It will be structured where we can see versions of the updates so we know what was changed when. This is extremely important in regards to the business name, address, etc. but is also important to know when these Places are changing their hours of operation. I think I want to breakout out the general details into a separate table from the hours of operation table.
Results (#25) should be extended to include Video Listings. I'm trying to decide if these should be a new model that has a nullable relationship with Videos (drewroberts/media#2) or if the Webpages (#19) model can be updated to accommodate it.
example from the Fees package:
public function up()
{
$permissions = [
'view fees' => ['Owner', 'Staff'],
'create fees' => ['Owner'],
'update fees' => ['Owner'],
'delete fees' => [], // Admin only
];
$this->createPermissions($permissions);
}
update required validation for fields.
update css-fixer
@drewroberts I see we have Keys to add the API keys, but I believe this requires each company to add their API keys for each product. I just want to confirm this is still the direction you want to go and not have OAuth to pull in the keys automatically for each account.
@phuclh
Places are the tracked Google Places that will require a Google Places ID and the remainder of the details will be pulled by the API.
When these are pulled, a Company (#13) will be created for each new Domain (#14) name. After creation, the company will not ever be updated by the application code.
I would like for these to eventually be refactored to use the new version of Address (TIPOFF/addresses#19).
They will have an optional relationship where it belongs to a Market (TIPOFF/locations#41) if the tipoff/locations package is also included.
Domains are the core model of this package. They will be saved as the root domain name with a TLD.
Domains will have an optional One to One relationship with Companies (#13) and also contain additional fields from the Domain RDAP API and we will use a scraper to store the Domain's Favicon and other information.
Similar to User Profile Links (TIPOFF/authorization#27), Companies (#13) will be updated with Links to their own website and to their social media profiles. I will probably call the model Profile Links because it will also be used for the profiles of Locations (TIPOFF/locations#42) and potentially other polymorphic relationships.
Since these Links will depend on the Domains (#14) & Webpages (#19) models of this SEO package, it makes sense to add them to this package instead of the tipoff/authorization package.
Companies will be either the company for the application or a competitor company. They will be used for Locations and for Places. They must have a unique website domain.
With the new Phone (TIPOFF/addresses#58) model, all strings of phone numbers in this package should be replaced with a relationship to that model.
Need to update the README file to keep it current with package features and document how to best utilize it in a Laravel project.
There will be a many to many relationship with a pivot table for Company (#13) and User (TIPOFF/authorization#20) and it will be implemented similar to Teams in Laravel Spark. There should also be additional fields in the pivot table:
The primary contact should only have one relationship with a true value per Company.
There will be a unique key for company_id and user_id.
@drewroberts what is the queries column in the search_volumes table supposed to be for? It's an INT that isn't nullable. Should impressions go in here?
@phuclh
Monthly Search Volume for Keywords (#17) will be pulled monthly from estimates on both SerpAPI and Google Search Ads. The most accurate will be from the project's own Company (#13) when it consistently ranks in the first few results on the first page of Google results and will be pulled from Google Search Console.
Companies (#13) and Place Details (#22) should belong to a Domestic Address (TIPOFF/addresses#19) in a one-to-many relationship per discussion on new Address structure (TIPOFF/addresses#54).
For the search Rankings (#18) we need to create a model for Search Locales and add a relationship to them. More info in the SerpApi documentation:
I don't want to get too granular with these. For this package, I just want to use the United States as the default Search Locale and then create one for all 210 of the DMA Regions (TIPOFF/addresses#42) in the United States.
Webpages are exact URL's in search results (Rankings #18) that will be stored in a different table, so their movement in the Rankings will be documented. They belong to a Domain (#14) but in many cases, the Domain will not have a Company (#13).
When new Webpages are created, a domain will also be created, but a Company will not be created. New Companies are only created through the Google Places API.
Nova resources in this package that require slugs should mimic resources in https://github.com/tipoff/locations and https://github.com/drewroberts/blog that autofill slugs when providing input for a field such as title. It can be somewhat frustrating to a non-technical user on trying to figure out what might be acceptable for a slug field if they have to fill it out manually.
Refer to TIPOFF/addresses#57 (comment) for refactoring how exceptions are handled in package models
Need to implement tests for every feature of the package.
"organic_results": [
{
"position": 1,
"title": "Apple",
"link": "https://www.apple.com/",
"displayed_link": "https://www.apple.com/",
"snippet": "Discover the innovative world of Apple and shop everything iPhone, iPad, Apple Watch, Mac, and Apple TV, plus explore accessories, entertainment, and expert device support.",
"sitelinks_search_box": true,
"sitelinks": {
"expanded": [
{
"title": "iPhone",
"link": "https://www.apple.com/iphone/",
"snippet": "Explore iPhone, the world`s ..."
},
{
"title": "iPad",
"link": "https://www.apple.com/ipad/",
"snippet": "Compare iPad Models - iPad mini 4 - iPad Accessories - ..."
},
{
"title": "Mac",
"link": "https://www.apple.com/mac/",
"snippet": "MacBook Pro - MacBook - MacBook Air - iMac - Compare"
},
{
"title": "Music",
"link": "https://www.apple.com/music/",
"snippet": "Listen to your favorite music ad-free on all your devices, online ..."
},
{
"title": "Apple Support",
"link": "https://support.apple.com/",
"snippet": "Apple support is here to help. Learn more about popular ..."
},
{
"title": "Accessories",
"link": "https://www.apple.com/shop/accessories/all-accessories",
"snippet": "Shop Apple accessories for Apple Watch, iPhone, iPad, iPod, and ..."
}
]
},
"cached_page_link": "https://webcache.googleusercontent.com/search?q=cache:xEELJvdODswJ:https://www.apple.com/+&cd=1&hl=en&ct=clnk&gl=us"
}
]
I think this case should be handled, if it can happen with real response data
Expanding on the Places (#15) model, I want to save the Industry categories from the Google Places API. These should be saved into an Industries model that then has a many-to-many relationship with Places.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.