Webサービス
個人開発

twitter仲間募集サービス「BOOSHOO」を作る時に考えた色々(その1)

この記事の目的

webサービスを作るときに色々考えたこと、具体的にはなぜその仕様にしたのか?をまとめる。ちなみに自分は普段はエンジニアではないがこの記事のようにディレクションする上で技術も知ってたほうがいいなあと思って個人開発を始めました。文系職が開発するにあたって準備した内容は下記記事に。

「【1週間ブートキャンプ】文系職が夏休みを使ってプログラミングを覚えた話」
http://you88.space/103

サービス概要

twitterでの友達をもっと増やしたいのでこういう人相互フォローしてくださいという募集ページとそこ経由でフォローしてくれた人を補足するサービスを作れば相互フォローのtwitter友達が増えるなあと思って作ることにした。

BOOSHOO
http://www.booshoo.net/

個人開発者仲間に相談しながら一緒に作るスタイル

今回試したかったのが他の人ってどんな考え方をしながら開発しているのか知りたかったので個人開発者のコミュニティでレビューしてもらいながら作った。もちろん全部皆の意見を聞くわけではないが多角的にサービスを見れて良かった。

ユーザーフロー

  • twitterで認証
  • 募集文の投稿
  • フォローされたら通知
  • 通知がきたユーザーをフォローして相互フォロー

仕様

  • twitter認証
  • 募集文の投稿
  • 募集文経由でフォローした際にサービス内でユーザーに通知

twitter認証

「OmniAuthを利用して、Twitterログイン機能を作る【初心者向け】」
https://qiita.com/To_BB/items/01863aa50d628c069b64

上記を参考にして実装。userは下記のDB構成。

scheme.rb
  create_table "users", force: :cascade do |t|
    t.string "provider"
    t.string "uid"
    t.string "nickname"
    t.string "image_url"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

将来的にはtwitter以外の認証が付く可能性があるのでユーザーの判別はuidではなくidにした。

募集文の投稿機能

scheme.rb
  create_table "posts", force: :cascade do |t|
    t.integer "user_id"
    t.text "content"
    t.text "title"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

募集文をpostするtableは上記の構成。

フォローしてくれたユーザーを通知→フォローリスト作成

募集を出してフォローしてくれたユーザーが出た場合、通知をして相互フォローしてもらおうと思ったがtwitterへのnotificationはできないので諦めた。変わりにフォローしてくれたユーザーのリストを作成。listページを作成し、ログインユーザーのポストをまず展開し、そのポストそれぞれのフォローユーザーをリスト化した。

フォローリストでやる値の受け渡し方

  • current_user(ログイン中のユーザー)に投稿したポストがないかを見る
  • そのpostに紐付いたフォロワーがいないかをfollow_usersから探す
  • そのfollow_usersを並べる

実装

list/top.html.erb
<%
current_user_post_ids = Post.where(user_id: @current_user.id).pluck(:id)
@current_user_posts = Post.where(id: current_user_post_ids)
@current_user_posts.each do |current_user_post|
follow_user_list = FollowUser.where(post_id: current_user_post.id)
follow_user_list_id = follow_user_list.pluck(:follow_user_id)
@follow_user = User.where(id: follow_user_list_id)
%>
<div class="row">
  <h2 class="col-xs-12 col-md-12 list_post_title">
    <%= current_user_post.title %>
  </h2>
</div><!--row-->
<div class="row">
  <div class="col-xs-12 col-md-12">
    <%= render "layouts/follow_user_list" %>
  </div><!--12-->
</div><!--row-->
<% end %>
<% if @current_user_posts.count == 0 %>
<div class="row">
  <div class="col-xs-6 col-md-6">
    <div class="card">
      <%= image_tag("boshu.png", :alt => "Card image cap", :class => "card-img-top") %>
      <div class="card-body">
        <p class="card-text">
          まだあなたの募集がありません。新規作成してtweetしよう!
        </p><!--card-text-->
      </div><!--card-body-->
    </div><!--card-->
  </div><!--6-->
</div><!--row-->
<% end %>
_follow_user_list.html.erb
<ul class="list-group">
  <% @follow_user.each do |follow_user| %>
  <li class="list-group-item d-flex justify-content-between align-items-center">
    <img src="<%= follow_user.image_url %>"/>
    <a href="https://twitter.com/intent/user?user_id=<%= follow_user.uid %>">
    <%= follow_user.nickname %>
    </a>
    <a href="/list/<%= follow_user.uid %>/follow">
    <button type="button" class="btn btn-primary" data-toggle="button" aria-pressed="false" autocomplete="off">
      相互follow
    </button>
    </a>
  </li>
  <% end %>
</ul>

twitterでのtweet文

どんな伸ばし方があり得るか?

twitterの〜な人募集とか相互フォロー募集とかを取りたいなと思っているので基本はtwitterの検索をうまく拾えるかだと考えている。ってかタイムラインは基本フォロー済みの人ばかり見ると思うので検索されないと難しい。

なので文章にデフォルトでハッシュタグを入れるのは重要だと思う。逆にhomeに一覧を表示させていないのはtweetしないと誰にも見られないという状態にしたほうがtweetが促されるなと思ってそういう仕様に。

開発者同士で話してでた話題

homeに他の人の募集を出すべきか?

  • homeに最新だしても閲覧者とのマッチング率は低い
  • tweetしないと露出しないようにしてtweetを促したい

などの理由でhomeに他人の募集一覧を出すのはやめた。ただどんな投稿すればいいのかわかりにくいので例を1つ表示。この例をハードコードで実装しようとしたけど今後詳細ページの仕様変わったりしたときに面倒なので一つだけfind_byで取ってきて表示する形に

ログイン後のフローの改善

未ログインで詳細ページにいってフォローをしようとすると下記のフロー

  • 詳細ページ
  • ログイン
  • homeに飛ぶ
  • 詳細ページ

になっていたので下記の実装で

  • 詳細ページ
  • ログイン
  • 詳細ページ

https://qiita.com/azusanakano/items/8af1266f53a656ef787d

twitterログイン挟むとうまくredirect_backがきかなかった。

付けたい機能

OGPを画像生成して募集内容テキストを入れる

本当はtwitterでシェアした際にogpに文字情報入ってたほうがいいなと思うがそこまで実装コストをかけたくないので一旦保留。