Skip to content

Commit dc532b3

Browse files
committed
feat: an acutal landing page :O
1 parent 5bab495 commit dc532b3

7 files changed

Lines changed: 151 additions & 24 deletions

File tree

config.sample.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ IMG_URL_TEXT: 'http://127.0.0.1:3000/img/{shortcode}' # if you want to do a redi
2828
VID_DISPLAY_TEXT: 'pic.twitter.com/{shortcode}'
2929

3030
# Same as the above (again), but for videos
31-
VID_URL_TEXT: 'http://127.0.0.1:3000/img/{shortcode}'
31+
VID_URL_TEXT: 'http://127.0.0.1:3000/img/{shortcode}' # even though it says images, this handles videos too.
3232

3333

3434
# SERVER_PORT is the port the server will listen on.

config/config.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
)
1313

1414
type Config struct {
15+
// Version of the server
16+
Version string `mapstructure:"VERSION"`
1517
// Accessible server address
1618
CdnURL string `mapstructure:"CDN_URL"`
1719
// The port to run the server on
@@ -43,21 +45,20 @@ func LoadConfig() (*Config, error) {
4345

4446
// Read environment variables with a specific prefix
4547
viper.SetEnvPrefix("TWITTER_BRIDGE")
46-
viper.AutomaticEnv()
4748

4849
// Set default values
50+
viper.SetDefault("VERSION", "1.0.4-beta") // wait till i forget to update this
4951
viper.SetDefault("SERVER_PORT", "3000")
5052
viper.SetDefault("DEVELOPER_MODE", false)
5153
viper.SetDefault("DATABASE_TYPE", "sqlite")
5254
viper.SetDefault("DATABASE_PATH", "./db/twitterbridge.db")
5355
viper.SetDefault("TRACK_ANALYTICS", true)
54-
viper.SetDefault("CDN_URL", "http://localhost:3000")
56+
viper.SetDefault("CDN_URL", "http://127.0.0.1:3000")
5557
viper.SetDefault("USE_X_FORWARDED_FOR", false)
56-
//viper.SetDefault("IMG_DISPLAY_TEXT", "pic.twitter.com/{shortblob}")
57-
// Since IMG_DISPLAY_TEXT isn't fully implemented, we'll have it disabled
58-
viper.SetDefault("IMG_DISPLAY_TEXT", "")
58+
viper.SetDefault("IMG_DISPLAY_TEXT", "pic.twitter.com/{shortblob}")
5959
viper.SetDefault("VID_DISPLAY_TEXT", "pic.twitter.com/{shortblob}")
60-
60+
viper.SetDefault("IMG_URL_TEXT", "http://127.0.0.1:3000/img/{shortblob}")
61+
viper.SetDefault("VID_URL_TEXT", "http://127.0.0.1:3000/img/{shortblob}")
6162
// Read config file
6263
if err := viper.ReadInConfig(); err != nil {
6364
fmt.Println("No config file found, relying on environment variables")

go.mod

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ require (
1313
require (
1414
filippo.io/edwards25519 v1.1.0 // indirect
1515
github.com/go-sql-driver/mysql v1.8.1 // indirect
16+
github.com/gofiber/template v1.8.3 // indirect
17+
github.com/gofiber/utils v1.1.0 // indirect
1618
github.com/jackc/pgpassfile v1.0.0 // indirect
1719
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
1820
github.com/jackc/pgx/v5 v5.7.2 // indirect
@@ -24,6 +26,7 @@ require (
2426
require (
2527
github.com/andybalholm/brotli v1.1.1 // indirect
2628
github.com/fsnotify/fsnotify v1.8.0 // indirect
29+
github.com/gofiber/template/html/v2 v2.1.3
2730
github.com/hashicorp/hcl v1.0.0 // indirect
2831
github.com/jinzhu/inflection v1.0.0 // indirect
2932
github.com/jinzhu/now v1.1.5 // indirect

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,12 @@ github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpv
1515
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
1616
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
1717
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
18+
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
19+
github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
20+
github.com/gofiber/template/html/v2 v2.1.3 h1:n1LYBtmr9C0V/k/3qBblXyMxV5B0o/gpb6dFLp8ea+o=
21+
github.com/gofiber/template/html/v2 v2.1.3/go.mod h1:U5Fxgc5KpyujU9OqKzy6Kn6Qup6Tm7zdsISR+VpnHRE=
22+
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
23+
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
1824
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
1925
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
2026
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=

static/bluetweety.png

954 KB
Loading

static/index.html

Lines changed: 119 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,14 @@
1111
padding: 0;
1212
background-color: #f4f4f4;
1313
}
14-
h1 {
15-
text-align: center;
16-
}
17-
h2 {
18-
text-align: center;
19-
}
20-
p {
14+
.text-center {
2115
text-align: center;
2216
}
2317
.bar {
18+
background: -webkit-linear-gradient(#1da1f2, #1d56f2);
19+
background: -moz-linear-gradient(#1da1f2, #1d56f2);
20+
background: -o-linear-gradient(#1da1f2, #1d56f2);
21+
background: -ms-linear-gradient(#1da1f2, #1d56f2);
2422
background: linear-gradient(#1da1f2, #1d56f2);;
2523
box-shadow: 0 1px 3px rgba(0,0,0,0.25),0 -1px 0 rgba(0,0,0,0.1) inset;
2624
height: 5px;
@@ -39,27 +37,132 @@
3937
.dev-warning img {
4038
vertical-align: middle;
4139
}
40+
.subtext {
41+
color: #ccc;
42+
font-size: 0.8em;
43+
}
44+
.info {
45+
margin: 1em;
46+
}
47+
.promoImage {
48+
max-width: 1000px;
49+
width: 100%;
50+
51+
display: block;
52+
text-align:center;
53+
margin-left:auto;margin-right:auto;
54+
}
55+
code {
56+
background-color: #242424;
57+
border-color: #181818;
58+
color:#f4f4f4;
59+
padding: 0.2em;
60+
border-radius: 0.2em;
61+
}
4262
</style>
4363
</head>
4464
<body>
45-
<h1>A Twitter API Translator</h1>
46-
<h2>Specifically Bluesky -> Twitter API V1</h2>
65+
<h1 class="text-center">A Twitter API Translator</h1>
66+
<h2 class="text-center">Specifically Bluesky -> Twitter API V1</h2>
67+
<p class="subtext text-center">Running version {{.Version}}</p>
4768
<div class="bar"></div>
4869
<br>
70+
{{if .NotConfigured}}
71+
<div class="dev-warning">
72+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAACGFjVEwAAAACAAAAAPONk3AAAAAMUExURf//AP+uAP///wAAAB/mRh0AAAABdFJOUwBA5thmAAAAGmZjVEwAAAAAAAAAGAAAABgAAAAAAAAAAABkAGQAALb1ADAAAABmSURBVCjPfdJBEsAgCANAjP//cyugKAZzzE5qx1YkAggNWkPRU9GeSQWjB4hUYD0RbXq/wAY/ZKnATxhwSgV2GQFL5rsqbJM58MQER79N1sAetSYxcPBJOiEm/h1yHsAF9tfcEfkAAuECObCQ8esAAAAaZmNUTAAAAAEAAAACAAAACwAAAAsAAAAIAGQAZAAABgD2jwAAABFmZEFUAAAAAijPY2BiYsCLAAL3AC2FC0/sAAAAGHRFWHRTb2Z0d2FyZQBnaWYyYXBuZy5zZi5uZXSW/xPIAAAAAElFTkSuQmCC">
73+
<b>This instance of A Twitter Bridge has not been configured properly! In present moment, images will not load. If you are the instance hoster, <a href="https://github.com/Preloading/TwitterAPIBridge?tab=readme-ov-file#3-configure-configyaml-edit-the-file-youll-see-decription-of-what-each-thing-does">jump back to step 3</a>. More specifically, configure CDN_URL from the default in config.yaml.</b>
74+
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAACGFjVEwAAAACAAAAAPONk3AAAAAMUExURf//AP+uAP///wAAAB/mRh0AAAABdFJOUwBA5thmAAAAGmZjVEwAAAAAAAAAGAAAABgAAAAAAAAAAABkAGQAALb1ADAAAABmSURBVCjPfdJBEsAgCANAjP//cyugKAZzzE5qx1YkAggNWkPRU9GeSQWjB4hUYD0RbXq/wAY/ZKnATxhwSgV2GQFL5rsqbJM58MQER79N1sAetSYxcPBJOiEm/h1yHsAF9tfcEfkAAuECObCQ8esAAAAaZmNUTAAAAAEAAAACAAAACwAAAAsAAAAIAGQAZAAABgD2jwAAABFmZEFUAAAAAijPY2BiYsCLAAL3AC2FC0/sAAAAGHRFWHRTb2Z0d2FyZQBnaWYyYXBuZy5zZi5uZXSW/xPIAAAAAElFTkSuQmCC">
75+
</div>
76+
<br>
77+
<div class="bar"></div>
78+
<br>
79+
{{end}}
80+
{{if .DeveloperMode}}
4981
<!-- Developer Mode Warning -->
50-
<!-- <div class="dev-warning">
82+
<div class="dev-warning">
5183
<img src="data:image/png;base64,R0lGODlhGAAYAPMAAP////vzBf9kA90JB/IIhEcApQAA0wKr6h+3FABkElYsBZBxOr+/v4CAgEBAQAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/h1HaWZCdWlsZGVyIDAuMiBieSBZdmVzIFBpZ3VldAAh+QQNZAAMACwAAAAAGAAYAEMEZ5DJSRkANWcwOngP52lWN1xoipoYWZqjK4nnBa7xDO9832q0k2zDov1cxk/ISEralhcWxYm6qaSvnhaLzA2nvOMwyZVRy8CiFQ32PHFCYlEJj0+CqmsZprLWMXh5gnxBW1stgokqEhEAIfkEDWQADAAsAAAAABgAGABDBGCQyUkZADVnMPq93YBpnPedZzhqVqiyVCmioBe7eK6vm8vDE1lNBJQIUS+SivZJGpdMpK2lq/qKpV/xidPCjk7gcei9mVJT5VlK7EHZ7aAvKosz5vQ6Rp9vLq2ASX10EhEAOw==">
5284
<b>
5385
This server has developer mode enabled. This means the owner of this instance can view plaintext credentials and tokens. Use with caution!
5486
</b>
5587
<img src="data:image/png;base64,R0lGODlhGAAYAPMAAP////vzBf9kA90JB/IIhEcApQAA0wKr6h+3FABkElYsBZBxOr+/v4CAgEBAQAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/h1HaWZCdWlsZGVyIDAuMiBieSBZdmVzIFBpZ3VldAAh+QQNZAAMACwAAAAAGAAYAEMEZ5DJSRkANWcwOngP52lWN1xoipoYWZqjK4nnBa7xDO9832q0k2zDov1cxk/ISEralhcWxYm6qaSvnhaLzA2nvOMwyZVRy8CiFQ32PHFCYlEJj0+CqmsZprLWMXh5gnxBW1stgokqEhEAIfkEDWQADAAsAAAAABgAGABDBGCQyUkZADVnMPq93YBpnPedZzhqVqiyVCmioBe7eK6vm8vDE1lNBJQIUS+SivZJGpdMpK2lq/qKpV/xidPCjk7gcei9mVJT5VlK7EHZ7aAvKosz5vQ6Rp9vLq2ASX10EhEAOw==">
56-
</div> -->
57-
<h3>What is this?</h3>
58-
<p>This is a server that allows you to access Bluesky using the Twitter API format. This allows old twitter clients to be useful again, and gives a way to browse Bluesky using a native app, without needing to write a custom one.</p>
59-
<h3>What versions of twitter is this compatible with?</h3>
60-
<p>A list of tested & compatible twitter clients can be found on my github, <a href="https://github.com/Preloading/TwitterAPIBridge/blob/main/COMPATIBILITY.md">or by clicking here</a></p> <!-- sorry SEO-->
88+
</div>
89+
<br>
90+
<div class="bar"></div>
91+
92+
{{end}}
93+
<img class="promoImage" src="/static/bluetweety.png" alt="An iPhone 3G, iPhone 4S, and Nexus 4 showing the Twitter home timeline" class="text-center">
94+
<div class="info">
95+
<h2>What is this?</h2>
96+
<p>This is a server that allows you to access Bluesky using the Twitter API format. This allows old twitter clients to be useful again, and gives a way to browse Bluesky using a native app on old devices, without needing to write a custom one.</p>
97+
<div class="bar"></div>
98+
<div>
99+
<h2>Usage Instructions</h2>
100+
<div>
101+
<h3>Official iOS app</h3>
102+
<ol>
103+
<li>Install Twitter. <a href="https://loganserver.net/twitters/">You can find versions of twitter here.</a> Recommended versions are 4.1.3, and 5.0.3</li>
104+
<li>Create a Bluesky app password. <a href="https://bsky.app/settings/security">You can find this here.</a> Enabling DMs is currently optional, though will be used for future versions.<p style="font-size:0.8em;">or do this thru Bluesky > Settings > Privacy and security > App passwords</p></li>
105+
<li>Open the Twitter app on your device.</li>
106+
107+
<li>Press the Login button (or signin depending on version)</li>
108+
<li>Press the cog/settings menu</li>
109+
<li>Put <code>{{.PrefixedURL}}</code> into the URL spots. <a href="https://github.com/Preloading/TwitterAPIBridge?tab=readme-ov-file#public-instances">Other public instances can be found on the twitter bridge github.</a></li>
110+
<li>Go back to the login prompt.</li>
111+
<li>Enter your bluesky handle for the username, and your Bluesky app password as the password. <b>Usage of normal passwords is not recommended, and will be forbidden in the future</b></li>
112+
<li>Press the sign in button</li>
113+
<li>If everything worked, you should be in! Enjoy!</li>
114+
</ol>
115+
<h3>iOS Twitter Integration + image uploads in app</h3>
116+
<p>Thanks to <a href="https://bag-xml.com">bag.xml</a> & <a href="https://cydia.skyglow.es">Requis</a>, a Cydia tweak now exists to redirect the iOS integration, and to enable for image uploads.</p>
117+
<ol>
118+
<li>Have a jailbroken device. For intergation, it should be running iOS 5-7. The min iOS version for image uploads isn't known right now.</li>
119+
<li>Add either <code>http://cydia.bag-xml.com</code> or <code>http://cydia.skyglow.es</code> to Cydia's sources tab.</li>
120+
<li>Install the package <code>Bluetweety</code> from the repo.</li>
121+
<li>Go to Settings > Bluetweety. (if it does not show up, check that it actually installed)</li>
122+
<li>Input <code>{{.UnPrefixedURL}}</code> into the URL. <b>Do NOT include https:// at the start, and a / at the end!!!!</b></li>
123+
<li>Reboot your phone. Yes this is a required step.</li>
124+
<li>Go to Settings > Twitter.</li>
125+
<li>Type your bluesky handle (example: preloading.bsky.social) and your app password (can be the same from the app) in the respective areas.</li>
126+
<li>Click Login</li>
127+
<li>Scroll down, and disable the ability for the Twitter app to view Twitter accounts.</li>
128+
<li>Hopefully success!</li>
129+
</ol>
61130

62-
<p>If you find this useful, please add a <a href=https://github.com/Preloading/TwitterAPIBridge><img src="./static/star.png" alt="star" height="15"></a>!</p>
131+
</div>
132+
133+
</div>
134+
<div class="bar"></div>
135+
<h1>FAQ.</h1>
136+
<h2>What is this compatible with?</h2>
137+
<p>A list of tested & compatible twitter clients can be found on my github, <a href="https://github.com/Preloading/TwitterAPIBridge/blob/main/COMPATIBILITY.md">or by clicking here</a>. If it's not there <a href="https://tryitands.ee">try it and see!</a> (and maybe make a PR of the outcome). In general, this bridge supports around 2010-2012.</p> <!-- sorry SEO-->
138+
<h2>Bluesky is cool and all, but I want it to be actually <abbr title="X/Twitter">Xitter</abbr>!</h2>
139+
<p>There are various reasons why having this be with twitter data is infeasible, and would not work. This includes:</p>
140+
<ol>
141+
<li><a href="https://docs.x.com/x-api/getting-started/about-x-api">Running it (and making it) would cost $5000/month</a>, or potentially even more!</li>
142+
<li>Twitter has become a hellscape.</li>
143+
<li>Sign in would likely be extremely hard/impossible.</li>
144+
<li>Twitter has been extremely hostile to <a href="https://x.com/fenix_app/status/1616577597042728961">third</a> <a href="https://tapbots.com/tweetbot/">party</a> <a href="https://twitterrific.com/beyond">clients</a></li>
145+
</ol>
146+
<h2>I found the mobile app API keys! Can't you use those!??!?!?</h2>
147+
<p>No.</p>
148+
<ol>
149+
<li>We would be violating the TOS of Xitter using these keys, we would get IP banned, and potentially the users of the service banned.</li>
150+
<li>It would have to be self-host only. Any pre-hosted version would get IP banned extremely quickly</li>
151+
<li>These keys have restricted access, and only allow internal API points, which have little to no documentation.</li>
152+
</ol>
153+
<h2>Can you do {INSERT OTHER SOCIAL MEDIA APP}</h2>
154+
<p>Probably not. I have some plans to potentially do mastodon in the far future, but anything other than that, no.</p>
155+
<h2>Support?</h2>
156+
<p>I give support on the <a href="https://discord.gg/bag-xml">bag.xml discord server</a>, in the #bluetweety channel. You can also @ me on Bluesky, <a href="https://bsky.app/profile/preloading.bsky.social">@preloading.bsky.social</a>, if using my hosted version.</p>
157+
<h2>Is this open source/Can I host a version?</h2>
158+
<p>Yes! <a href="https://github.com/Preloading/TwitterAPIBridge">You can find the source code here.</a></p>
159+
<h2>Is Twitter API v1.1 planned?</h2>
160+
<p>It is planned, but I'd like to finish v1.0 first.</p>
161+
</div>
162+
<div class="bar"></div>
163+
<p class="text-center">Made with ❤️, by Preloading</p>
164+
<p class="text-center">If you find this useful, please add a <a href=https://github.com/Preloading/TwitterAPIBridge><img src="./static/star.png" alt="star" height="15"></a>!</p>
165+
<p class="text-center subtext">This is not affiliated with Twitter (now X) nor Bluesky.</p>
63166
<!--
64167
<img src="./static/old_twitter.png" alt="Twitter">
65168
<img src="./static/bluesky.png" alt="Bluesky" height="75"> -->

twitterv1/twitterv1.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/Preloading/TwitterAPIBridge/config"
1111
"github.com/gofiber/fiber/v2"
1212
"github.com/gofiber/fiber/v2/middleware/logger"
13+
"github.com/gofiber/template/html/v2"
1314
)
1415

1516
var (
@@ -19,6 +20,7 @@ var (
1920
func InitServer(config *config.Config) {
2021
configData = config
2122
blueskyapi.InitConfig(configData)
23+
engine := html.New("./static", ".html")
2224
app := fiber.New(fiber.Config{
2325
//DisablePreParseMultipartForm: true,
2426
ProxyHeader: func() string {
@@ -27,6 +29,7 @@ func InitServer(config *config.Config) {
2729
}
2830
return ""
2931
}(),
32+
Views: engine,
3033
})
3134

3235
// Initialize default config
@@ -47,11 +50,22 @@ func InitServer(config *config.Config) {
4750
// app.Get("/", func(c *fiber.Ctx) error {
4851
// return c.SendString("Hello, World!")
4952
// Serve static files from the "static" folder
50-
app.Static("/", "./static")
5153
app.Static("/favicon.ico", "./static/favicon.ico")
5254
app.Static("/robots.txt", "./static/robots.txt")
5355
app.Static("/static", "./static")
5456

57+
// Serve /
58+
app.Get("/", func(c *fiber.Ctx) error {
59+
// Render index within layouts/nested/main within layouts/nested/base
60+
return c.Render("index", fiber.Map{
61+
"DeveloperMode": config.DeveloperMode,
62+
"NotConfigured": configData.CdnURL == "http://127.0.0.1:3000",
63+
"PrefixedURL": "https://" + c.Hostname(),
64+
"UnPrefixedURL": c.Hostname(),
65+
"Version": config.Version,
66+
}, "index")
67+
})
68+
5569
// Auth
5670
app.Post("/oauth/access_token", access_token)
5771
app.Get("/1/account/verify_credentials.:filetype", VerifyCredentials)

0 commit comments

Comments
 (0)