5.8 KiB
5.8 KiB
+++ date = "2022-02-06" tags = ["rust", "mastodon"] title = "mammutのexampleをまとめてみる" slug = "rust-mammut" +++
mastodon apiのrust libであるmammutですが、exampleがあるとわかりやすいと思ったので、作ってみました。
まず、mastodonへのrequestはこんな感じになります。
curl -H "Content-Type: application/json" -X POST -Ss https://$host/oauth/token \
-d "{
\"client_id\": \"$client_id\",
\"client_secret\": \"$client_secret\",
\"grant_type\": \"password\",
\"username\": \"$username\",
\"password\": \"$password\",
\"scope\": \"$scope\"
}"
mammutではData
として認証に必要な要素がまとめられてますので、各種要素を入れてMastodon::from_data(data)
すると認証できます。
[package]
name = "test"
version = "0.0.1"
[dependencies]
dotenv = "0.15"
mammut = "0.13.0"
extern crate mammut;
extern crate dotenv;
use std::env;
use mammut::{Data, Mastodon};
fn main() -> mammut::Result<()> {
let data = Data {
base: env::var("BASE").unwrap().into(),
client_id: env::var("CLIENT_ID").unwrap().into(),
client_secret: env::var("CLIENT_SECRET").unwrap().into(),
redirect: env::var("REDIRECT").unwrap().into(),
token: env::var("TOKEN").unwrap().into(),
};
let mastodon = Mastodon::from_data(data);
let t = mastodon.verify_credentials();
println!("{:?}", t);
Ok(())
}
export TOKEN=''
export CLIENT_ID=''
export CLIENT_SECRET=''
export REDIRECT=''
export BASE='https://mstdn.syui.ai'
$ cargo run
$ ./target/debug/test
Data : https://docs.rs/mammut/latest/mammut/struct.Data.html
src/data
ちなみに、struct Data
はmammutが用意してるので、作る必要がありませんが、ファイルを分けて、何度も呼び出す場合、下記のようになります。env
をやめてconfig
にtokenなどを書いて読み込む例です。
なお、edition
を2021
にすることで、様々な記法を省略できたりします。
[package]
name = "test"
version = "0.0.1"
edition = "2021"
[dependencies]
dotenv = "0.15"
mammut = "0.13.0"
serde_derive = "*"
serde = "*"
config = { git = "https://github.com/mehcode/config-rs", branch = "master" }
use config::{Config, ConfigError, File};
use serde_derive::Deserialize;
use std::borrow::Cow;
#[derive(Debug, Deserialize)]
#[allow(unused)]
pub struct Data {
pub base: Cow<'static, str>,
pub token: Cow<'static, str>,
pub client_id: Cow<'static, str>,
pub client_secret: Cow<'static, str>,
pub redirect: Cow<'static, str>,
}
impl Data {
pub fn new() -> Result<Self, ConfigError> {
let s = Config::builder()
.add_source(File::with_name("config"))
.build()?;
s.try_deserialize()
}
}
pub mod data;
use data::Data as Datas;
use mammut::{Data, Mastodon};
fn token() -> Mastodon {
let data = Datas::new().unwrap();
let data = Data {
base: data.base,
token: data.token,
client_id: data.client_id,
client_secret: data.client_secret,
redirect: data.redirect,
};
let t = Mastodon::from_data(data);
return t;
}
fn main() {
let mastodon = token();
let t = mastodon.verify_credentials();
println!("{:#?}", t);
}
token = ""
client_id = ""
client_secret = ""
redirect = "localhost"
base = "https://mstdn.syui.ai"
$ cargo run
home dir
ここからは簡潔に紹介します。
$HOME
を使うにはshellexpand
が便利です。
[dependencies]
shellexpand = "*"
impl Data {
pub fn new() -> Result<Self, ConfigError> {
let d = shellexpand::tilde("~") + "/.config/msr/config.toml";
let s = Config::builder()
.add_source(File::with_name(&d))
.add_source(config::Environment::with_prefix("APP"))
.build()?;
s.try_deserialize()
}
}
toot post
fn post() {
let mastodon = token();
let message = "test".to_string();
let status_b = StatusBuilder::new(format!("{}", message));
let post = mastodon.new_status(status_b);
println!("{:?}", post);
}
timeline
fn timeline() -> mammut::Result<()> {
let mastodon = token();
let t = mastodon.get_home_timeline()?.initial_items;
println!("{:?}", t);
Ok(())
}
toot delete
#[allow(unused_must_use)]
fn delete() -> mammut::Result<()> {
let mastodon = token();
let id = &mastodon.get_home_timeline()?.initial_items[0].id;
mastodon.delete_status(id);
Ok(())
}
upload media
media_ids
が必要になるので、手順としては、画像をmastodonのmedia serverにuploadする処理と、その出力にあるmedia_ids
をtootとしてpostする処理が必要になります。
use mammut::{Data, Mastodon, StatusBuilder, MediaBuilder};
fn media() {
let mastodon = token();
let file = "./test.png".to_string();
let t = mastodon.media(file.into());
println!("{:?}", t);
let id = t.as_ref().unwrap();
let mid = Some(vec![id.id.to_string()]);
let status = "#media".to_string();
let status_b = StatusBuilder {
status: status,
in_reply_to_id: None,
media_ids: mid,
sensitive: None,
spoiler_text: None,
visibility: None,
};
let post = mastodon.new_status(status_b);
println!("{:?}", post);
}
}
StatusBuilder : https://docs.rs/mammut/0.11.0/mammut/status_builder/struct.StatusBuilder.html
text
も同時に投稿するのはこっち。
use std::borrow::Cow;
let text = "test";
let s = Cow::Owned(String::from(text));
let status_b = StatusBuilder {
status: s,
in_reply_to_id: None,
media_ids: mid,
sensitive: None,
spoiler_text: None,
visibility: None,
};