twitter-api.ts 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. import { Injectable } from "@angular/core";
  2. import { HttpClient } from "@angular/common/http";
  3. import { Storage } from "@ionic/storage";
  4. import Twit from "twit";
  5. @Injectable()
  6. export class TwitterApiProvider {
  7. client: Twit;
  8. constructor(public http: HttpClient, private storage: Storage) {
  9. this.initApi();
  10. }
  11. /**
  12. * initialize Twitter API provider
  13. */
  14. public async initApi() {
  15. const access_token_key = await this.storage.get("accessTokenKey");
  16. const access_token_secret = await this.storage.get("accessTokenSecret");
  17. if (access_token_key && access_token_secret) {
  18. this.client = new Twit({
  19. consumer_key: "UxZkbKotkr8Uc6seupnaZ1kDE",
  20. consumer_secret: "fEAas8iugR60FOEXsFG0iajq6oyfIIXRBVMlTgWxBd1stWIKHq",
  21. access_token: access_token_key,
  22. access_token_secret: access_token_secret,
  23. timeout_ms: 60 * 1000 // optional HTTP request timeout to apply to all requests.
  24. });
  25. } else {
  26. console.error(
  27. "Access Token Key and Secret not set. Creating Twit-client not possible."
  28. );
  29. console.info("This error can be ignored if no user is logged in.");
  30. }
  31. }
  32. /**
  33. * fetch home feed in batches of 20 tweets starting at maxId
  34. * @param maxId tweet id
  35. */
  36. public async fetchHomeFeed(maxId?) {
  37. const res = await this.client.get("statuses/home_timeline", {
  38. count: 20,
  39. include_entities: true,
  40. tweet_mode: "extended",
  41. max_id: maxId
  42. });
  43. return res.data;
  44. }
  45. /**
  46. * fetch user object to given id
  47. * @param userId user id
  48. */
  49. public async fetchUser(userId) {
  50. const res = await this.client.get("users/show", { user_id: userId });
  51. return res.data;
  52. }
  53. /**
  54. * lookup user for screenname
  55. */
  56. public async fetchUserFromScreenName(screenName) {
  57. const res = await this.client.get("users/lookup", {
  58. screen_name: screenName
  59. });
  60. return res.data;
  61. }
  62. /**
  63. * fetch user feed in batches of 20 tweets starting at maxId
  64. * @param userId user id
  65. * @param maxId max tweet id
  66. */
  67. public async fetchUserTimeline(userId, maxId?) {
  68. try {
  69. const res = await this.client.get("statuses/user_timeline", {
  70. user_id: userId,
  71. max_id: maxId,
  72. include_entities: true,
  73. tweet_mode: "extended",
  74. count: 20
  75. });
  76. return res.data;
  77. } catch (e) {
  78. console.error(e);
  79. return [];
  80. }
  81. }
  82. /**
  83. * Follow user
  84. * @param userId user id
  85. */
  86. public async createFriendship(userId) {
  87. return await this.client.post("friendships/create", { user_id: userId });
  88. }
  89. /**
  90. * Unfollow user
  91. * @param userId user id
  92. */
  93. public async destroyFriendship(userId) {
  94. return await this.client.post("friendships/destroy", { user_id: userId });
  95. }
  96. /**
  97. * Mute user
  98. * @param userId user id
  99. */
  100. public async muteUser(userId) {
  101. return await this.client.post("mutes/users/create", { user_id: userId });
  102. }
  103. /**
  104. * Unmute user
  105. * @param userId user id
  106. */
  107. public async unmuteUser(userId) {
  108. return await this.client.post("mutes/users/destroy", { user_id: userId });
  109. }
  110. /**
  111. * Block user
  112. * @param userId user id
  113. */
  114. public async blockUser(userId) {
  115. return await this.client.post("blocks/create", { user_id: userId });
  116. }
  117. /**
  118. * Unblock user
  119. * @param userId user id
  120. */
  121. public async unblockUser(userId) {
  122. return await this.client.post("blocks/destroy", { user_id: userId });
  123. }
  124. /**
  125. * Post tweet
  126. * @param status tweet message
  127. * @param retweet tweet object to retweet
  128. * @param replyToStatusId tweet id to reply to
  129. */
  130. public async tweet(status, retweet?, replyToStatusId?) {
  131. if (status.length === 0 && retweet) {
  132. // Simple retweet
  133. return await this.client.post("statuses/retweet", {
  134. id: retweet.data.id_str
  135. });
  136. } else if (!retweet) {
  137. // Simple tweet
  138. return await this.client.post("statuses/update", {
  139. status: status,
  140. in_reply_to_status_id: replyToStatusId
  141. });
  142. } else if (status.length > 0 && retweet) {
  143. // Quoted tweet
  144. const url =
  145. "https://twitter.com/" +
  146. retweet.data.user.screen_name +
  147. "/status/" +
  148. retweet.data.id_str;
  149. return await this.client.post("statuses/update", {
  150. status: status,
  151. attachment_url: url
  152. });
  153. } else {
  154. return;
  155. }
  156. }
  157. /**
  158. * Fetch friends for user id
  159. * @param userId user id
  160. */
  161. public async fetchFriends(userId) {
  162. let friends = [];
  163. let cursor = -1;
  164. while (cursor != 0) {
  165. const res = await this.client.get("friends/list", {
  166. user_id: userId,
  167. count: 200,
  168. include_user_entities: false,
  169. cursor: cursor
  170. });
  171. cursor = res.data["next_cursor"];
  172. friends = friends.concat(res.data["users"]);
  173. }
  174. return friends;
  175. }
  176. /**
  177. * Like tweet
  178. * @param tweetId tweet id
  179. */
  180. public async likeTweet(tweetId) {
  181. return await this.client.post("favorites/create", { id: tweetId });
  182. }
  183. /**
  184. * Remove like from tweet
  185. * @param tweetId tweet id
  186. */
  187. public async unlikeTweet(tweetId) {
  188. return await this.client.post("favorites/destroy", { id: tweetId });
  189. }
  190. /**
  191. * Retrieve a single tweet
  192. * @param tweetId tweet id
  193. */
  194. public async fetchTweet(tweetId) {
  195. return await this.client.get("statuses/show", {
  196. id: tweetId,
  197. tweet_mode: "extended"
  198. });
  199. }
  200. /**
  201. * Search Twitter for recent tweets
  202. * Since the results are loaded in batches of 20 tweets, max tweet id is a reference for the next batch
  203. * @param keyword keyword
  204. * @param maxId max tweet id
  205. */
  206. public async searchRecentTweets(keyword: string, maxId?: string) {
  207. const res = await this.client.get("search/tweets", {
  208. q: keyword,
  209. result_type: "recent",
  210. count: 20,
  211. include_entities: true,
  212. tweet_mode: "extended",
  213. max_id: maxId
  214. });
  215. return res.data;
  216. }
  217. /**
  218. * Search Twitter for popular tweets
  219. * Since the results are loaded in batches of 20 tweets, max tweet id is a reference for the next batch
  220. * @param keyword keyword
  221. * @param maxId max tweet id
  222. */
  223. public async searchPopularTweets(keyword: string, maxId?: string) {
  224. const res = await this.client.get("search/tweets", {
  225. q: keyword,
  226. result_type: "popular",
  227. count: 20,
  228. include_entities: true,
  229. tweet_mode: "extended",
  230. max_id: maxId
  231. });
  232. return res.data;
  233. }
  234. /**
  235. * Search Twitter for users
  236. * Since the API returns users paginated, a page has to be provided
  237. * @param keyword keyword
  238. * @param page page number
  239. */
  240. public async searchUsers(keyword: string, page?: number) {
  241. const res = await this.client.get("users/search", {
  242. q: keyword,
  243. count: 10,
  244. include_entities: true,
  245. page: page
  246. });
  247. return res.data;
  248. }
  249. /**
  250. * Updates the profile description
  251. * @param description profile description
  252. */
  253. public async updateProfileDescription(description: string) {
  254. const res = await this.client.post("account/update_profile", {
  255. description: description
  256. });
  257. return res.data;
  258. }
  259. }